]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/dbalib.php
log
[SourceForge/phpwiki.git] / lib / dbalib.php
1 <?php  
2
3    rcs_id('$Id: dbalib.php,v 1.3 2001-02-12 01:43:10 dairiki 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 // Initialize our globals:
30 function _dbname($base)
31 {
32   extract($GLOBALS['DBParams']);
33   return "$directory/${database}${prefix}${base}";
34 }
35
36 $WikiPageStore = "wiki";
37 $ArchivePageStore = "archive";
38 $WikiDB = array('wiki'          => _dbname('pagesdb'),
39                 'archive'       => _dbname('archivedb'),
40                 'wikilinks'     => _dbname('linksdb'),
41                 'hottopics'     => _dbname('hottopicsdb'),
42                 'hitcount'      => _dbname('hitcountdb'));
43
44 if (preg_match('@%/tmp\b@', $DBParams['directory']))
45    $DBWarning = "DBA files are in the /tmp directory.";
46
47 define('MAX_DBM_ATTEMPTS', $DBParams['timeout']);
48    
49    // open a database and return the handle
50    // loop until we get a handle; php has its own
51    // locking mechanism, thank god.
52    // Suppress ugly error message with @.
53
54    function OpenDataBase($dbname) {
55       global $WikiDB; // hash of all the DBM file names
56
57       reset($WikiDB);
58       while (list($key, $file) = each($WikiDB)) {
59          while (($dbi[$key] = @dba_open($file, "c", "gdbm")) < 1) {
60             $numattempts++;
61             if ($numattempts > MAX_DBM_ATTEMPTS) {
62                ExitWiki("Cannot open database '$key' : '$file', giving up.");
63             }
64             sleep(1);
65          }
66       }
67       return $dbi;
68    }
69
70
71    function CloseDataBase($dbi) {
72       reset($dbi);
73       while (list($dbmfile, $dbihandle) = each($dbi)) {
74          dba_close($dbihandle);
75       }
76       return;
77    }
78
79
80    // take a serialized hash, return same padded out to
81    // the next largest number bytes divisible by 500. This
82    // is to save disk space in the long run, since DBM files
83    // leak memory.
84    function PadSerializedData($data) {
85       // calculate the next largest number divisible by 500
86       $nextincr = 500 * ceil(strlen($data) / 500);
87       // pad with spaces
88       $data = sprintf("%-${nextincr}s", $data);
89       return $data;
90    }
91
92    // strip trailing whitespace from the serialized data 
93    // structure.
94    function UnPadSerializedData($data) {
95       return chop($data);
96    }
97
98    // Return hash of page + attributes or default
99    function RetrievePage($dbi, $pagename, $pagestore) {
100       if ($data = dba_fetch($pagename, $dbi[$pagestore])) {
101          // unserialize $data into a hash
102          $pagehash = unserialize(UnPadSerializedData($data));
103          return $pagehash;
104       } else {
105          return -1;
106       }
107    }
108
109    // Either insert or replace a key/value (a page)
110    function InsertPage($dbi, $pagename, $pagehash) {
111       $pagedata = PadSerializedData(serialize($pagehash));
112
113       if (!dba_insert($pagename, $pagedata, $dbi['wiki'])) {
114          if (!dba_replace($pagename, $pagedata, $dbi['wiki'])) {
115             ExitWiki("Error inserting page '$pagename'");
116          }
117       } 
118    }
119
120
121    // for archiving pages to a seperate dbm
122    function SaveCopyToArchive($dbi, $pagename, $pagehash) {
123       global $ArchivePageStore;
124
125       $pagedata = PadSerializedData(serialize($pagehash));
126
127       if (!dba_insert($pagename, $pagedata, $dbi[$ArchivePageStore])) {
128          if (!dba_replace($pagename, $pagedata, $dbi['archive'])) {
129             ExitWiki("Error storing '$pagename' into archive");
130          }
131       } 
132    }
133
134
135    function IsWikiPage($dbi, $pagename) {
136       return dba_exists($pagename, $dbi['wiki']);
137    }
138
139
140    function IsInArchive($dbi, $pagename) {
141       return dba_exists($pagename, $dbi['archive']);
142    }
143
144
145    // setup for title-search
146    function InitTitleSearch($dbi, $search) {
147       $pos['search'] = $search;
148       $pos['key'] = dba_firstkey($dbi['wiki']);
149
150       return $pos;
151    }
152
153    // iterating through database
154    function TitleSearchNextMatch($dbi, &$pos) {
155       while ($pos['key']) {
156          $page = $pos['key'];
157          $pos['key'] = dba_nextkey($dbi['wiki']);
158
159          if (eregi($pos['search'], $page)) {
160             return $page;
161          }
162       }
163       return 0;
164    }
165
166    // setup for full-text search
167    function InitFullSearch($dbi, $search) {
168       return InitTitleSearch($dbi, $search);
169    }
170
171    //iterating through database
172    function FullSearchNextMatch($dbi, &$pos) {
173       while ($pos['key']) {
174          $key = $pos['key'];
175          $pos['key'] = dba_nextkey($dbi['wiki']);
176
177          $pagedata = dba_fetch($key, $dbi['wiki']);
178          // test the serialized data
179          if (eregi($pos['search'], $pagedata)) {
180             $page['pagename'] = $key;
181             $pagedata = unserialize(UnPadSerializedData($pagedata));
182             $page['content'] = $pagedata['content'];
183             return $page;
184          }
185       }
186       return 0;
187    }
188
189    ////////////////////////
190    // new database features
191
192
193    function IncreaseHitCount($dbi, $pagename) {
194
195       if (dba_exists($pagename, $dbi['hitcount'])) {
196          // increase the hit count
197          // echo "$pagename there, incrementing...<br>\n";
198          $count = dba_fetch($pagename, $dbi['hitcount']);
199          $count++;
200          dba_replace($pagename, $count, $dbi['hitcount']);
201       } else {
202          // add it, set the hit count to one
203          // echo "adding $pagename to hitcount...<br>\n";
204          $count = 1;
205          dba_insert($pagename, $count, $dbi['hitcount']);
206       }
207    }
208
209    function GetHitCount($dbi, $pagename) {
210
211       if (dba_exists($pagename, $dbi['hitcount'])) {
212          // increase the hit count
213          $count = dba_fetch($pagename, $dbi['hitcount']);
214          return $count;
215       } else {
216          return 0;
217       }
218    }
219
220
221    function InitMostPopular($dbi, $limit) {
222       // iterate through the whole dbm file for hit counts
223       // sort the results highest to lowest, and return 
224       // n..$limit results
225
226       $pagename = dba_firstkey($dbi['hitcount']);
227       $res[$pagename] = dba_fetch($pagename, $dbi['hitcount']);
228
229       while ($pagename = dba_nextkey($dbi['hitcount'])) {
230          $res[$pagename] = dba_fetch($pagename, $dbi['hitcount']);
231          //echo "got $pagename with value " . $res[$pagename] . "<br>\n";
232       }
233
234       arsort($res);
235       return($res);
236    }
237
238    function MostPopularNextMatch($dbi, &$res) {
239
240       // the return result is a two element array with 'hits'
241       // and 'pagename' as the keys
242
243       if (count($res) == 0)
244          return 0;
245
246       if (list($pagename, $hits) = each($res)) {
247          //echo "most popular next match called<br>\n";
248          //echo "got $pagename, $hits back<br>\n";
249          $nextpage = array(
250             "hits" => $hits,
251             "pagename" => $pagename
252          );
253          // $dbm_mostpopular_cntr++;
254          return $nextpage;
255       } else {
256          return 0;
257       }
258    } 
259
260    function GetAllWikiPagenames($dbi) {
261       $namelist = array();
262       $ctr = 0;
263
264       $namelist[$ctr] = $key = dba_firstkey($dbi);
265
266       while ($key = dba_nextkey($dbi)) {
267          $ctr++;
268          $namelist[$ctr] = $key;
269       }
270
271       return $namelist;
272    }
273
274 // For emacs users
275 // Local Variables:
276 // mode: php
277 // c-file-style: "ellemtel"
278 // End:   
279 ?>