![]() ![]() | ![]() |
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.3 ! misho 5: | Copyright (c) 1997-2013 The PHP Group |
1.1 misho 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: | Author: Sascha Schumann <sascha@schumann.cx> |
16: +----------------------------------------------------------------------+
17: */
18:
1.1.1.2 misho 19: /* $Id$ */
1.1 misho 20:
21: #ifdef HAVE_CONFIG_H
22: #include "config.h"
23: #endif
24:
25: #include "php.h"
26:
27: #if DBA_DB3
28: #include "php_db3.h"
29: #include <sys/stat.h>
30:
31: #include <string.h>
32: #ifdef DB3_INCLUDE_FILE
33: #include DB3_INCLUDE_FILE
34: #else
35: #include <db.h>
36: #endif
37:
38: static void php_dba_db3_errcall_fcn(const char *errpfx, char *msg)
39: {
40: TSRMLS_FETCH();
41:
42: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s%s", errpfx?errpfx:"", msg);
43: }
44:
45: #define DB3_DATA dba_db3_data *dba = info->dbf
46: #define DB3_GKEY \
47: DBT gkey; \
48: memset(&gkey, 0, sizeof(gkey)); \
49: gkey.data = (char *) key; gkey.size = keylen
50:
51: typedef struct {
52: DB *dbp;
53: DBC *cursor;
54: } dba_db3_data;
55:
56: DBA_OPEN_FUNC(db3)
57: {
58: DB *dbp = NULL;
59: DBTYPE type;
60: int gmode = 0, err;
61: int filemode = 0644;
62: struct stat check_stat;
63: int s = VCWD_STAT(info->path, &check_stat);
64:
65: if (!s && !check_stat.st_size) {
66: info->mode = DBA_TRUNC; /* force truncate */
67: }
68:
69: type = info->mode == DBA_READER ? DB_UNKNOWN :
70: info->mode == DBA_TRUNC ? DB_BTREE :
71: s ? DB_BTREE : DB_UNKNOWN;
72:
73: gmode = info->mode == DBA_READER ? DB_RDONLY :
74: (info->mode == DBA_CREAT && s) ? DB_CREATE :
75: (info->mode == DBA_CREAT && !s) ? 0 :
76: info->mode == DBA_WRITER ? 0 :
77: info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1;
78:
79: if (gmode == -1) {
80: return FAILURE; /* not possible */
81: }
82:
83: if (info->argc > 0) {
84: convert_to_long_ex(info->argv[0]);
85: filemode = Z_LVAL_PP(info->argv[0]);
86: }
87:
88: #ifdef DB_FCNTL_LOCKING
89: gmode |= DB_FCNTL_LOCKING;
90: #endif
91:
92: if ((err=db_create(&dbp, NULL, 0)) == 0) {
93: dbp->set_errcall(dbp, php_dba_db3_errcall_fcn);
94: if ((err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) {
95: dba_db3_data *data;
96:
97: data = pemalloc(sizeof(*data), info->flags&DBA_PERSISTENT);
98: data->dbp = dbp;
99: data->cursor = NULL;
100: info->dbf = data;
101:
102: return SUCCESS;
103: } else {
104: dbp->close(dbp, 0);
105: *error = db_strerror(err);
106: }
107: } else {
108: *error = db_strerror(err);
109: }
110:
111: return FAILURE;
112: }
113:
114: DBA_CLOSE_FUNC(db3)
115: {
116: DB3_DATA;
117:
118: if (dba->cursor) dba->cursor->c_close(dba->cursor);
119: dba->dbp->close(dba->dbp, 0);
120: pefree(dba, info->flags&DBA_PERSISTENT);
121: }
122:
123: DBA_FETCH_FUNC(db3)
124: {
125: DBT gval;
126: char *new = NULL;
127: DB3_DATA;
128: DB3_GKEY;
129:
130: memset(&gval, 0, sizeof(gval));
131: if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
132: if (newlen) *newlen = gval.size;
133: new = estrndup(gval.data, gval.size);
134: }
135: return new;
136: }
137:
138: DBA_UPDATE_FUNC(db3)
139: {
140: DBT gval;
141: DB3_DATA;
142: DB3_GKEY;
143:
144: memset(&gval, 0, sizeof(gval));
145: gval.data = (char *) val;
146: gval.size = vallen;
147:
148: if (!dba->dbp->put(dba->dbp, NULL, &gkey, &gval,
149: mode == 1 ? DB_NOOVERWRITE : 0)) {
150: return SUCCESS;
151: }
152: return FAILURE;
153: }
154:
155: DBA_EXISTS_FUNC(db3)
156: {
157: DBT gval;
158: DB3_DATA;
159: DB3_GKEY;
160:
161: memset(&gval, 0, sizeof(gval));
162: if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
163: return SUCCESS;
164: }
165: return FAILURE;
166: }
167:
168: DBA_DELETE_FUNC(db3)
169: {
170: DB3_DATA;
171: DB3_GKEY;
172:
173: return dba->dbp->del(dba->dbp, NULL, &gkey, 0) ? FAILURE : SUCCESS;
174: }
175:
176: DBA_FIRSTKEY_FUNC(db3)
177: {
178: DB3_DATA;
179:
180: if (dba->cursor) {
181: dba->cursor->c_close(dba->cursor);
182: }
183:
184: dba->cursor = NULL;
185: if (dba->dbp->cursor(dba->dbp, NULL, &dba->cursor, 0) != 0) {
186: return NULL;
187: }
188:
189: /* we should introduce something like PARAM_PASSTHRU... */
190: return dba_nextkey_db3(info, newlen TSRMLS_CC);
191: }
192:
193: DBA_NEXTKEY_FUNC(db3)
194: {
195: DB3_DATA;
196: DBT gkey, gval;
197: char *nkey = NULL;
198:
199: memset(&gkey, 0, sizeof(gkey));
200: memset(&gval, 0, sizeof(gval));
201:
202: if (dba->cursor->c_get(dba->cursor, &gkey, &gval, DB_NEXT) == 0) {
203: if (gkey.data) {
204: nkey = estrndup(gkey.data, gkey.size);
205: if (newlen) *newlen = gkey.size;
206: }
207: }
208:
209: return nkey;
210: }
211:
212: DBA_OPTIMIZE_FUNC(db3)
213: {
214: return SUCCESS;
215: }
216:
217: DBA_SYNC_FUNC(db3)
218: {
219: DB3_DATA;
220:
221: return dba->dbp->sync(dba->dbp, 0) ? FAILURE : SUCCESS;
222: }
223:
224: DBA_INFO_FUNC(db3)
225: {
226: return estrdup(DB_VERSION_STRING);
227: }
228:
229: #endif
230:
231: /*
232: * Local variables:
233: * tab-width: 4
234: * c-basic-offset: 4
235: * End:
236: * vim600: sw=4 ts=4 fdm=marker
237: * vim<600: sw=4 ts=4
238: */