Bug #13629 Updated: DB3 fails (driver initialization failure)
| From: | swm@php.net | Date: | Sat, 12 Jan 2002 07:32:37 +0000 |
| Subject: | Bug #13629 Updated: DB3 fails (driver initialization failure) | ||
| References: | 1 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-76737@lists.php.net to get a copy of this message | ||
ID: 13629
Updated by: swm
Reported By: nclemons@vesn.com
Old Status: Open
Status: Closed
Bug Type: DBM/DBA related
Operating System: Solaris 8
PHP Version: 4.0.6
Previous Comments:
------------------------------------------------------------------------
[2002-01-12 02:30:10] swm@php.net
Fixed in current CVS.
------------------------------------------------------------------------
[2001-10-10 15:40:30] nclemons@vesn.com
Er, just noticed the duplicity of the DBA_TRUNC code. Missed that the
first time.
ext/dba/dba_db3.c should change:
type = info->mode == DBA_READER ? DB_UNKNOWN :
info->mode == DBA_TRUNC ? DB_BTREE :
info->mode == DBA_CREAT ? DB_BTREE :
VCWD_STAT(info->path, &check_stat) ? DB_BTREE :
DB_UNKNOWN;
--Nathan
------------------------------------------------------------------------
[2001-10-10 15:36:52] nclemons@vesn.com
The following script runs fine the first time:
<?
$id = dba_open ("testdb.db", "c", "db3");
if (!$id) {
echo "dba_open failed\n";
exit;
}
dba_close($id);
?>
But second time (after the DB is created) it fails. After a long day of
research, I found the Berkley DB code changed:
db-3.2.9/db/db.c:
switch (type) {
case DB_UNKNOWN:
if (LF_ISSET(DB_CREATE|DB_TRUNCATE)) {
__db_err(dbenv,
"%s: DB_UNKNOWN type specified with DB_CREATE or
DB_TRUNCATE",
name);
return (EINVAL);
}
ok_flags = 0;
break;
case DB_BTREE:
ok_flags = DB_OK_BTREE;
break;
case DB_HASH:
ok_flags = DB_OK_HASH;
break;
case DB_QUEUE:
ok_flags = DB_OK_QUEUE;
break;
case DB_RECNO:
ok_flags = DB_OK_RECNO;
break;
default:
__db_err(dbenv, "unknown type: %lu", (u_long)type);
return (EINVAL);
}
When using "c" mode in dba_open, if the file does not exist, PHP calls
dbp->open as:
dbp->open(dbp, <file>, NULL, 1, 1, 420)
When using "c" mode and the file does not exist, it calls dbp->open
as:
dbp->open(dbp, <file>, NULL, 5, 1, 420)
DB_UNKNOWN and DB_CREATE are no longer valid options to pass together.
My fix was to change ext/dba/dba_db3.c as follows:
Before
------
type = info->mode == DBA_READER ? DB_UNKNOWN :
info->mode == DBA_TRUNC ? DB_BTREE :
VCWD_STAT(info->path, &check_stat) ? DB_BTREE :
DB_UNKNOWN;
After
-----
type = info->mode == DBA_READER ? DB_UNKNOWN :
info->mode == DBA_TRUNC ? DB_BTREE :
(VCWD_STAT(info->path, &check_stat) ||
(info->mode == DBA_CREAT) || (info->mode ==
DBA_TRUNC)) ? DB_BTREE : DB_UNKNOWN;
The only other way to solve this would be to attempt to determine the
type of DB before trying to open it, as the PHP interface does not give
the capability to distinguish between BTREE/RECNO/HASH/QUEUE/etc.
This should solve the following bug reports:
http://bugs.php.net/bug.php?id=10798
http://bugs.php.net/bug.php?id=13358
http://bugs.php.net/bug.php?id=8574
http://bugs.php.net/bug.php?id=11732
http://bugs.php.net/bug.php?id=10380
HTH,
Nathan Clemons,
Director of Virtual E-Services Network, Inc.
------------------------------------------------------------------------
Edit this bug report at http://bugs.php.net/?id=13629&edit=1