Back to index

php5  5.3.10
dba_db3.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    | Author: Sascha Schumann <sascha@schumann.cx>                         |
00016    +----------------------------------------------------------------------+
00017  */
00018 
00019 /* $Id: dba_db3.c 321634 2012-01-01 13:15:04Z felipe $ */
00020 
00021 #ifdef HAVE_CONFIG_H
00022 #include "config.h"
00023 #endif
00024 
00025 #include "php.h"
00026 
00027 #if DBA_DB3
00028 #include "php_db3.h"
00029 #include <sys/stat.h>
00030 
00031 #include <string.h>
00032 #ifdef DB3_INCLUDE_FILE
00033 #include DB3_INCLUDE_FILE
00034 #else
00035 #include <db.h>
00036 #endif
00037 
00038 static void php_dba_db3_errcall_fcn(const char *errpfx, char *msg)
00039 {
00040        TSRMLS_FETCH();
00041        
00042        php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s%s", errpfx?errpfx:"", msg);
00043 }
00044 
00045 #define DB3_DATA dba_db3_data *dba = info->dbf
00046 #define DB3_GKEY \
00047        DBT gkey; \
00048        memset(&gkey, 0, sizeof(gkey)); \
00049        gkey.data = (char *) key; gkey.size = keylen
00050 
00051 typedef struct {
00052        DB *dbp;
00053        DBC *cursor;
00054 } dba_db3_data;
00055 
00056 DBA_OPEN_FUNC(db3)
00057 {
00058        DB *dbp = NULL;
00059        DBTYPE type;
00060        int gmode = 0, err;
00061        int filemode = 0644;
00062        struct stat check_stat;
00063        int s = VCWD_STAT(info->path, &check_stat);
00064 
00065        if (!s && !check_stat.st_size) {
00066               info->mode = DBA_TRUNC; /* force truncate */
00067        }
00068 
00069        type = info->mode == DBA_READER ? DB_UNKNOWN :
00070               info->mode == DBA_TRUNC ? DB_BTREE :
00071               s ? DB_BTREE : DB_UNKNOWN;
00072          
00073        gmode = info->mode == DBA_READER ? DB_RDONLY :
00074               (info->mode == DBA_CREAT && s) ? DB_CREATE : 
00075               (info->mode == DBA_CREAT && !s) ? 0 :
00076               info->mode == DBA_WRITER ? 0         : 
00077               info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1;
00078 
00079        if (gmode == -1) {
00080               return FAILURE; /* not possible */
00081        }
00082 
00083        if (info->argc > 0) {
00084               convert_to_long_ex(info->argv[0]);
00085               filemode = Z_LVAL_PP(info->argv[0]);
00086        }
00087 
00088 #ifdef DB_FCNTL_LOCKING
00089        gmode |= DB_FCNTL_LOCKING;
00090 #endif
00091 
00092        if ((err=db_create(&dbp, NULL, 0)) == 0) {
00093            dbp->set_errcall(dbp, php_dba_db3_errcall_fcn);
00094            if ((err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) {
00095                      dba_db3_data *data;
00096 
00097                      data = pemalloc(sizeof(*data), info->flags&DBA_PERSISTENT);
00098                      data->dbp = dbp;
00099                      data->cursor = NULL;
00100                      info->dbf = data;
00101               
00102                      return SUCCESS;
00103               } else {
00104                      dbp->close(dbp, 0);
00105                      *error = db_strerror(err);
00106               }
00107        } else {
00108               *error = db_strerror(err);
00109        }
00110 
00111        return FAILURE;
00112 }
00113 
00114 DBA_CLOSE_FUNC(db3)
00115 {
00116        DB3_DATA;
00117        
00118        if (dba->cursor) dba->cursor->c_close(dba->cursor);
00119        dba->dbp->close(dba->dbp, 0);
00120        pefree(dba, info->flags&DBA_PERSISTENT);
00121 }
00122 
00123 DBA_FETCH_FUNC(db3)
00124 {
00125        DBT gval;
00126        char *new = NULL;
00127        DB3_DATA;
00128        DB3_GKEY;
00129        
00130        memset(&gval, 0, sizeof(gval));
00131        if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
00132               if (newlen) *newlen = gval.size;
00133               new = estrndup(gval.data, gval.size);
00134        }
00135        return new;
00136 }
00137 
00138 DBA_UPDATE_FUNC(db3)
00139 {
00140        DBT gval;
00141        DB3_DATA;
00142        DB3_GKEY;
00143        
00144        memset(&gval, 0, sizeof(gval));
00145        gval.data = (char *) val;
00146        gval.size = vallen;
00147 
00148        if (!dba->dbp->put(dba->dbp, NULL, &gkey, &gval, 
00149                             mode == 1 ? DB_NOOVERWRITE : 0)) {
00150               return SUCCESS;
00151        }
00152        return FAILURE;
00153 }
00154 
00155 DBA_EXISTS_FUNC(db3)
00156 {
00157        DBT gval;
00158        DB3_DATA;
00159        DB3_GKEY;
00160        
00161        memset(&gval, 0, sizeof(gval));
00162        if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
00163               return SUCCESS;
00164        }
00165        return FAILURE;
00166 }
00167 
00168 DBA_DELETE_FUNC(db3)
00169 {
00170        DB3_DATA;
00171        DB3_GKEY;
00172 
00173        return dba->dbp->del(dba->dbp, NULL, &gkey, 0) ? FAILURE : SUCCESS;
00174 }
00175 
00176 DBA_FIRSTKEY_FUNC(db3)
00177 {
00178        DB3_DATA;
00179 
00180        if (dba->cursor) {
00181               dba->cursor->c_close(dba->cursor);
00182        }
00183 
00184        dba->cursor = NULL;
00185        if (dba->dbp->cursor(dba->dbp, NULL, &dba->cursor, 0) != 0) {
00186               return NULL;
00187        }
00188 
00189        /* we should introduce something like PARAM_PASSTHRU... */
00190        return dba_nextkey_db3(info, newlen TSRMLS_CC);
00191 }
00192 
00193 DBA_NEXTKEY_FUNC(db3)
00194 {
00195        DB3_DATA;
00196        DBT gkey, gval;
00197        char *nkey = NULL;
00198        
00199        memset(&gkey, 0, sizeof(gkey));
00200        memset(&gval, 0, sizeof(gval));
00201 
00202        if (dba->cursor->c_get(dba->cursor, &gkey, &gval, DB_NEXT) == 0) {
00203               if (gkey.data) {
00204                      nkey = estrndup(gkey.data, gkey.size);
00205                      if (newlen) *newlen = gkey.size;
00206               }
00207        }
00208 
00209        return nkey;
00210 }
00211 
00212 DBA_OPTIMIZE_FUNC(db3)
00213 {
00214        return SUCCESS;
00215 }
00216 
00217 DBA_SYNC_FUNC(db3)
00218 {
00219        DB3_DATA;
00220 
00221        return dba->dbp->sync(dba->dbp, 0) ? FAILURE : SUCCESS;
00222 }
00223 
00224 DBA_INFO_FUNC(db3)
00225 {
00226        return estrdup(DB_VERSION_STRING);
00227 }
00228 
00229 #endif
00230 
00231 /*
00232  * Local variables:
00233  * tab-width: 4
00234  * c-basic-offset: 4
00235  * End:
00236  * vim600: sw=4 ts=4 fdm=marker
00237  * vim<600: sw=4 ts=4
00238  */