]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/DbaDatabase.php
add rcsid log
[SourceForge/phpwiki.git] / lib / DbaDatabase.php
1 <?php rcs_id('$Id: DbaDatabase.php,v 1.19 2006-06-18 11:01:25 rurban Exp $');
2
3 require_once('lib/ErrorManager.php');
4
5 define('DBA_DATABASE_DEFAULT_TIMEOUT', 5);
6
7 class DbaDatabase
8 {
9     function DbaDatabase($filename, $mode = false, $handler = 'gdbm') {
10         $this->_file = $filename;
11         $this->_handler = $handler;
12         $this->_timeout = DBA_DATABASE_DEFAULT_TIMEOUT;
13         $this->_dbh = false;
14         if (function_exists("dba_handlers")) { // since 4.3.0
15             if (!in_array($handler, dba_handlers()))
16                 $this->_error(
17                     sprintf(
18                             _("The DBA handler %s is unsupported!")."\n".
19                             _("Supported handlers are: %s"), 
20                             $handler, join(",",dba_handlers())));
21         }
22         if ($mode)
23             $this->open($mode);
24     }
25
26     function set_timeout($timeout) {
27         $this->_timeout = $timeout;
28     }
29     
30     function open($mode = 'w') {
31         if ($this->_dbh)
32             return;             // already open.
33         
34         $watchdog = $this->_timeout;
35
36         global $ErrorManager;
37         $this->_dba_open_error = false;
38         $ErrorManager->pushErrorHandler(new WikiMethodCb($this, '_dba_open_error_handler'));
39
40         // oops, you don't have DBA support.
41         if (!function_exists("dba_open")) {
42             echo "You don't seem to have DBA support compiled into PHP.";
43         }
44         
45         // lock supported since 4.3.0:
46         if (check_php_version(4,3,0) and (strlen($mode) == 1)) {
47             // PHP 4.3.x Windows lock bug workaround: http://bugs.php.net/bug.php?id=23975
48             if (isWindows()) {
49                 $mode .= "-";                   // suppress locking, or
50             } elseif ($this->_handler != 'gdbm') {      // gdbm does it internally
51                 $mode .= "d";                   // else use internal locking
52             }
53         }
54         while (($dbh = dba_open($this->_file, $mode, $this->_handler)) < 1) {
55             if ($watchdog <= 0)
56                 break;
57             flush();
58             // "c" failed, try "w" instead.
59             if (substr($mode,0,1) == "c" and file_exists($this->_file))
60                 $mode = "w";
61             // conflict: wait some random time to unlock (see ethernet)
62             $secs = 0.5 + ((double)rand(1,32767)/32767);
63             sleep($secs);
64             $watchdog -= $secs;
65             if (strlen($mode) == 2) $mode = substr($mode,0,-1);
66         }
67         $ErrorManager->popErrorHandler();
68
69         if (!$dbh) {
70             if ( ($error = $this->_dba_open_error) ) {
71                 $error->errno = E_USER_ERROR;
72                 $error->errstr .= "\nfile: " . $this->_file
73                                .  "\nmode: " . $mode
74                                .  "\nhandler: " . $this->_handler;
75                 $ErrorManager->handleError($error);
76             }
77             else {
78                 trigger_error("dba_open failed", E_USER_ERROR);
79             }
80         }
81         $this->_dbh = $dbh;
82         return !empty($dbh);
83     }
84
85     function close() {
86         if ($this->_dbh)
87             dba_close($this->_dbh);
88         $this->_dbh = false;
89     }
90
91     function exists($key) {
92         return dba_exists($key, $this->_dbh);
93     }
94     
95     function fetch($key) {
96         $val = dba_fetch($key, $this->_dbh);
97         if ($val === false)
98             return $this->_error("fetch($key)");
99         return $val;
100     }
101
102     function insert($key, $val) {
103         if (!dba_insert($key, $val, $this->_dbh))
104             return $this->_error("insert($key)");
105     }
106
107     function replace($key, $val) {
108         if (!dba_replace($key, $val, $this->_dbh))
109             return $this->_error("replace($key)");
110     }
111
112     
113     function firstkey() {
114         return dba_firstkey($this->_dbh);
115     }
116
117     function nextkey() {
118         return dba_nextkey($this->_dbh);
119     }
120
121     function delete($key) {
122         if (!dba_delete($key, $this->_dbh))
123             return $this->_error("delete($key)");
124     }
125
126     function get($key) {
127         return dba_fetch($key, $this->_dbh);
128     }
129
130     function set($key, $val) {
131         $dbh = &$this->_dbh;
132         if (dba_exists($key, $dbh)) {
133             if ($val !== false) {
134                 if (!dba_replace($key, $val, $dbh))
135                     return $this->_error("store[replace]($key)");
136             }
137             else {
138                 if (!dba_delete($key, $dbh))
139                     return $this->_error("store[delete]($key)");
140             }
141         }
142         else {
143             if (!dba_insert($key, $val, $this->_dbh))
144                 return $this->_error("store[insert]($key)");
145         }
146     }
147
148     function sync() {
149         if (!dba_sync($this->_dbh))
150             return $this->_error("sync()");
151     }
152
153     function optimize () {
154         if (!dba_optimize($this->_dbh))
155             return $this->_error("optimize()");
156         return 1;
157     }
158     
159     function _error($mes) {
160         //trigger_error("DbaDatabase: $mes", E_USER_WARNING);
161         //return false;
162         trigger_error("$this->_file: dba error: $mes", E_USER_ERROR);
163     }
164
165     function _dump() {
166         $dbh = &$this->_dbh;
167         for ($key = $this->firstkey($dbh); $key; $key = $this->nextkey($dbh))
168             printf("%10s: %s\n", $key, $this->fetch($key));
169     }
170
171     function _dba_open_error_handler ($error) {
172         $this->_dba_open_error = $error;
173         return true;
174     }
175 }
176
177 // $Log: not supported by cvs2svn $
178
179 // (c-file-style: "gnu")
180 // Local Variables:
181 // mode: php
182 // tab-width: 8
183 // c-basic-offset: 4
184 // c-hanging-comment-ender-p: nil
185 // indent-tabs-mode: nil
186 // End:   
187 ?>