1 <?php // rcs_id('$Id$');
3 require_once('lib/ErrorManager.php');
6 define('DBA_DATABASE_DEFAULT_TIMEOUT', 60);
8 define('DBA_DATABASE_DEFAULT_TIMEOUT', 5);
12 function DbaDatabase($filename, $mode = false, $handler = 'gdbm') {
13 $this->_file = $filename;
14 $this->_handler = $handler;
15 $this->_timeout = DBA_DATABASE_DEFAULT_TIMEOUT;
17 if (function_exists("dba_handlers")) { // since php-4.3.0
18 if (!in_array($handler, dba_handlers()))
21 _("The DBA handler %s is unsupported!")."\n".
22 _("Supported handlers are: %s"),
23 $handler, join(",",dba_handlers())));
25 $this->readonly = false;
30 function set_timeout($timeout) {
31 $this->_timeout = $timeout;
34 function open($mode = 'w') {
36 return; // already open.
38 $watchdog = $this->_timeout;
41 $this->_dba_open_error = false;
42 $ErrorManager->pushErrorHandler(new WikiMethodCb($this, '_dba_open_error_handler'));
44 // oops, you don't have DBA support.
45 if (!function_exists("dba_open")) {
46 echo "You don't seem to have DBA support compiled into PHP.";
53 // lock supported since 4.3.0:
54 if (check_php_version(4,3,0) and (strlen($mode) == 1)) {
55 // PHP 4.3.x Windows lock bug workaround: http://bugs.php.net/bug.php?id=23975
57 $mode .= "-"; // suppress locking, or
58 } elseif ($this->_handler != 'gdbm') { // gdbm does it internally
59 $mode .= "d"; // else use internal locking
62 while (($dbh = dba_open($this->_file, $mode, $this->_handler)) < 1) {
65 // "c" failed, try "w" instead.
67 and file_exists($this->_file)
68 and (isWindows() or !is_writable($this->_file)))
70 // try to continue with read-only
71 if (!defined("READONLY"))
72 define("READONLY", true);
73 $GLOBALS['request']->_dbi->readonly = true;
74 $this->readonly = true;
77 if (substr($mode,0,1) == "c" and file_exists($this->_file) and !READONLY)
79 // conflict: wait some random time to unlock (as with ethernet)
80 $secs = 0.5 + ((double)rand(1,32767)/32767);
83 if (strlen($mode) == 2) $mode = substr($mode,0,-1);
85 $ErrorManager->popErrorHandler();
88 if ( ($error = $this->_dba_open_error) ) {
89 $error->errno = E_USER_ERROR;
90 $error->errstr .= "\nfile: " . $this->_file
92 . "\nhandler: " . $this->_handler;
93 // try to continue with read-only
94 if (!defined("READONLY"))
95 define("READONLY", true);
96 $GLOBALS['request']->_dbi->readonly = true;
97 $this->readonly = true;
98 if (!file_exists($this->_file)) {
99 $ErrorManager->handleError($error);
104 trigger_error("dba_open failed", E_USER_ERROR);
113 dba_close($this->_dbh);
117 function exists($key) {
118 return dba_exists($key, $this->_dbh);
121 function fetch($key) {
122 $val = dba_fetch($key, $this->_dbh);
124 return $this->_error("fetch($key)");
128 function insert($key, $val) {
129 if (!dba_insert($key, $val, $this->_dbh))
130 return $this->_error("insert($key)");
133 function replace($key, $val) {
134 if (!dba_replace($key, $val, $this->_dbh))
135 return $this->_error("replace($key)");
139 function firstkey() {
140 return dba_firstkey($this->_dbh);
144 return dba_nextkey($this->_dbh);
147 function delete($key) {
148 if ($this->readonly) return;
149 if (!dba_delete($key, $this->_dbh))
150 return $this->_error("delete($key)");
154 return dba_fetch($key, $this->_dbh);
157 function set($key, $val) {
159 if ($this->readonly) return;
160 if (dba_exists($key, $dbh)) {
161 if ($val !== false) {
162 if (!dba_replace($key, $val, $dbh))
163 return $this->_error("store[replace]($key)");
166 if (!dba_delete($key, $dbh))
167 return $this->_error("store[delete]($key)");
171 if (!dba_insert($key, $val, $dbh))
172 return $this->_error("store[insert]($key)");
177 if (!dba_sync($this->_dbh))
178 return $this->_error("sync()");
181 function optimize() {
182 if (!dba_optimize($this->_dbh))
183 return $this->_error("optimize()");
187 function _error($mes) {
188 //trigger_error("DbaDatabase: $mes", E_USER_WARNING);
190 trigger_error("$this->_file: dba error: $mes", E_USER_ERROR);
195 for ($key = $this->firstkey($dbh); $key; $key = $this->nextkey($dbh))
196 printf("%10s: %s\n", $key, $this->fetch($key));
199 function _dba_open_error_handler($error) {
200 $this->_dba_open_error = $error;
205 // (c-file-style: "gnu")
210 // c-hanging-comment-ender-p: nil
211 // indent-tabs-mode: nil