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.
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
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.
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).
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!)
34 #-- plugin registration
35 $ewiki_plugins["database"][0] = "ewiki_database_dba";
40 class ewiki_database_dba {
43 var $gz = EWIKI_DBFILES_GZLEVEL;
45 function ewiki_database_dba() {
46 $this->handle = ewiki_database_dba::CONNECT(EWIKI_DBA);
51 function GET($id, $version=false) {
52 if (!$version && !($version = $this->LASTVER($id))) {
55 if ($r = dba_fetch("$id.$version", $this->handle)) {
56 if ($uu = gzuncompress($r)) {
60 if ($r = unserialize($r)) {
67 function WRITE($hash, $overwrite=0) {
68 $key = $hash["id"].".".$hash["version"];
69 $ex = dba_exists($key, $this->handle);
70 if (!$overwrite && $ex) {
73 $hash = serialize($hash);
75 $hash = gzcompress($hash, $this->gz);
78 $r = dba_replace($key, $hash, $this->handle);
80 $r = dba_insert($key, $hash, $this->handle);
88 if ($r = unserialize(gzuncompress(dba_fetch($key, $this->handle)))) {
90 dba_replace($key, gzcompress(serialize($r), $this->gz), $this->handle);
95 function FIND($list) {
97 foreach ($list as $id) {
98 if (dba_exists("$id.1", $this->handle) || $this->LASTVER($id)) {
100 if (EWIKI_DBFF_ACCURATE) {
101 $row = $this->GET($id);
103 $r[$id] = $row["meta"];
104 $r[$id]["flags"] = $row["flags"];
106 $r[$id] = $row["flags"];
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);
125 function SEARCH($field, $content, $ci="i", $regex=0, $mask=0, $filter=0) {
126 if ($ci && !$regex) {
127 $content = strtolower($content);
129 $r = new ewiki_dbquery_result(array($field));
130 foreach ($this->ALLFILES() as $id) {
131 $page = ewiki_db::GET($id);
133 $check = preg_match("\007$content\007$ci", $page[$field]);
136 $check = strpos(strtolower($page[$field]), $content)!==false;
139 $check = strpos($page[$field], $content)!==false;
149 function DELETE($id, $version) {
150 dba_delete("$id.$version", $this->handle);
155 if (!$this->handle) {
156 die("dba database not writable!\n");
161 //@FIXME: uh, oh, bad
162 // but everything else would be VERY VERY slow
163 function LASTVER($id) {
165 while (dba_exists("$id.$n", $this->handle)) {
172 function ALLFILES() {
173 $id = dba_firstkey($this->handle);
174 while ($id != false) {
175 $p = strrpos($id, ".");
176 $id = substr($id, 0, $p);
178 $id = dba_nextkey($this->handle);
180 $r = array_values($r);
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);
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), ";
198 $handle = dba_open($dba_file, "w", $dba_handler);