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 7                                                        |
   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 
  46 #if (DB_VERSION_MAJOR == 5 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 8))
  47 /* Bug 51086, Berkeley DB 4.8.26 */
  48 /* This code suppresses a BDB 4.8+ error message, thus keeping PHP test compatibility */
  49         {
  50                 const char *function = get_active_function_name();
  51                 if (function && (!strcmp(function,"dba_popen") || !strcmp(function,"dba_open"))
  52                         && (!strncmp(msg, "fop_read_meta", sizeof("fop_read_meta")-1)
  53                                 || !strncmp(msg, "BDB0004 fop_read_meta", sizeof("BDB0004 fop_read_meta")-1))) {
  54                         return;
  55                 }
  56         }
  57 #endif
  58 
  59         php_error_docref(NULL, E_NOTICE, "%s%s", errpfx?errpfx:"", msg);
  60 }
  61 
  62 #define DB4_DATA dba_db4_data *dba = info->dbf
  63 #define DB4_GKEY \
  64         DBT gkey; \
  65         memset(&gkey, 0, sizeof(gkey)); \
  66         gkey.data = (char *) key; gkey.size = keylen
  67 
  68 typedef struct {
  69         DB *dbp;
  70         DBC *cursor;
  71 } dba_db4_data;
  72 
  73 DBA_OPEN_FUNC(db4)
  74 {
  75         DB *dbp = NULL;
  76         DBTYPE type;
  77         int gmode = 0, err;
  78         int filemode = 0644;
  79         struct stat check_stat;
  80         int s = VCWD_STAT(info->path, &check_stat);
  81 
  82 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR <= 7)  /* Bug 51086 */
  83         if (!s && !check_stat.st_size) {
  84                 info->mode = DBA_TRUNC; /* force truncate */
  85         }
  86 
  87         type = info->mode == DBA_READER ? DB_UNKNOWN :
  88                 info->mode == DBA_TRUNC ? DB_BTREE :
  89                 s ? DB_BTREE : DB_UNKNOWN;
  90 
  91         gmode = info->mode == DBA_READER ? DB_RDONLY :
  92                 (info->mode == DBA_CREAT && s) ? DB_CREATE :
  93                 (info->mode == DBA_CREAT && !s) ? 0 :
  94                 info->mode == DBA_WRITER ? 0         :
  95                 info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1;
  96 #else
  97         if (!s && !check_stat.st_size) {
  98                 info->mode = DBA_CREAT; /* force creation */
  99         }
 100 
 101         type = info->mode == DBA_READER ? DB_UNKNOWN :
 102                 (info->mode == DBA_TRUNC || info->mode == DBA_CREAT) ? DB_BTREE :
 103                 s ? DB_BTREE : DB_UNKNOWN;
 104 
 105         gmode = info->mode == DBA_READER ? DB_RDONLY :
 106                 info->mode == DBA_CREAT ? DB_CREATE :
 107                 info->mode == DBA_WRITER ? 0         :
 108                 info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1;
 109 #endif
 110 
 111         if (gmode == -1) {
 112                 return FAILURE; /* not possible */
 113         }
 114 
 115         if (info->flags & DBA_PERSISTENT) {
 116                 gmode |= DB_THREAD;
 117         }
 118 
 119         if (info->argc > 0) {
 120                 convert_to_long_ex(&info->argv[0]);
 121                 filemode = Z_LVAL(info->argv[0]);
 122         }
 123 
 124         if ((err=db_create(&dbp, NULL, 0)) == 0) {
 125             dbp->set_errcall(dbp, php_dba_db4_errcall_fcn);
 126             if (
 127 #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1))
 128                         (err=dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) {
 129 #else
 130                         (err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) {
 131 #endif
 132                         dba_db4_data *data;
 133 
 134                         data = pemalloc(sizeof(*data), info->flags&DBA_PERSISTENT);
 135                         data->dbp = dbp;
 136                         data->cursor = NULL;
 137                         info->dbf = data;
 138 
 139                         return SUCCESS;
 140                 } else {
 141                         dbp->close(dbp, 0);
 142                         *error = db_strerror(err);
 143                 }
 144         } else {
 145                 *error = db_strerror(err);
 146         }
 147 
 148         return FAILURE;
 149 }
 150 
 151 DBA_CLOSE_FUNC(db4)
 152 {
 153         DB4_DATA;
 154 
 155         if (dba->cursor) dba->cursor->c_close(dba->cursor);
 156         dba->dbp->close(dba->dbp, 0);
 157         pefree(dba, info->flags&DBA_PERSISTENT);
 158 }
 159 
 160 DBA_FETCH_FUNC(db4)
 161 {
 162         DBT gval;
 163         char *new = NULL;
 164         DB4_DATA;
 165         DB4_GKEY;
 166 
 167         memset(&gval, 0, sizeof(gval));
 168         if (info->flags & DBA_PERSISTENT) {
 169                 gval.flags |= DB_DBT_MALLOC;
 170         }
 171         if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
 172                 if (newlen) *newlen = gval.size;
 173                 new = estrndup(gval.data, gval.size);
 174                 if (info->flags & DBA_PERSISTENT) {
 175                         free(gval.data);
 176                 }
 177         }
 178         return new;
 179 }
 180 
 181 DBA_UPDATE_FUNC(db4)
 182 {
 183         DBT gval;
 184         DB4_DATA;
 185         DB4_GKEY;
 186 
 187         memset(&gval, 0, sizeof(gval));
 188         gval.data = (char *) val;
 189         gval.size = vallen;
 190 
 191         if (!dba->dbp->put(dba->dbp, NULL, &gkey, &gval,
 192                                 mode == 1 ? DB_NOOVERWRITE : 0)) {
 193                 return SUCCESS;
 194         }
 195         return FAILURE;
 196 }
 197 
 198 DBA_EXISTS_FUNC(db4)
 199 {
 200         DBT gval;
 201         DB4_DATA;
 202         DB4_GKEY;
 203 
 204         memset(&gval, 0, sizeof(gval));
 205 
 206         if (info->flags & DBA_PERSISTENT) {
 207                 gval.flags |= DB_DBT_MALLOC;
 208         }
 209 
 210         if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
 211                 if (info->flags & DBA_PERSISTENT) {
 212                         free(gval.data);
 213                 }
 214                 return SUCCESS;
 215         }
 216         return FAILURE;
 217 }
 218 
 219 DBA_DELETE_FUNC(db4)
 220 {
 221         DB4_DATA;
 222         DB4_GKEY;
 223 
 224         return dba->dbp->del(dba->dbp, NULL, &gkey, 0) ? FAILURE : SUCCESS;
 225 }
 226 
 227 DBA_FIRSTKEY_FUNC(db4)
 228 {
 229         DB4_DATA;
 230 
 231         if (dba->cursor) {
 232                 dba->cursor->c_close(dba->cursor);
 233         }
 234 
 235         dba->cursor = NULL;
 236         if (dba->dbp->cursor(dba->dbp, NULL, &dba->cursor, 0) != 0) {
 237                 return NULL;
 238         }
 239 
 240         /* we should introduce something like PARAM_PASSTHRU... */
 241         return dba_nextkey_db4(info, newlen);
 242 }
 243 
 244 DBA_NEXTKEY_FUNC(db4)
 245 {
 246         DB4_DATA;
 247         DBT gkey, gval;
 248         char *nkey = NULL;
 249 
 250         memset(&gkey, 0, sizeof(gkey));
 251         memset(&gval, 0, sizeof(gval));
 252 
 253         if (info->flags & DBA_PERSISTENT) {
 254                 gkey.flags |= DB_DBT_MALLOC;
 255                 gval.flags |= DB_DBT_MALLOC;
 256         }
 257         if (dba->cursor && dba->cursor->c_get(dba->cursor, &gkey, &gval, DB_NEXT) == 0) {
 258                 if (gkey.data) {
 259                         nkey = estrndup(gkey.data, gkey.size);
 260                         if (newlen) *newlen = gkey.size;
 261                 }
 262                 if (info->flags & DBA_PERSISTENT) {
 263                         if (gkey.data) {
 264                                 free(gkey.data);
 265                         }
 266                         if (gval.data) {
 267                                 free(gval.data);
 268                         }
 269                 }
 270         }
 271 
 272         return nkey;
 273 }
 274 
 275 DBA_OPTIMIZE_FUNC(db4)
 276 {
 277         return SUCCESS;
 278 }
 279 
 280 DBA_SYNC_FUNC(db4)
 281 {
 282         DB4_DATA;
 283 
 284         return dba->dbp->sync(dba->dbp, 0) ? FAILURE : SUCCESS;
 285 }
 286 
 287 DBA_INFO_FUNC(db4)
 288 {
 289         return estrdup(DB_VERSION_STRING);
 290 }
 291 
 292 #endif
 293 
 294 /*
 295  * Local variables:
 296  * tab-width: 4
 297  * c-basic-offset: 4
 298  * End:
 299  * vim600: sw=4 ts=4 fdm=marker
 300  * vim<600: sw=4 ts=4
 301  */

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