root/ext/dba/dba_db4.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. php_dba_db4_errcall_fcn
  2. DBA_OPEN_FUNC
  3. DBA_CLOSE_FUNC
  4. DBA_FETCH_FUNC
  5. DBA_UPDATE_FUNC
  6. DBA_EXISTS_FUNC
  7. DBA_DELETE_FUNC
  8. DBA_FIRSTKEY_FUNC
  9. DBA_NEXTKEY_FUNC
  10. DBA_OPTIMIZE_FUNC
  11. DBA_SYNC_FUNC
  12. DBA_INFO_FUNC

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 5                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 The PHP Group                                |
   6    +----------------------------------------------------------------------+
   7    | This source file is subject to version 3.01 of the PHP license,      |
   8    | that is bundled with this package in the file LICENSE, and is        |
   9    | available through the world-wide-web at the following url:           |
  10    | http://www.php.net/license/3_01.txt                                  |
  11    | If you did not receive a copy of the PHP license and are unable to   |
  12    | obtain it through the world-wide-web, please send a note to          |
  13    | license@php.net so we can mail you a copy immediately.               |
  14    +----------------------------------------------------------------------+
  15    | Authors: Marcus Boerger <helly@php.net>                              |
  16    |          Sascha Schumann <sascha@schumann.cx>                        |
  17    +----------------------------------------------------------------------+
  18  */
  19 
  20 /* $Id$ */
  21 
  22 #ifdef HAVE_CONFIG_H
  23 #include "config.h"
  24 #endif
  25 
  26 #include "php.h"
  27 
  28 #if DBA_DB4
  29 #include "php_db4.h"
  30 #include <sys/stat.h>
  31 
  32 #include <string.h>
  33 #ifdef DB4_INCLUDE_FILE
  34 #include DB4_INCLUDE_FILE
  35 #else
  36 #include <db.h>
  37 #endif
  38 
  39 static void php_dba_db4_errcall_fcn(
  40 #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3))
  41         const DB_ENV *dbenv, 
  42 #endif
  43         const char *errpfx, const char *msg)
  44 {
  45         TSRMLS_FETCH();
  46 
  47 #if (DB_VERSION_MAJOR == 5 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 8))
  48 /* Bug 51086, Berkeley DB 4.8.26 */
  49 /* This code suppresses a BDB 4.8+ error message, thus keeping PHP test compatibility */
  50         {
  51                 const char *function = get_active_function_name(TSRMLS_C);
  52                 if (function && (!strcmp(function,"dba_popen") || !strcmp(function,"dba_open"))
  53                         && (!strncmp(msg, "fop_read_meta", sizeof("fop_read_meta")-1)
  54                                 || !strncmp(msg, "BDB0004 fop_read_meta", sizeof("BDB0004 fop_read_meta")-1))) {
  55                         return;
  56                 }
  57         }
  58 #endif
  59 
  60         php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s%s", errpfx?errpfx:"", msg);
  61 }
  62 
  63 #define DB4_DATA dba_db4_data *dba = info->dbf
  64 #define DB4_GKEY \
  65         DBT gkey; \
  66         memset(&gkey, 0, sizeof(gkey)); \
  67         gkey.data = (char *) key; gkey.size = keylen
  68 
  69 typedef struct {
  70         DB *dbp;
  71         DBC *cursor;
  72 } dba_db4_data;
  73 
  74 DBA_OPEN_FUNC(db4)
  75 {
  76         DB *dbp = NULL;
  77         DBTYPE type;
  78         int gmode = 0, err;
  79         int filemode = 0644;
  80         struct stat check_stat;
  81         int s = VCWD_STAT(info->path, &check_stat);
  82 
  83 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR <= 7)  /* Bug 51086 */
  84         if (!s && !check_stat.st_size) {
  85                 info->mode = DBA_TRUNC; /* force truncate */
  86         }
  87 
  88         type = info->mode == DBA_READER ? DB_UNKNOWN :
  89                 info->mode == DBA_TRUNC ? DB_BTREE :
  90                 s ? DB_BTREE : DB_UNKNOWN;
  91           
  92         gmode = info->mode == DBA_READER ? DB_RDONLY :
  93                 (info->mode == DBA_CREAT && s) ? DB_CREATE : 
  94                 (info->mode == DBA_CREAT && !s) ? 0 :
  95                 info->mode == DBA_WRITER ? 0         : 
  96                 info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1;
  97 #else
  98         if (!s && !check_stat.st_size) {
  99                 info->mode = DBA_CREAT; /* force creation */
 100         }
 101 
 102         type = info->mode == DBA_READER ? DB_UNKNOWN :
 103                 (info->mode == DBA_TRUNC || info->mode == DBA_CREAT) ? DB_BTREE :
 104                 s ? DB_BTREE : DB_UNKNOWN;
 105           
 106         gmode = info->mode == DBA_READER ? DB_RDONLY :
 107                 info->mode == DBA_CREAT ? DB_CREATE : 
 108                 info->mode == DBA_WRITER ? 0         : 
 109                 info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1;
 110 #endif
 111 
 112         if (gmode == -1) {
 113                 return FAILURE; /* not possible */
 114         }
 115 
 116         if (info->flags & DBA_PERSISTENT) {
 117                 gmode |= DB_THREAD;
 118         }
 119 
 120         if (info->argc > 0) {
 121                 convert_to_long_ex(info->argv[0]);
 122                 filemode = Z_LVAL_PP(info->argv[0]);
 123         }
 124 
 125         if ((err=db_create(&dbp, NULL, 0)) == 0) {
 126             dbp->set_errcall(dbp, php_dba_db4_errcall_fcn);
 127             if (
 128 #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1))
 129                         (err=dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) {
 130 #else
 131                         (err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) {
 132 #endif
 133                         dba_db4_data *data;
 134 
 135                         data = pemalloc(sizeof(*data), info->flags&DBA_PERSISTENT);
 136                         data->dbp = dbp;
 137                         data->cursor = NULL;
 138                         info->dbf = data;
 139                 
 140                         return SUCCESS;
 141                 } else {
 142                         dbp->close(dbp, 0);
 143                         *error = db_strerror(err);
 144                 }
 145         } else {
 146                 *error = db_strerror(err);
 147         }
 148 
 149         return FAILURE;
 150 }
 151 
 152 DBA_CLOSE_FUNC(db4)
 153 {
 154         DB4_DATA;
 155         
 156         if (dba->cursor) dba->cursor->c_close(dba->cursor);
 157         dba->dbp->close(dba->dbp, 0);
 158         pefree(dba, info->flags&DBA_PERSISTENT);
 159 }
 160 
 161 DBA_FETCH_FUNC(db4)
 162 {
 163         DBT gval;
 164         char *new = NULL;
 165         DB4_DATA;
 166         DB4_GKEY;
 167         
 168         memset(&gval, 0, sizeof(gval));
 169         if (info->flags & DBA_PERSISTENT) {
 170                 gval.flags |= DB_DBT_MALLOC;
 171         }
 172         if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
 173                 if (newlen) *newlen = gval.size;
 174                 new = estrndup(gval.data, gval.size);
 175                 if (info->flags & DBA_PERSISTENT) {
 176                         free(gval.data);
 177                 }
 178         }
 179         return new;
 180 }
 181 
 182 DBA_UPDATE_FUNC(db4)
 183 {
 184         DBT gval;
 185         DB4_DATA;
 186         DB4_GKEY;
 187         
 188         memset(&gval, 0, sizeof(gval));
 189         gval.data = (char *) val;
 190         gval.size = vallen;
 191 
 192         if (!dba->dbp->put(dba->dbp, NULL, &gkey, &gval, 
 193                                 mode == 1 ? DB_NOOVERWRITE : 0)) {
 194                 return SUCCESS;
 195         }
 196         return FAILURE;
 197 }
 198 
 199 DBA_EXISTS_FUNC(db4)
 200 {
 201         DBT gval;
 202         DB4_DATA;
 203         DB4_GKEY;
 204         
 205         memset(&gval, 0, sizeof(gval));
 206         
 207         if (info->flags & DBA_PERSISTENT) {
 208                 gval.flags |= DB_DBT_MALLOC;
 209         }
 210 
 211         if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
 212                 if (info->flags & DBA_PERSISTENT) {
 213                         free(gval.data);
 214                 }
 215                 return SUCCESS;
 216         }
 217         return FAILURE;
 218 }
 219 
 220 DBA_DELETE_FUNC(db4)
 221 {
 222         DB4_DATA;
 223         DB4_GKEY;
 224 
 225         return dba->dbp->del(dba->dbp, NULL, &gkey, 0) ? FAILURE : SUCCESS;
 226 }
 227 
 228 DBA_FIRSTKEY_FUNC(db4)
 229 {
 230         DB4_DATA;
 231 
 232         if (dba->cursor) {
 233                 dba->cursor->c_close(dba->cursor);
 234         }
 235 
 236         dba->cursor = NULL;
 237         if (dba->dbp->cursor(dba->dbp, NULL, &dba->cursor, 0) != 0) {
 238                 return NULL;
 239         }
 240 
 241         /* we should introduce something like PARAM_PASSTHRU... */
 242         return dba_nextkey_db4(info, newlen TSRMLS_CC);
 243 }
 244 
 245 DBA_NEXTKEY_FUNC(db4)
 246 {
 247         DB4_DATA;
 248         DBT gkey, gval;
 249         char *nkey = NULL;
 250         
 251         memset(&gkey, 0, sizeof(gkey));
 252         memset(&gval, 0, sizeof(gval));
 253 
 254         if (info->flags & DBA_PERSISTENT) {
 255                 gkey.flags |= DB_DBT_MALLOC;
 256                 gval.flags |= DB_DBT_MALLOC;
 257         }
 258         if (dba->cursor && dba->cursor->c_get(dba->cursor, &gkey, &gval, DB_NEXT) == 0) {
 259                 if (gkey.data) {
 260                         nkey = estrndup(gkey.data, gkey.size);
 261                         if (newlen) *newlen = gkey.size;
 262                 }
 263                 if (info->flags & DBA_PERSISTENT) {
 264                         if (gkey.data) {
 265                                 free(gkey.data);
 266                         }
 267                         if (gval.data) {
 268                                 free(gval.data);
 269                         }
 270                 }
 271         }
 272 
 273         return nkey;
 274 }
 275 
 276 DBA_OPTIMIZE_FUNC(db4)
 277 {
 278         return SUCCESS;
 279 }
 280 
 281 DBA_SYNC_FUNC(db4)
 282 {
 283         DB4_DATA;
 284 
 285         return dba->dbp->sync(dba->dbp, 0) ? FAILURE : SUCCESS;
 286 }
 287 
 288 DBA_INFO_FUNC(db4)
 289 {
 290         return estrdup(DB_VERSION_STRING);
 291 }
 292 
 293 #endif
 294 
 295 /*
 296  * Local variables:
 297  * tab-width: 4
 298  * c-basic-offset: 4
 299  * End:
 300  * vim600: sw=4 ts=4 fdm=marker
 301  * vim<600: sw=4 ts=4
 302  */

/* [<][>][^][v][top][bottom][index][help] */