changed git call from https to git readonly
[atutor.git] / mods / wiki / plugins / db / dba.php
1 <?php
2
3 ## This database plugin utilizes PHPs "dba" extension. You can also use
4 #  the older and now deprecated "dbm" extension, if you just load the
5 #  plugins/lib/fakedba.php sript.
6 #
7 ## Unlike the flat file databases all data is stored in one binary file,
8 #  as defined by the EWIKI_DBA constant. The filename extension of this
9 #  tells which dba database type to use:
10 #   - .flatfile      almost always supported by PHP, recommended
11 #   - .db3           most wide-spread variant
12 #   - .db2           is also still in wide use
13 #   - .gdbm          from the GNU project
14 #   - .db4 or .db5   if you have enough memory to waste
15 #   - .ndbm          also not the best
16 #   - .dbm           very old format (the original BerkelyDB)
17 #   - .inifile       is not binary safe, avoid or disable compression
18 #
19 ## That database file will get opened automatically when needed (unlike
20 #  most other ewiki db interfaces). EWIKI_DBFILES_GZLEVEL says how much
21 #  time to spend on compressing the pages content.
22 #
23 ## Try to avoid any BDB variants from Sleepycat - they haven't managed to
24 #  get something backwards compatible until today, and each version sucks
25 #  more memory. Use .flatfile if you can, because it is supported by all
26 #  PHP versions (regardless of how the interpreter was compiled).
27
28
29 #-- config
30 // define("EWIKI_DBA", "/tmp/mywiki.flatfile");  // or use extension .db2
31 // define("EWIKI_DBFILES_GZLEVEL", 0);   // if you want .inifile format (this is not binary safe - also disable image upload then!)
32
33
34 #-- plugin registration
35 $ewiki_plugins["database"][0] = "ewiki_database_dba";
36
37
38
39 #-- backend
40 class ewiki_database_dba {
41
42    var $handle = false;
43    var $gz = EWIKI_DBFILES_GZLEVEL;
44
45    function ewiki_database_dba() {
46       $this->handle = ewiki_database_dba::CONNECT(EWIKI_DBA);
47    }
48
49
50
51    function GET($id, $version=false) {
52       if (!$version && !($version = $this->LASTVER($id))) {
53          return;
54       }
55       if ($r = dba_fetch("$id.$version", $this->handle)) {
56          if ($uu = gzuncompress($r)) {
57             $r = $uu;
58             unset($uu);
59          }
60          if ($r = unserialize($r)) {
61             return($r);
62          }
63       }
64    }
65
66
67    function WRITE($hash, $overwrite=0) {
68       $key = $hash["id"].".".$hash["version"];
69       $ex = dba_exists($key, $this->handle);
70       if (!$overwrite && $ex) {
71          return;
72       }
73       $hash = serialize($hash);
74       if ($this->gz) {
75          $hash = gzcompress($hash, $this->gz);
76       }
77       if ($ex) {
78          $r = dba_replace($key, $hash, $this->handle);
79       } else {
80          $r = dba_insert($key, $hash, $this->handle);
81       }
82       return($r);
83    }
84
85
86    function HIT($id) {
87       $key = "$id.1";
88       if ($r = unserialize(gzuncompress(dba_fetch($key, $this->handle)))) {
89          $r["hits"] += 1;
90          dba_replace($key, gzcompress(serialize($r), $this->gz), $this->handle);
91       }
92    }
93
94
95    function FIND($list) {
96       $r = array();
97       foreach ($list as $id) {
98          if (dba_exists("$id.1", $this->handle) || $this->LASTVER($id)) {
99             $r[$id] = 1;
100             if (EWIKI_DBFF_ACCURATE) {
101                $row = $this->GET($id);
102                if ($row["meta"]) {
103                   $r[$id] = $row["meta"];
104                   $r[$id]["flags"] = $row["flags"];
105                } else {
106                   $r[$id] = $row["flags"];
107                }
108             }
109          }
110       }
111       return($r);
112    }
113
114
115    function GETALL($fields, $mask=0, $filter=0) {
116       $r = new ewiki_dbquery_result($fields);
117       foreach ($this->ALLFILES() as $id) {
118          $row = $this->GET($id);
119          $r->add($row);
120       }
121       return($r);
122    }
123
124
125    function SEARCH($field, $content, $ci="i", $regex=0, $mask=0, $filter=0) {
126       if ($ci && !$regex)  {
127          $content = strtolower($content);
128       }
129       $r = new ewiki_dbquery_result(array($field));
130       foreach ($this->ALLFILES() as $id) {
131          $page = ewiki_db::GET($id);
132          if ($regex) {
133             $check = preg_match("\007$content\007$ci", $page[$field]);
134          }
135          elseif ($ci) {
136             $check = strpos(strtolower($page[$field]), $content)!==false;
137          }
138          else {
139             $check = strpos($page[$field], $content)!==false;
140          }
141          if ($check) {
142             $r->add($page);
143          }
144       }
145       return($r);
146    }
147
148
149    function DELETE($id, $version) {
150       dba_delete("$id.$version", $this->handle);
151    }
152
153
154    function INIT() {
155       if (!$this->handle) {
156          die("dba database not writable!\n");
157       }
158    }
159
160
161 //@FIXME: uh, oh, bad
162 // but everything else would be VERY VERY slow
163    function LASTVER($id) {
164       $n = 1;
165       while (dba_exists("$id.$n", $this->handle)) {
166          $n++;
167       }
168       return(--$n);
169    }
170
171
172    function ALLFILES() {
173       $id = dba_firstkey($this->handle);
174       while ($id != false) {
175          $p = strrpos($id, ".");
176          $id = substr($id, 0, $p);
177          $r[$id] = $id;
178          $id = dba_nextkey($this->handle);
179       }
180       $r = array_values($r);
181       return($r);
182    }
183
184
185    #-- open dba connection
186    function CONNECT($dba_file) {
187       $avail = array_reverse(dba_handlers());
188       $try = substr($dba_file, strrpos($dba_file, ".") + 1);
189       $try = array_merge(array($try, "gdbm", "db7", "db3", "db2", "flatfile", "db6", "db4", "db5", "ndbm", "dbm"), $avail);
190       $handle = false;
191       foreach ($try as $dba_handler) {
192          if (in_array($dba_handler, $avail)) {
193             foreach (array("w", "c", "n") as $mode) {
194                if ($handle = dba_open($dba_file, $mode, $dba_handler)) {
195 #echo "USING($dba_handler), ";
196                   if ($mode != "w") {
197                      dba_close($handle);
198                      $handle = dba_open($dba_file, "w", $dba_handler);
199                   }
200                   break 2;
201                }
202             }
203          }
204       }
205       return($handle);
206    }
207
208
209 } // end of class
210
211
212 ?>