]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/dbalib.php
Fix the backlink code which I just broke.
[SourceForge/phpwiki.git] / lib / dbalib.php
1 <?php  
2
3    rcs_id('$Id: dbalib.php,v 1.2.2.5 2001-11-07 23:19:16 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       MakeBackLinkSearchRegexp($pagename)
22       InitBackLinkSearch($dbi, $pagename) 
23       BackLinkSearchNextMatch($dbi, &$pos) 
24       IncreaseHitCount($dbi, $pagename) 
25       GetHitCount($dbi, $pagename) 
26       InitMostPopular($dbi, $limit) 
27       MostPopularNextMatch($dbi, &$res) 
28       GetAllWikiPagenames($dbi) 
29    */
30
31
32    // open a database and return the handle
33    // loop until we get a handle; php has its own
34    // locking mechanism, thank god.
35    // Suppress ugly error message with @.
36
37    function OpenDataBase($dbname) {
38       global $WikiDB; // hash of all the DBM file names
39
40       reset($WikiDB);
41       while (list($key, $file) = each($WikiDB)) {
42          while (($dbi[$key] = @dba_open($file, "c", DBM_FILE_TYPE)) < 1) {
43             $numattempts++;
44             if ($numattempts > MAX_DBM_ATTEMPTS) {
45                ExitWiki("Cannot open database '$key' : '$file', giving up.");
46             }
47             sleep(1);
48          }
49       }
50       return $dbi;
51    }
52
53
54    function CloseDataBase($dbi) {
55       reset($dbi);
56       while (list($dbmfile, $dbihandle) = each($dbi)) {
57          dba_close($dbihandle);
58       }
59       return;
60    }
61
62
63    // take a serialized hash, return same padded out to
64    // the next largest number bytes divisible by 500. This
65    // is to save disk space in the long run, since DBM files
66    // leak memory.
67    function PadSerializedData($data) {
68       // calculate the next largest number divisible by 500
69       $nextincr = 500 * ceil(strlen($data) / 500);
70       // pad with spaces
71       $data = sprintf("%-${nextincr}s", $data);
72       return $data;
73    }
74
75    // strip trailing whitespace from the serialized data 
76    // structure.
77    function UnPadSerializedData($data) {
78       return chop($data);
79    }
80
81
82
83    // Return hash of page + attributes or default
84    function RetrievePage($dbi, $pagename, $pagestore) {
85       if ($data = dba_fetch($pagename, $dbi[$pagestore])) {
86          // unserialize $data into a hash
87          $pagehash = unserialize(UnPadSerializedData($data));
88          $pagehash['pagename'] = $pagename;
89          return $pagehash;
90       } else {
91          return -1;
92       }
93    }
94
95
96    // Either insert or replace a key/value (a page)
97    function InsertPage($dbi, $pagename, $pagehash) {
98       $pagedata = PadSerializedData(serialize($pagehash));
99
100       if (!dba_insert($pagename, $pagedata, $dbi['wiki'])) {
101          if (!dba_replace($pagename, $pagedata, $dbi['wiki'])) {
102             ExitWiki("Error inserting page '$pagename'");
103          }
104       } 
105    }
106
107
108    // for archiving pages to a seperate dbm
109    function SaveCopyToArchive($dbi, $pagename, $pagehash) {
110       global $ArchivePageStore;
111
112       $pagedata = PadSerializedData(serialize($pagehash));
113
114       if (!dba_insert($pagename, $pagedata, $dbi[$ArchivePageStore])) {
115          if (!dba_replace($pagename, $pagedata, $dbi['archive'])) {
116             ExitWiki("Error storing '$pagename' into archive");
117          }
118       } 
119    }
120
121
122    function IsWikiPage($dbi, $pagename) {
123       return dba_exists($pagename, $dbi['wiki']);
124    }
125
126
127    function IsInArchive($dbi, $pagename) {
128       return dba_exists($pagename, $dbi['archive']);
129    }
130
131
132    // setup for title-search
133    function InitTitleSearch($dbi, $search) {
134       $pos['search'] = '=' . preg_quote($search) . '=i';
135       $pos['key'] = dba_firstkey($dbi['wiki']);
136
137       return $pos;
138    }
139
140    // iterating through database
141    function TitleSearchNextMatch($dbi, &$pos) {
142       while ($pos['key']) {
143          $page = $pos['key'];
144          $pos['key'] = dba_nextkey($dbi['wiki']);
145
146          if (preg_match($pos['search'], $page)) {
147             return $page;
148          }
149       }
150       return 0;
151    }
152
153    // setup for full-text search
154    function InitFullSearch($dbi, $search) {
155       return InitTitleSearch($dbi, $search);
156    }
157
158    //iterating through database
159    function FullSearchNextMatch($dbi, &$pos) {
160       while ($pos['key']) {
161          $key = $pos['key'];
162          $pos['key'] = dba_nextkey($dbi['wiki']);
163
164          $pagedata = dba_fetch($key, $dbi['wiki']);
165          // test the serialized data
166          if (preg_match($pos['search'], $pagedata)) {
167             $page['pagename'] = $key;
168             $pagedata = unserialize(UnPadSerializedData($pagedata));
169             $page['content'] = $pagedata['content'];
170             return $page;
171          }
172       }
173       return 0;
174    }
175
176    ////////////////////////
177    // new database features
178
179    // Compute PCRE suitable for searching for links to the given page.
180    function MakeBackLinkSearchRegexp($pagename) {
181       global $WikiNameRegexp;
182      
183       $quoted_pagename = preg_quote($pagename, '/');
184       if (preg_match("/^$WikiNameRegexp\$/", $pagename)) {
185          // FIXME: This may need modification for non-standard (non-english) $WikiNameRegexp.
186          return "/(?<![A-Za-z0-9!])$quoted_pagename(?![A-Za-z0-9])/";
187       }
188       else {
189          // Note from author: Sorry. :-/
190          return ( '/'
191                   . '(?<!\[)\[(?!\[)' // Single, isolated '['
192                   . '([^]|]*\|)?'     // Optional stuff followed by '|'
193                   . '\s*'             // Optional space
194                   . $quoted_pagename  // Pagename
195                   . '\s*\]/' );       // Optional space, followed by ']'
196          // FIXME: the above regexp is still not quite right.
197          // Consider the text: " [ [ test page ]".  This is a link to a page
198          // named '[ test page'.  The above regexp will recognize this
199          // as a link either to '[ test page' (good) or to 'test page' (wrong).
200       } 
201    }
202
203    // setup for back-link search
204    function InitBackLinkSearch($dbi, $pagename) {
205       $pos['search'] = MakeBackLinkSearchRegexp($pagename);
206       $pos['key'] = dba_firstkey($dbi['wiki']);
207       
208       return $pos;
209    }
210
211    // iterating through back-links
212    function BackLinkSearchNextMatch($dbi, &$pos) {
213       while ($pos['key']) {
214          $page = $pos['key'];
215          $pos['key'] = dba_nextkey($dbi['wiki']);
216
217          $rawdata = dba_fetch($page, $dbi['wiki']);
218          if ( ! preg_match($pos['search'], $rawdata))
219              continue;
220          
221          $pagedata = unserialize(UnPadSerializedData($rawdata));
222          while (list($i, $line) = each($pagedata['content'])) {
223             if (preg_match($pos['search'], $line))
224                return $page;
225          }
226       }
227       return 0;
228    }
229
230    function IncreaseHitCount($dbi, $pagename) {
231
232       if (dba_exists($pagename, $dbi['hitcount'])) {
233          // increase the hit count
234          // echo "$pagename there, incrementing...<br>\n";
235          $count = dba_fetch($pagename, $dbi['hitcount']);
236          $count++;
237          dba_replace($pagename, $count, $dbi['hitcount']);
238       } else {
239          // add it, set the hit count to one
240          // echo "adding $pagename to hitcount...<br>\n";
241          $count = 1;
242          dba_insert($pagename, $count, $dbi['hitcount']);
243       }
244    }
245
246    function GetHitCount($dbi, $pagename) {
247
248       if (dba_exists($pagename, $dbi['hitcount'])) {
249          // increase the hit count
250          $count = dba_fetch($pagename, $dbi['hitcount']);
251          return $count;
252       } else {
253          return 0;
254       }
255    }
256
257    function InitMostPopular($dbi, $limit) {
258       // iterate through the whole dbm file for hit counts
259       // sort the results highest to lowest, and return 
260       // n..$limit results
261
262       $pagename = dba_firstkey($dbi['hitcount']);
263       $res[$pagename] = dba_fetch($pagename, $dbi['hitcount']);
264
265       while ($pagename = dba_nextkey($dbi['hitcount'])) {
266          $res[$pagename] = dba_fetch($pagename, $dbi['hitcount']);
267          //echo "got $pagename with value " . $res[$pagename] . "<br>\n";
268       }
269
270       arsort($res);
271       return($res);
272    }
273
274    function MostPopularNextMatch($dbi, &$res) {
275
276       // the return result is a two element array with 'hits'
277       // and 'pagename' as the keys
278
279       if (count($res) == 0)
280          return 0;
281
282       if (list($pagename, $hits) = each($res)) {
283          //echo "most popular next match called<br>\n";
284          //echo "got $pagename, $hits back<br>\n";
285          $nextpage = array(
286             "hits" => $hits,
287             "pagename" => $pagename
288          );
289          // $dbm_mostpopular_cntr++;
290          return $nextpage;
291       } else {
292          return 0;
293       }
294    } 
295
296    function GetAllWikiPagenames($dbi) {
297       $namelist = array();
298       $ctr = 0;
299
300       $namelist[$ctr] = $key = dba_firstkey($dbi);
301
302       while ($key = dba_nextkey($dbi)) {
303          $ctr++;
304          $namelist[$ctr] = $key;
305       }
306
307       return $namelist;
308    }
309
310 ?>