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