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