Back to index

php5  5.3.10
dba_db4.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Authors: Marcus Boerger <helly@php.net>                              |
00016    |          Sascha Schumann <sascha@schumann.cx>                        |
00017    +----------------------------------------------------------------------+
00018  */
00019 
00020 /* $Id: dba_db4.c 321634 2012-01-01 13:15:04Z felipe $ */
00021 
00022 #ifdef HAVE_CONFIG_H
00023 #include "config.h"
00024 #endif
00025 
00026 #include "php.h"
00027 
00028 #if DBA_DB4
00029 #include "php_db4.h"
00030 #include <sys/stat.h>
00031 
00032 #include <string.h>
00033 #ifdef DB4_INCLUDE_FILE
00034 #include DB4_INCLUDE_FILE
00035 #else
00036 #include <db.h>
00037 #endif
00038 
00039 static void php_dba_db4_errcall_fcn(
00040 #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3))
00041        const DB_ENV *dbenv, 
00042 #endif
00043        const char *errpfx, const char *msg)
00044 {
00045        TSRMLS_FETCH();
00046 
00047 #if (DB_VERSION_MAJOR == 5 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 8))
00048 /* Bug 51086, Berkeley DB 4.8.26 */
00049 /* This code suppresses a BDB 4.8+ error message, thus keeping PHP test compatibility */
00050        {
00051               char *function = get_active_function_name(TSRMLS_C);
00052               if (function && (!strcmp(function,"dba_popen") || !strcmp(function,"dba_open"))
00053                      && (!strncmp(msg, "fop_read_meta", sizeof("fop_read_meta")-1)
00054                             || !strncmp(msg, "BDB0004 fop_read_meta", sizeof("BDB0004 fop_read_meta")-1))) {
00055                      return;
00056               }
00057        }
00058 #endif
00059 
00060        php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s%s", errpfx?errpfx:"", msg);
00061 }
00062 
00063 #define DB4_DATA dba_db4_data *dba = info->dbf
00064 #define DB4_GKEY \
00065        DBT gkey; \
00066        memset(&gkey, 0, sizeof(gkey)); \
00067        gkey.data = (char *) key; gkey.size = keylen
00068 
00069 typedef struct {
00070        DB *dbp;
00071        DBC *cursor;
00072 } dba_db4_data;
00073 
00074 DBA_OPEN_FUNC(db4)
00075 {
00076        DB *dbp = NULL;
00077        DBTYPE type;
00078        int gmode = 0, err;
00079        int filemode = 0644;
00080        struct stat check_stat;
00081        int s = VCWD_STAT(info->path, &check_stat);
00082 
00083 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR <= 7)  /* Bug 51086 */
00084        if (!s && !check_stat.st_size) {
00085               info->mode = DBA_TRUNC; /* force truncate */
00086        }
00087 
00088        type = info->mode == DBA_READER ? DB_UNKNOWN :
00089               info->mode == DBA_TRUNC ? DB_BTREE :
00090               s ? DB_BTREE : DB_UNKNOWN;
00091          
00092        gmode = info->mode == DBA_READER ? DB_RDONLY :
00093               (info->mode == DBA_CREAT && s) ? DB_CREATE : 
00094               (info->mode == DBA_CREAT && !s) ? 0 :
00095               info->mode == DBA_WRITER ? 0         : 
00096               info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1;
00097 #else
00098        if (!s && !check_stat.st_size) {
00099               info->mode = DBA_CREAT; /* force creation */
00100        }
00101 
00102        type = info->mode == DBA_READER ? DB_UNKNOWN :
00103               (info->mode == DBA_TRUNC || info->mode == DBA_CREAT) ? DB_BTREE :
00104               s ? DB_BTREE : DB_UNKNOWN;
00105          
00106        gmode = info->mode == DBA_READER ? DB_RDONLY :
00107               info->mode == DBA_CREAT ? DB_CREATE : 
00108               info->mode == DBA_WRITER ? 0         : 
00109               info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1;
00110 #endif
00111 
00112        if (gmode == -1) {
00113               return FAILURE; /* not possible */
00114        }
00115 
00116        if (info->flags & DBA_PERSISTENT) {
00117               gmode |= DB_THREAD;
00118        }
00119 
00120        if (info->argc > 0) {
00121               convert_to_long_ex(info->argv[0]);
00122               filemode = Z_LVAL_PP(info->argv[0]);
00123        }
00124 
00125        if ((err=db_create(&dbp, NULL, 0)) == 0) {
00126            dbp->set_errcall(dbp, php_dba_db4_errcall_fcn);
00127            if (
00128 #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1))
00129                      (err=dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) {
00130 #else
00131                      (err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) {
00132 #endif
00133                      dba_db4_data *data;
00134 
00135                      data = pemalloc(sizeof(*data), info->flags&DBA_PERSISTENT);
00136                      data->dbp = dbp;
00137                      data->cursor = NULL;
00138                      info->dbf = data;
00139               
00140                      return SUCCESS;
00141               } else {
00142                      dbp->close(dbp, 0);
00143                      *error = db_strerror(err);
00144               }
00145        } else {
00146               *error = db_strerror(err);
00147        }
00148 
00149        return FAILURE;
00150 }
00151 
00152 DBA_CLOSE_FUNC(db4)
00153 {
00154        DB4_DATA;
00155        
00156        if (dba->cursor) dba->cursor->c_close(dba->cursor);
00157        dba->dbp->close(dba->dbp, 0);
00158        pefree(dba, info->flags&DBA_PERSISTENT);
00159 }
00160 
00161 DBA_FETCH_FUNC(db4)
00162 {
00163        DBT gval;
00164        char *new = NULL;
00165        DB4_DATA;
00166        DB4_GKEY;
00167        
00168        memset(&gval, 0, sizeof(gval));
00169        if (info->flags & DBA_PERSISTENT) {
00170               gval.flags |= DB_DBT_MALLOC;
00171        }
00172        if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
00173               if (newlen) *newlen = gval.size;
00174               new = estrndup(gval.data, gval.size);
00175               if (info->flags & DBA_PERSISTENT) {
00176                      free(gval.data);
00177               }
00178        }
00179        return new;
00180 }
00181 
00182 DBA_UPDATE_FUNC(db4)
00183 {
00184        DBT gval;
00185        DB4_DATA;
00186        DB4_GKEY;
00187        
00188        memset(&gval, 0, sizeof(gval));
00189        gval.data = (char *) val;
00190        gval.size = vallen;
00191 
00192        if (!dba->dbp->put(dba->dbp, NULL, &gkey, &gval, 
00193                             mode == 1 ? DB_NOOVERWRITE : 0)) {
00194               return SUCCESS;
00195        }
00196        return FAILURE;
00197 }
00198 
00199 DBA_EXISTS_FUNC(db4)
00200 {
00201        DBT gval;
00202        DB4_DATA;
00203        DB4_GKEY;
00204        
00205        memset(&gval, 0, sizeof(gval));
00206        
00207        if (info->flags & DBA_PERSISTENT) {
00208               gval.flags |= DB_DBT_MALLOC;
00209        }
00210 
00211        if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
00212               if (info->flags & DBA_PERSISTENT) {
00213                      free(gval.data);
00214               }
00215               return SUCCESS;
00216        }
00217        return FAILURE;
00218 }
00219 
00220 DBA_DELETE_FUNC(db4)
00221 {
00222        DB4_DATA;
00223        DB4_GKEY;
00224 
00225        return dba->dbp->del(dba->dbp, NULL, &gkey, 0) ? FAILURE : SUCCESS;
00226 }
00227 
00228 DBA_FIRSTKEY_FUNC(db4)
00229 {
00230        DB4_DATA;
00231 
00232        if (dba->cursor) {
00233               dba->cursor->c_close(dba->cursor);
00234        }
00235 
00236        dba->cursor = NULL;
00237        if (dba->dbp->cursor(dba->dbp, NULL, &dba->cursor, 0) != 0) {
00238               return NULL;
00239        }
00240 
00241        /* we should introduce something like PARAM_PASSTHRU... */
00242        return dba_nextkey_db4(info, newlen TSRMLS_CC);
00243 }
00244 
00245 DBA_NEXTKEY_FUNC(db4)
00246 {
00247        DB4_DATA;
00248        DBT gkey, gval;
00249        char *nkey = NULL;
00250        
00251        memset(&gkey, 0, sizeof(gkey));
00252        memset(&gval, 0, sizeof(gval));
00253 
00254        if (info->flags & DBA_PERSISTENT) {
00255               gkey.flags |= DB_DBT_MALLOC;
00256               gval.flags |= DB_DBT_MALLOC;
00257        }
00258        if (dba->cursor && dba->cursor->c_get(dba->cursor, &gkey, &gval, DB_NEXT) == 0) {
00259               if (gkey.data) {
00260                      nkey = estrndup(gkey.data, gkey.size);
00261                      if (newlen) *newlen = gkey.size;
00262               }
00263               if (info->flags & DBA_PERSISTENT) {
00264                      if (gkey.data) {
00265                             free(gkey.data);
00266                      }
00267                      if (gval.data) {
00268                             free(gval.data);
00269                      }
00270               }
00271        }
00272 
00273        return nkey;
00274 }
00275 
00276 DBA_OPTIMIZE_FUNC(db4)
00277 {
00278        return SUCCESS;
00279 }
00280 
00281 DBA_SYNC_FUNC(db4)
00282 {
00283        DB4_DATA;
00284 
00285        return dba->dbp->sync(dba->dbp, 0) ? FAILURE : SUCCESS;
00286 }
00287 
00288 DBA_INFO_FUNC(db4)
00289 {
00290        return estrdup(DB_VERSION_STRING);
00291 }
00292 
00293 #endif
00294 
00295 /*
00296  * Local variables:
00297  * tab-width: 4
00298  * c-basic-offset: 4
00299  * End:
00300  * vim600: sw=4 ts=4 fdm=marker
00301  * vim<600: sw=4 ts=4
00302  */