]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/dbmlib.php
Reverted to version 1.4; there is a bug in Jan Hidders' patch for dbmlib.
[SourceForge/phpwiki.git] / lib / dbmlib.php
1 <?php  
2
3    rcs_id('$Id: dbmlib.php,v 1.6 2001-01-09 19:02:52 wainstead Exp $');
4
5    /*
6       Database functions:
7
8       OpenDataBase($dbname) 
9       CloseDataBase($dbi) 
10       PadSerializedData($data) 
11       UnPadSerializedData($data) 
12       RetrievePage($dbi, $pagename, $pagestore) 
13       InsertPage($dbi, $pagename, $pagehash) 
14       SaveCopyToArchive($dbi, $pagename, $pagehash) 
15       IsWikiPage($dbi, $pagename) 
16       IsInArchive($dbi, $pagename) 
17       InitTitleSearch($dbi, $search) 
18       TitleSearchNextMatch($dbi, &$pos) 
19       InitFullSearch($dbi, $search) 
20       FullSearchNextMatch($dbi, &$pos) 
21       IncreaseHitCount($dbi, $pagename) 
22       GetHitCount($dbi, $pagename) 
23       InitMostPopular($dbi, $limit) 
24       MostPopularNextMatch($dbi, &$res) 
25       GetAllWikiPagenames($dbi) 
26    */
27
28
29    // open a database and return the handle
30    // loop until we get a handle; php has its own
31    // locking mechanism, thank god.
32    // Suppress ugly error message with @.
33
34    function OpenDataBase($dbname) {
35       global $WikiDB; // hash of all the DBM file names
36
37       reset($WikiDB);
38       while (list($key, $file) = each($WikiDB)) {
39          while (($dbi[$key] = @dbmopen($file, "c")) < 1) {
40             $numattempts++;
41             if ($numattempts > MAX_DBM_ATTEMPTS) {
42                ExitWiki("Cannot open database '$key' : '$file', giving up.");
43             }
44             sleep(1);
45          }
46       }
47       return $dbi;
48    }
49
50
51    function CloseDataBase($dbi) {
52       reset($dbi);
53       while (list($dbmfile, $dbihandle) = each($dbi)) {
54          dbmclose($dbihandle);
55       }
56       return;
57    }
58
59
60    // take a serialized hash, return same padded out to
61    // the next largest number bytes divisible by 500. This
62    // is to save disk space in the long run, since DBM files
63    // leak memory.
64    function PadSerializedData($data) {
65       // calculate the next largest number divisible by 500
66       $nextincr = 500 * ceil(strlen($data) / 500);
67       // pad with spaces
68       $data = sprintf("%-${nextincr}s", $data);
69       return $data;
70    }
71
72    // strip trailing whitespace from the serialized data 
73    // structure.
74    function UnPadSerializedData($data) {
75       return chop($data);
76    }
77
78
79
80    // Return hash of page + attributes or default
81    function RetrievePage($dbi, $pagename, $pagestore) {
82       if ($data = dbmfetch($dbi[$pagestore], $pagename)) {
83          // unserialize $data into a hash
84          $pagehash = unserialize(UnPadSerializedData($data));
85          return $pagehash;
86       } else {
87          return -1;
88       }
89    }
90
91
92    // Either insert or replace a key/value (a page)
93    function InsertPage($dbi, $pagename, $pagehash) {
94       $pagedata = PadSerializedData(serialize($pagehash));
95
96       if (dbminsert($dbi['wiki'], $pagename, $pagedata)) {
97          if (dbmreplace($dbi['wiki'], $pagename, $pagedata)) {
98             ExitWiki("Error inserting page '$pagename'");
99          }
100       } 
101    }
102
103
104    // for archiving pages to a seperate dbm
105    function SaveCopyToArchive($dbi, $pagename, $pagehash) {
106       global $ArchivePageStore;
107
108       $pagedata = PadSerializedData(serialize($pagehash));
109
110       if (dbminsert($dbi[$ArchivePageStore], $pagename, $pagedata)) {
111          if (dbmreplace($dbi['archive'], $pagename, $pagedata)) {
112             ExitWiki("Error storing '$pagename' into archive");
113          }
114       } 
115    }
116
117
118    function IsWikiPage($dbi, $pagename) {
119       return dbmexists($dbi['wiki'], $pagename);
120    }
121
122
123    function IsInArchive($dbi, $pagename) {
124       return dbmexists($dbi['archive'], $pagename);
125    }
126
127
128    // setup for title-search
129    function InitTitleSearch($dbi, $search) {
130       $pos['search'] = $search;
131       $pos['key'] = dbmfirstkey($dbi['wiki']);
132
133       return $pos;
134    }
135
136    // iterating through database
137    function TitleSearchNextMatch($dbi, &$pos) {
138       while ($pos['key']) {
139          $page = $pos['key'];
140          $pos['key'] = dbmnextkey($dbi['wiki'], $pos['key']);
141
142          if (eregi($pos['search'], $page)) {
143             return $page;
144          }
145       }
146       return 0;
147    }
148
149    // setup for full-text search
150    function InitFullSearch($dbi, $search) {
151       return InitTitleSearch($dbi, $search);
152    }
153
154    //iterating through database
155    function FullSearchNextMatch($dbi, &$pos) {
156       while ($pos['key']) {
157          $key = $pos['key'];
158          $pos['key'] = dbmnextkey($dbi['wiki'], $pos['key']);
159
160          $pagedata = dbmfetch($dbi['wiki'], $key);
161          // test the serialized data
162          if (eregi($pos['search'], $pagedata)) {
163             $page['pagename'] = $key;
164             $pagedata = unserialize(UnPadSerializedData($pagedata));
165             $page['content'] = $pagedata['content'];
166             return $page;
167          }
168       }
169       return 0;
170    }
171
172    ////////////////////////
173    // new database features
174
175
176    function IncreaseHitCount($dbi, $pagename) {
177
178       if (dbmexists($dbi['hitcount'], $pagename)) {
179          // increase the hit count
180          // echo "$pagename there, incrementing...<br>\n";
181          $count = dbmfetch($dbi['hitcount'], $pagename);
182          $count++;
183          dbmreplace($dbi['hitcount'], $pagename, $count);
184       } else {
185          // add it, set the hit count to one
186          // echo "adding $pagename to hitcount...<br>\n";
187          $count = 1;
188          dbminsert($dbi['hitcount'], $pagename, $count);
189       }
190    }
191
192    function GetHitCount($dbi, $pagename) {
193
194       if (dbmexists($dbi['hitcount'], $pagename)) {
195          // increase the hit count
196          $count = dbmfetch($dbi['hitcount'], $pagename);
197          return $count;
198       } else {
199          return 0;
200       }
201    }
202
203
204    function InitMostPopular($dbi, $limit) {
205       // iterate through the whole dbm file for hit counts
206       // sort the results highest to lowest, and return 
207       // n..$limit results
208
209       $pagename = dbmfirstkey($dbi['hitcount']);
210       $res[$pagename] = dbmfetch($dbi['hitcount'], $pagename);
211
212       while ($pagename = dbmnextkey($dbi['hitcount'], $pagename)) {
213          $res[$pagename] = dbmfetch($dbi['hitcount'], $pagename);
214          //echo "got $pagename with value " . $res[$pagename] . "<br>\n";
215       }
216
217       arsort($res);
218       return($res);
219    }
220
221    function MostPopularNextMatch($dbi, &$res) {
222
223       // the return result is a two element array with 'hits'
224       // and 'pagename' as the keys
225
226       if (count($res) == 0)
227          return 0;
228
229       if (list($pagename, $hits) = each($res)) {
230          //echo "most popular next match called<br>\n";
231          //echo "got $pagename, $hits back<br>\n";
232          $nextpage = array(
233             "hits" => $hits,
234             "pagename" => $pagename
235          );
236          // $dbm_mostpopular_cntr++;
237          return $nextpage;
238       } else {
239          return 0;
240       }
241    } 
242
243    function GetAllWikiPagenames($dbi) {
244       $namelist = array();
245       $ctr = 0;
246
247       $namelist[$ctr] = $key = dbmfirstkey($dbi);
248
249       while ($key = dbmnextkey($dbi, $key)) {
250          $ctr++;
251          $namelist[$ctr] = $key;
252       }
253
254       return $namelist;
255    }
256
257 ?>