File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / dba / dba_db4.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:34:37 2012 UTC (12 years, 1 month ago) by misho
Branches: php, MAIN
CVS tags: v5_4_3elwix, v5_4_17p0, HEAD
php 5.4.3+patches

    1: /*
    2:    +----------------------------------------------------------------------+
    3:    | PHP Version 5                                                        |
    4:    +----------------------------------------------------------------------+
    5:    | Copyright (c) 1997-2012 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: dba_db4.c,v 1.1.1.2 2012/05/29 12:34:37 misho Exp $ */
   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:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>