1 /*-
2  * Copyright (c) 2004, 2020 Oracle and/or its affiliates.  All rights reserved.
3  *
4  * See the file LICENSE for license information.
5  *
6  * http://www.apache.org/licenses/LICENSE-2.0.txt
7  *
8  * authors: George Schlossnagle <george@omniti.com>
9  */
10 
11 #ifdef HAVE_CONFIG_H
12 #include "config.h"
13 #endif
14 
15 // this is here to work around a PHP build issue on Windows
16 #include <iostream>
17 
18 extern "C"
19 {
20 #include "php.h"
21 #include "php_ini.h"
22 #include "ext/standard/info.h"
23 #include "php_db4.h"
24 }
25 #include "db_cxx.h"
26 
27 #define my_db_create db_create
28 #define my_db_env_create db_env_create
29 
30 /* True global resources - no need for thread safety here */
31 static int le_db;
32 static int le_dbc;
33 static int le_db_txn;
34 static int le_dbenv;
35 
36 struct php_DB_TXN {
37     DB_TXN *db_txn;
38     struct my_llist *open_cursors;
39     struct my_llist *open_dbs;
40 };
41 
42 struct php_DBC {
43     DBC *dbc;
44     struct php_DB_TXN *parent_txn;
45     struct php_DB *parent_db;
46 };
47 
48 struct php_DB {
49     DB *db;
50     struct my_llist *open_cursors;
51 };
52 
53 struct php_DB_ENV {
54     DB_ENV *dbenv;
55 };
56 
_free_php_db_txn(zend_resource * rsrc TSRMLS_DC)57 static void _free_php_db_txn(zend_resource *rsrc TSRMLS_DC)
58 {
59     struct php_DB_TXN *pdbtxn = (struct php_DB_TXN *) rsrc->ptr;
60     /* should probably iterate over open_cursors */
61     if(pdbtxn->db_txn) pdbtxn->db_txn->abort(pdbtxn->db_txn);
62     pdbtxn->db_txn = NULL;
63     if(pdbtxn) efree(pdbtxn);
64 }
65 
_free_php_dbc(zend_resource * rsrc TSRMLS_DC)66 static void _free_php_dbc(zend_resource *rsrc TSRMLS_DC)
67 {
68     struct php_DBC *pdbc = (struct php_DBC *) rsrc->ptr;
69     pdbc->dbc = NULL;
70     if(pdbc) efree(pdbc);
71     rsrc->ptr = NULL;
72 }
73 
_free_php_db(zend_resource * rsrc TSRMLS_DC)74 static void _free_php_db(zend_resource *rsrc TSRMLS_DC)
75 {
76     struct php_DB *pdb = (struct php_DB *) rsrc->ptr;
77     if(pdb->db) pdb->db->close(pdb->db, 0);
78     pdb->db = NULL;
79     if(pdb) efree(pdb);
80 }
81 
_free_php_dbenv(zend_resource * rsrc TSRMLS_DC)82 static void _free_php_dbenv(zend_resource *rsrc TSRMLS_DC)
83 {
84     struct php_DB_ENV *pdb = (struct php_DB_ENV *)rsrc->ptr;
85     DbEnv *dbe;
86 	if(pdb->dbenv) {
87 		dbe = DbEnv::get_DbEnv(pdb->dbenv);
88 	    if(dbe) dbe->close(0);
89 		delete dbe;
90 	}
91 	if(pdb) efree(pdb);
92 }
93 
94 static zend_class_entry *db_txn_ce;
95 static zend_class_entry *dbc_ce;
96 static zend_class_entry *db_ce;
97 static zend_class_entry *db_env_ce;
98 
99 /* helpers */
100 struct my_llist {
101     void *data;
102     struct my_llist *next;
103     struct my_llist *prev;
104 };
105 
my_llist_add(struct my_llist * list,void * data)106 static struct my_llist *my_llist_add(struct my_llist *list, void *data) {
107     if(!list) {
108         list = (struct my_llist *)emalloc(sizeof(*list));
109         list->data = data;
110         list->next = list->prev = NULL;
111         return list;
112     } else {
113         struct my_llist *node;
114         node = (struct my_llist *)emalloc(sizeof(*node));
115         node->data = data;
116         node->next = list;
117         node->prev = NULL;
118         return node;
119     }
120 }
121 
my_llist_del(struct my_llist * list,void * data)122 static struct my_llist *my_llist_del(struct my_llist *list, void *data) {
123     struct my_llist *ptr = list;
124     if(!ptr) return NULL;
125     if(ptr->data == data) { /* special case, first element */
126         ptr = ptr->next;
127         efree(list);
128         return ptr;
129     }
130     while(ptr) {
131         if(data == ptr->data) {
132             if(ptr->prev) ptr->prev->next = ptr->next;
133             if(ptr->next) ptr->next->prev = ptr->prev;
134             efree(ptr);
135             break;
136         }
137         ptr = ptr->next;
138     }
139     return list;
140 }
141 
142 /* {{{ db4_functions[]
143  *
144  * Every user visible function must have an entry in db4_functions[].
145  */
146 zend_function_entry db4_functions[] = {
147     /* PHP_FE(db4_dbenv_create, NULL) */
148     {NULL, NULL, NULL}  /* Must be the last line in db4_functions[] */
149 };
150 /* }}} */
151 
152 PHP_MINIT_FUNCTION(db4);
153 PHP_MSHUTDOWN_FUNCTION(db4);
154 PHP_RINIT_FUNCTION(db4);
155 PHP_RSHUTDOWN_FUNCTION(db4);
156 PHP_MINFO_FUNCTION(db4);
157 
158 /* {{{ db4_module_entry
159  */
160 zend_module_entry db4_module_entry = {
161     STANDARD_MODULE_HEADER,
162     "db4",
163     db4_functions,
164     PHP_MINIT(db4),
165     PHP_MSHUTDOWN(db4),
166     NULL,
167     NULL,
168     PHP_MINFO(db4),
169     "0.9", /* Replace with version number for your extension */
170     STANDARD_MODULE_PROPERTIES
171 };
172 /* }}} */
173 
174 /* {{{ class entries
175  */
176 
177 /* {{{ DB4Txn method forward declarations
178  */
179 
db_txn_ce_get(void)180 zend_class_entry *db_txn_ce_get(void)
181 {
182     return db_txn_ce;
183 }
184 
185 ZEND_NAMED_FUNCTION(_wrap_db_txn_abort);
186 ZEND_NAMED_FUNCTION(_wrap_db_txn_commit);
187 ZEND_NAMED_FUNCTION(_wrap_db_txn_discard);
188 ZEND_NAMED_FUNCTION(_wrap_db_txn_id);
189 ZEND_NAMED_FUNCTION(_wrap_db_txn_set_timeout);
190 ZEND_NAMED_FUNCTION(_wrap_db_txn_set_name);
191 ZEND_NAMED_FUNCTION(_wrap_db_txn_get_name);
192 ZEND_NAMED_FUNCTION(_wrap_new_DbTxn);
193 
194 static zend_function_entry DbTxn_functions[] = {
195         ZEND_NAMED_FE(abort, _wrap_db_txn_abort, NULL)
196         ZEND_NAMED_FE(commit, _wrap_db_txn_commit, NULL)
197         ZEND_NAMED_FE(discard, _wrap_db_txn_discard, NULL)
198         ZEND_NAMED_FE(id, _wrap_db_txn_id, NULL)
199         ZEND_NAMED_FE(set_timeout, _wrap_db_txn_set_timeout, NULL)
200         ZEND_NAMED_FE(set_name, _wrap_db_txn_set_name, NULL)
201         ZEND_NAMED_FE(get_name, _wrap_db_txn_get_name, NULL)
202         ZEND_NAMED_FE(db4txn, _wrap_new_DbTxn, NULL)
203         { NULL, NULL, NULL}
204 };
205 /* }}} */
206 
207 /* {{{ DB4Cursor method forward declarations
208  */
209 
dbc_ce_get(void)210 zend_class_entry *dbc_ce_get(void)
211 {
212     return dbc_ce;
213 }
214 
215 ZEND_NAMED_FUNCTION(_wrap_dbc_close);
216 ZEND_NAMED_FUNCTION(_wrap_dbc_count);
217 ZEND_NAMED_FUNCTION(_wrap_dbc_del);
218 ZEND_NAMED_FUNCTION(_wrap_dbc_dup);
219 ZEND_NAMED_FUNCTION(_wrap_dbc_get);
220 ZEND_NAMED_FUNCTION(_wrap_dbc_put);
221 ZEND_NAMED_FUNCTION(_wrap_dbc_pget);
222 
223 ZEND_BEGIN_ARG_INFO(first_and_second_args_force_ref, 0)
224     ZEND_ARG_PASS_INFO(1)
225     ZEND_ARG_PASS_INFO(1)
226 ZEND_END_ARG_INFO();
227 
228 ZEND_BEGIN_ARG_INFO(first_and_second_and_third_args_force_ref, 0)
229     ZEND_ARG_PASS_INFO(1)
230     ZEND_ARG_PASS_INFO(1)
231 ZEND_END_ARG_INFO();
232 
233 static zend_function_entry Dbc_functions[] = {
234         ZEND_NAMED_FE(close, _wrap_dbc_close, NULL)
235         ZEND_NAMED_FE(count, _wrap_dbc_count, NULL)
236         ZEND_NAMED_FE(del, _wrap_dbc_del, NULL)
237         ZEND_NAMED_FE(dup, _wrap_dbc_dup, NULL)
238         ZEND_NAMED_FE(get, _wrap_dbc_get, first_and_second_args_force_ref)
239         ZEND_NAMED_FE(put, _wrap_dbc_put, NULL)
240         ZEND_NAMED_FE(pget, _wrap_dbc_pget, first_and_second_and_third_args_force_ref)
241         { NULL, NULL, NULL}
242 };
243 /* }}} */
244 
245 /* {{{ DB4Env method forward declarations
246  */
247 
db_env_ce_get(void)248 zend_class_entry *db_env_ce_get(void)
249 {
250     return db_env_ce;
251 }
252 
253 ZEND_NAMED_FUNCTION(_wrap_new_DbEnv);
254 ZEND_NAMED_FUNCTION(_wrap_db_env_close);
255 ZEND_NAMED_FUNCTION(_wrap_db_env_dbremove);
256 ZEND_NAMED_FUNCTION(_wrap_db_env_dbrename);
257 ZEND_NAMED_FUNCTION(_wrap_db_env_get_encrypt_flags);
258 ZEND_NAMED_FUNCTION(_wrap_db_env_open);
259 ZEND_NAMED_FUNCTION(_wrap_db_env_remove);
260 ZEND_NAMED_FUNCTION(_wrap_db_env_set_data_dir);
261 ZEND_NAMED_FUNCTION(_wrap_db_env_set_encrypt);
262 ZEND_NAMED_FUNCTION(_wrap_db_env_txn_begin);
263 ZEND_NAMED_FUNCTION(_wrap_db_env_txn_checkpoint);
264 
265 static zend_function_entry DbEnv_functions[] = {
266         ZEND_NAMED_FE(db4env, _wrap_new_DbEnv, NULL)
267         ZEND_NAMED_FE(close, _wrap_db_env_close, NULL)
268         ZEND_NAMED_FE(dbremove, _wrap_db_env_dbremove, NULL)
269         ZEND_NAMED_FE(dbrename, _wrap_db_env_dbrename, NULL)
270 		ZEND_NAMED_FE(get_encrypt, _wrap_db_env_get_encrypt_flags, NULL)
271         ZEND_NAMED_FE(open, _wrap_db_env_open, NULL)
272         ZEND_NAMED_FE(remove, _wrap_db_env_remove, NULL)
273         ZEND_NAMED_FE(set_data_dir, _wrap_db_env_set_data_dir, NULL)
274 		ZEND_NAMED_FE(set_encrypt, _wrap_db_env_set_encrypt, NULL)
275         ZEND_NAMED_FE(txn_begin, _wrap_db_env_txn_begin, NULL)
276         ZEND_NAMED_FE(txn_checkpoint, _wrap_db_env_txn_checkpoint, NULL)
277         { NULL, NULL, NULL}
278 };
279 
280 /* }}} */
281 
282 /* {{{ DB4 method forward declarations
283  */
284 
db_ce_get(void)285 zend_class_entry *db_ce_get(void)
286 {
287     return db_ce;
288 }
289 
290 ZEND_NAMED_FUNCTION(_wrap_new_db4);
291 ZEND_NAMED_FUNCTION(_wrap_db_open);
292 ZEND_NAMED_FUNCTION(_wrap_db_close);
293 ZEND_NAMED_FUNCTION(_wrap_db_del);
294 ZEND_NAMED_FUNCTION(_wrap_db_get);
295 ZEND_NAMED_FUNCTION(_wrap_db_get_encrypt_flags);
296 ZEND_NAMED_FUNCTION(_wrap_db_pget);
297 ZEND_NAMED_FUNCTION(_wrap_db_get_type);
298 ZEND_NAMED_FUNCTION(_wrap_db_join);
299 ZEND_NAMED_FUNCTION(_wrap_db_put);
300 ZEND_NAMED_FUNCTION(_wrap_db_set_encrypt);
301 ZEND_NAMED_FUNCTION(_wrap_db_stat);
302 ZEND_NAMED_FUNCTION(_wrap_db_sync);
303 ZEND_NAMED_FUNCTION(_wrap_db_truncate);
304 ZEND_NAMED_FUNCTION(_wrap_db_cursor);
305 
306 static zend_function_entry Db4_functions[] = {
307         ZEND_NAMED_FE(db4, _wrap_new_db4, NULL)
308         ZEND_NAMED_FE(open, _wrap_db_open, NULL)
309         ZEND_NAMED_FE(close, _wrap_db_close, NULL)
310         ZEND_NAMED_FE(cursor, _wrap_db_cursor, NULL)
311         ZEND_NAMED_FE(del, _wrap_db_del, NULL)
312         ZEND_NAMED_FE(get, _wrap_db_get, NULL)
313 	ZEND_NAMED_FE(get_encrypt_flags, _wrap_db_get_encrypt_flags, NULL)
314 	ZEND_NAMED_FE(pget, _wrap_db_pget, NULL)
315         ZEND_NAMED_FE(get_type, _wrap_db_get_type, NULL)
316         ZEND_NAMED_FE(join, _wrap_db_join, NULL)
317         ZEND_NAMED_FE(put, _wrap_db_put, NULL)
318 		ZEND_NAMED_FE(set_encrypt, _wrap_db_set_encrypt, NULL)
319         ZEND_NAMED_FE(stat, _wrap_db_stat, NULL)
320         ZEND_NAMED_FE(sync, _wrap_db_sync, NULL)
321         ZEND_NAMED_FE(truncate, _wrap_db_truncate, NULL)
322         { NULL, NULL, NULL}
323 };
324 /* }}} */
325 /* }}} */
326 
327 #ifdef COMPILE_DL_DB4
328 #ifdef PHP_WIN32
329 #if (!(PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 3) || !(PHP_MAJOR_VERSION > 5))
330 #include "zend_arg_defs.c"
331 #endif
332 #endif
333 BEGIN_EXTERN_C()
ZEND_GET_MODULE(db4)334 ZEND_GET_MODULE(db4)
335 END_EXTERN_C()
336 #endif
337 
338 /* {{{ PHP_INI
339  */
340 /* Remove comments and fill if you need to have entries in php.ini
341 PHP_INI_BEGIN()
342 PHP_INI_END()
343 */
344 /* }}} */
345 
346 /* {{{ php_db4_init_globals
347  */
348 /* Uncomment this function if you have INI entries
349 static void php_db4_init_globals(zend_db4_globals *db4_globals)
350 {
351 }
352 */
353 /* }}} */
354 
355 /* {{{ PHP_MINIT_FUNCTION
356  */
357 PHP_MINIT_FUNCTION(db4)
358 {
359     /* If you have INI entries, uncomment these lines
360     ZEND_INIT_MODULE_GLOBALS(db4, php_db4_init_globals, NULL);
361     REGISTER_INI_ENTRIES();
362     */
363     static zend_class_entry _db_txn_ce;
364     static zend_class_entry _dbc_ce;
365     static zend_class_entry _db_ce;
366     static zend_class_entry _db_env_ce;
367 
368     INIT_CLASS_ENTRY(_db_txn_ce, "db4txn", DbTxn_functions);
369     db_txn_ce = zend_register_internal_class(&_db_txn_ce TSRMLS_CC);
370 
371     INIT_CLASS_ENTRY(_dbc_ce, "db4cursor", Dbc_functions);
372     dbc_ce = zend_register_internal_class(&_dbc_ce TSRMLS_CC);
373 
374     INIT_CLASS_ENTRY(_db_ce, "db4", Db4_functions);
375     db_ce = zend_register_internal_class(&_db_ce TSRMLS_CC);
376 
377     INIT_CLASS_ENTRY(_db_env_ce, "db4env", DbEnv_functions);
378     db_env_ce = zend_register_internal_class(&_db_env_ce TSRMLS_CC);
379 
380     le_db_txn = zend_register_list_destructors_ex(_free_php_db_txn, NULL, "Db4Txn", module_number);
381     le_dbc = zend_register_list_destructors_ex(_free_php_dbc, NULL, "Db4Cursor", module_number);
382     le_db = zend_register_list_destructors_ex(_free_php_db, NULL, "Db4", module_number);
383     le_dbenv = zend_register_list_destructors_ex(_free_php_dbenv, NULL, "Db4Env", module_number);
384 
385     REGISTER_LONG_CONSTANT("DB_VERSION_MAJOR", DB_VERSION_MAJOR, CONST_CS | CONST_PERSISTENT);
386     REGISTER_LONG_CONSTANT("DB_VERSION_MINOR", DB_VERSION_MINOR, CONST_CS | CONST_PERSISTENT);
387     REGISTER_LONG_CONSTANT("DB_VERSION_PATCH", DB_VERSION_PATCH, CONST_CS | CONST_PERSISTENT);
388     REGISTER_STRING_CONSTANT("DB_VERSION_STRING", (char *)DB_VERSION_STRING, CONST_CS | CONST_PERSISTENT);
389     REGISTER_LONG_CONSTANT("DB_MAX_PAGES", DB_MAX_PAGES, CONST_CS | CONST_PERSISTENT);
390     REGISTER_LONG_CONSTANT("DB_MAX_RECORDS", DB_MAX_RECORDS, CONST_CS | CONST_PERSISTENT);
391     REGISTER_LONG_CONSTANT("DB_DBT_APPMALLOC", DB_DBT_APPMALLOC, CONST_CS | CONST_PERSISTENT);
392     REGISTER_LONG_CONSTANT("DB_DBT_ISSET", DB_DBT_ISSET, CONST_CS | CONST_PERSISTENT);
393     REGISTER_LONG_CONSTANT("DB_DBT_MALLOC", DB_DBT_MALLOC, CONST_CS | CONST_PERSISTENT);
394     REGISTER_LONG_CONSTANT("DB_DBT_PARTIAL", DB_DBT_PARTIAL, CONST_CS | CONST_PERSISTENT);
395     REGISTER_LONG_CONSTANT("DB_DBT_REALLOC", DB_DBT_REALLOC, CONST_CS | CONST_PERSISTENT);
396     REGISTER_LONG_CONSTANT("DB_DBT_USERMEM", DB_DBT_USERMEM, CONST_CS | CONST_PERSISTENT);
397     REGISTER_LONG_CONSTANT("DB_DBT_DUPOK", DB_DBT_DUPOK, CONST_CS | CONST_PERSISTENT);
398     REGISTER_LONG_CONSTANT("DB_CREATE", DB_CREATE, CONST_CS | CONST_PERSISTENT);
399     REGISTER_LONG_CONSTANT("DB_CXX_NO_EXCEPTIONS", DB_CXX_NO_EXCEPTIONS, CONST_CS | CONST_PERSISTENT);
400     REGISTER_LONG_CONSTANT("DB_FORCE", DB_FORCE, CONST_CS | CONST_PERSISTENT);
401     REGISTER_LONG_CONSTANT("DB_NOMMAP", DB_NOMMAP, CONST_CS | CONST_PERSISTENT);
402     REGISTER_LONG_CONSTANT("DB_RDONLY", DB_RDONLY, CONST_CS | CONST_PERSISTENT);
403     REGISTER_LONG_CONSTANT("DB_RECOVER", DB_RECOVER, CONST_CS | CONST_PERSISTENT);
404     REGISTER_LONG_CONSTANT("DB_MULTIVERSION", DB_MULTIVERSION, CONST_CS | CONST_PERSISTENT);
405     REGISTER_LONG_CONSTANT("DB_TXN_SNAPSHOT", DB_TXN_SNAPSHOT, CONST_CS | CONST_PERSISTENT);
406     REGISTER_LONG_CONSTANT("DB_THREAD", DB_THREAD, CONST_CS | CONST_PERSISTENT);
407     REGISTER_LONG_CONSTANT("DB_TRUNCATE", DB_TRUNCATE, CONST_CS | CONST_PERSISTENT);
408     REGISTER_LONG_CONSTANT("DB_TXN_NOSYNC", DB_TXN_NOSYNC, CONST_CS | CONST_PERSISTENT);
409     REGISTER_LONG_CONSTANT("DB_TXN_NOT_DURABLE", DB_TXN_NOT_DURABLE, CONST_CS | CONST_PERSISTENT);
410     REGISTER_LONG_CONSTANT("DB_USE_ENVIRON", DB_USE_ENVIRON, CONST_CS | CONST_PERSISTENT);
411     REGISTER_LONG_CONSTANT("DB_USE_ENVIRON_ROOT", DB_USE_ENVIRON_ROOT, CONST_CS | CONST_PERSISTENT);
412     REGISTER_LONG_CONSTANT("DB_AUTO_COMMIT", DB_AUTO_COMMIT, CONST_CS | CONST_PERSISTENT);
413     REGISTER_LONG_CONSTANT("DB_DIRTY_READ", DB_READ_UNCOMMITTED, CONST_CS | CONST_PERSISTENT);
414     REGISTER_LONG_CONSTANT("DB_DEGREE_2", DB_READ_COMMITTED, CONST_CS | CONST_PERSISTENT);
415     REGISTER_LONG_CONSTANT("DB_READ_COMMITTED", DB_READ_COMMITTED, CONST_CS | CONST_PERSISTENT);
416     REGISTER_LONG_CONSTANT("DB_READ_UNCOMMITTED", DB_READ_UNCOMMITTED, CONST_CS | CONST_PERSISTENT);
417     REGISTER_LONG_CONSTANT("DB_NO_AUTO_COMMIT", DB_NO_AUTO_COMMIT, CONST_CS | CONST_PERSISTENT);
418     REGISTER_LONG_CONSTANT("DB_INIT_CDB", DB_INIT_CDB, CONST_CS | CONST_PERSISTENT);
419     REGISTER_LONG_CONSTANT("DB_INIT_LOCK", DB_INIT_LOCK, CONST_CS | CONST_PERSISTENT);
420     REGISTER_LONG_CONSTANT("DB_INIT_LOG", DB_INIT_LOG, CONST_CS | CONST_PERSISTENT);
421     REGISTER_LONG_CONSTANT("DB_INIT_MPOOL", DB_INIT_MPOOL, CONST_CS | CONST_PERSISTENT);
422     REGISTER_LONG_CONSTANT("DB_INIT_REP", DB_INIT_REP, CONST_CS | CONST_PERSISTENT);
423     REGISTER_LONG_CONSTANT("DB_INIT_TXN", DB_INIT_TXN, CONST_CS | CONST_PERSISTENT);
424     REGISTER_LONG_CONSTANT("DB_JOINENV", DB_JOINENV, CONST_CS | CONST_PERSISTENT);
425     REGISTER_LONG_CONSTANT("DB_LOCKDOWN", DB_LOCKDOWN, CONST_CS | CONST_PERSISTENT);
426     REGISTER_LONG_CONSTANT("DB_PRIVATE", DB_PRIVATE, CONST_CS | CONST_PERSISTENT);
427     REGISTER_LONG_CONSTANT("DB_RECOVER_FATAL", DB_RECOVER_FATAL, CONST_CS | CONST_PERSISTENT);
428     REGISTER_LONG_CONSTANT("DB_SYSTEM_MEM", DB_SYSTEM_MEM, CONST_CS | CONST_PERSISTENT);
429     REGISTER_LONG_CONSTANT("DB_EXCL", DB_EXCL, CONST_CS | CONST_PERSISTENT);
430     REGISTER_LONG_CONSTANT("DB_FCNTL_LOCKING", DB_FCNTL_LOCKING, CONST_CS | CONST_PERSISTENT);
431     REGISTER_LONG_CONSTANT("DB_RDWRMASTER", DB_RDWRMASTER, CONST_CS | CONST_PERSISTENT);
432     REGISTER_LONG_CONSTANT("DB_WRITEOPEN", DB_WRITEOPEN, CONST_CS | CONST_PERSISTENT);
433     REGISTER_LONG_CONSTANT("DB_TXN_NOWAIT", DB_TXN_NOWAIT, CONST_CS | CONST_PERSISTENT);
434     REGISTER_LONG_CONSTANT("DB_TXN_SYNC", DB_TXN_SYNC, CONST_CS | CONST_PERSISTENT);
435     REGISTER_LONG_CONSTANT("DB_ENCRYPT_AES", DB_ENCRYPT_AES, CONST_CS | CONST_PERSISTENT);
436     REGISTER_LONG_CONSTANT("DB_CDB_ALLDB", DB_CDB_ALLDB, CONST_CS | CONST_PERSISTENT);
437     REGISTER_LONG_CONSTANT("DB_DIRECT_DB", DB_DIRECT_DB, CONST_CS | CONST_PERSISTENT);
438     REGISTER_LONG_CONSTANT("DB_NOLOCKING", DB_NOLOCKING, CONST_CS | CONST_PERSISTENT);
439     REGISTER_LONG_CONSTANT("DB_NOPANIC", DB_NOPANIC, CONST_CS | CONST_PERSISTENT);
440     REGISTER_LONG_CONSTANT("DB_OVERWRITE", DB_OVERWRITE, CONST_CS | CONST_PERSISTENT);
441     REGISTER_LONG_CONSTANT("DB_PANIC_ENVIRONMENT", DB_PANIC_ENVIRONMENT, CONST_CS | CONST_PERSISTENT);
442     REGISTER_LONG_CONSTANT("DB_REGION_INIT", DB_REGION_INIT, CONST_CS | CONST_PERSISTENT);
443     REGISTER_LONG_CONSTANT("DB_TIME_NOTGRANTED", DB_TIME_NOTGRANTED, CONST_CS | CONST_PERSISTENT);
444     REGISTER_LONG_CONSTANT("DB_TXN_WRITE_NOSYNC", DB_TXN_WRITE_NOSYNC, CONST_CS | CONST_PERSISTENT);
445     REGISTER_LONG_CONSTANT("DB_YIELDCPU", DB_YIELDCPU, CONST_CS | CONST_PERSISTENT);
446     REGISTER_LONG_CONSTANT("DB_UPGRADE", DB_UPGRADE, CONST_CS | CONST_PERSISTENT);
447     REGISTER_LONG_CONSTANT("DB_VERIFY", DB_VERIFY, CONST_CS | CONST_PERSISTENT);
448     REGISTER_LONG_CONSTANT("DB_DIRECT", DB_DIRECT, CONST_CS | CONST_PERSISTENT);
449     REGISTER_LONG_CONSTANT("DB_EXTENT", DB_EXTENT, CONST_CS | CONST_PERSISTENT);
450     REGISTER_LONG_CONSTANT("DB_ODDFILESIZE", DB_ODDFILESIZE, CONST_CS | CONST_PERSISTENT);
451     REGISTER_LONG_CONSTANT("DB_CHKSUM", DB_CHKSUM, CONST_CS | CONST_PERSISTENT);
452     REGISTER_LONG_CONSTANT("DB_DUP", DB_DUP, CONST_CS | CONST_PERSISTENT);
453     REGISTER_LONG_CONSTANT("DB_DUPSORT", DB_DUPSORT, CONST_CS | CONST_PERSISTENT);
454     REGISTER_LONG_CONSTANT("DB_ENCRYPT", DB_ENCRYPT, CONST_CS | CONST_PERSISTENT);
455     REGISTER_LONG_CONSTANT("DB_RECNUM", DB_RECNUM, CONST_CS | CONST_PERSISTENT);
456     REGISTER_LONG_CONSTANT("DB_RENUMBER", DB_RENUMBER, CONST_CS | CONST_PERSISTENT);
457     REGISTER_LONG_CONSTANT("DB_REVSPLITOFF", DB_REVSPLITOFF, CONST_CS | CONST_PERSISTENT);
458     REGISTER_LONG_CONSTANT("DB_SNAPSHOT", DB_SNAPSHOT, CONST_CS | CONST_PERSISTENT);
459     REGISTER_LONG_CONSTANT("DB_STAT_CLEAR", DB_STAT_CLEAR, CONST_CS | CONST_PERSISTENT);
460     REGISTER_LONG_CONSTANT("DB_JOIN_NOSORT", DB_JOIN_NOSORT, CONST_CS | CONST_PERSISTENT);
461     REGISTER_LONG_CONSTANT("DB_AGGRESSIVE", DB_AGGRESSIVE, CONST_CS | CONST_PERSISTENT);
462     REGISTER_LONG_CONSTANT("DB_NOORDERCHK", DB_NOORDERCHK, CONST_CS | CONST_PERSISTENT);
463     REGISTER_LONG_CONSTANT("DB_ORDERCHKONLY", DB_ORDERCHKONLY, CONST_CS | CONST_PERSISTENT);
464     REGISTER_LONG_CONSTANT("DB_PR_PAGE", DB_PR_PAGE, CONST_CS | CONST_PERSISTENT);
465     REGISTER_LONG_CONSTANT("DB_PR_RECOVERYTEST", DB_PR_RECOVERYTEST, CONST_CS | CONST_PERSISTENT);
466     REGISTER_LONG_CONSTANT("DB_PRINTABLE", DB_PRINTABLE, CONST_CS | CONST_PERSISTENT);
467     REGISTER_LONG_CONSTANT("DB_SALVAGE", DB_SALVAGE, CONST_CS | CONST_PERSISTENT);
468     REGISTER_LONG_CONSTANT("DB_REP_NOBUFFER", DB_REP_NOBUFFER, CONST_CS | CONST_PERSISTENT);
469     REGISTER_LONG_CONSTANT("DB_REP_PERMANENT", DB_REP_PERMANENT, CONST_CS | CONST_PERSISTENT);
470     REGISTER_LONG_CONSTANT("DB_LOCKVERSION", DB_LOCKVERSION, CONST_CS | CONST_PERSISTENT);
471     REGISTER_LONG_CONSTANT("DB_FILE_ID_LEN", DB_FILE_ID_LEN, CONST_CS | CONST_PERSISTENT);
472     REGISTER_LONG_CONSTANT("DB_LOCK_NORUN", DB_LOCK_NORUN, CONST_CS | CONST_PERSISTENT);
473     REGISTER_LONG_CONSTANT("DB_LOCK_DEFAULT", DB_LOCK_DEFAULT, CONST_CS | CONST_PERSISTENT);
474     REGISTER_LONG_CONSTANT("DB_LOCK_EXPIRE", DB_LOCK_EXPIRE, CONST_CS | CONST_PERSISTENT);
475     REGISTER_LONG_CONSTANT("DB_LOCK_MAXLOCKS", DB_LOCK_MAXLOCKS, CONST_CS | CONST_PERSISTENT);
476     REGISTER_LONG_CONSTANT("DB_LOCK_MINLOCKS", DB_LOCK_MINLOCKS, CONST_CS | CONST_PERSISTENT);
477     REGISTER_LONG_CONSTANT("DB_LOCK_MINWRITE", DB_LOCK_MINWRITE, CONST_CS | CONST_PERSISTENT);
478     REGISTER_LONG_CONSTANT("DB_LOCK_OLDEST", DB_LOCK_OLDEST, CONST_CS | CONST_PERSISTENT);
479     REGISTER_LONG_CONSTANT("DB_LOCK_RANDOM", DB_LOCK_RANDOM, CONST_CS | CONST_PERSISTENT);
480     REGISTER_LONG_CONSTANT("DB_LOCK_YOUNGEST", DB_LOCK_YOUNGEST, CONST_CS | CONST_PERSISTENT);
481     REGISTER_LONG_CONSTANT("DB_LOCK_NOWAIT", DB_LOCK_NOWAIT, CONST_CS | CONST_PERSISTENT);
482     REGISTER_LONG_CONSTANT("DB_LOCK_RECORD", DB_LOCK_RECORD, CONST_CS | CONST_PERSISTENT);
483     REGISTER_LONG_CONSTANT("DB_LOCK_SET_TIMEOUT", DB_LOCK_SET_TIMEOUT, CONST_CS | CONST_PERSISTENT);
484     REGISTER_LONG_CONSTANT("DB_LOCK_SWITCH", DB_LOCK_SWITCH, CONST_CS | CONST_PERSISTENT);
485     REGISTER_LONG_CONSTANT("DB_LOCK_UPGRADE", DB_LOCK_UPGRADE, CONST_CS | CONST_PERSISTENT);
486     REGISTER_LONG_CONSTANT("DB_HANDLE_LOCK", DB_HANDLE_LOCK, CONST_CS | CONST_PERSISTENT);
487     REGISTER_LONG_CONSTANT("DB_RECORD_LOCK", DB_RECORD_LOCK, CONST_CS | CONST_PERSISTENT);
488     REGISTER_LONG_CONSTANT("DB_PAGE_LOCK", DB_PAGE_LOCK, CONST_CS | CONST_PERSISTENT);
489     REGISTER_LONG_CONSTANT("DB_LOGVERSION", DB_LOGVERSION, CONST_CS | CONST_PERSISTENT);
490     REGISTER_LONG_CONSTANT("DB_LOGOLDVER", DB_LOGOLDVER, CONST_CS | CONST_PERSISTENT);
491     REGISTER_LONG_CONSTANT("DB_LOGMAGIC", DB_LOGMAGIC, CONST_CS | CONST_PERSISTENT);
492     REGISTER_LONG_CONSTANT("DB_ARCH_ABS", DB_ARCH_ABS, CONST_CS | CONST_PERSISTENT);
493     REGISTER_LONG_CONSTANT("DB_ARCH_DATA", DB_ARCH_DATA, CONST_CS | CONST_PERSISTENT);
494     REGISTER_LONG_CONSTANT("DB_ARCH_LOG", DB_ARCH_LOG, CONST_CS | CONST_PERSISTENT);
495     REGISTER_LONG_CONSTANT("DB_ARCH_REMOVE", DB_ARCH_REMOVE, CONST_CS | CONST_PERSISTENT);
496     REGISTER_LONG_CONSTANT("DB_FLUSH", DB_FLUSH, CONST_CS | CONST_PERSISTENT);
497     REGISTER_LONG_CONSTANT("DB_LOG_CHKPNT", DB_LOG_CHKPNT, CONST_CS | CONST_PERSISTENT);
498     REGISTER_LONG_CONSTANT("DB_LOG_COMMIT", DB_LOG_COMMIT, CONST_CS | CONST_PERSISTENT);
499     REGISTER_LONG_CONSTANT("DB_LOG_NOCOPY", DB_LOG_NOCOPY, CONST_CS | CONST_PERSISTENT);
500     REGISTER_LONG_CONSTANT("DB_LOG_NOT_DURABLE", DB_LOG_NOT_DURABLE, CONST_CS | CONST_PERSISTENT);
501     REGISTER_LONG_CONSTANT("DB_LOG_WRNOSYNC", DB_LOG_WRNOSYNC, CONST_CS | CONST_PERSISTENT);
502     REGISTER_LONG_CONSTANT("DB_user_BEGIN", DB_user_BEGIN, CONST_CS | CONST_PERSISTENT);
503     REGISTER_LONG_CONSTANT("DB_debug_FLAG", DB_debug_FLAG, CONST_CS | CONST_PERSISTENT);
504     REGISTER_LONG_CONSTANT("DB_LOG_DISK", DB_LOG_DISK, CONST_CS | CONST_PERSISTENT);
505     REGISTER_LONG_CONSTANT("DB_LOG_LOCKED", DB_LOG_LOCKED, CONST_CS | CONST_PERSISTENT);
506     REGISTER_LONG_CONSTANT("DB_LOG_SILENT_ERR", DB_LOG_SILENT_ERR, CONST_CS | CONST_PERSISTENT);
507     REGISTER_LONG_CONSTANT("DB_MPOOL_CREATE", DB_MPOOL_CREATE, CONST_CS | CONST_PERSISTENT);
508     REGISTER_LONG_CONSTANT("DB_MPOOL_LAST", DB_MPOOL_LAST, CONST_CS | CONST_PERSISTENT);
509     REGISTER_LONG_CONSTANT("DB_MPOOL_NEW", DB_MPOOL_NEW, CONST_CS | CONST_PERSISTENT);
510     REGISTER_LONG_CONSTANT("DB_MPOOL_DIRTY", DB_MPOOL_DIRTY, CONST_CS | CONST_PERSISTENT);
511     REGISTER_LONG_CONSTANT("DB_MPOOL_DISCARD", DB_MPOOL_DISCARD, CONST_CS | CONST_PERSISTENT);
512     REGISTER_LONG_CONSTANT("DB_MPOOL_NOFILE", DB_MPOOL_NOFILE, CONST_CS | CONST_PERSISTENT);
513     REGISTER_LONG_CONSTANT("DB_MPOOL_UNLINK", DB_MPOOL_UNLINK, CONST_CS | CONST_PERSISTENT);
514     REGISTER_LONG_CONSTANT("DB_TXNVERSION", DB_TXNVERSION, CONST_CS | CONST_PERSISTENT);
515     REGISTER_LONG_CONSTANT("DB_GID_SIZE", DB_GID_SIZE, CONST_CS | CONST_PERSISTENT);
516     REGISTER_LONG_CONSTANT("DB_EID_BROADCAST", DB_EID_BROADCAST, CONST_CS | CONST_PERSISTENT);
517     REGISTER_LONG_CONSTANT("DB_EID_INVALID", DB_EID_INVALID, CONST_CS | CONST_PERSISTENT);
518     REGISTER_LONG_CONSTANT("DB_REP_CLIENT", DB_REP_CLIENT, CONST_CS | CONST_PERSISTENT);
519     REGISTER_LONG_CONSTANT("DB_REP_MASTER", DB_REP_MASTER, CONST_CS | CONST_PERSISTENT);
520     REGISTER_LONG_CONSTANT("DB_RENAMEMAGIC", DB_RENAMEMAGIC, CONST_CS | CONST_PERSISTENT);
521     REGISTER_LONG_CONSTANT("DB_BTREEVERSION", DB_BTREEVERSION, CONST_CS | CONST_PERSISTENT);
522     REGISTER_LONG_CONSTANT("DB_BTREEOLDVER", DB_BTREEOLDVER, CONST_CS | CONST_PERSISTENT);
523     REGISTER_LONG_CONSTANT("DB_BTREEMAGIC", DB_BTREEMAGIC, CONST_CS | CONST_PERSISTENT);
524     REGISTER_LONG_CONSTANT("DB_HASHVERSION", DB_HASHVERSION, CONST_CS | CONST_PERSISTENT);
525     REGISTER_LONG_CONSTANT("DB_HASHOLDVER", DB_HASHOLDVER, CONST_CS | CONST_PERSISTENT);
526     REGISTER_LONG_CONSTANT("DB_HASHMAGIC", DB_HASHMAGIC, CONST_CS | CONST_PERSISTENT);
527     REGISTER_LONG_CONSTANT("DB_QAMVERSION", DB_QAMVERSION, CONST_CS | CONST_PERSISTENT);
528     REGISTER_LONG_CONSTANT("DB_QAMOLDVER", DB_QAMOLDVER, CONST_CS | CONST_PERSISTENT);
529     REGISTER_LONG_CONSTANT("DB_QAMMAGIC", DB_QAMMAGIC, CONST_CS | CONST_PERSISTENT);
530     REGISTER_LONG_CONSTANT("DB_AFTER", DB_AFTER, CONST_CS | CONST_PERSISTENT);
531     REGISTER_LONG_CONSTANT("DB_APPEND", DB_APPEND, CONST_CS | CONST_PERSISTENT);
532     REGISTER_LONG_CONSTANT("DB_BEFORE", DB_BEFORE, CONST_CS | CONST_PERSISTENT);
533     REGISTER_LONG_CONSTANT("DB_CONSUME", DB_CONSUME, CONST_CS | CONST_PERSISTENT);
534     REGISTER_LONG_CONSTANT("DB_CONSUME_WAIT", DB_CONSUME_WAIT, CONST_CS | CONST_PERSISTENT);
535     REGISTER_LONG_CONSTANT("DB_CURRENT", DB_CURRENT, CONST_CS | CONST_PERSISTENT);
536     REGISTER_LONG_CONSTANT("DB_FAST_STAT", DB_FAST_STAT, CONST_CS | CONST_PERSISTENT);
537     REGISTER_LONG_CONSTANT("DB_FIRST", DB_FIRST, CONST_CS | CONST_PERSISTENT);
538     REGISTER_LONG_CONSTANT("DB_GET_BOTH", DB_GET_BOTH, CONST_CS | CONST_PERSISTENT);
539     REGISTER_LONG_CONSTANT("DB_GET_BOTHC", DB_GET_BOTHC, CONST_CS | CONST_PERSISTENT);
540     REGISTER_LONG_CONSTANT("DB_GET_BOTH_RANGE", DB_GET_BOTH_RANGE, CONST_CS | CONST_PERSISTENT);
541     REGISTER_LONG_CONSTANT("DB_GET_RECNO", DB_GET_RECNO, CONST_CS | CONST_PERSISTENT);
542     REGISTER_LONG_CONSTANT("DB_JOIN_ITEM", DB_JOIN_ITEM, CONST_CS | CONST_PERSISTENT);
543     REGISTER_LONG_CONSTANT("DB_KEYFIRST", DB_KEYFIRST, CONST_CS | CONST_PERSISTENT);
544     REGISTER_LONG_CONSTANT("DB_KEYLAST", DB_KEYLAST, CONST_CS | CONST_PERSISTENT);
545     REGISTER_LONG_CONSTANT("DB_LAST", DB_LAST, CONST_CS | CONST_PERSISTENT);
546     REGISTER_LONG_CONSTANT("DB_NEXT", DB_NEXT, CONST_CS | CONST_PERSISTENT);
547     REGISTER_LONG_CONSTANT("DB_NEXT_DUP", DB_NEXT_DUP, CONST_CS | CONST_PERSISTENT);
548     REGISTER_LONG_CONSTANT("DB_NEXT_NODUP", DB_NEXT_NODUP, CONST_CS | CONST_PERSISTENT);
549     REGISTER_LONG_CONSTANT("DB_NODUPDATA", DB_NODUPDATA, CONST_CS | CONST_PERSISTENT);
550     REGISTER_LONG_CONSTANT("DB_NOOVERWRITE", DB_NOOVERWRITE, CONST_CS | CONST_PERSISTENT);
551     REGISTER_LONG_CONSTANT("DB_NOSYNC", DB_NOSYNC, CONST_CS | CONST_PERSISTENT);
552     REGISTER_LONG_CONSTANT("DB_POSITION", DB_POSITION, CONST_CS | CONST_PERSISTENT);
553     REGISTER_LONG_CONSTANT("DB_PREV", DB_PREV, CONST_CS | CONST_PERSISTENT);
554     REGISTER_LONG_CONSTANT("DB_PREV_NODUP", DB_PREV_NODUP, CONST_CS | CONST_PERSISTENT);
555     REGISTER_LONG_CONSTANT("DB_SET", DB_SET, CONST_CS | CONST_PERSISTENT);
556     REGISTER_LONG_CONSTANT("DB_SET_LOCK_TIMEOUT", DB_SET_LOCK_TIMEOUT, CONST_CS | CONST_PERSISTENT);
557     REGISTER_LONG_CONSTANT("DB_SET_RANGE", DB_SET_RANGE, CONST_CS | CONST_PERSISTENT);
558     REGISTER_LONG_CONSTANT("DB_SET_RECNO", DB_SET_RECNO, CONST_CS | CONST_PERSISTENT);
559     REGISTER_LONG_CONSTANT("DB_SET_TXN_NOW", DB_SET_TXN_NOW, CONST_CS | CONST_PERSISTENT);
560     REGISTER_LONG_CONSTANT("DB_SET_TXN_TIMEOUT", DB_SET_TXN_TIMEOUT, CONST_CS | CONST_PERSISTENT);
561     REGISTER_LONG_CONSTANT("DB_UPDATE_SECONDARY", DB_UPDATE_SECONDARY, CONST_CS | CONST_PERSISTENT);
562     REGISTER_LONG_CONSTANT("DB_WRITECURSOR", DB_WRITECURSOR, CONST_CS | CONST_PERSISTENT);
563     REGISTER_LONG_CONSTANT("DB_WRITELOCK", DB_WRITELOCK, CONST_CS | CONST_PERSISTENT);
564     REGISTER_LONG_CONSTANT("DB_OPFLAGS_MASK", DB_OPFLAGS_MASK, CONST_CS | CONST_PERSISTENT);
565     REGISTER_LONG_CONSTANT("DB_MULTIPLE", DB_MULTIPLE, CONST_CS | CONST_PERSISTENT);
566     REGISTER_LONG_CONSTANT("DB_MULTIPLE_KEY", DB_MULTIPLE_KEY, CONST_CS | CONST_PERSISTENT);
567     REGISTER_LONG_CONSTANT("DB_RMW", DB_RMW, CONST_CS | CONST_PERSISTENT);
568     REGISTER_LONG_CONSTANT("DB_DONOTINDEX", DB_DONOTINDEX, CONST_CS | CONST_PERSISTENT);
569     REGISTER_LONG_CONSTANT("DB_KEYEMPTY", DB_KEYEMPTY, CONST_CS | CONST_PERSISTENT);
570     REGISTER_LONG_CONSTANT("DB_KEYEXIST", DB_KEYEXIST, CONST_CS | CONST_PERSISTENT);
571     REGISTER_LONG_CONSTANT("DB_LOCK_DEADLOCK", DB_LOCK_DEADLOCK, CONST_CS | CONST_PERSISTENT);
572     REGISTER_LONG_CONSTANT("DB_LOCK_NOTGRANTED", DB_LOCK_NOTGRANTED, CONST_CS | CONST_PERSISTENT);
573     REGISTER_LONG_CONSTANT("DB_NOSERVER", DB_NOSERVER, CONST_CS | CONST_PERSISTENT);
574     REGISTER_LONG_CONSTANT("DB_NOTFOUND", DB_NOTFOUND, CONST_CS | CONST_PERSISTENT);
575     REGISTER_LONG_CONSTANT("DB_OLD_VERSION", DB_OLD_VERSION, CONST_CS | CONST_PERSISTENT);
576     REGISTER_LONG_CONSTANT("DB_PAGE_NOTFOUND", DB_PAGE_NOTFOUND, CONST_CS | CONST_PERSISTENT);
577     REGISTER_LONG_CONSTANT("DB_REP_DUPMASTER", DB_REP_DUPMASTER, CONST_CS | CONST_PERSISTENT);
578     REGISTER_LONG_CONSTANT("DB_REP_HANDLE_DEAD", DB_REP_HANDLE_DEAD, CONST_CS | CONST_PERSISTENT);
579     REGISTER_LONG_CONSTANT("DB_REP_HOLDELECTION", DB_REP_HOLDELECTION, CONST_CS | CONST_PERSISTENT);
580     REGISTER_LONG_CONSTANT("DB_REP_ISPERM", DB_REP_ISPERM, CONST_CS | CONST_PERSISTENT);
581     REGISTER_LONG_CONSTANT("DB_REP_NEWMASTER", DB_REP_NEWMASTER, CONST_CS | CONST_PERSISTENT);
582     REGISTER_LONG_CONSTANT("DB_REP_NEWSITE", DB_REP_NEWSITE, CONST_CS | CONST_PERSISTENT);
583     REGISTER_LONG_CONSTANT("DB_REP_NOTPERM", DB_REP_NOTPERM, CONST_CS | CONST_PERSISTENT);
584     REGISTER_LONG_CONSTANT("DB_REP_UNAVAIL", DB_REP_UNAVAIL, CONST_CS | CONST_PERSISTENT);
585     REGISTER_LONG_CONSTANT("DB_RUNRECOVERY", DB_RUNRECOVERY, CONST_CS | CONST_PERSISTENT);
586     REGISTER_LONG_CONSTANT("DB_SECONDARY_BAD", DB_SECONDARY_BAD, CONST_CS | CONST_PERSISTENT);
587     REGISTER_LONG_CONSTANT("DB_VERIFY_BAD", DB_VERIFY_BAD, CONST_CS | CONST_PERSISTENT);
588     REGISTER_LONG_CONSTANT("DB_VERB_BACKUP", DB_VERB_BACKUP, CONST_CS | CONST_PERSISTENT);
589     REGISTER_LONG_CONSTANT("DB_VERB_DEADLOCK", DB_VERB_DEADLOCK, CONST_CS | CONST_PERSISTENT);
590     REGISTER_LONG_CONSTANT("DB_VERB_RECOVERY", DB_VERB_RECOVERY, CONST_CS | CONST_PERSISTENT);
591     REGISTER_LONG_CONSTANT("DB_VERB_REPLICATION", DB_VERB_REPLICATION, CONST_CS | CONST_PERSISTENT);
592     REGISTER_LONG_CONSTANT("DB_VERB_WAITSFOR", DB_VERB_WAITSFOR, CONST_CS | CONST_PERSISTENT);
593 	return SUCCESS;
594 }
595 /* }}} */
596 
597 /* {{{ PHP_MSHUTDOWN_FUNCTION
598  */
PHP_MSHUTDOWN_FUNCTION(db4)599 PHP_MSHUTDOWN_FUNCTION(db4)
600 {
601     /* uncomment this line if you have INI entries
602     UNREGISTER_INI_ENTRIES();
603     */
604     return SUCCESS;
605 }
606 /* }}} */
607 
608 /* {{{ PHP_MINFO_FUNCTION
609  */
PHP_MINFO_FUNCTION(db4)610 PHP_MINFO_FUNCTION(db4)
611 {
612     php_info_print_table_start();
613     php_info_print_table_header(2, "db4 support", "enabled");
614     php_info_print_table_end();
615 
616     /* Remove comments if you have entries in php.ini
617     DISPLAY_INI_ENTRIES();
618     */
619 }
620 /* }}} */
621 
622 
623 /* {{{ resource accessors
624  */
setDbEnv(zval * z,DB_ENV * dbenv TSRMLS_DC)625 void setDbEnv(zval *z, DB_ENV *dbenv TSRMLS_DC)
626 {
627     zend_resource *env_res;
628     struct php_DB_ENV *pdb = (struct php_DB_ENV *) emalloc(sizeof(*pdb));
629     pdb->dbenv = dbenv;
630     env_res = zend_register_resource(pdb, le_dbenv);
631     env_res->gc.refcount++;
632     add_property_resource(z, "_dbenv_ptr", env_res);
633 }
634 
php_db4_getDbEnvFromObj(zval * z TSRMLS_DC)635 DB_ENV *php_db4_getDbEnvFromObj(zval *z TSRMLS_DC)
636 {
637     struct php_DB_ENV *pdb;
638     zval *zv;
639     if((zv = zend_hash_str_find(HASH_OF(z), "_dbenv_ptr", sizeof("_dbenv_ptr") - 1)) != NULL)
640     {
641         pdb = (struct php_DB_ENV *) zend_fetch_resource(Z_RES_P(zv), "Db4Env", le_dbenv);
642         return pdb->dbenv;
643     }
644     return NULL;
645 }
646 
php_db4_getPhpDbEnvFromObj(zval * z TSRMLS_DC)647 struct php_DB_ENV *php_db4_getPhpDbEnvFromObj(zval *z TSRMLS_DC)
648 {
649     struct php_DB_ENV *pdb;
650     zval *zv;
651     if((zv = zend_hash_str_find(HASH_OF(z), "_dbenv_ptr", sizeof("_dbenv_ptr") -1)) != NULL)
652     {
653         pdb = (struct php_DB_ENV *) zend_fetch_resource(Z_RES_P(zv), "Db4Env", le_dbenv);
654         return pdb;
655     }
656     return NULL;
657 }
658 
659 #define getDbEnvFromThis(a)        \
660 do { \
661   zval *_self = getThis(); \
662   if(!_self) { \
663     php_error_docref(NULL TSRMLS_CC, E_WARNING, "must be called as a method"); \
664     RETURN_FALSE; \
665   } \
666   (a) = php_db4_getDbEnvFromObj(_self TSRMLS_CC); \
667   if(!(a)) { \
668     php_error_docref(NULL TSRMLS_CC, E_WARNING, "not a valid db4Env object"); \
669     RETURN_FALSE; \
670   } \
671 } while(0)
672 
setDb(zval * z,DB * db TSRMLS_DC)673 void setDb(zval *z, DB *db TSRMLS_DC)
674 {
675     zend_resource *db_res;
676     struct php_DB *pdb = (struct php_DB *) emalloc(sizeof(*pdb));
677     memset(pdb, 0, sizeof(*pdb));
678     pdb->db = db;
679     db_res = zend_register_resource(pdb, le_db);
680     db_res->gc.refcount++;
681     add_property_resource(z, "_db_ptr", db_res);
682 }
683 
getPhpDbFromObj(zval * z TSRMLS_DC)684 struct php_DB *getPhpDbFromObj(zval *z TSRMLS_DC)
685 {
686     struct php_DB *pdb;
687     zval *zv;
688     if((zv = zend_hash_str_find(HASH_OF(z), "_db_ptr", sizeof("_db_ptr") - 1)) != NULL) {
689         pdb = (struct php_DB *) zend_fetch_resource(Z_RES_P(zv), "Db4", le_db);
690         return pdb;
691     }
692     return NULL;
693 }
694 
php_db4_getDbFromObj(zval * z TSRMLS_DC)695 DB *php_db4_getDbFromObj(zval *z TSRMLS_DC)
696 {
697     struct php_DB *pdb;
698     zval *zv;
699     if((zv = zend_hash_str_find(HASH_OF(z), "_db_ptr", sizeof("_db_ptr") - 1)) != NULL) {
700         pdb = (struct php_DB *) zend_fetch_resource(Z_RES_P(zv), "Db4", le_db);
701         return pdb->db;
702     }
703     return NULL;
704 }
705 
706 #define getDbFromThis(a)        \
707 do { \
708   struct php_DB *pdb; \
709   zval *_self = getThis(); \
710   if(!_self) { \
711     php_error_docref(NULL TSRMLS_CC, E_WARNING, "must be called as a method"); \
712     RETURN_FALSE; \
713   } \
714    pdb = getPhpDbFromObj(_self TSRMLS_CC); \
715   if(!pdb || !pdb->db) { \
716     assert(0); \
717     php_error_docref(NULL TSRMLS_CC, E_WARNING, "not a valid db4 object"); \
718     RETURN_FALSE; \
719   } \
720   (a) = pdb->db; \
721 } while(0)
722 
723 #define getPhpDbFromThis(a)        \
724 do { \
725   struct php_DB *pdb; \
726   zval *_self = getThis(); \
727   if(!_self) { \
728     php_error_docref(NULL TSRMLS_CC, E_WARNING, "must be called as a method"); \
729     RETURN_FALSE; \
730   } \
731    pdb = getPhpDbFromObj(_self TSRMLS_CC); \
732   if(!pdb) { \
733     assert(0); \
734     php_error_docref(NULL TSRMLS_CC, E_WARNING, "not a valid db4 object"); \
735     RETURN_FALSE; \
736   } \
737   (a) = pdb; \
738 } while(0)
739 
setDbTxn(zval * z,DB_TXN * dbtxn TSRMLS_DC)740 void setDbTxn(zval *z, DB_TXN *dbtxn TSRMLS_DC)
741 {
742     zend_resource *txn_res;
743     struct php_DB_TXN *txn = (struct php_DB_TXN *) emalloc(sizeof(*txn));
744     memset(txn, 0, sizeof(*txn));
745     txn->db_txn = dbtxn;
746     txn_res = zend_register_resource(txn, le_db_txn);
747     txn_res->gc.refcount++;
748     add_property_resource(z, "_dbtxn_ptr", txn_res);
749 }
750 
php_db4_getDbTxnFromObj(zval * z TSRMLS_DC)751 DB_TXN *php_db4_getDbTxnFromObj(zval *z TSRMLS_DC)
752 {
753     struct php_DB_TXN *pdbtxn;
754     zval *zv;
755     if((zv = zend_hash_str_find(HASH_OF(z), "_dbtxn_ptr", sizeof("_dbtxn_ptr") - 1)) != NULL)
756     {
757         pdbtxn = (struct php_DB_TXN *) zend_fetch_resource(Z_RES_P(zv), "Db4Txn", le_db_txn);
758         return pdbtxn->db_txn;
759     }
760     return NULL;
761 }
762 
getPhpDbTxnFromObj(zval * z TSRMLS_DC)763 struct php_DB_TXN *getPhpDbTxnFromObj(zval *z TSRMLS_DC)
764 {
765     struct php_DB_TXN *pdbtxn;
766     zval *zv;
767     if((zv = zend_hash_str_find(HASH_OF(z), "_dbtxn_ptr", sizeof("_dbtxn_ptr") - 1)) != NULL)
768     {
769         pdbtxn = (struct php_DB_TXN *) zend_fetch_resource(Z_RES_P(zv), "Db4Txn", le_db_txn);
770         return pdbtxn;
771     }
772     return NULL;
773 }
774 
775 #define getDbTxnFromThis(a)        \
776 do { \
777   zval *_self = getThis(); \
778   if(!_self) { \
779     php_error_docref(NULL TSRMLS_CC, E_WARNING, "must be called as a method"); \
780     RETURN_FALSE; \
781   } \
782   (a) = php_db4_getDbTxnFromObj(_self TSRMLS_CC); \
783   if(!(a)) { \
784     php_error_docref(NULL TSRMLS_CC, E_WARNING, "not a valid db4txn object"); \
785     RETURN_FALSE; \
786   } \
787 } while(0)
788 
789 #define getPhpDbTxnFromThis(a)        \
790 do { \
791   zval *_self = getThis(); \
792   if(!_self) { \
793     php_error_docref(NULL TSRMLS_CC, E_WARNING, "must be called as a method"); \
794     RETURN_FALSE; \
795   } \
796   (a) = getPhpDbTxnFromObj(_self TSRMLS_CC); \
797   if(!(a) || !(a)->db_txn) { \
798     php_error_docref(NULL TSRMLS_CC, E_WARNING, "not a valid db4txn object"); \
799     RETURN_FALSE; \
800   } \
801 } while(0)
802 
closeDbTxnDependencies(zval * obj TSRMLS_DC)803 void closeDbTxnDependencies(zval *obj TSRMLS_DC) {
804     struct php_DB_TXN *pdbtxn = getPhpDbTxnFromObj(obj TSRMLS_CC);
805     if(pdbtxn) {
806         while(pdbtxn->open_cursors) {
807             struct my_llist *el = pdbtxn->open_cursors;
808             struct php_DBC *pdbc = (struct php_DBC *) el->data;
809             if(pdbc) {
810                 if(pdbc->dbc) {
811                     pdbc->dbc->c_close(pdbc->dbc);
812                     pdbc->dbc = NULL;
813                 }
814                 pdbc->parent_txn = NULL;
815             }
816 //          efree(el->data);
817             pdbtxn->open_cursors = el->next;
818             efree(el);
819             php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempting to end a transaction without closing it's child cursors.");
820         }
821         /* should handle open dbs with pending transactions */
822     }
823 }
824 
825 
setDbc(zval * z,DBC * dbc,struct php_DB_TXN * txn TSRMLS_DC)826 void setDbc(zval *z, DBC *dbc, struct php_DB_TXN *txn TSRMLS_DC)
827 {
828     zend_resource *dbc_res;
829     struct php_DBC *pdbc = (struct php_DBC *) emalloc(sizeof(*pdbc));
830     memset(pdbc, 0, sizeof(*pdbc));
831     pdbc->dbc = dbc;
832     if(txn) {
833         pdbc->parent_txn = txn;
834         txn->open_cursors = my_llist_add(txn->open_cursors, pdbc);
835     }
836     dbc_res = zend_register_resource(pdbc, le_dbc);
837     dbc_res->gc.refcount++;
838     add_property_resource(z, "_dbc_ptr", dbc_res);
839 }
840 
php_db4_getDbcFromObj(zval * z TSRMLS_DC)841 DBC *php_db4_getDbcFromObj(zval *z TSRMLS_DC)
842 {
843     struct php_DBC *pdbc;
844     zval *zv;
845     if((zv = zend_hash_str_find(HASH_OF(z), "_dbc_ptr", sizeof("_dbc_ptr") - 1)) != NULL)
846     {
847         pdbc = (struct php_DBC *) zend_fetch_resource(Z_RES_P(zv), "Db4Cursor", le_dbc);
848         return pdbc->dbc;
849     }
850     return NULL;
851 }
852 
getPhpDbcFromObj(zval * z TSRMLS_DC)853 struct php_DBC *getPhpDbcFromObj(zval *z TSRMLS_DC)
854 {
855     struct php_DBC *pdbc;
856     zval *zv;
857     if((zv = zend_hash_str_find(HASH_OF(z), "_dbc_ptr", sizeof("_dbc_ptr") - 1)) != NULL)
858     {
859         pdbc = (struct php_DBC *) zend_fetch_resource(Z_RES_P(zv), "Db4Cursor", le_dbc);
860         return pdbc;
861     }
862     return NULL;
863 }
864 
865 #define getDbcFromThis(a)        \
866 do { \
867   zval *_self = getThis(); \
868   if(!_self) { \
869     php_error_docref(NULL TSRMLS_CC, E_WARNING, "must be called as a method"); \
870     RETURN_FALSE; \
871   } \
872   (a) = php_db4_getDbcFromObj(_self TSRMLS_CC); \
873   if(!(a)) { \
874     php_error_docref(NULL TSRMLS_CC, E_WARNING, "not a valid db4Cursor object"); \
875     RETURN_FALSE; \
876   } \
877 } while(0)
878 
closeDbc(zval * obj TSRMLS_DC)879 int closeDbc(zval *obj TSRMLS_DC)
880 {
881     int ret = 0;
882     struct php_DBC *pdbc = getPhpDbcFromObj(obj TSRMLS_CC);
883     if(pdbc) {
884         if(pdbc->parent_txn) {
885             pdbc->parent_txn->open_cursors =
886                 my_llist_del(pdbc->parent_txn->open_cursors, pdbc);
887         }
888         ret = pdbc->dbc->c_close(pdbc->dbc);
889         pdbc->dbc = NULL;
890         pdbc->parent_txn = NULL;
891     }
892     return ret;
893 }
894 
895 /* }}} */
896 
897 /* {{{ DB4Txn method definitions
898  */
899 
900 /* {{{ proto bool Db4Txn::abort()
901  */
ZEND_NAMED_FUNCTION(_wrap_db_txn_abort)902 ZEND_NAMED_FUNCTION(_wrap_db_txn_abort)
903 {
904     struct php_DB_TXN *ptxn;
905     zval *self;
906     int ret;
907 
908     if(ZEND_NUM_ARGS()) {
909         WRONG_PARAM_COUNT;
910     }
911     self = getThis();
912     getPhpDbTxnFromThis(ptxn);
913     closeDbTxnDependencies(self TSRMLS_CC);
914     if((ret = ptxn->db_txn->abort(ptxn->db_txn)) != 0) {
915         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", db_strerror(ret));
916         RETURN_FALSE;
917     }
918     ptxn->db_txn = NULL;
919     RETURN_TRUE;
920 }
921 /* }}} */
922 
923 /* {{{ proto bool Db4Txn::commit()
924  */
ZEND_NAMED_FUNCTION(_wrap_db_txn_commit)925 ZEND_NAMED_FUNCTION(_wrap_db_txn_commit)
926 {
927     struct php_DB_TXN *ptxn;
928     u_int32_t flags = 0;
929     int ret;
930     zval *self;
931 
932     self = getThis();
933     getPhpDbTxnFromThis(ptxn);
934     closeDbTxnDependencies(self TSRMLS_CC);
935     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags) == FAILURE)
936     {
937         return;
938     }
939     if((ret = ptxn->db_txn->commit(ptxn->db_txn, flags)) != 0) {
940         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", db_strerror(ret));
941         RETURN_FALSE;
942     }
943     ptxn->db_txn = NULL;
944     RETURN_TRUE;
945 }
946 /* }}} */
947 
948 /* {{{ proto bool Db4Txn::discard()
949  */
ZEND_NAMED_FUNCTION(_wrap_db_txn_discard)950 ZEND_NAMED_FUNCTION(_wrap_db_txn_discard)
951 {
952     struct php_DB_TXN *ptxn;
953     int ret;
954     zval *self;
955 
956     self = getThis();
957     getPhpDbTxnFromThis(ptxn);
958     closeDbTxnDependencies(self TSRMLS_CC);
959     if(ZEND_NUM_ARGS()) WRONG_PARAM_COUNT;
960     if((ret = ptxn->db_txn->discard(ptxn->db_txn, 0)) != 0) {
961         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", db_strerror(ret));
962         RETURN_FALSE;
963     }
964     ptxn->db_txn = NULL;
965     /* FIXME should destroy $self */
966     RETURN_TRUE;
967 }
968 /* }}} */
969 
970 /* {{{ proto long Db4Txn::id()
971  */
ZEND_NAMED_FUNCTION(_wrap_db_txn_id)972 ZEND_NAMED_FUNCTION(_wrap_db_txn_id)
973 {
974     DB_TXN *txn;
975 
976     getDbTxnFromThis(txn);
977     if(ZEND_NUM_ARGS()) WRONG_PARAM_COUNT;
978     RETURN_LONG(txn->id(txn));
979 }
980 /* }}} */
981 
982 /* {{{ proto bool Db4Txn::set_timeout(long $timeout [, long $flags])
983  */
ZEND_NAMED_FUNCTION(_wrap_db_txn_set_timeout)984 ZEND_NAMED_FUNCTION(_wrap_db_txn_set_timeout)
985 {
986     DB_TXN *txn;
987     u_int32_t flags = 0;
988     long timeout;
989     int ret;
990 
991     getDbTxnFromThis(txn);
992     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &timeout, &flags) == FAILURE)
993     {
994         return;
995     }
996     if((ret = txn->set_timeout(txn, timeout, flags)) != 0) {
997         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", db_strerror(ret));
998         RETURN_FALSE;
999     }
1000     RETURN_TRUE;
1001 }
1002 /* }}} */
1003 
1004 /* {{{ proto bool Db4Txn::set_name(string $name)
1005  */
ZEND_NAMED_FUNCTION(_wrap_db_txn_set_name)1006 ZEND_NAMED_FUNCTION(_wrap_db_txn_set_name)
1007 {
1008     DB_TXN *txn;
1009     char *name;
1010     int name_len;
1011 
1012     getDbTxnFromThis(txn);
1013     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE)
1014     {
1015         return;
1016     }
1017     txn->set_name(txn, name);
1018     RETURN_TRUE;
1019 }
1020 /* }}} */
1021 
1022 /* {{{ proto bool Db4Txn::get_name()
1023  */
ZEND_NAMED_FUNCTION(_wrap_db_txn_get_name)1024 ZEND_NAMED_FUNCTION(_wrap_db_txn_get_name)
1025 {
1026     DB_TXN *txn;
1027     const char *name;
1028     int ret;
1029 
1030     getDbTxnFromThis(txn);
1031     if(ZEND_NUM_ARGS())
1032     {
1033 		WRONG_PARAM_COUNT;
1034     }
1035     if((ret = txn->get_name(txn, &name)) != 0) {
1036         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", db_strerror(ret));
1037         RETURN_FALSE;
1038     }
1039     RETURN_STRING((char *)name);
1040 }
1041 /* }}} */
1042 
1043 /* {{{ private Db4Txn::Db4Txn()
1044  */
ZEND_NAMED_FUNCTION(_wrap_new_DbTxn)1045 ZEND_NAMED_FUNCTION(_wrap_new_DbTxn)
1046 {
1047     php_error_docref(NULL TSRMLS_CC, E_ERROR, "DB4Txn objects must be created with Db4Env::begin_txn()");
1048 }
1049 /* }}} */
1050 
1051 /* }}} */
1052 
1053 
1054 /* {{{ DB4 method definitions
1055  */
1056 
1057 /* {{{ proto object DB4::DB4([object $dbenv])
1058  */
ZEND_NAMED_FUNCTION(_wrap_new_db4)1059 ZEND_NAMED_FUNCTION(_wrap_new_db4)
1060 {
1061     DB *db;
1062     DB_ENV *dbenv = NULL;
1063     zval *dbenv_obj = NULL;
1064     zval *self;
1065     int ret;
1066 
1067     self = getThis();
1068     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|O",
1069                              &dbenv_obj, db_env_ce) == FAILURE)
1070     {
1071         return;
1072     }
1073     if(dbenv_obj) {
1074         dbenv = php_db4_getDbEnvFromObj(dbenv_obj TSRMLS_CC);
1075         zval_add_ref(dbenv_obj);
1076         add_property_zval(self, "dbenv", dbenv_obj);
1077     }
1078     if((ret = my_db_create(&db, dbenv, 0)) != 0) {
1079         php_error_docref(NULL TSRMLS_CC,
1080 			 E_WARNING, "error occurred during open");
1081         RETURN_FALSE;
1082     }
1083     setDb(self, db TSRMLS_CC);
1084 }
1085 /* }}} */
1086 
1087 /* {{{ proto bool DB4::open([object $txn [, string $file [, string $database [, long $flags [, long $mode]]]]])
1088  */
ZEND_NAMED_FUNCTION(_wrap_db_open)1089 ZEND_NAMED_FUNCTION(_wrap_db_open)
1090 {
1091     DB *db = NULL;
1092     DB_TXN *dbtxn = NULL;
1093     zval *dbtxn_obj = NULL;
1094     char *file = NULL, *database = NULL;
1095     long filelen = 0, databaselen = 0;
1096     DBTYPE type = DB_BTREE;
1097     u_int32_t flags = DB_CREATE;
1098     int mode = 0;
1099     int ret;
1100 
1101     zval *self;
1102     self = getThis();
1103     getDbFromThis(db);
1104 
1105     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|O!sslll",
1106                              &dbtxn_obj, db_txn_ce,
1107                              &file, &filelen,
1108                              &database, &databaselen,
1109                              &type, &flags, &mode) == FAILURE)
1110     {
1111         return;
1112     }
1113     if(dbtxn_obj) {
1114         dbtxn = php_db4_getDbTxnFromObj(dbtxn_obj TSRMLS_CC);
1115     }
1116     add_property_string(self, "file", file);
1117     add_property_string(self, "database", database);
1118     if(strcmp(file, "") == 0) file = NULL;
1119     if(strcmp(database, "") == 0) database = NULL;
1120     /* add type and other introspection data */
1121     if((ret = db->open(db, dbtxn, file, database, type, flags, mode)) == 0) {
1122         RETURN_TRUE;
1123     }
1124     else {
1125         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", db_strerror(ret));
1126         add_property_string(self, "lastError", db_strerror(ret));
1127         RETURN_FALSE;
1128     }
1129 }
1130 /* }}} */
1131 
1132 /* {{{ proto bool DB4::close()
1133  */
ZEND_NAMED_FUNCTION(_wrap_db_close)1134 ZEND_NAMED_FUNCTION(_wrap_db_close)
1135 {
1136     struct php_DB *pdb = NULL;
1137     getPhpDbFromThis(pdb);
1138 
1139     if(ZEND_NUM_ARGS()) {
1140         WRONG_PARAM_COUNT;
1141     }
1142 	if(pdb && pdb->db) {
1143       pdb->db->close(pdb->db, 0);
1144 	  pdb->db = NULL;
1145 	}
1146     RETURN_TRUE;
1147 }
1148 /* }}} */
1149 
1150 /* {{{ proto bool DB4::del(string $key [, object $txn])
1151  */
ZEND_NAMED_FUNCTION(_wrap_db_del)1152 ZEND_NAMED_FUNCTION(_wrap_db_del)
1153 {
1154     DB *db = NULL;
1155     DB_TXN *txn = NULL;
1156     zval *txn_obj = NULL;
1157     u_int32_t flags;
1158     DBT key;
1159     char *keyname;
1160     int keylen;
1161 
1162     getDbFromThis(db);
1163     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|O", &keyname, &keylen,
1164                              &txn_obj, db_txn_ce) == FAILURE)
1165     {
1166         return;
1167     }
1168     if(txn_obj) {
1169         getDbTxnFromThis(txn);
1170         flags = 0;
1171     }
1172     memset(&key, 0, sizeof(DBT));
1173     key.data = keyname;
1174     key.size = keylen;
1175     RETURN_LONG(db->del(db, txn, &key, flags));
1176 }
1177 /* }}} */
1178 
1179 /* {{{ proto string DB4::get(string $key [,object $txn [, long flags]])
1180  */
ZEND_NAMED_FUNCTION(_wrap_db_get)1181 ZEND_NAMED_FUNCTION(_wrap_db_get)
1182 {
1183     DB *db = NULL;
1184     DB_TXN *txn = NULL;
1185     zval *txn_obj = NULL;
1186     DBT key, value;
1187     char *keyname;
1188     int keylen;
1189     u_int32_t flags = 0;
1190 
1191     getDbFromThis(db);
1192     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Ol", &keyname, &keylen,
1193                              &txn_obj, db_txn_ce, &flags) == FAILURE)
1194     {
1195         return;
1196     }
1197     if(txn_obj) {
1198         txn = php_db4_getDbTxnFromObj(txn_obj TSRMLS_CC);
1199     }
1200     memset(&key, 0, sizeof(DBT));
1201     key.data = keyname;
1202     key.size = keylen;
1203     memset(&value, 0, sizeof(DBT));
1204     if(db->get(db, txn, &key, &value, flags) == 0) {
1205         RETURN_STRINGL((char *)value.data, value.size);
1206     }
1207     RETURN_FALSE;
1208 }
1209 /* }}} */
1210 
1211 /* {{{ proto string DB4::pget(string $key, string &$pkey [,object $txn [, long flags]])
1212  */
ZEND_NAMED_FUNCTION(_wrap_db_pget)1213 ZEND_NAMED_FUNCTION(_wrap_db_pget)
1214 {
1215     /*DB *db = NULL;
1216     DB_TXN *txn = NULL;
1217     zval *txn_obj = NULL;
1218     DBT key, value, pkey;
1219     char *keyname;
1220     int keylen;
1221     zval *z_pkey;
1222     u_int32_t flags = 0;
1223 
1224     getDbFromThis(db);
1225     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|Ol",
1226                              &keyname, &keylen, &z_pkey,
1227                              &txn_obj, db_txn_ce, &flags) == FAILURE)
1228     {
1229         return;
1230     }
1231     if(txn_obj) {
1232         txn = php_db4_getDbTxnFromObj(txn_obj TSRMLS_CC);
1233     }
1234     memset(&key, 0, sizeof(DBT));
1235     key.data = keyname;
1236     key.size = keylen;
1237     memset(&pkey, 0, sizeof(DBT));
1238     memset(&value, 0, sizeof(DBT));
1239     if(db->pget(db, txn, &key, &pkey, &value, flags) == 0) {
1240         if(Z_STRLEN_P(z_pkey) == 0) {
1241             Z_STRVAL_P(z_pkey) = (char *) emalloc(pkey.size);
1242         } else {
1243             Z_STRVAL_P(z_pkey) = (char *) erealloc(Z_STRVAL_P(z_pkey), pkey.size);
1244         }
1245         memcpy(Z_STRVAL_P(z_pkey), pkey.data, pkey.size);
1246         Z_STRLEN_P(z_pkey) = pkey.size;
1247         RETURN_STRINGL((char *)value.data, value.size);
1248     }*/
1249     php_error_docref(NULL TSRMLS_CC, E_ERROR,
1250          "Function pget currently not implemented.");
1251     RETURN_FALSE;
1252 }
1253 /* }}} */
1254 
1255 /* {{{ proto string DB4::get_type()
1256  */
ZEND_NAMED_FUNCTION(_wrap_db_get_type)1257 ZEND_NAMED_FUNCTION(_wrap_db_get_type)
1258 {
1259     DB *db = NULL;
1260     DBTYPE type;
1261 
1262     getDbFromThis(db);
1263     if(db->get_type(db, &type)) {
1264         RETURN_FALSE;
1265     }
1266     switch(type) {
1267         case DB_BTREE:
1268             RETURN_STRING("DB_BTREE");
1269             break;
1270         case DB_HASH:
1271             RETURN_STRING("DB_HASH");
1272             break;
1273         case DB_RECNO:
1274             RETURN_STRING("DB_RECNO");
1275             break;
1276         case DB_QUEUE:
1277             RETURN_STRING("DB_QUEUE");
1278             break;
1279         default:
1280             RETURN_STRING("UNKNOWN");
1281             break;
1282     }
1283 }
1284 /* }}} */
1285 
1286 /* {{{ proto bool DB4::set_encrypt(string $password [, long $flags])
1287  */
ZEND_NAMED_FUNCTION(_wrap_db_set_encrypt)1288 ZEND_NAMED_FUNCTION(_wrap_db_set_encrypt)
1289 {
1290     DB *db = NULL;
1291     char *pass;
1292     long passlen;
1293 	u_int32_t flags = 0;
1294     getDbFromThis(db);
1295     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &pass, &passlen,
1296 							 &flags) == FAILURE)
1297     {
1298         return;
1299     }
1300     RETURN_BOOL(db->set_encrypt(db, pass, flags)?0:1);
1301 }
1302 /* }}} */
1303 
1304 /* {{{ proto int DB4::get_encrypt_flags()
1305  */
ZEND_NAMED_FUNCTION(_wrap_db_get_encrypt_flags)1306 ZEND_NAMED_FUNCTION(_wrap_db_get_encrypt_flags)
1307 {
1308     DB *db = NULL;
1309 
1310     getDbFromThis(db);
1311 	u_int32_t flags = 0;
1312 	if (db->get_encrypt_flags(db, &flags) != 0)
1313 			RETURN_FALSE;
1314 	RETURN_LONG(flags);
1315 }
1316 /* }}} */
1317 
1318 /* {{{ proto array DB4::stat([object $txn [, long flags]])
1319  */
ZEND_NAMED_FUNCTION(_wrap_db_stat)1320 ZEND_NAMED_FUNCTION(_wrap_db_stat)
1321 {
1322     DB *db = NULL;
1323     DB_TXN *txn = NULL;
1324     zval *txn_obj = NULL;
1325     DBTYPE type;
1326     u_int32_t flags = 0;
1327 
1328     getDbFromThis(db);
1329     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zl", &txn_obj, db_txn_ce, &flags) == FAILURE) {
1330         return;
1331     }
1332     if(db->get_type(db, &type)) {
1333         RETURN_FALSE;
1334     }
1335     if(txn_obj) {
1336         txn = php_db4_getDbTxnFromObj(txn_obj TSRMLS_CC);
1337 	}
1338     switch(type) {
1339 #define ADD_STAT_LONG(a)  add_assoc_long(return_value, #a, sb.a)
1340         case DB_HASH:
1341         {
1342             DB_HASH_STAT sb;
1343             if(db->stat(db, txn, (void *)&sb, flags)) {
1344                 RETURN_FALSE;
1345             }
1346             array_init(return_value);
1347             if(flags & DB_FAST_STAT) {
1348                 ADD_STAT_LONG(hash_magic);
1349                 ADD_STAT_LONG(hash_version);
1350                 ADD_STAT_LONG(hash_nkeys);
1351                 ADD_STAT_LONG(hash_ndata);
1352                 ADD_STAT_LONG(hash_pagesize);
1353                 ADD_STAT_LONG(hash_ffactor);
1354                 ADD_STAT_LONG(hash_buckets);
1355             }
1356             ADD_STAT_LONG(hash_free);
1357             ADD_STAT_LONG(hash_bfree);
1358             ADD_STAT_LONG(hash_bigpages);
1359             ADD_STAT_LONG(hash_bfree);
1360             ADD_STAT_LONG(hash_overflows);
1361             ADD_STAT_LONG(hash_ovfl_free);
1362             ADD_STAT_LONG(hash_dup);
1363             ADD_STAT_LONG(hash_dup_free);
1364         }
1365             break;
1366         case DB_BTREE:
1367         case DB_RECNO:
1368         {
1369             DB_BTREE_STAT sb;
1370             if(db->stat(db, txn, (void *)&sb, flags)) {
1371                 RETURN_FALSE;
1372             }
1373             array_init(return_value);
1374             if(flags & DB_FAST_STAT) {
1375                 ADD_STAT_LONG(bt_magic);
1376                 ADD_STAT_LONG(bt_version);
1377                 ADD_STAT_LONG(bt_nkeys);
1378                 ADD_STAT_LONG(bt_ndata);
1379                 ADD_STAT_LONG(bt_pagesize);
1380                 ADD_STAT_LONG(bt_minkey);
1381                 ADD_STAT_LONG(bt_re_len);
1382                 ADD_STAT_LONG(bt_re_pad);
1383             }
1384             ADD_STAT_LONG(bt_levels);
1385             ADD_STAT_LONG(bt_int_pg);
1386             ADD_STAT_LONG(bt_leaf_pg);
1387             ADD_STAT_LONG(bt_dup_pg);
1388             ADD_STAT_LONG(bt_over_pg);
1389             ADD_STAT_LONG(bt_free);
1390             ADD_STAT_LONG(bt_int_pgfree);
1391             ADD_STAT_LONG(bt_leaf_pgfree);
1392             ADD_STAT_LONG(bt_dup_pgfree);
1393             ADD_STAT_LONG(bt_over_pgfree);
1394         }
1395             break;
1396         case DB_QUEUE:
1397         {
1398             DB_QUEUE_STAT sb;
1399             if(db->stat(db, txn, (void *)&sb, flags)) {
1400                 RETURN_FALSE;
1401             }
1402             array_init(return_value);
1403             if(flags & DB_FAST_STAT) {
1404                 ADD_STAT_LONG(qs_magic);
1405                 ADD_STAT_LONG(qs_version);
1406                 ADD_STAT_LONG(qs_nkeys);
1407                 ADD_STAT_LONG(qs_ndata);
1408                 ADD_STAT_LONG(qs_pagesize);
1409                 ADD_STAT_LONG(qs_extentsize);
1410                 ADD_STAT_LONG(qs_re_len);
1411                 ADD_STAT_LONG(qs_re_pad);
1412                 ADD_STAT_LONG(qs_first_recno);
1413                 ADD_STAT_LONG(qs_cur_recno);
1414             }
1415             ADD_STAT_LONG(qs_pages);
1416             ADD_STAT_LONG(qs_pgfree);
1417             break;
1418         }
1419         default:
1420             RETURN_FALSE;
1421     }
1422 }
1423 /* }}} */
1424 
1425 /* {{{ proto DBCursor DB4::join(array $curslist [, long $flags])
1426  */
ZEND_NAMED_FUNCTION(_wrap_db_join)1427 ZEND_NAMED_FUNCTION(_wrap_db_join)
1428 {
1429     DB *db = NULL;
1430     DBC *dbcp;
1431     DBC **curslist;
1432     zval *z_array;
1433     HashTable *array;
1434     HashPosition pos;
1435     zval **z_cursor;
1436     int num_cursors, rv, i;
1437 
1438     u_int32_t flags = 0;
1439 
1440     getDbFromThis(db);
1441     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l",
1442                              &z_array, &flags) == FAILURE)
1443     {
1444         return;
1445     }
1446     array = HASH_OF(z_array);
1447     num_cursors = zend_hash_num_elements(array);
1448     curslist = (DBC **) calloc(sizeof(DBC *), num_cursors + 1);
1449     for(zend_hash_internal_pointer_reset_ex(array, &pos), i=0;
1450         (*z_cursor = zend_hash_get_current_data_ex(array, &pos)) != NULL;
1451         zend_hash_move_forward_ex(array, &pos), i++) {
1452         curslist[i] = php_db4_getDbcFromObj(*z_cursor TSRMLS_CC);
1453     }
1454     rv = db->join(db, curslist, &dbcp, flags);
1455     free(curslist);
1456     if(rv) {
1457         RETURN_FALSE;
1458     } else {
1459         object_init_ex(return_value, dbc_ce);
1460         setDbc(return_value, dbcp, NULL TSRMLS_CC);
1461     }
1462 }
1463 /* }}} */
1464 
1465 /* {{{ proto bool DB4::put(string $key, string $value [, object $txn [, long flags]])
1466  */
ZEND_NAMED_FUNCTION(_wrap_db_put)1467 ZEND_NAMED_FUNCTION(_wrap_db_put)
1468 {
1469     DB *db = NULL;
1470     DB_TXN *txn = NULL;
1471     zval *txn_obj = NULL;
1472     DBT key, value;
1473     char *keyname, *dataname;
1474     int keylen, datalen;
1475     int ret;
1476     zval *self;
1477     long flags = 0;
1478 
1479     self = getThis();
1480     getDbFromThis(db);
1481     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|Ol", &keyname, &keylen,
1482                              &dataname, &datalen, &txn_obj, db_txn_ce, &flags) == FAILURE)
1483     {
1484         return;
1485     }
1486     if(txn_obj) {
1487         txn = php_db4_getDbTxnFromObj(txn_obj TSRMLS_CC);
1488     }
1489     memset(&key, 0, sizeof(DBT));
1490     key.data = keyname;
1491     key.size = keylen;
1492     memset(&value, 0, sizeof(DBT));
1493     value.data = dataname;
1494     value.size = datalen;
1495     if((ret = db->put(db, txn, &key, &value, flags)) != 0) {
1496         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", db_strerror(ret));
1497         add_property_string(self, "lastError", db_strerror(ret));
1498         RETURN_FALSE;
1499     }
1500     RETURN_TRUE;
1501 }
1502 /* }}} */
1503 
1504 /* {{{ proto bool DB4::sync()
1505  */
ZEND_NAMED_FUNCTION(_wrap_db_sync)1506 ZEND_NAMED_FUNCTION(_wrap_db_sync)
1507 {
1508     DB *db = NULL;
1509     getDbFromThis(db);
1510     if(ZEND_NUM_ARGS()) {
1511         WRONG_PARAM_COUNT;
1512     }
1513     db->sync(db, 0);
1514     RETURN_TRUE;
1515 }
1516 /* }}} */
1517 
1518 /* {{{ proto bool DB4::truncate([object $txn [, long $flags]])
1519  */
ZEND_NAMED_FUNCTION(_wrap_db_truncate)1520 ZEND_NAMED_FUNCTION(_wrap_db_truncate)
1521 {
1522     DB *db = NULL;
1523     DB_TXN *txn = NULL;
1524     zval *txn_obj = NULL;
1525     long flags = DB_AUTO_COMMIT;
1526     u_int32_t countp;
1527 
1528     getDbFromThis(db);
1529     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|Ol",
1530                              &txn_obj, db_txn_ce, &flags) == FAILURE)
1531     {
1532         return;
1533     }
1534     if(txn_obj) {
1535         txn = php_db4_getDbTxnFromObj(txn_obj TSRMLS_CC);
1536         flags = 0;
1537     }
1538     if(db->truncate(db, txn, &countp, flags) == 0) {
1539         RETURN_LONG(countp);
1540     }
1541     RETURN_FALSE;
1542 }
1543 /* }}} */
1544 
1545 /* {{{ proto DB4Cursor DB4::cursor([object $txn [, long flags]])
1546  */
ZEND_NAMED_FUNCTION(_wrap_db_cursor)1547 ZEND_NAMED_FUNCTION(_wrap_db_cursor)
1548 {
1549     DB *db;
1550     DB_TXN *txn = NULL;
1551     zval *txn_obj = NULL, *self;
1552     DBC *cursor = NULL;
1553     u_int32_t flags = 0;
1554     int ret;
1555 
1556     self = getThis();
1557     getDbFromThis(db);
1558     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|Ol", &txn_obj, db_txn_ce, &flags) == FAILURE)
1559     {
1560         return;
1561     }
1562     if(txn_obj) {
1563         txn = php_db4_getDbTxnFromObj(txn_obj TSRMLS_CC);
1564     }
1565     if((ret = db->cursor(db, txn, &cursor, flags)) != 0 ) {
1566         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", db_strerror(ret));
1567         add_property_string(self, "lastError", db_strerror(ret));
1568         RETURN_FALSE;
1569     }
1570     else {
1571         object_init_ex(return_value, dbc_ce);
1572         setDbc(return_value, cursor, txn_obj?getPhpDbTxnFromObj(txn_obj TSRMLS_CC):NULL TSRMLS_CC);
1573     }
1574 
1575 }
1576 /* }}} */
1577 
1578 /* }}} end DB4 method definitions */
1579 
1580 /* {{{ DB4Cursor method definitions
1581  */
1582 
1583 /* {{{ proto bool Db4Cursor::close()
1584  */
ZEND_NAMED_FUNCTION(_wrap_dbc_close)1585 ZEND_NAMED_FUNCTION(_wrap_dbc_close)
1586 {
1587     DBC *dbc;
1588     int ret;
1589     zval *self;
1590 
1591     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) return;
1592     self = getThis();
1593     getDbcFromThis(dbc);
1594     if((ret = closeDbc(self TSRMLS_CC)) != 0) {
1595         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", db_strerror(ret));
1596         RETURN_FALSE;
1597     }
1598     RETURN_TRUE;
1599 }
1600 /* }}} */
1601 
1602 /* {{{ proto long Db4Cursor::count()
1603  */
ZEND_NAMED_FUNCTION(_wrap_dbc_count)1604 ZEND_NAMED_FUNCTION(_wrap_dbc_count)
1605 {
1606     DBC *dbc;
1607     db_recno_t count;
1608     int ret;
1609 
1610     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) return;
1611     getDbcFromThis(dbc);
1612     if((ret = dbc->c_count(dbc, &count, 0)) != 0) {
1613         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", db_strerror(ret));
1614         RETURN_FALSE;
1615     }
1616     RETURN_LONG(count);
1617 }
1618 /* }}} */
1619 
1620 /* {{{ proto bool Db4Cursor::del()
1621  */
ZEND_NAMED_FUNCTION(_wrap_dbc_del)1622 ZEND_NAMED_FUNCTION(_wrap_dbc_del)
1623 {
1624     DBC *dbc;
1625     int ret;
1626 
1627     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) return;
1628     getDbcFromThis(dbc);
1629     if((ret = dbc->c_del(dbc, 0)) != 0) {
1630         if(ret != DB_KEYEMPTY) {
1631             php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", db_strerror(ret));
1632         }
1633         RETURN_FALSE;
1634     }
1635     RETURN_TRUE;
1636 }
1637 /* }}} */
1638 
1639 /* {{{ proto object Db4Cursor::dup([long $flags])
1640  */
ZEND_NAMED_FUNCTION(_wrap_dbc_dup)1641 ZEND_NAMED_FUNCTION(_wrap_dbc_dup)
1642 {
1643     DBC *dbc, *newdbc;
1644     u_int32_t flags = 0;
1645     int ret;
1646 
1647     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags) == FAILURE) return;
1648     getDbcFromThis(dbc);
1649     if((ret = dbc->c_dup(dbc, &newdbc, flags)) != 0) {
1650         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", db_strerror(ret));
1651         RETURN_FALSE;
1652     }
1653     object_init_ex(return_value, dbc_ce);
1654     /* FIXME should pass in dbc's parent txn */
1655     setDbc(return_value, newdbc, NULL TSRMLS_CC);
1656 }
1657 /* }}} */
1658 
1659 /* {{{ proto string Db4Cursor::get(string &$key, string &$data [, long $flags])
1660  */
ZEND_NAMED_FUNCTION(_wrap_dbc_get)1661 ZEND_NAMED_FUNCTION(_wrap_dbc_get)
1662 {
1663     DBC *dbc;
1664     DBT key, value;
1665     zval *zkey, *zvalue;
1666     u_int32_t flags = DB_NEXT;
1667     zval *self;
1668     int ret;
1669 
1670     self = getThis();
1671     getDbcFromThis(dbc);
1672     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/z/|l", &zkey, &zvalue, &flags) == FAILURE)
1673     {
1674         return;
1675     }
1676     memset(&key, 0, sizeof(DBT));
1677 	key.data = Z_STRVAL_P(zkey);
1678 	key.size = Z_STRLEN_P(zkey);
1679     memset(&value, 0, sizeof(DBT));
1680 	value.data = Z_STRVAL_P(zvalue);
1681 	value.size = Z_STRLEN_P(zvalue);
1682     if((ret = dbc->c_get(dbc, &key, &value, flags)) == 0) {
1683 		zval_dtor(zkey); ZVAL_STRINGL(zkey, (char *) key.data, key.size);
1684 		zval_dtor(zvalue); ZVAL_STRINGL(zvalue, (char *) value.data, value.size);
1685 		RETURN_LONG(0);
1686     }
1687 	if(ret != DB_NOTFOUND) {
1688     	php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", db_strerror(ret));
1689     	add_property_string(self, "lastError", db_strerror(ret));
1690     }
1691     RETURN_LONG(1);
1692 }
1693 /* }}} */
1694 
1695 /* {{{ proto string Db4Cursor::pget(string &$key, string &$pkey, string &$data [, long $flags])
1696  */
ZEND_NAMED_FUNCTION(_wrap_dbc_pget)1697 ZEND_NAMED_FUNCTION(_wrap_dbc_pget)
1698 {
1699     DBC *dbc;
1700     DBT key, pkey, value;
1701     zval *zkey, *zvalue, *zpkey;
1702     u_int32_t flags = DB_NEXT;
1703     zval *self;
1704     int ret;
1705 
1706     self = getThis();
1707     getDbcFromThis(dbc);
1708     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/z/z/|l", &zkey, &zpkey, &zvalue, &flags) == FAILURE)
1709     {
1710         return;
1711     }
1712     memset(&key, 0, sizeof(DBT));
1713 	key.data = Z_STRVAL_P(zkey);
1714 	key.size = Z_STRLEN_P(zkey);
1715     memset(&pkey, 0, sizeof(DBT));
1716 	pkey.data = Z_STRVAL_P(zpkey);
1717 	pkey.size = Z_STRLEN_P(zpkey);
1718     memset(&value, 0, sizeof(DBT));
1719 	value.data = Z_STRVAL_P(zvalue);
1720 	value.size = Z_STRLEN_P(zvalue);
1721     if((ret = dbc->c_pget(dbc, &key, &pkey, &value, flags)) == 0) {
1722 		zval_dtor(zkey); ZVAL_STRINGL(zkey, (char *) key.data, key.size);
1723 		zval_dtor(zpkey); ZVAL_STRINGL(zpkey, (char *) pkey.data, pkey.size);
1724 		zval_dtor(zvalue); ZVAL_STRINGL(zvalue, (char *) value.data, value.size);
1725 		RETURN_LONG(0);
1726     }
1727 	if(ret != DB_NOTFOUND) {
1728     	php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", db_strerror(ret));
1729     	add_property_string(self, "lastError", db_strerror(ret));
1730     }
1731     RETURN_LONG(1);
1732 }
1733 /* }}} */
1734 
1735 /* {{{ proto bool Db4Cursor::put(string $key, string $data [, long $flags])
1736  */
ZEND_NAMED_FUNCTION(_wrap_dbc_put)1737 ZEND_NAMED_FUNCTION(_wrap_dbc_put)
1738 {
1739     DBC *dbc;
1740     DBT key, value;
1741     char *keyname, *dataname;
1742     int keylen, datalen;
1743     u_int32_t flags = 0;
1744     int ret;
1745 
1746     getDbcFromThis(dbc);
1747     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &keyname, &keylen,
1748           &dataname, &datalen, &flags) == FAILURE)
1749     {
1750         return;
1751     }
1752     memset(&key, 0, sizeof(DBT));
1753     key.data = keyname;
1754     key.size = keylen;
1755     memset(&value, 0, sizeof(DBT));
1756     value.data = dataname;
1757     value.size = datalen;
1758     if((ret = dbc->c_put(dbc, &key, &value, flags)) == 0) {
1759         RETURN_TRUE;
1760     }
1761     php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", db_strerror(ret));
1762     RETURN_FALSE;
1763 
1764 }
1765 /* }}} */
1766 
1767 /* }}} */
1768 
1769 /* {{{ DB4Env method definitions
1770  */
1771 
1772 /* {{{ php_db4_error ( zend_error wrapper )
1773  */
1774 
php_db4_error(const DB_ENV * dp,const char * errpfx,const char * msg)1775 void php_db4_error(const DB_ENV *dp, const char *errpfx, const char *msg)
1776 {
1777 	TSRMLS_FETCH();
1778     php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s %s\n", errpfx, msg);
1779 }
1780 /* }}} */
1781 
1782 /* {{{ proto object DB4Env::Db4Env([long $flags])
1783  */
ZEND_NAMED_FUNCTION(_wrap_new_DbEnv)1784 ZEND_NAMED_FUNCTION(_wrap_new_DbEnv)
1785 {
1786     DB_ENV *dbenv;
1787     u_int32_t flags = 0;
1788 
1789     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags) == FAILURE)
1790     {
1791         return;
1792     }
1793     if(my_db_env_create(&dbenv, flags) != 0) {
1794         php_error_docref(NULL TSRMLS_CC, E_WARNING, "bad things here: %s:%d\n", __FILE__, __LINE__);
1795         RETURN_FALSE;
1796     }
1797 	DbEnv::wrap_DB_ENV(dbenv);
1798     dbenv->set_errcall(dbenv, php_db4_error);
1799     setDbEnv(getThis(), dbenv TSRMLS_CC);
1800 }
1801 /* }}} */
1802 
1803 /* {{{ proto bool DB4Env::close([long $flags])
1804  */
ZEND_NAMED_FUNCTION(_wrap_db_env_close)1805 ZEND_NAMED_FUNCTION(_wrap_db_env_close)
1806 {
1807     struct php_DB_ENV *pdb;
1808     DbEnv *dbe;
1809     u_int32_t flags = 0;
1810 
1811     pdb = php_db4_getPhpDbEnvFromObj(getThis() TSRMLS_CC);
1812     if(!pdb || !pdb->dbenv) {
1813       RETURN_FALSE;
1814     }
1815     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags) == FAILURE) {
1816     	RETURN_FALSE;
1817     }
1818     dbe = DbEnv::get_DbEnv(pdb->dbenv);
1819     dbe->close(flags);
1820     pdb->dbenv = NULL;
1821     RETURN_TRUE;
1822 }
1823 /* }}} */
1824 
1825 /* {{{ proto bool DB4Env::dbremove(object $txn, string $file [, string $database [, long flags]])
1826  */
ZEND_NAMED_FUNCTION(_wrap_db_env_dbremove)1827 ZEND_NAMED_FUNCTION(_wrap_db_env_dbremove)
1828 {
1829     DB_ENV *dbenv;
1830     DB_TXN *txn;
1831     zval *txn_obj;
1832     char *filename=NULL, *database=NULL;
1833     int filenamelen, databaselen;
1834     u_int32_t flags = 0;
1835 
1836     getDbEnvFromThis(dbenv);
1837     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!s|sl", &txn_obj, db_txn_ce,
1838          &filename, &filenamelen, &database, &databaselen, &flags) == FAILURE)
1839     {
1840         return;
1841     }
1842     if(txn_obj) {
1843         txn = php_db4_getDbTxnFromObj(txn_obj TSRMLS_CC);
1844         flags = 0;
1845     }
1846     if(dbenv->dbremove(dbenv, txn, filename, database, flags) == 0) {
1847         RETURN_TRUE;
1848     }
1849     RETURN_FALSE;
1850 }
1851 /* }}} */
1852 
1853 /* {{{ proto bool DB4Env::dbrename(object $txn, string $file, string $database, string $newdatabase [, long flags])
1854  */
ZEND_NAMED_FUNCTION(_wrap_db_env_dbrename)1855 ZEND_NAMED_FUNCTION(_wrap_db_env_dbrename)
1856 {
1857     DB_ENV *dbenv;
1858     DB_TXN *txn;
1859     zval *txn_obj;
1860     char *filename=NULL, *database=NULL, *newname=NULL;
1861     int filenamelen, databaselen, newnamelen;
1862     u_int32_t flags = 0;
1863 
1864     getDbEnvFromThis(dbenv);
1865     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!sss|l", &txn_obj, db_txn_ce,
1866          &filename, &filenamelen, &database, &databaselen,
1867          &newname, &newnamelen, &flags) == FAILURE)
1868     {
1869         return;
1870     }
1871     if(txn_obj) {
1872         txn = php_db4_getDbTxnFromObj(txn_obj TSRMLS_CC);
1873         flags = 0;
1874     }
1875     if(dbenv->dbrename(dbenv, txn, filename, database, newname, flags) == 0) {
1876         RETURN_TRUE;
1877     }
1878     RETURN_FALSE;
1879 }
1880 /* }}} */
1881 
1882 /* {{{ proto bool DB4Env::open(string $home [, long flags [, long mode]])
1883  */
ZEND_NAMED_FUNCTION(_wrap_db_env_open)1884 ZEND_NAMED_FUNCTION(_wrap_db_env_open)
1885 {
1886     DB_ENV *dbenv;
1887     zval *self;
1888     char *home = NULL;
1889     long  homelen;
1890     u_int32_t flags = DB_CREATE  | DB_INIT_LOCK | DB_INIT_LOG | \
1891             DB_INIT_MPOOL | DB_INIT_TXN ;
1892     int mode = 0666;
1893     int ret;
1894 
1895     getDbEnvFromThis(dbenv);
1896     self = getThis();
1897     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!ll", &home, &homelen,
1898         &flags, &mode) == FAILURE)
1899     {
1900         return;
1901     }
1902     if((ret = dbenv->open(dbenv, home, flags, mode) != 0)) {
1903         php_error_docref(NULL TSRMLS_CC, E_WARNING, "open(%s, %d, %o) failed: %s (%d) %s:%d\n", home, flags, mode, strerror(ret), ret, __FILE__, __LINE__);
1904         RETURN_FALSE;
1905     }
1906 	if(home) add_property_stringl(self, "home", home, homelen);
1907 }
1908 /* }}} */
1909 
1910 /* {{{ proto bool DB4Env::remove(string $home [, long flags])
1911  */
ZEND_NAMED_FUNCTION(_wrap_db_env_remove)1912 ZEND_NAMED_FUNCTION(_wrap_db_env_remove)
1913 {
1914     DB_ENV *dbenv;
1915 	DbEnv *dbe;
1916     zval *self;
1917     char *home;
1918     long homelen;
1919     u_int32_t flags = 0;
1920     self = getThis();
1921     getDbEnvFromThis(dbenv);
1922 	dbe = DbEnv::get_DbEnv(dbenv);
1923     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &home, &homelen, &flags) == FAILURE)
1924     {
1925         return;
1926     }
1927     RETURN_BOOL(dbe->remove(home, flags)?0:1);
1928 }
1929 /* }}} */
1930 
1931 /* {{{ proto bool DB4Env::set_data_dir(string $dir)
1932  */
ZEND_NAMED_FUNCTION(_wrap_db_env_set_data_dir)1933 ZEND_NAMED_FUNCTION(_wrap_db_env_set_data_dir)
1934 {
1935     DB_ENV *dbenv;
1936     zval *self;
1937     char *dir;
1938     long dirlen;
1939     self = getThis();
1940     getDbEnvFromThis(dbenv);
1941     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &dir, &dirlen) == FAILURE)
1942     {
1943         return;
1944     }
1945     RETURN_BOOL(dbenv->set_data_dir(dbenv, dir)?0:1);
1946 }
1947 /* }}} */
1948 
1949 /* {{{ proto bool DB4Env::set_encrypt(string $password [, long $flags])
1950  */
ZEND_NAMED_FUNCTION(_wrap_db_env_set_encrypt)1951 ZEND_NAMED_FUNCTION(_wrap_db_env_set_encrypt)
1952 {
1953     DB_ENV *dbenv;
1954     zval *self;
1955     char *pass;
1956     long passlen;
1957 	u_int32_t flags = 0;
1958     self = getThis();
1959     getDbEnvFromThis(dbenv);
1960     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &pass, &passlen,
1961 							 &flags) == FAILURE)
1962     {
1963         return;
1964     }
1965     RETURN_BOOL(dbenv->set_encrypt(dbenv, pass, flags)?0:1);
1966 }
1967 /* }}} */
1968 
1969 /* {{{ proto int DB4Env::get_encrypt_flags()
1970  */
ZEND_NAMED_FUNCTION(_wrap_db_env_get_encrypt_flags)1971 ZEND_NAMED_FUNCTION(_wrap_db_env_get_encrypt_flags)
1972 {
1973     DB_ENV *dbenv;
1974     zval *self;
1975 	u_int32_t flags = 0;
1976     self = getThis();
1977     getDbEnvFromThis(dbenv);
1978 	if (dbenv->get_encrypt_flags(dbenv, &flags) != 0)
1979 			RETURN_FALSE;
1980 	RETURN_LONG(flags);
1981 }
1982 /* }}} */
1983 
1984 /* {{{ proto object Db4Env::txn_begin([object $parent_txn [, long $flags]])
1985  */
ZEND_NAMED_FUNCTION(_wrap_db_env_txn_begin)1986 ZEND_NAMED_FUNCTION(_wrap_db_env_txn_begin)
1987 {
1988     DB_ENV *dbenv;
1989     DB_TXN *txn, *parenttxn = NULL;
1990     zval *self;
1991     zval cursor_array;
1992     zval *parenttxn_obj = NULL;
1993     u_int32_t flags = 0;
1994     int ret;
1995 
1996     self = getThis();
1997     getDbEnvFromThis(dbenv);
1998     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|Ol", &parenttxn_obj, db_txn_ce,
1999          &flags) == FAILURE)
2000     {
2001         return;
2002     }
2003     if(parenttxn_obj) {
2004         parenttxn = php_db4_getDbTxnFromObj(parenttxn_obj TSRMLS_CC);
2005     }
2006     if((ret = dbenv->txn_begin(dbenv, parenttxn, &txn, flags)) != 0) {
2007         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", db_strerror(ret));
2008         add_property_string(self, "lastError", db_strerror(ret));
2009         RETURN_FALSE;
2010     }
2011     object_init_ex(return_value, db_txn_ce);
2012     array_init(&cursor_array);
2013     add_property_zval(return_value, "openCursors", &cursor_array);
2014     setDbTxn(return_value, txn TSRMLS_CC);
2015 }
2016 /* }}} */
2017 
2018 /* {{{ Db4Env::txn_checkpoint(long $kbytes, long $minutes [, long $flags])
2019  */
ZEND_NAMED_FUNCTION(_wrap_db_env_txn_checkpoint)2020 ZEND_NAMED_FUNCTION(_wrap_db_env_txn_checkpoint)
2021 {
2022     DB_ENV *dbenv;
2023     zval *self;
2024     u_int32_t kbytes = 0;
2025     u_int32_t mins = 0;
2026     u_int32_t flags = 0;
2027     int ret;
2028 
2029     self = getThis();
2030     getDbEnvFromThis(dbenv);
2031     if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll|l", &kbytes, &mins, &flags) == FAILURE)
2032     {
2033         return;
2034     }
2035     if((ret = dbenv->txn_checkpoint(dbenv, kbytes, mins, flags)) != 0) {
2036         add_property_string(self, "lastError", db_strerror(ret));
2037         RETURN_FALSE;
2038     }
2039     RETURN_TRUE;
2040 }
2041 /* }}} */
2042 
2043 /* }}} end db4env */
2044 
2045 /*
2046  * Local variables:
2047  * tab-width: 4
2048   c-basic-offset: 4
2049  * End:
2050  * vim600: noet sw=4 ts=4 fdm=marker
2051  * vim<600: noet sw=4 ts=4
2052  */
2053