3 rcs_id('$Id: dbalib.php,v 1.2.2.2 2001-11-06 20:43:11 dairiki Exp $');
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)
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 @.
37 function OpenDataBase($dbname) {
38 global $WikiDB; // hash of all the DBM file names
41 while (list($key, $file) = each($WikiDB)) {
42 while (($dbi[$key] = @dba_open($file, "c", "gdbm")) < 1) {
44 if ($numattempts > MAX_DBM_ATTEMPTS) {
45 ExitWiki("Cannot open database '$key' : '$file', giving up.");
54 function CloseDataBase($dbi) {
56 while (list($dbmfile, $dbihandle) = each($dbi)) {
57 dba_close($dbihandle);
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
67 function PadSerializedData($data) {
68 // calculate the next largest number divisible by 500
69 $nextincr = 500 * ceil(strlen($data) / 500);
71 $data = sprintf("%-${nextincr}s", $data);
75 // strip trailing whitespace from the serialized data
77 function UnPadSerializedData($data) {
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;
96 // Either insert or replace a key/value (a page)
97 function InsertPage($dbi, $pagename, $pagehash) {
98 $pagedata = PadSerializedData(serialize($pagehash));
100 if (!dba_insert($pagename, $pagedata, $dbi['wiki'])) {
101 if (!dba_replace($pagename, $pagedata, $dbi['wiki'])) {
102 ExitWiki("Error inserting page '$pagename'");
108 // for archiving pages to a seperate dbm
109 function SaveCopyToArchive($dbi, $pagename, $pagehash) {
110 global $ArchivePageStore;
112 $pagedata = PadSerializedData(serialize($pagehash));
114 if (!dba_insert($pagename, $pagedata, $dbi[$ArchivePageStore])) {
115 if (!dba_replace($pagename, $pagedata, $dbi['archive'])) {
116 ExitWiki("Error storing '$pagename' into archive");
122 function IsWikiPage($dbi, $pagename) {
123 return dba_exists($pagename, $dbi['wiki']);
127 function IsInArchive($dbi, $pagename) {
128 return dba_exists($pagename, $dbi['archive']);
132 // setup for title-search
133 function InitTitleSearch($dbi, $search) {
134 $pos['search'] = $search;
135 $pos['key'] = dba_firstkey($dbi['wiki']);
140 // iterating through database
141 function TitleSearchNextMatch($dbi, &$pos) {
142 while ($pos['key']) {
144 $pos['key'] = dba_nextkey($dbi['wiki']);
146 if (eregi($pos['search'], $page)) {
153 // setup for full-text search
154 function InitFullSearch($dbi, $search) {
155 return InitTitleSearch($dbi, $search);
158 //iterating through database
159 function FullSearchNextMatch($dbi, &$pos) {
160 while ($pos['key']) {
162 $pos['key'] = dba_nextkey($dbi['wiki']);
164 $pagedata = dba_fetch($key, $dbi['wiki']);
165 // test the serialized data
166 if (eregi($pos['search'], $pagedata)) {
167 $page['pagename'] = $key;
168 $pagedata = unserialize(UnPadSerializedData($pagedata));
169 $page['content'] = $pagedata['content'];
176 ////////////////////////
177 // new database features
179 // Compute PCRE suitable for searching for links to the given page.
180 function MakeBackLinkSearchRegexp($pagename) {
181 global $WikiNameRegexp;
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])/";
189 // Note from author: Sorry. :-/
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).
203 // setup for back-link search
204 function InitBackLinkSearch($dbi, $pagename) {
205 return InitTitleSearch($dbi, MakeBackLinkSearchRegexp($pagename));
208 // iterating through back-links
209 function BackLinkSearchNextMatch($dbi, &$pos) {
210 while ($pos['key']) {
212 $pos['key'] = dba_nextkey($dbi['wiki']);
214 $rawdata = dba_fetch($page, $dbi['wiki']);
215 if ( ! preg_match($pos['search'], $rawdata))
218 $pagedata = unserialize(UnPadSerializedData($rawdata));
219 while (list($i, $line) = each($pagedata['content'])) {
220 if (preg_match($pos['search'], $line))
227 function IncreaseHitCount($dbi, $pagename) {
229 if (dba_exists($pagename, $dbi['hitcount'])) {
230 // increase the hit count
231 // echo "$pagename there, incrementing...<br>\n";
232 $count = dba_fetch($pagename, $dbi['hitcount']);
234 dba_replace($pagename, $count, $dbi['hitcount']);
236 // add it, set the hit count to one
237 // echo "adding $pagename to hitcount...<br>\n";
239 dba_insert($pagename, $count, $dbi['hitcount']);
243 function GetHitCount($dbi, $pagename) {
245 if (dba_exists($pagename, $dbi['hitcount'])) {
246 // increase the hit count
247 $count = dba_fetch($pagename, $dbi['hitcount']);
254 function InitMostPopular($dbi, $limit) {
255 // iterate through the whole dbm file for hit counts
256 // sort the results highest to lowest, and return
259 $pagename = dba_firstkey($dbi['hitcount']);
260 $res[$pagename] = dba_fetch($pagename, $dbi['hitcount']);
262 while ($pagename = dba_nextkey($dbi['hitcount'])) {
263 $res[$pagename] = dba_fetch($pagename, $dbi['hitcount']);
264 //echo "got $pagename with value " . $res[$pagename] . "<br>\n";
271 function MostPopularNextMatch($dbi, &$res) {
273 // the return result is a two element array with 'hits'
274 // and 'pagename' as the keys
276 if (count($res) == 0)
279 if (list($pagename, $hits) = each($res)) {
280 //echo "most popular next match called<br>\n";
281 //echo "got $pagename, $hits back<br>\n";
284 "pagename" => $pagename
286 // $dbm_mostpopular_cntr++;
293 function GetAllWikiPagenames($dbi) {
297 $namelist[$ctr] = $key = dba_firstkey($dbi);
299 while ($key = dba_nextkey($dbi)) {
301 $namelist[$ctr] = $key;