]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiDB/backend.php
Converted presentational markup to semantic markup (just nitpicking, the <b> is only...
[SourceForge/phpwiki.git] / lib / WikiDB / backend.php
1 <?php // -*-php-*-
2 rcs_id('$Id: backend.php,v 1.3 2002-01-10 23:32:04 carstenklapp Exp $');
3
4 /*
5   Pagedata
6
7    maintained by WikiPage 
8     //:latestversion
9     //:deleted (*)     (Set if latest content is empty.)
10     //:pagename (*)
11
12     hits
13     is_locked
14
15   Versiondata
16
17     %content (?should this be here?)
18     _supplanted : Time version ceased to be the current version
19
20     mtime (*)   : Time of version edit.
21     orig_mtime
22     is_minor_edit (*)
23     author      : nominal author
24     author_id   : authenticated author
25     summary
26
27     //version
28     //created (*)
29     //%superceded
30         
31     //:serial
32
33      (types are scalars: strings, ints, bools)
34 */     
35
36 /**
37  * A WikiDB_backend handles the storage and retrieval of data for a WikiDB.
38  *
39  * A WikiDB_backend handles the storage and retrieval of data for a WikiDB.
40  * It does not have to be this way, of course, but the standard WikiDB uses
41  * a WikiDB_backend.  (Other WikiDB's could be written which use some other
42  * method to access their underlying data store.)
43  *
44  * The interface outlined here seems to work well with both RDBM based
45  * and flat DBM/hash based methods of data storage.
46  *
47  * Though it contains some default implementation of certain methods,
48  * this is an abstract base class.  It is expected that most effificient
49  * backends will override nearly all the methods in this class.
50  *
51  * @access protected
52  * @see WikiDB
53  */
54 class WikiDB_backend
55 {
56     /**
57      * Get page meta-data from database.
58      *
59      * @param $pagename string Page name.
60      * @return hash
61      * Returns a hash containing the page meta-data.
62      * Returns an empty array if there is no meta-data for the requested page.
63      * Keys which might be present in the hash are:
64      * <dl>
65      *  <dt> locked  <dd> If the page is locked.
66      *  <dt> hits    <dd> The page hit count.
67      *  <dt> created <dd> Unix time of page creation. (FIXME: Deprecated: I
68      *                    don't think we need this...) 
69      * </dl>
70      */
71     function get_pagedata($pagename) {
72         trigger_error("virtual", E_USER_ERROR);
73     }
74
75     /**
76      * Update the page meta-data.
77      *
78      * Set page meta-data.
79      *
80      * Only meta-data whose keys are preset in $newdata is affected.
81      *
82      * For example:
83      * <pre>
84      *   $backend->update_pagedata($pagename, array('locked' => 1)); 
85      * </pre>
86      * will set the value of 'locked' to 1 for the specified page, but it
87      * will not affect the value of 'hits' (or whatever other meta-data
88      * may have been stored for the page.)
89      *
90      * To delete a particular piece of meta-data, set it's value to false.
91      * <pre>
92      *   $backend->update_pagedata($pagename, array('locked' => false)); 
93      * </pre>
94      *
95      * @param $pagename string Page name.
96      * @param $newdata hash New meta-data.
97      */
98     function update_pagedata($pagename, $newdata) {
99         trigger_error("virtual", E_USER_ERROR);
100     }
101     
102
103     /**
104      * Get the current version number for a page.
105      *
106      * @param $pagename string Page name.
107      * @return int The latest version number for the page.  Returns zero if
108      *  no versions of a page exist.
109      */
110     function get_latest_version($pagename) {
111         trigger_error("virtual", E_USER_ERROR);
112     }
113     
114     /**
115      * Get preceding version number.
116      *
117      * @param $pagename string Page name.
118      * @param $version int Find version before this one.
119      * @return int The version number of the version in the database which
120      *  immediately preceeds $version.
121      */
122     function get_previous_version($pagename, $version) {
123         trigger_error("virtual", E_USER_ERROR);
124     }
125     
126     /**
127      * Get revision meta-data and content.
128      *
129      * @param $pagename string Page name.
130      * @param $version integer Which version to get.
131      * @param $want_content boolean
132      *  Indicates the caller really wants the page content.  If this
133      *  flag is not set, the backend is free to skip fetching of the
134      *  page content (as that may be expensive).  If the backend omits
135      *  the content, the backend might still want to set the value of
136      *  '%content' to the empty string if it knows there's no content.
137      *
138      * @return hash The version data, or false if specified version does not
139      *    exist.
140      *
141      * Some keys which might be present in the $versiondata hash are:
142      * <dl>
143      * <dt> %content
144      *  <dd> This is a pseudo-meta-data element (since it's actually
145      *       the page data, get it?) containing the page content.
146      *       If the content was not fetched, this key may not be present.
147      * </dl>
148      * For description of other version meta-data see WikiDB_PageRevision::get().
149      * @see WikiDB_PageRevision::get
150      */
151     function get_versiondata($pagename, $version, $want_content = false) {
152         trigger_error("virtual", E_USER_ERROR);
153     }
154
155     /**
156      * Delete page from the database.
157      *
158      * Delete page (and all it's revisions) from the database.
159      *
160      * @param $pagename string Page name.
161      */
162     function delete_page($pagename) {
163         trigger_error("virtual", E_USER_ERROR);
164     }
165             
166     /**
167      * Delete an old revision of a page.
168      *
169      * Note that one is never allowed to delete the most recent version,
170      * but that this requirement is enforced by WikiDB not by the backend.
171      *
172      * In fact, to be safe, backends should probably allow the deletion of
173      * the most recent version.
174      *
175      * @param $pagename string Page name.
176      * @param $version integer Version to delete.
177      */
178     function delete_versiondata($pagename, $version) {
179         trigger_error("virtual", E_USER_ERROR);
180     }
181
182     /**
183      * Create a new page revision.
184      *
185      * If the given ($pagename,$version) is already in the database,
186      * this method completely overwrites any stored data for that version.
187      *
188      * @param $pagename string Page name.
189      * @param $version int New revisions content.
190      * @param $data hash New revision metadata.
191      *
192      * @see get_versiondata
193      */
194     function set_versiondata($pagename, $version, $data) {
195         trigger_error("virtual", E_USER_ERROR);
196     }
197
198     /**
199      * Update page version meta-data.
200      *
201      * If the given ($pagename,$version) is already in the database,
202      * this method only changes those meta-data values whose keys are
203      * explicity listed in $newdata.
204      *
205      * @param $pagename string Page name.
206      * @param $version int New revisions content.
207      * @param $newdata hash New revision metadata.
208      * @see set_versiondata, get_versiondata
209      */
210     function update_versiondata($pagename, $version, $newdata) {
211         $data = $this->get_versiondata($pagename, $version, true);
212         if (!$data) {
213             assert($data);
214             return;
215         }
216         foreach ($newdata as $key => $val) {
217             if (empty($val))
218                 unset($data[$key]);
219             else
220                 $data[$key] = $val;
221         }
222         $this->set_versiondata($pagename, $version, $data);
223     }
224     
225     /**
226      * Set links for page.
227      *
228      * @param $pagename string Page name.
229      *
230      * @param $links array List of page(names) which page links to.
231      */
232     function set_links($pagename, $links) {
233         trigger_error("virtual", E_USER_ERROR);
234     }
235         
236     /**
237      * Find pages which link to or are linked from a page.
238      *
239      * @param $pagename string Page name.
240      * @param $reversed boolean True to get backlinks.
241      *
242      * FIXME: array or iterator?
243      * @return object A WikiDB_backend_iterator.
244      */
245     function get_links($pagename, $reversed) {
246         //FIXME: implement simple (but slow) link finder.
247         die("FIXME");
248     }
249
250     /**
251      * Get all revisions of a page.
252      *
253      * @param $pagename string The page name.
254      * @return object A WikiDB_backend_iterator.
255      */
256     function get_all_revisions($pagename) {
257         include_once('lib/WikiDB/backend/dumb/AllRevisionsIter.php');
258         return new WikiDB_backend_dumb_AllRevisionsIter($this, $pagename);
259     }
260     
261     /**
262      * Get all pages in the database.
263      *
264      * Pages should be returned in alphabetical order if that is
265      * feasable.
266      *
267      * @access protected
268      *
269      * @param $include_defaulted boolean
270      * If set, even pages with no content will be returned
271      * --- but still only if they have at least one revision (not
272      * counting the default revision 0) entered in the database.
273      *
274      * Normally pages whose current revision has empty content
275      * are not returned as these pages are considered to be
276      * non-existing.
277      *
278      * @return object A WikiDB_backend_iterator.
279      */
280     function get_all_pages($include_defaulted) {
281         trigger_error("virtual", E_USER_ERROR);
282     }
283         
284     /**
285      * Title or full text search.
286      *
287      * Pages should be returned in alphabetical order if that is
288      * feasable.
289      *
290      * @access protected
291      *
292      * @param $search object A TextSearchQuery object describing what pages
293      * are to be searched for.
294      *
295      * @param $fullsearch boolean If true, a full text search is performed,
296      *  otherwise a title search is performed.
297      *
298      * @return object A WikiDB_backend_iterator.
299      *
300      * @see WikiDB::titleSearch
301      */
302     function text_search($search = '', $fullsearch = false) {
303         // This is method implements a simple linear search
304         // through all the pages in the database.
305         //
306         // It is expected that most backends will overload
307         // method with something more efficient.
308         include_once('lib/WikiDB/backend/dumb/TextSearchIter.php');
309         $pages = $this->get_all_pages(false);
310         return new WikiDB_backend_dumb_TextSearchIter($this, $pages, $search, $fullsearch);
311     }
312
313     /**
314      * Find pages with highest hit counts.
315      *
316      * Find the pages with the highest hit counts.  The pages should
317      * be returned in reverse order by hit count.
318      *
319      * @access protected
320      * @param $limit integer  No more than this many pages
321      * @return object A WikiDB_backend_iterator.
322      */
323     function most_popular($limit) {
324         // This is method fetches all pages, then
325         // sorts them by hit count.
326         // (Not very efficient.)
327         //
328         // It is expected that most backends will overload
329         // method with something more efficient.
330         include_once('lib/WikiDB/backend/dumb/MostPopularIter.php');
331         $pages = $this->get_all_pages(false);
332         
333         return new WikiDB_backend_dumb_MostPopularIter($this, $pages, $limit);
334     }
335
336     /**
337      * Find recent changes.
338      *
339      * @access protected
340      * @param $params hash See WikiDB::mostRecent for a description
341      *  of parameters which can be included in this hash.
342      * @return object A WikiDB_backend_iterator.
343      * @see WikiDB::mostRecent
344      */
345     function most_recent($params) {
346         // This method is very inefficient and searches through
347         // all pages for the most recent changes.
348         //
349         // It is expected that most backends will overload
350         // method with something more efficient.
351         include_once('lib/WikiDB/backend/dumb/MostRecentIter.php');
352         $pages = $this->get_all_pages(true);
353         return new WikiDB_backend_dumb_MostRecentIter($this, $pages, $params);
354     }
355
356     /**
357      * Lock backend database.
358      *
359      * Calls may be nested.
360      *
361      * @param $write_lock boolean Unless this is set to false, a write lock
362      *     is acquired, otherwise a read lock.  If the backend doesn't support
363      *     read locking, then it should make a write lock no matter which type
364      *     of lock was requested.
365      *
366      *     All backends <em>should</em> support write locking.
367      */
368     function lock($write_lock = true) {
369     }
370
371     /**
372      * Unlock backend database.
373      *
374      * @param $force boolean Normally, the database is not unlocked until
375      *  unlock() is called as many times as lock() has been.  If $force is
376      *  set to true, the the database is unconditionally unlocked.
377      */
378     function unlock($force = false) {
379     }
380
381
382     /**
383      * Close database.
384      */
385     function close () {
386     }
387
388     /**
389      * Synchronize with filesystem.
390      *
391      * This should flush all unwritten data to the filesystem.
392      */
393     function sync() {
394     }
395
396     /**
397      * Optimize the database.
398      */
399     function optimize() {
400     }
401
402     /**
403      * Check database integrity.
404      *
405      * This should check the validity of the internal structure of the database.
406      * Errors should be reported via:
407      * <pre>
408      *   trigger_error("Message goes here.", E_USER_WARNING);
409      * </pre>
410      *
411      * @return boolean True iff database is in a consistent state.
412      */
413     function check() {
414     }
415
416     /**
417      * Put the database into a consistent state.
418      *
419      * This should put the database into a consistent state.
420      * (I.e. rebuild indexes, etc...)
421      *
422      * @return boolean True iff successful.
423      */
424     function rebuild() {
425     }
426
427     function _parse_searchwords($search) {
428         $search = strtolower(trim($search));
429         if (!$search)
430             return array(array(),array());
431         
432         $words = preg_split('/\s+/', $search);
433         $exclude = array();
434         foreach ($words as $key => $word) {
435             if ($word[0] == '-' && $word != '-') {
436                 $word = substr($word, 1);
437                 $exclude[] = preg_quote($word);
438                 unset($words[$key]);
439             }
440         }
441         return array($words, $exclude);
442     }
443         
444 };
445
446 /**
447  * Iterator returned by backend methods which (possibly) return
448  * multiple records.
449  *
450  * FIXME: this should be two seperate classes: page_iter and version_iter.
451  */
452 class WikiDB_backend_iterator
453 {
454     /**
455      * Get the next record in the interator set.
456      *
457      * This returns a hash.  The has may contain the following keys:
458      * <dl>
459      * <dt> pagename <dt> (string) the page name
460      * <dt> version  <dt> (int) the version number
461      * <dt> pagedata <dt> (hash) page meta-data (as returned from backend::get_pagedata().)
462      * <dt> versiondata <dt> (hash) page meta-data (as returned from backend::get_versiondata().)
463      *
464      * If this is a page iterator, it must contain the 'pagename' entry --- the others
465      * are optional.
466      *
467      * If this is a version iterator, the 'pagename', 'version', <strong>and</strong> 'versiondata'
468      * entries are mandatory.  ('pagedata' is optional.)
469      */
470     function next() {
471         trigger_error("virtual", E_USER_ERROR);
472     }
473
474     /**
475      * Release resources held by this iterator.
476      */
477     function free() {
478     }
479 };
480
481 // For emacs users
482 // Local Variables:
483 // mode: php
484 // tab-width: 8
485 // c-basic-offset: 4
486 // c-hanging-comment-ender-p: nil
487 // indent-tabs-mode: nil
488 // End:
489
490 ?>