JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
optimize and test db_reposition_respace()
[wfpl.git] / test / db_reposition.php
1 <?php
2
3 # This program is in the public domain within the United States. Additionally,
4 # we waive copyright and related rights in the work worldwide through the CC0
5 # 1.0 Universal public domain dedication, which can be found at
6 # http://creativecommons.org/publicdomain/zero/1.0/
7
8
9 # to run this test:
10 #
11 # option 1: with wfpl-cms
12 #
13 #     set up wfpl-cms
14 #
15 #     copy/rename this file to test_db_reposition.php in your main dir
16 #
17 #     visit http://yourdomain.tld/test_db_reposition
18 #
19 #     refresh to test more times
20 #
21 #     drop the "test_db_reposition" table when you're done
22 #
23 # option 2:
24 #
25 #     require inc/wfpl/db.php
26 #     function message($msg) { print "$msg\n"; }
27 #     db_connect(...)
28 #     test_db_reposition_main()
29
30
31 function test_db_reposition_main () {
32         db_send_query(
33                 'create table if not exists test_db_reposition ('
34                 . ' id int unique auto_increment,'
35                 . ' ord int(11) not null default 0'
36                 . ')'
37         );
38         db_delete('test_db_reposition');
39         $ids = [];
40         for ($i = 0; $i < 10; ++$i) {
41                 db_insert('test_db_reposition', 'ord', $i + 1);
42                 $ids[] = db_auto_id();
43         }
44
45         $max_tests = 2000;
46         for ($tests = 0; $tests < $max_tests; ++$tests) {
47                 # decide which one to move, and to where
48                 $to = $from = rand(0, 9);
49                 while ($to === $from) {
50                         if ($tests < $max_tests / 3) {
51                                 # full range (respace rare)
52                                 $to = rand(0, 10);
53                         } elseif ($tests < $max_tests / 3 * 2) {
54                                 # never place first (respaces)
55                                 $to = rand(1, 10);
56                         } else {
57                                 # never place last (respaces)
58                                 $to = rand(0, 9);
59                         }
60                 }
61
62                 #message("from: $from (id " . $ids[$from] . "), to: $to");
63
64                 # move it in the db
65                 $new_ord = db_reposition(
66                         'test_db_reposition', # table
67                         $ids[$from], # id of row to move
68                         $to, # position to move it to (0 for first, 1 for 2nd, etc)
69                 );
70                 db_update('test_db_reposition', 'ord', $new_ord, 'where id=%i', $ids[$from]);
71
72                 # move it in our cache
73                 $moving = array_splice($ids, $from, 1);
74                 array_splice(
75                         $ids, # array to operate on
76                         ($to > $from) ? ($to - 1) : ($to), # adjust if moving into the part we moved in the first splice
77                         0, # don't delete anything
78                         $moving # insert these
79                 );
80
81                 # check if it matches
82                 if (($tests % 10) === 9) {
83                         $db_ids = db_get_column('test_db_reposition', 'id', 'order by ord');
84                         for ($i = 0; $i < 10; ++$i) {
85                                 if ($ids[$i] != $db_ids[$i]) {
86                                         message('fail');
87                                         return;
88                                 }
89                         }
90                 }
91         }
92         message("pass! $max_tests repositions checked every 10");
93 }