mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 12:32:27 +01:00
155e78f014
BitKeeper/deleted/.del-ex_access.wpj~3df6ae8c99bf7c5f: Delete: bdb/build_vxworks/ex_access/ex_access.wpj BitKeeper/deleted/.del-ex_btrec.wpj~a7622f1c6f432dc6: Delete: bdb/build_vxworks/ex_btrec/ex_btrec.wpj BitKeeper/deleted/.del-ex_dbclient.wpj~7345440f3b204cdd: Delete: bdb/build_vxworks/ex_dbclient/ex_dbclient.wpj BitKeeper/deleted/.del-ex_env.wpj~fbe1ab10b04e8b74: Delete: bdb/build_vxworks/ex_env/ex_env.wpj BitKeeper/deleted/.del-ex_mpool.wpj~4479cfd5c45f327d: Delete: bdb/build_vxworks/ex_mpool/ex_mpool.wpj BitKeeper/deleted/.del-ex_tpcb.wpj~f78093006e14bf41: Delete: bdb/build_vxworks/ex_tpcb/ex_tpcb.wpj BitKeeper/deleted/.del-db_buildall.dsp~bd749ff6da11682: Delete: bdb/build_win32/db_buildall.dsp BitKeeper/deleted/.del-cxx_app.cpp~ad8df8e0791011ed: Delete: bdb/cxx/cxx_app.cpp BitKeeper/deleted/.del-cxx_log.cpp~a50ff3118fe06952: Delete: bdb/cxx/cxx_log.cpp BitKeeper/deleted/.del-cxx_table.cpp~ecd751e79b055556: Delete: bdb/cxx/cxx_table.cpp BitKeeper/deleted/.del-namemap.txt~796a3acd3885d8fd: Delete: bdb/cxx/namemap.txt BitKeeper/deleted/.del-Design.fileop~3ca4da68f1727373: Delete: bdb/db/Design.fileop BitKeeper/deleted/.del-db185_int.h~61bee3736e7959ef: Delete: bdb/db185/db185_int.h BitKeeper/deleted/.del-acconfig.h~411e8854d67ad8b5: Delete: bdb/dist/acconfig.h BitKeeper/deleted/.del-mutex.m4~a13383cde18a64e1: Delete: bdb/dist/aclocal/mutex.m4 BitKeeper/deleted/.del-options.m4~b9d0ca637213750a: Delete: bdb/dist/aclocal/options.m4 BitKeeper/deleted/.del-programs.m4~3ce7890b47732b30: Delete: bdb/dist/aclocal/programs.m4 BitKeeper/deleted/.del-tcl.m4~f944e2db93c3b6db: Delete: bdb/dist/aclocal/tcl.m4 BitKeeper/deleted/.del-types.m4~59cae158c9a32cff: Delete: bdb/dist/aclocal/types.m4 BitKeeper/deleted/.del-script~d38f6d3a4f159cb4: Delete: bdb/dist/build/script BitKeeper/deleted/.del-configure.in~ac795a92c8fe049c: Delete: bdb/dist/configure.in BitKeeper/deleted/.del-ltconfig~66bbd007d8024af: Delete: bdb/dist/ltconfig BitKeeper/deleted/.del-rec_ctemp~a28554362534f00a: Delete: bdb/dist/rec_ctemp BitKeeper/deleted/.del-s_tcl~2ffe4326459fcd9f: Delete: bdb/dist/s_tcl BitKeeper/deleted/.del-.IGNORE_ME~d8148b08fa7d5d15: Delete: bdb/dist/template/.IGNORE_ME BitKeeper/deleted/.del-btree.h~179f2aefec1753d: Delete: bdb/include/btree.h BitKeeper/deleted/.del-cxx_int.h~6b649c04766508f8: Delete: bdb/include/cxx_int.h BitKeeper/deleted/.del-db.src~6b433ae615b16a8d: Delete: bdb/include/db.src BitKeeper/deleted/.del-db_185.h~ad8b373d9391d35c: Delete: bdb/include/db_185.h BitKeeper/deleted/.del-db_am.h~a714912b6b75932f: Delete: bdb/include/db_am.h BitKeeper/deleted/.del-db_cxx.h~fcafadf45f5d19e9: Delete: bdb/include/db_cxx.h BitKeeper/deleted/.del-db_dispatch.h~6844f20f7eb46904: Delete: bdb/include/db_dispatch.h BitKeeper/deleted/.del-db_int.src~419a3f48b6a01da7: Delete: bdb/include/db_int.src BitKeeper/deleted/.del-db_join.h~76f9747a42c3399a: Delete: bdb/include/db_join.h BitKeeper/deleted/.del-db_page.h~e302ca3a4db3abdc: Delete: bdb/include/db_page.h BitKeeper/deleted/.del-db_server_int.h~e1d20b6ba3bca1ab: Delete: bdb/include/db_server_int.h BitKeeper/deleted/.del-db_shash.h~5fbf2d696fac90f3: Delete: bdb/include/db_shash.h BitKeeper/deleted/.del-db_swap.h~1e60887550864a59: Delete: bdb/include/db_swap.h BitKeeper/deleted/.del-db_upgrade.h~c644eee73701fc8d: Delete: bdb/include/db_upgrade.h BitKeeper/deleted/.del-db_verify.h~b8d6c297c61f342e: Delete: bdb/include/db_verify.h BitKeeper/deleted/.del-debug.h~dc2b4f2cf27ccebc: Delete: bdb/include/debug.h BitKeeper/deleted/.del-hash.h~2aaa548b28882dfb: Delete: bdb/include/hash.h BitKeeper/deleted/.del-lock.h~a761c1b7de57b77f: Delete: bdb/include/lock.h BitKeeper/deleted/.del-log.h~ff20184238e35e4d: Delete: bdb/include/log.h BitKeeper/deleted/.del-mp.h~7e317597622f3411: Delete: bdb/include/mp.h BitKeeper/deleted/.del-mutex.h~d3ae7a2977a68137: Delete: bdb/include/mutex.h BitKeeper/deleted/.del-os.h~91867cc8757cd0e3: Delete: bdb/include/os.h BitKeeper/deleted/.del-os_jump.h~e1b939fa5151d4be: Delete: bdb/include/os_jump.h BitKeeper/deleted/.del-qam.h~6fad0c1b5723d597: Delete: bdb/include/qam.h BitKeeper/deleted/.del-queue.h~4c72c0826c123d5: Delete: bdb/include/queue.h BitKeeper/deleted/.del-region.h~513fe04d977ca0fc: Delete: bdb/include/region.h BitKeeper/deleted/.del-shqueue.h~525fc3e6c2025c36: Delete: bdb/include/shqueue.h BitKeeper/deleted/.del-tcl_db.h~c536fd61a844f23f: Delete: bdb/include/tcl_db.h BitKeeper/deleted/.del-txn.h~c8d94b221ec147e4: Delete: bdb/include/txn.h BitKeeper/deleted/.del-xa.h~ecc466493aae9d9a: Delete: bdb/include/xa.h BitKeeper/deleted/.del-DbRecoveryInit.java~756b52601a0b9023: Delete: bdb/java/src/com/sleepycat/db/DbRecoveryInit.java BitKeeper/deleted/.del-DbTxnRecover.java~74607cba7ab89d6d: Delete: bdb/java/src/com/sleepycat/db/DbTxnRecover.java BitKeeper/deleted/.del-lock_conflict.c~fc5e0f14cf597a2b: Delete: bdb/lock/lock_conflict.c BitKeeper/deleted/.del-log.src~53ac9e7b5cb023f2: Delete: bdb/log/log.src BitKeeper/deleted/.del-log_findckp.c~24287f008916e81f: Delete: bdb/log/log_findckp.c BitKeeper/deleted/.del-log_rec.c~d51711f2cac09297: Delete: bdb/log/log_rec.c BitKeeper/deleted/.del-log_register.c~b40bb4efac75ca15: Delete: bdb/log/log_register.c BitKeeper/deleted/.del-Design~b3d0f179f2767b: Delete: bdb/mp/Design BitKeeper/deleted/.del-os_finit.c~95dbefc6fe79b26c: Delete: bdb/os/os_finit.c BitKeeper/deleted/.del-os_abs.c~df95d1e7db81924: Delete: bdb/os_vxworks/os_abs.c BitKeeper/deleted/.del-os_finit.c~803b484bdb9d0122: Delete: bdb/os_vxworks/os_finit.c BitKeeper/deleted/.del-os_map.c~3a6d7926398b76d3: Delete: bdb/os_vxworks/os_map.c BitKeeper/deleted/.del-os_finit.c~19a227c6d3c78ad: Delete: bdb/os_win32/os_finit.c BitKeeper/deleted/.del-log-corruption.patch~1cf2ecc7c6408d5d: Delete: bdb/patches/log-corruption.patch BitKeeper/deleted/.del-Btree.pm~af6d0c5eaed4a98e: Delete: bdb/perl.BerkeleyDB/BerkeleyDB/Btree.pm BitKeeper/deleted/.del-BerkeleyDB.pm~7244036d4482643: Delete: bdb/perl.BerkeleyDB/BerkeleyDB.pm BitKeeper/deleted/.del-BerkeleyDB.pod~e7b18fd6132448e3: Delete: bdb/perl.BerkeleyDB/BerkeleyDB.pod BitKeeper/deleted/.del-Hash.pm~10292a26c06a5c95: Delete: bdb/perl.BerkeleyDB/BerkeleyDB/Hash.pm BitKeeper/deleted/.del-BerkeleyDB.pod.P~79f76a1495eda203: Delete: bdb/perl.BerkeleyDB/BerkeleyDB.pod.P BitKeeper/deleted/.del-BerkeleyDB.xs~80c99afbd98e392c: Delete: bdb/perl.BerkeleyDB/BerkeleyDB.xs BitKeeper/deleted/.del-Changes~729c1891efa60de9: Delete: bdb/perl.BerkeleyDB/Changes BitKeeper/deleted/.del-MANIFEST~63a1e34aecf157a0: Delete: bdb/perl.BerkeleyDB/MANIFEST BitKeeper/deleted/.del-Makefile.PL~c68797707d8df87a: Delete: bdb/perl.BerkeleyDB/Makefile.PL BitKeeper/deleted/.del-README~5f2f579b1a241407: Delete: bdb/perl.BerkeleyDB/README BitKeeper/deleted/.del-Todo~dca3c66c193adda9: Delete: bdb/perl.BerkeleyDB/Todo BitKeeper/deleted/.del-config.in~ae81681e450e0999: Delete: bdb/perl.BerkeleyDB/config.in BitKeeper/deleted/.del-dbinfo~28ad67d83be4f68e: Delete: bdb/perl.BerkeleyDB/dbinfo BitKeeper/deleted/.del-mkconsts~543ab60669c7a04e: Delete: bdb/perl.BerkeleyDB/mkconsts BitKeeper/deleted/.del-mkpod~182c0ca54e439afb: Delete: bdb/perl.BerkeleyDB/mkpod BitKeeper/deleted/.del-5.004~e008cb5a48805543: Delete: bdb/perl.BerkeleyDB/patches/5.004 BitKeeper/deleted/.del-irix_6_5.pl~61662bb08afcdec8: Delete: bdb/perl.BerkeleyDB/hints/irix_6_5.pl BitKeeper/deleted/.del-solaris.pl~6771e7182394e152: Delete: bdb/perl.BerkeleyDB/hints/solaris.pl BitKeeper/deleted/.del-typemap~783b8f5295b05f3d: Delete: bdb/perl.BerkeleyDB/typemap BitKeeper/deleted/.del-5.004_01~6081ce2fff7b0bc: Delete: bdb/perl.BerkeleyDB/patches/5.004_01 BitKeeper/deleted/.del-5.004_02~87214eac35ad9e6: Delete: bdb/perl.BerkeleyDB/patches/5.004_02 BitKeeper/deleted/.del-5.004_03~9a672becec7cb40f: Delete: bdb/perl.BerkeleyDB/patches/5.004_03 BitKeeper/deleted/.del-5.004_04~e326cb51af09d154: Delete: bdb/perl.BerkeleyDB/patches/5.004_04 BitKeeper/deleted/.del-5.004_05~7ab457a1e41a92fe: Delete: bdb/perl.BerkeleyDB/patches/5.004_05 BitKeeper/deleted/.del-5.005~f9e2d59b5964cd4b: Delete: bdb/perl.BerkeleyDB/patches/5.005 BitKeeper/deleted/.del-5.005_01~3eb9fb7b5842ea8e: Delete: bdb/perl.BerkeleyDB/patches/5.005_01 BitKeeper/deleted/.del-5.005_02~67477ce0bef717cb: Delete: bdb/perl.BerkeleyDB/patches/5.005_02 BitKeeper/deleted/.del-5.005_03~c4c29a1fb21e290a: Delete: bdb/perl.BerkeleyDB/patches/5.005_03 BitKeeper/deleted/.del-5.6.0~e1fb9897d124ee22: Delete: bdb/perl.BerkeleyDB/patches/5.6.0 BitKeeper/deleted/.del-btree.t~e4a1a3c675ddc406: Delete: bdb/perl.BerkeleyDB/t/btree.t BitKeeper/deleted/.del-db-3.0.t~d2c60991d84558f2: Delete: bdb/perl.BerkeleyDB/t/db-3.0.t BitKeeper/deleted/.del-db-3.1.t~6ee88cd13f55e018: Delete: bdb/perl.BerkeleyDB/t/db-3.1.t BitKeeper/deleted/.del-db-3.2.t~f73b6461f98fd1cf: Delete: bdb/perl.BerkeleyDB/t/db-3.2.t BitKeeper/deleted/.del-destroy.t~cc6a2ae1980a2ecd: Delete: bdb/perl.BerkeleyDB/t/destroy.t BitKeeper/deleted/.del-env.t~a8604a4499c4bd07: Delete: bdb/perl.BerkeleyDB/t/env.t BitKeeper/deleted/.del-examples.t~2571b77c3cc75574: Delete: bdb/perl.BerkeleyDB/t/examples.t BitKeeper/deleted/.del-examples.t.T~8228bdd75ac78b88: Delete: bdb/perl.BerkeleyDB/t/examples.t.T BitKeeper/deleted/.del-examples3.t.T~66a186897a87026d: Delete: bdb/perl.BerkeleyDB/t/examples3.t.T BitKeeper/deleted/.del-examples3.t~fe3822ba2f2d7f83: Delete: bdb/perl.BerkeleyDB/t/examples3.t BitKeeper/deleted/.del-filter.t~f87b045c1b708637: Delete: bdb/perl.BerkeleyDB/t/filter.t BitKeeper/deleted/.del-hash.t~616bfb4d644de3a3: Delete: bdb/perl.BerkeleyDB/t/hash.t BitKeeper/deleted/.del-join.t~29fc39f74a83ca22: Delete: bdb/perl.BerkeleyDB/t/join.t BitKeeper/deleted/.del-mldbm.t~31f5015341eea040: Delete: bdb/perl.BerkeleyDB/t/mldbm.t BitKeeper/deleted/.del-queue.t~8f338034ce44a641: Delete: bdb/perl.BerkeleyDB/t/queue.t BitKeeper/deleted/.del-recno.t~d4ddbd3743add63e: Delete: bdb/perl.BerkeleyDB/t/recno.t BitKeeper/deleted/.del-strict.t~6885cdd2ea71ca2d: Delete: bdb/perl.BerkeleyDB/t/strict.t BitKeeper/deleted/.del-subdb.t~aab62a5d5864c603: Delete: bdb/perl.BerkeleyDB/t/subdb.t BitKeeper/deleted/.del-txn.t~65033b8558ae1216: Delete: bdb/perl.BerkeleyDB/t/txn.t BitKeeper/deleted/.del-unknown.t~f3710458682665e1: Delete: bdb/perl.BerkeleyDB/t/unknown.t BitKeeper/deleted/.del-Changes~436f74a5c414c65b: Delete: bdb/perl.DB_File/Changes BitKeeper/deleted/.del-DB_File.pm~ae0951c6c7665a82: Delete: bdb/perl.DB_File/DB_File.pm BitKeeper/deleted/.del-DB_File.xs~89e49a0b5556f1d8: Delete: bdb/perl.DB_File/DB_File.xs BitKeeper/deleted/.del-DB_File_BS~290fad5dbbb87069: Delete: bdb/perl.DB_File/DB_File_BS BitKeeper/deleted/.del-MANIFEST~90ee581572bdd4ac: Delete: bdb/perl.DB_File/MANIFEST BitKeeper/deleted/.del-Makefile.PL~ac0567bb5a377e38: Delete: bdb/perl.DB_File/Makefile.PL BitKeeper/deleted/.del-README~77e924a5a9bae6b3: Delete: bdb/perl.DB_File/README BitKeeper/deleted/.del-config.in~ab4c2792b86a810b: Delete: bdb/perl.DB_File/config.in BitKeeper/deleted/.del-dbinfo~461c43b30fab2cb: Delete: bdb/perl.DB_File/dbinfo BitKeeper/deleted/.del-dynixptx.pl~50dcddfae25d17e9: Delete: bdb/perl.DB_File/hints/dynixptx.pl BitKeeper/deleted/.del-typemap~55cffb3288a9e587: Delete: bdb/perl.DB_File/typemap BitKeeper/deleted/.del-version.c~a4df0e646f8b3975: Delete: bdb/perl.DB_File/version.c BitKeeper/deleted/.del-5.004_01~d6830d0082702af7: Delete: bdb/perl.DB_File/patches/5.004_01 BitKeeper/deleted/.del-5.004_02~78b082dc80c91031: Delete: bdb/perl.DB_File/patches/5.004_02 BitKeeper/deleted/.del-5.004~4411ec2e3c9e008b: Delete: bdb/perl.DB_File/patches/5.004 BitKeeper/deleted/.del-sco.pl~1e795fe14fe4dcfe: Delete: bdb/perl.DB_File/hints/sco.pl BitKeeper/deleted/.del-5.004_03~33f274648b160d95: Delete: bdb/perl.DB_File/patches/5.004_03 BitKeeper/deleted/.del-5.004_04~8f3d1b3cf18bb20a: Delete: bdb/perl.DB_File/patches/5.004_04 BitKeeper/deleted/.del-5.004_05~9c0f02e7331e142: Delete: bdb/perl.DB_File/patches/5.004_05 BitKeeper/deleted/.del-5.005~c2108cb2e3c8d951: Delete: bdb/perl.DB_File/patches/5.005 BitKeeper/deleted/.del-5.005_01~3b45e9673afc4cfa: Delete: bdb/perl.DB_File/patches/5.005_01 BitKeeper/deleted/.del-5.005_02~9fe5766bb02a4522: Delete: bdb/perl.DB_File/patches/5.005_02 BitKeeper/deleted/.del-5.005_03~ffa1c38c19ae72ea: Delete: bdb/perl.DB_File/patches/5.005_03 BitKeeper/deleted/.del-5.6.0~373be3a5ce47be85: Delete: bdb/perl.DB_File/patches/5.6.0 BitKeeper/deleted/.del-db-btree.t~3231595a1c241eb3: Delete: bdb/perl.DB_File/t/db-btree.t BitKeeper/deleted/.del-db-hash.t~7c4ad0c795c7fad2: Delete: bdb/perl.DB_File/t/db-hash.t BitKeeper/deleted/.del-db-recno.t~6c2d3d80b9ba4a50: Delete: bdb/perl.DB_File/t/db-recno.t BitKeeper/deleted/.del-db_server.sed~cdb00ebcd48a64e2: Delete: bdb/rpc_server/db_server.sed BitKeeper/deleted/.del-db_server_proc.c~d46c8f409c3747f4: Delete: bdb/rpc_server/db_server_proc.c BitKeeper/deleted/.del-db_server_svc.sed~3f5e59f334fa4607: Delete: bdb/rpc_server/db_server_svc.sed BitKeeper/deleted/.del-db_server_util.c~a809f3a4629acda: Delete: bdb/rpc_server/db_server_util.c BitKeeper/deleted/.del-log.tcl~ff1b41f1355b97d7: Delete: bdb/test/log.tcl BitKeeper/deleted/.del-mpool.tcl~b0df4dc1b04db26c: Delete: bdb/test/mpool.tcl BitKeeper/deleted/.del-mutex.tcl~52fd5c73a150565: Delete: bdb/test/mutex.tcl BitKeeper/deleted/.del-txn.tcl~c4ff071550b5446e: Delete: bdb/test/txn.tcl BitKeeper/deleted/.del-README~e800a12a5392010a: Delete: bdb/test/upgrade/README BitKeeper/deleted/.del-pack-2.6.6.pl~89d5076d758d3e98: Delete: bdb/test/upgrade/generate-2.X/pack-2.6.6.pl BitKeeper/deleted/.del-test-2.6.patch~4a52dc83d447547b: Delete: bdb/test/upgrade/generate-2.X/test-2.6.patch
1125 lines
28 KiB
C
1125 lines
28 KiB
C
/*-
|
|
* See the file LICENSE for redistribution information.
|
|
*
|
|
* Copyright (c) 1997-2002
|
|
* Sleepycat Software. All rights reserved.
|
|
*/
|
|
#include "db_config.h"
|
|
|
|
#ifndef lint
|
|
static const char revid[] = "$Id: java_info.c,v 11.46 2002/08/29 14:22:23 margo Exp $";
|
|
#endif /* not lint */
|
|
|
|
#include <jni.h>
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "db_int.h"
|
|
#include "java_util.h"
|
|
|
|
/****************************************************************
|
|
*
|
|
* Callback functions
|
|
*/
|
|
|
|
static int Db_assoc_callback(DB *db,
|
|
const DBT *key,
|
|
const DBT *data,
|
|
DBT *retval)
|
|
{
|
|
DB_JAVAINFO *dbinfo;
|
|
|
|
DB_ASSERT(db != NULL);
|
|
dbinfo = (DB_JAVAINFO *)db->api_internal;
|
|
return (dbji_call_assoc(dbinfo, db, dbinfo->jdbref,
|
|
key, data, retval));
|
|
}
|
|
|
|
static void Db_feedback_callback(DB *db, int opcode, int percent)
|
|
{
|
|
DB_JAVAINFO *dbinfo;
|
|
|
|
DB_ASSERT(db != NULL);
|
|
dbinfo = (DB_JAVAINFO *)db->api_internal;
|
|
dbji_call_feedback(dbinfo, db, dbinfo->jdbref, opcode, percent);
|
|
}
|
|
|
|
static int Db_append_recno_callback(DB *db, DBT *dbt, db_recno_t recno)
|
|
{
|
|
DB_JAVAINFO *dbinfo;
|
|
|
|
dbinfo = (DB_JAVAINFO *)db->api_internal;
|
|
return (dbji_call_append_recno(dbinfo, db, dbinfo->jdbref, dbt, recno));
|
|
}
|
|
|
|
static int Db_bt_compare_callback(DB *db, const DBT *dbt1, const DBT *dbt2)
|
|
{
|
|
DB_JAVAINFO *dbinfo;
|
|
|
|
dbinfo = (DB_JAVAINFO *)db->api_internal;
|
|
return (dbji_call_bt_compare(dbinfo, db, dbinfo->jdbref, dbt1, dbt2));
|
|
}
|
|
|
|
static size_t Db_bt_prefix_callback(DB *db, const DBT *dbt1, const DBT *dbt2)
|
|
{
|
|
DB_JAVAINFO *dbinfo;
|
|
|
|
dbinfo = (DB_JAVAINFO *)db->api_internal;
|
|
return (dbji_call_bt_prefix(dbinfo, db, dbinfo->jdbref, dbt1, dbt2));
|
|
}
|
|
|
|
static int Db_dup_compare_callback(DB *db, const DBT *dbt1, const DBT *dbt2)
|
|
{
|
|
DB_JAVAINFO *dbinfo;
|
|
|
|
dbinfo = (DB_JAVAINFO *)db->api_internal;
|
|
return (dbji_call_dup_compare(dbinfo, db, dbinfo->jdbref, dbt1, dbt2));
|
|
}
|
|
|
|
static u_int32_t Db_h_hash_callback(DB *db, const void *data, u_int32_t len)
|
|
{
|
|
DB_JAVAINFO *dbinfo;
|
|
|
|
dbinfo = (DB_JAVAINFO *)db->api_internal;
|
|
return (dbji_call_h_hash(dbinfo, db, dbinfo->jdbref, data, len));
|
|
}
|
|
|
|
static void DbEnv_feedback_callback(DB_ENV *dbenv, int opcode, int percent)
|
|
{
|
|
DB_ENV_JAVAINFO *dbinfo;
|
|
|
|
DB_ASSERT(dbenv != NULL);
|
|
dbinfo = (DB_ENV_JAVAINFO *)dbenv->api2_internal;
|
|
dbjie_call_feedback(dbinfo, dbenv, dbinfo->jenvref, opcode, percent);
|
|
}
|
|
|
|
static int DbEnv_rep_transport_callback(DB_ENV *dbenv,
|
|
const DBT *control, const DBT *rec,
|
|
int envid, u_int32_t flags)
|
|
{
|
|
DB_ENV_JAVAINFO *dbinfo;
|
|
|
|
dbinfo = (DB_ENV_JAVAINFO *)dbenv->api2_internal;
|
|
return (dbjie_call_rep_transport(dbinfo, dbenv,
|
|
dbinfo->jenvref, control, rec, envid, (int)flags));
|
|
}
|
|
|
|
static int DbEnv_app_dispatch_callback(DB_ENV *dbenv, DBT *dbt,
|
|
DB_LSN *lsn, db_recops recops)
|
|
{
|
|
DB_ENV_JAVAINFO *dbinfo;
|
|
|
|
DB_ASSERT(dbenv != NULL);
|
|
dbinfo = (DB_ENV_JAVAINFO *)dbenv->api2_internal;
|
|
return (dbjie_call_app_dispatch(dbinfo, dbenv, dbinfo->jenvref, dbt,
|
|
lsn, recops));
|
|
}
|
|
|
|
/****************************************************************
|
|
*
|
|
* Implementation of class DBT_javainfo
|
|
*/
|
|
DBT_JAVAINFO *
|
|
dbjit_construct()
|
|
{
|
|
DBT_JAVAINFO *dbjit;
|
|
int err;
|
|
|
|
/*XXX should return err*/
|
|
if ((err = __os_malloc(NULL, sizeof(DBT_JAVAINFO), &dbjit)) != 0)
|
|
return (NULL);
|
|
|
|
memset(dbjit, 0, sizeof(DBT_JAVAINFO));
|
|
return (dbjit);
|
|
}
|
|
|
|
void dbjit_destroy(DBT_JAVAINFO *dbjit)
|
|
{
|
|
DB_ASSERT(!F_ISSET(dbjit, DBT_JAVAINFO_LOCKED));
|
|
/* Extra paranoia */
|
|
memset(dbjit, 0, sizeof(DBT_JAVAINFO));
|
|
(void)__os_free(NULL, dbjit);
|
|
}
|
|
|
|
/****************************************************************
|
|
*
|
|
* Implementation of class DB_ENV_JAVAINFO
|
|
*/
|
|
|
|
/* create/initialize an object */
|
|
DB_ENV_JAVAINFO *
|
|
dbjie_construct(JNIEnv *jnienv,
|
|
jobject jenv,
|
|
jobject default_errcall,
|
|
int is_dbopen)
|
|
{
|
|
DB_ENV_JAVAINFO *dbjie;
|
|
int err;
|
|
|
|
/*XXX should return err*/
|
|
if ((err = __os_malloc(NULL, sizeof(DB_ENV_JAVAINFO), &dbjie)) != 0)
|
|
return (NULL);
|
|
memset(dbjie, 0, sizeof(DB_ENV_JAVAINFO));
|
|
dbjie->is_dbopen = is_dbopen;
|
|
|
|
if ((*jnienv)->GetJavaVM(jnienv, &dbjie->javavm) != 0) {
|
|
__os_free(NULL, dbjie);
|
|
report_exception(jnienv, "cannot get Java VM", 0, 0);
|
|
return (NULL);
|
|
}
|
|
|
|
/*
|
|
* The default error call just prints to the 'System.err'
|
|
* stream. If the user does set_errcall to null, we'll
|
|
* want to have a reference to set it back to.
|
|
*
|
|
* Why do we have always set db_errcall to our own callback?
|
|
* Because it makes the interaction between setting the
|
|
* error prefix, error stream, and user's error callback
|
|
* that much easier.
|
|
*/
|
|
dbjie->default_errcall = NEW_GLOBAL_REF(jnienv, default_errcall);
|
|
dbjie->errcall = NEW_GLOBAL_REF(jnienv, default_errcall);
|
|
dbjie->jenvref = NEW_GLOBAL_REF(jnienv, jenv);
|
|
return (dbjie);
|
|
}
|
|
|
|
/* release all objects held by this this one */
|
|
void dbjie_dealloc(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv)
|
|
{
|
|
if (dbjie->feedback != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbjie->feedback);
|
|
dbjie->feedback = NULL;
|
|
}
|
|
if (dbjie->app_dispatch != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbjie->app_dispatch);
|
|
dbjie->app_dispatch = NULL;
|
|
}
|
|
if (dbjie->errcall != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbjie->errcall);
|
|
dbjie->errcall = NULL;
|
|
}
|
|
if (dbjie->default_errcall != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbjie->default_errcall);
|
|
dbjie->default_errcall = NULL;
|
|
}
|
|
if (dbjie->jenvref != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbjie->jenvref);
|
|
dbjie->jenvref = NULL;
|
|
}
|
|
|
|
if (dbjie->conflict != NULL) {
|
|
__os_free(NULL, dbjie->conflict);
|
|
dbjie->conflict = NULL;
|
|
dbjie->conflict_size = 0;
|
|
}
|
|
if (dbjie->errpfx != NULL) {
|
|
__os_free(NULL, dbjie->errpfx);
|
|
dbjie->errpfx = NULL;
|
|
}
|
|
}
|
|
|
|
/* free this object, releasing anything allocated on its behalf */
|
|
void dbjie_destroy(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv)
|
|
{
|
|
dbjie_dealloc(dbjie, jnienv);
|
|
|
|
/* Extra paranoia */
|
|
memset(dbjie, 0, sizeof(DB_ENV_JAVAINFO));
|
|
(void)__os_free(NULL, dbjie);
|
|
}
|
|
|
|
/*
|
|
* Attach to the current thread that is running and
|
|
* return that. We use the java virtual machine
|
|
* that we saved in the constructor.
|
|
*/
|
|
JNIEnv *
|
|
dbjie_get_jnienv(DB_ENV_JAVAINFO *dbjie)
|
|
{
|
|
/*
|
|
* Note:
|
|
* Different versions of the JNI disagree on the signature
|
|
* for AttachCurrentThread. The most recent documentation
|
|
* seems to say that (JNIEnv **) is correct, but newer
|
|
* JNIs seem to use (void **), oddly enough.
|
|
*/
|
|
#ifdef JNI_VERSION_1_2
|
|
void *attachret = 0;
|
|
#else
|
|
JNIEnv *attachret = 0;
|
|
#endif
|
|
|
|
/*
|
|
* This should always succeed, as we are called via
|
|
* some Java activity. I think therefore I am (a thread).
|
|
*/
|
|
if ((*dbjie->javavm)->AttachCurrentThread(dbjie->javavm, &attachret, 0)
|
|
!= 0)
|
|
return (0);
|
|
|
|
return ((JNIEnv *)attachret);
|
|
}
|
|
|
|
jstring
|
|
dbjie_get_errpfx(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv)
|
|
{
|
|
return (get_java_string(jnienv, dbjie->errpfx));
|
|
}
|
|
|
|
void
|
|
dbjie_set_errcall(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv, jobject new_errcall)
|
|
{
|
|
/*
|
|
* If the new_errcall is null, we'll set the error call
|
|
* to the default one.
|
|
*/
|
|
if (new_errcall == NULL)
|
|
new_errcall = dbjie->default_errcall;
|
|
|
|
DELETE_GLOBAL_REF(jnienv, dbjie->errcall);
|
|
dbjie->errcall = NEW_GLOBAL_REF(jnienv, new_errcall);
|
|
}
|
|
|
|
void
|
|
dbjie_set_errpfx(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv, jstring errpfx)
|
|
{
|
|
if (dbjie->errpfx != NULL)
|
|
__os_free(NULL, dbjie->errpfx);
|
|
|
|
if (errpfx)
|
|
dbjie->errpfx = get_c_string(jnienv, errpfx);
|
|
else
|
|
dbjie->errpfx = NULL;
|
|
}
|
|
|
|
void
|
|
dbjie_set_conflict(DB_ENV_JAVAINFO *dbjie, u_char *newarr, size_t size)
|
|
{
|
|
if (dbjie->conflict != NULL)
|
|
(void)__os_free(NULL, dbjie->conflict);
|
|
dbjie->conflict = newarr;
|
|
dbjie->conflict_size = size;
|
|
}
|
|
|
|
void dbjie_set_feedback_object(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv,
|
|
DB_ENV *dbenv, jobject jfeedback)
|
|
{
|
|
int err;
|
|
|
|
if (dbjie->feedback != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbjie->feedback);
|
|
}
|
|
if (jfeedback == NULL) {
|
|
if ((err = dbenv->set_feedback(dbenv, NULL)) != 0)
|
|
report_exception(jnienv, "set_feedback failed",
|
|
err, 0);
|
|
}
|
|
else {
|
|
if ((err = dbenv->set_feedback(dbenv,
|
|
DbEnv_feedback_callback)) != 0)
|
|
report_exception(jnienv, "set_feedback failed",
|
|
err, 0);
|
|
}
|
|
|
|
dbjie->feedback = NEW_GLOBAL_REF(jnienv, jfeedback);
|
|
}
|
|
|
|
void dbjie_call_feedback(DB_ENV_JAVAINFO *dbjie, DB_ENV *dbenv, jobject jenv,
|
|
int opcode, int percent)
|
|
{
|
|
JNIEnv *jnienv;
|
|
jclass feedback_class;
|
|
jmethodID id;
|
|
|
|
COMPQUIET(dbenv, NULL);
|
|
jnienv = dbjie_get_jnienv(dbjie);
|
|
if (jnienv == NULL) {
|
|
fprintf(stderr, "Cannot attach to current thread!\n");
|
|
return;
|
|
}
|
|
|
|
if ((feedback_class =
|
|
get_class(jnienv, name_DbEnvFeedback)) == NULL) {
|
|
fprintf(stderr, "Cannot find callback class %s\n",
|
|
name_DbEnvFeedback);
|
|
return; /* An exception has been posted. */
|
|
}
|
|
id = (*jnienv)->GetMethodID(jnienv, feedback_class,
|
|
"feedback",
|
|
"(Lcom/sleepycat/db/DbEnv;II)V");
|
|
if (!id) {
|
|
fprintf(stderr, "Cannot find callback method feedback\n");
|
|
return;
|
|
}
|
|
|
|
(*jnienv)->CallVoidMethod(jnienv, dbjie->feedback, id,
|
|
jenv, (jint)opcode, (jint)percent);
|
|
}
|
|
|
|
void dbjie_set_rep_transport_object(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv,
|
|
DB_ENV *dbenv, int id, jobject jtransport)
|
|
{
|
|
int err;
|
|
|
|
if (dbjie->rep_transport != NULL)
|
|
DELETE_GLOBAL_REF(jnienv, dbjie->rep_transport);
|
|
|
|
err = dbenv->set_rep_transport(dbenv, id,
|
|
DbEnv_rep_transport_callback);
|
|
verify_return(jnienv, err, 0);
|
|
|
|
dbjie->rep_transport = NEW_GLOBAL_REF(jnienv, jtransport);
|
|
}
|
|
|
|
int dbjie_call_rep_transport(DB_ENV_JAVAINFO *dbjie, DB_ENV *dbenv,
|
|
jobject jenv, const DBT *control,
|
|
const DBT *rec, int flags, int envid)
|
|
{
|
|
JNIEnv *jnienv;
|
|
jclass rep_transport_class;
|
|
jmethodID jid;
|
|
jobject jcdbt, jrdbt;
|
|
|
|
COMPQUIET(dbenv, NULL);
|
|
jnienv = dbjie_get_jnienv(dbjie);
|
|
if (jnienv == NULL) {
|
|
fprintf(stderr, "Cannot attach to current thread!\n");
|
|
return (0);
|
|
}
|
|
|
|
if ((rep_transport_class =
|
|
get_class(jnienv, name_DbRepTransport)) == NULL) {
|
|
fprintf(stderr, "Cannot find callback class %s\n",
|
|
name_DbRepTransport);
|
|
return (0); /* An exception has been posted. */
|
|
}
|
|
jid = (*jnienv)->GetMethodID(jnienv, rep_transport_class,
|
|
"send",
|
|
"(Lcom/sleepycat/db/DbEnv;"
|
|
"Lcom/sleepycat/db/Dbt;"
|
|
"Lcom/sleepycat/db/Dbt;II)I");
|
|
|
|
if (!jid) {
|
|
fprintf(stderr, "Cannot find callback method send\n");
|
|
return (0);
|
|
}
|
|
|
|
jcdbt = get_const_Dbt(jnienv, control, NULL);
|
|
jrdbt = get_const_Dbt(jnienv, rec, NULL);
|
|
|
|
return (*jnienv)->CallIntMethod(jnienv, dbjie->rep_transport, jid, jenv,
|
|
jcdbt, jrdbt, flags, envid);
|
|
}
|
|
|
|
void dbjie_set_app_dispatch_object(DB_ENV_JAVAINFO *dbjie, JNIEnv *jnienv,
|
|
DB_ENV *dbenv, jobject japp_dispatch)
|
|
{
|
|
int err;
|
|
|
|
if (dbjie->app_dispatch != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbjie->app_dispatch);
|
|
}
|
|
if (japp_dispatch == NULL) {
|
|
if ((err = dbenv->set_app_dispatch(dbenv, NULL)) != 0)
|
|
report_exception(jnienv, "set_app_dispatch failed",
|
|
err, 0);
|
|
}
|
|
else {
|
|
if ((err = dbenv->set_app_dispatch(dbenv,
|
|
DbEnv_app_dispatch_callback)) != 0)
|
|
report_exception(jnienv, "set_app_dispatch failed",
|
|
err, 0);
|
|
}
|
|
|
|
dbjie->app_dispatch = NEW_GLOBAL_REF(jnienv, japp_dispatch);
|
|
}
|
|
|
|
int dbjie_call_app_dispatch(DB_ENV_JAVAINFO *dbjie, DB_ENV *dbenv, jobject jenv,
|
|
DBT *dbt, DB_LSN *lsn, int recops)
|
|
{
|
|
JNIEnv *jnienv;
|
|
jclass app_dispatch_class;
|
|
jmethodID id;
|
|
jobject jdbt;
|
|
jobject jlsn;
|
|
|
|
COMPQUIET(dbenv, NULL);
|
|
jnienv = dbjie_get_jnienv(dbjie);
|
|
if (jnienv == NULL) {
|
|
fprintf(stderr, "Cannot attach to current thread!\n");
|
|
return (0);
|
|
}
|
|
|
|
if ((app_dispatch_class =
|
|
get_class(jnienv, name_DbTxnRecover)) == NULL) {
|
|
fprintf(stderr, "Cannot find callback class %s\n",
|
|
name_DbTxnRecover);
|
|
return (0); /* An exception has been posted. */
|
|
}
|
|
id = (*jnienv)->GetMethodID(jnienv, app_dispatch_class,
|
|
"app_dispatch",
|
|
"(Lcom/sleepycat/db/DbEnv;"
|
|
"Lcom/sleepycat/db/Dbt;"
|
|
"Lcom/sleepycat/db/DbLsn;"
|
|
"I)I");
|
|
if (!id) {
|
|
fprintf(stderr, "Cannot find callback method app_dispatch\n");
|
|
return (0);
|
|
}
|
|
|
|
jdbt = get_Dbt(jnienv, dbt, NULL);
|
|
|
|
if (lsn == NULL)
|
|
jlsn = NULL;
|
|
else
|
|
jlsn = get_DbLsn(jnienv, *lsn);
|
|
|
|
return (*jnienv)->CallIntMethod(jnienv, dbjie->app_dispatch, id, jenv,
|
|
jdbt, jlsn, recops);
|
|
}
|
|
|
|
jobject dbjie_get_errcall(DB_ENV_JAVAINFO *dbjie)
|
|
{
|
|
return (dbjie->errcall);
|
|
}
|
|
|
|
jint dbjie_is_dbopen(DB_ENV_JAVAINFO *dbjie)
|
|
{
|
|
return (dbjie->is_dbopen);
|
|
}
|
|
|
|
/****************************************************************
|
|
*
|
|
* Implementation of class DB_JAVAINFO
|
|
*/
|
|
|
|
DB_JAVAINFO *dbji_construct(JNIEnv *jnienv, jobject jdb, jint flags)
|
|
{
|
|
DB_JAVAINFO *dbji;
|
|
int err;
|
|
|
|
/*XXX should return err*/
|
|
if ((err = __os_malloc(NULL, sizeof(DB_JAVAINFO), &dbji)) != 0)
|
|
return (NULL);
|
|
|
|
memset(dbji, 0, sizeof(DB_JAVAINFO));
|
|
|
|
if ((*jnienv)->GetJavaVM(jnienv, &dbji->javavm) != 0) {
|
|
report_exception(jnienv, "cannot get Java VM", 0, 0);
|
|
(void)__os_free(NULL, dbji);
|
|
return (NULL);
|
|
}
|
|
dbji->jdbref = NEW_GLOBAL_REF(jnienv, jdb);
|
|
dbji->construct_flags = flags;
|
|
return (dbji);
|
|
}
|
|
|
|
void
|
|
dbji_dealloc(DB_JAVAINFO *dbji, JNIEnv *jnienv)
|
|
{
|
|
if (dbji->append_recno != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbji->append_recno);
|
|
dbji->append_recno = NULL;
|
|
}
|
|
if (dbji->assoc != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbji->assoc);
|
|
dbji->assoc = NULL;
|
|
}
|
|
if (dbji->bt_compare != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbji->bt_compare);
|
|
dbji->bt_compare = NULL;
|
|
}
|
|
if (dbji->bt_prefix != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbji->bt_prefix);
|
|
dbji->bt_prefix = NULL;
|
|
}
|
|
if (dbji->dup_compare != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbji->dup_compare);
|
|
dbji->dup_compare = NULL;
|
|
}
|
|
if (dbji->feedback != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbji->feedback);
|
|
dbji->feedback = NULL;
|
|
}
|
|
if (dbji->h_hash != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbji->h_hash);
|
|
dbji->h_hash = NULL;
|
|
}
|
|
if (dbji->jdbref != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbji->jdbref);
|
|
dbji->jdbref = NULL;
|
|
}
|
|
}
|
|
|
|
void
|
|
dbji_destroy(DB_JAVAINFO *dbji, JNIEnv *jnienv)
|
|
{
|
|
dbji_dealloc(dbji, jnienv);
|
|
__os_free(NULL, dbji);
|
|
}
|
|
|
|
JNIEnv *dbji_get_jnienv(DB_JAVAINFO *dbji)
|
|
{
|
|
/*
|
|
* Note:
|
|
* Different versions of the JNI disagree on the signature
|
|
* for AttachCurrentThread. The most recent documentation
|
|
* seems to say that (JNIEnv **) is correct, but newer
|
|
* JNIs seem to use (void **), oddly enough.
|
|
*/
|
|
#ifdef JNI_VERSION_1_2
|
|
void *attachret = 0;
|
|
#else
|
|
JNIEnv *attachret = 0;
|
|
#endif
|
|
|
|
/*
|
|
* This should always succeed, as we are called via
|
|
* some Java activity. I think therefore I am (a thread).
|
|
*/
|
|
if ((*dbji->javavm)->AttachCurrentThread(dbji->javavm, &attachret, 0)
|
|
!= 0)
|
|
return (0);
|
|
|
|
return ((JNIEnv *)attachret);
|
|
}
|
|
|
|
jint dbji_get_flags(DB_JAVAINFO *dbji)
|
|
{
|
|
return (dbji->construct_flags);
|
|
}
|
|
|
|
void dbji_set_feedback_object(DB_JAVAINFO *dbji, JNIEnv *jnienv,
|
|
DB *db, jobject jfeedback)
|
|
{
|
|
jclass feedback_class;
|
|
|
|
if (dbji->feedback_method_id == NULL) {
|
|
if ((feedback_class =
|
|
get_class(jnienv, name_DbFeedback)) == NULL)
|
|
return; /* An exception has been posted. */
|
|
dbji->feedback_method_id =
|
|
(*jnienv)->GetMethodID(jnienv, feedback_class,
|
|
"feedback",
|
|
"(Lcom/sleepycat/db/Db;II)V");
|
|
if (dbji->feedback_method_id == NULL) {
|
|
/*
|
|
* XXX
|
|
* We should really have a better way
|
|
* to translate this to a Java exception class.
|
|
* In theory, it shouldn't happen.
|
|
*/
|
|
report_exception(jnienv, "Cannot find callback method",
|
|
EFAULT, 0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (dbji->feedback != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbji->feedback);
|
|
}
|
|
if (jfeedback == NULL) {
|
|
db->set_feedback(db, NULL);
|
|
}
|
|
else {
|
|
db->set_feedback(db, Db_feedback_callback);
|
|
}
|
|
|
|
dbji->feedback = NEW_GLOBAL_REF(jnienv, jfeedback);
|
|
|
|
}
|
|
|
|
void dbji_call_feedback(DB_JAVAINFO *dbji, DB *db, jobject jdb,
|
|
int opcode, int percent)
|
|
{
|
|
JNIEnv *jnienv;
|
|
|
|
COMPQUIET(db, NULL);
|
|
jnienv = dbji_get_jnienv(dbji);
|
|
if (jnienv == NULL) {
|
|
fprintf(stderr, "Cannot attach to current thread!\n");
|
|
return;
|
|
}
|
|
|
|
DB_ASSERT(dbji->feedback_method_id != NULL);
|
|
(*jnienv)->CallVoidMethod(jnienv, dbji->feedback,
|
|
dbji->feedback_method_id,
|
|
jdb, (jint)opcode, (jint)percent);
|
|
}
|
|
|
|
void dbji_set_append_recno_object(DB_JAVAINFO *dbji, JNIEnv *jnienv,
|
|
DB *db, jobject jcallback)
|
|
{
|
|
jclass append_recno_class;
|
|
|
|
if (dbji->append_recno_method_id == NULL) {
|
|
if ((append_recno_class =
|
|
get_class(jnienv, name_DbAppendRecno)) == NULL)
|
|
return; /* An exception has been posted. */
|
|
dbji->append_recno_method_id =
|
|
(*jnienv)->GetMethodID(jnienv, append_recno_class,
|
|
"db_append_recno",
|
|
"(Lcom/sleepycat/db/Db;"
|
|
"Lcom/sleepycat/db/Dbt;I)V");
|
|
if (dbji->append_recno_method_id == NULL) {
|
|
/*
|
|
* XXX
|
|
* We should really have a better way
|
|
* to translate this to a Java exception class.
|
|
* In theory, it shouldn't happen.
|
|
*/
|
|
report_exception(jnienv, "Cannot find callback method",
|
|
EFAULT, 0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (dbji->append_recno != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbji->append_recno);
|
|
}
|
|
if (jcallback == NULL) {
|
|
db->set_append_recno(db, NULL);
|
|
}
|
|
else {
|
|
db->set_append_recno(db, Db_append_recno_callback);
|
|
}
|
|
|
|
dbji->append_recno = NEW_GLOBAL_REF(jnienv, jcallback);
|
|
}
|
|
|
|
extern int dbji_call_append_recno(DB_JAVAINFO *dbji, DB *db, jobject jdb,
|
|
DBT *dbt, jint recno)
|
|
{
|
|
JNIEnv *jnienv;
|
|
jobject jresult;
|
|
DBT_JAVAINFO *dbtji;
|
|
LOCKED_DBT lresult;
|
|
DB_ENV *dbenv;
|
|
u_char *bytearray;
|
|
int err;
|
|
|
|
jnienv = dbji_get_jnienv(dbji);
|
|
dbenv = db->dbenv;
|
|
if (jnienv == NULL) {
|
|
fprintf(stderr, "Cannot attach to current thread!\n");
|
|
return (0);
|
|
}
|
|
|
|
jresult = get_Dbt(jnienv, dbt, &dbtji);
|
|
|
|
DB_ASSERT(dbji->append_recno_method_id != NULL);
|
|
(*jnienv)->CallVoidMethod(jnienv, dbji->append_recno,
|
|
dbji->append_recno_method_id,
|
|
jdb, jresult, recno);
|
|
|
|
/*
|
|
* The underlying C API requires that an errno be returned
|
|
* on error. Java users know nothing of errnos, so we
|
|
* allow them to throw exceptions instead. We leave the
|
|
* exception in place and return DB_JAVA_CALLBACK to the C API
|
|
* that called us. Eventually the DB->get will fail and
|
|
* when java prepares to throw an exception in
|
|
* report_exception(), this will be spotted as a special case,
|
|
* and the original exception will be preserved.
|
|
*
|
|
* Note: we have sometimes noticed strange behavior with
|
|
* exceptions under Linux 1.1.7 JVM. (i.e. multiple calls
|
|
* to ExceptionOccurred() may report different results).
|
|
* Currently we don't know of any problems related to this
|
|
* in our code, but if it pops up in the future, users are
|
|
* encouranged to get a more recent JVM.
|
|
*/
|
|
if ((*jnienv)->ExceptionOccurred(jnienv) != NULL)
|
|
return (DB_JAVA_CALLBACK);
|
|
|
|
/*
|
|
* Now get the DBT back from java, because the user probably
|
|
* changed it. We'll have to copy back the array too and let
|
|
* our caller free it.
|
|
*
|
|
* We expect that the user *has* changed the DBT (why else would
|
|
* they set up an append_recno callback?) so we don't
|
|
* worry about optimizing the unchanged case.
|
|
*/
|
|
if ((err = locked_dbt_get(&lresult, jnienv, dbenv, jresult, inOp)) != 0)
|
|
return (err);
|
|
|
|
memcpy(dbt, &lresult.javainfo->dbt, sizeof(DBT));
|
|
if ((err = __os_malloc(dbenv, dbt->size, &bytearray)) != 0)
|
|
goto out;
|
|
|
|
memcpy(bytearray, dbt->data, dbt->size);
|
|
dbt->data = bytearray;
|
|
dbt->flags |= DB_DBT_APPMALLOC;
|
|
|
|
out:
|
|
locked_dbt_put(&lresult, jnienv, dbenv);
|
|
return (err);
|
|
}
|
|
|
|
void dbji_set_assoc_object(DB_JAVAINFO *dbji, JNIEnv *jnienv,
|
|
DB *db, DB_TXN *txn, DB *second,
|
|
jobject jcallback, int flags)
|
|
{
|
|
jclass assoc_class;
|
|
int err;
|
|
|
|
if (dbji->assoc_method_id == NULL) {
|
|
if ((assoc_class =
|
|
get_class(jnienv, name_DbSecondaryKeyCreate)) == NULL)
|
|
return; /* An exception has been posted. */
|
|
dbji->assoc_method_id =
|
|
(*jnienv)->GetMethodID(jnienv, assoc_class,
|
|
"secondary_key_create",
|
|
"(Lcom/sleepycat/db/Db;"
|
|
"Lcom/sleepycat/db/Dbt;"
|
|
"Lcom/sleepycat/db/Dbt;"
|
|
"Lcom/sleepycat/db/Dbt;)I");
|
|
if (dbji->assoc_method_id == NULL) {
|
|
/*
|
|
* XXX
|
|
* We should really have a better way
|
|
* to translate this to a Java exception class.
|
|
* In theory, it shouldn't happen.
|
|
*/
|
|
report_exception(jnienv, "Cannot find callback method",
|
|
EFAULT, 0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (dbji->assoc != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbji->assoc);
|
|
dbji->assoc = NULL;
|
|
}
|
|
|
|
if (jcallback == NULL)
|
|
err = db->associate(db, txn, second, NULL, flags);
|
|
else
|
|
err = db->associate(db, txn, second, Db_assoc_callback, flags);
|
|
|
|
if (verify_return(jnienv, err, 0))
|
|
dbji->assoc = NEW_GLOBAL_REF(jnienv, jcallback);
|
|
}
|
|
|
|
extern int dbji_call_assoc(DB_JAVAINFO *dbji, DB *db, jobject jdb,
|
|
const DBT *key, const DBT *value, DBT *result)
|
|
{
|
|
JNIEnv *jnienv;
|
|
jobject jresult;
|
|
LOCKED_DBT lresult;
|
|
DB_ENV *dbenv;
|
|
int err;
|
|
int sz;
|
|
u_char *bytearray;
|
|
jint retval;
|
|
|
|
jnienv = dbji_get_jnienv(dbji);
|
|
if (jnienv == NULL) {
|
|
fprintf(stderr, "Cannot attach to current thread!\n");
|
|
return (0);
|
|
}
|
|
|
|
DB_ASSERT(dbji->assoc_method_id != NULL);
|
|
|
|
dbenv = db->dbenv;
|
|
jresult = create_default_object(jnienv, name_DBT);
|
|
|
|
retval = (*jnienv)->CallIntMethod(jnienv, dbji->assoc,
|
|
dbji->assoc_method_id, jdb,
|
|
get_const_Dbt(jnienv, key, NULL),
|
|
get_const_Dbt(jnienv, value, NULL),
|
|
jresult);
|
|
if (retval != 0)
|
|
return (retval);
|
|
|
|
if ((*jnienv)->ExceptionOccurred(jnienv) != NULL)
|
|
return (DB_JAVA_CALLBACK);
|
|
|
|
if ((err = locked_dbt_get(&lresult, jnienv, dbenv, jresult, inOp)) != 0)
|
|
return (err);
|
|
|
|
sz = lresult.javainfo->dbt.size;
|
|
if (sz > 0) {
|
|
bytearray = (u_char *)lresult.javainfo->dbt.data;
|
|
|
|
/*
|
|
* If the byte array is in the range of one of the
|
|
* arrays passed to us we can use it directly.
|
|
* If not, we must create our own array and
|
|
* fill it in with the java array. Since
|
|
* the java array may disappear and we don't
|
|
* want to keep its memory locked indefinitely,
|
|
* we cannot just pin the array.
|
|
*
|
|
* XXX consider pinning the array, and having
|
|
* some way for the C layer to notify the java
|
|
* layer when it can be unpinned.
|
|
*/
|
|
if ((bytearray < (u_char *)key->data ||
|
|
bytearray + sz > (u_char *)key->data + key->size) &&
|
|
(bytearray < (u_char *)value->data ||
|
|
bytearray + sz > (u_char *)value->data + value->size)) {
|
|
|
|
result->flags |= DB_DBT_APPMALLOC;
|
|
if ((err = __os_malloc(dbenv, sz, &bytearray)) != 0)
|
|
goto out;
|
|
memcpy(bytearray, lresult.javainfo->dbt.data, sz);
|
|
}
|
|
result->data = bytearray;
|
|
result->size = sz;
|
|
}
|
|
out:
|
|
locked_dbt_put(&lresult, jnienv, dbenv);
|
|
return (err);
|
|
}
|
|
|
|
void dbji_set_bt_compare_object(DB_JAVAINFO *dbji, JNIEnv *jnienv,
|
|
DB *db, jobject jcompare)
|
|
{
|
|
jclass bt_compare_class;
|
|
|
|
if (dbji->bt_compare_method_id == NULL) {
|
|
if ((bt_compare_class =
|
|
get_class(jnienv, name_DbBtreeCompare)) == NULL)
|
|
return; /* An exception has been posted. */
|
|
dbji->bt_compare_method_id =
|
|
(*jnienv)->GetMethodID(jnienv, bt_compare_class,
|
|
"bt_compare",
|
|
"(Lcom/sleepycat/db/Db;"
|
|
"Lcom/sleepycat/db/Dbt;"
|
|
"Lcom/sleepycat/db/Dbt;)I");
|
|
if (dbji->bt_compare_method_id == NULL) {
|
|
/*
|
|
* XXX
|
|
* We should really have a better way
|
|
* to translate this to a Java exception class.
|
|
* In theory, it shouldn't happen.
|
|
*/
|
|
report_exception(jnienv, "Cannot find callback method",
|
|
EFAULT, 0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (dbji->bt_compare != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbji->bt_compare);
|
|
}
|
|
if (jcompare == NULL) {
|
|
db->set_bt_compare(db, NULL);
|
|
}
|
|
else {
|
|
db->set_bt_compare(db, Db_bt_compare_callback);
|
|
}
|
|
|
|
dbji->bt_compare = NEW_GLOBAL_REF(jnienv, jcompare);
|
|
}
|
|
|
|
int dbji_call_bt_compare(DB_JAVAINFO *dbji, DB *db, jobject jdb,
|
|
const DBT *dbt1, const DBT *dbt2)
|
|
{
|
|
JNIEnv *jnienv;
|
|
jobject jdbt1, jdbt2;
|
|
|
|
COMPQUIET(db, NULL);
|
|
jnienv = dbji_get_jnienv(dbji);
|
|
if (jnienv == NULL) {
|
|
fprintf(stderr, "Cannot attach to current thread!\n");
|
|
return (0);
|
|
}
|
|
|
|
jdbt1 = get_const_Dbt(jnienv, dbt1, NULL);
|
|
jdbt2 = get_const_Dbt(jnienv, dbt2, NULL);
|
|
|
|
DB_ASSERT(dbji->bt_compare_method_id != NULL);
|
|
return (*jnienv)->CallIntMethod(jnienv, dbji->bt_compare,
|
|
dbji->bt_compare_method_id,
|
|
jdb, jdbt1, jdbt2);
|
|
}
|
|
|
|
void dbji_set_bt_prefix_object(DB_JAVAINFO *dbji, JNIEnv *jnienv,
|
|
DB *db, jobject jprefix)
|
|
{
|
|
jclass bt_prefix_class;
|
|
|
|
if (dbji->bt_prefix_method_id == NULL) {
|
|
if ((bt_prefix_class =
|
|
get_class(jnienv, name_DbBtreePrefix)) == NULL)
|
|
return; /* An exception has been posted. */
|
|
dbji->bt_prefix_method_id =
|
|
(*jnienv)->GetMethodID(jnienv, bt_prefix_class,
|
|
"bt_prefix",
|
|
"(Lcom/sleepycat/db/Db;"
|
|
"Lcom/sleepycat/db/Dbt;"
|
|
"Lcom/sleepycat/db/Dbt;)I");
|
|
if (dbji->bt_prefix_method_id == NULL) {
|
|
/*
|
|
* XXX
|
|
* We should really have a better way
|
|
* to translate this to a Java exception class.
|
|
* In theory, it shouldn't happen.
|
|
*/
|
|
report_exception(jnienv, "Cannot find callback method",
|
|
EFAULT, 0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (dbji->bt_prefix != NULL) {
|
|
DELETE_GLOBAL_REF(jnienv, dbji->bt_prefix);
|
|
}
|
|
if (jprefix == NULL) {
|
|
db->set_bt_prefix(db, NULL);
|
|
}
|
|
else {
|
|
db->set_bt_prefix(db, Db_bt_prefix_callback);
|
|
}
|
|
|
|
dbji->bt_prefix = NEW_GLOBAL_REF(jnienv, jprefix);
|
|
}
|
|
|
|
size_t dbji_call_bt_prefix(DB_JAVAINFO *dbji, DB *db, jobject jdb,
|
|
const DBT *dbt1, const DBT *dbt2)
|
|
{
|
|
JNIEnv *jnienv;
|
|
jobject jdbt1, jdbt2;
|
|
|
|
COMPQUIET(db, NULL);
|
|
jnienv = dbji_get_jnienv(dbji);
|
|
if (jnienv == NULL) {
|
|
fprintf(stderr, "Cannot attach to current thread!\n");
|
|
return (0);
|
|
}
|
|
|
|
jdbt1 = get_const_Dbt(jnienv, dbt1, NULL);
|
|
jdbt2 = get_const_Dbt(jnienv, dbt2, NULL);
|
|
|
|
DB_ASSERT(dbji->bt_prefix_method_id != NULL);
|
|
return (size_t)(*jnienv)->CallIntMethod(jnienv, dbji->bt_prefix,
|
|
dbji->bt_prefix_method_id,
|
|
jdb, jdbt1, jdbt2);
|
|
}
|
|
|
|
void dbji_set_dup_compare_object(DB_JAVAINFO *dbji, JNIEnv *jnienv,
|
|
DB *db, jobject jcompare)
|
|
{
|
|
jclass dup_compare_class;
|
|
|
|
if (dbji->dup_compare_method_id == NULL) {
|
|
if ((dup_compare_class =
|
|
get_class(jnienv, name_DbDupCompare)) == NULL)
|
|
return; /* An exception has been posted. */
|
|
dbji->dup_compare_method_id =
|
|
(*jnienv)->GetMethodID(jnienv, dup_compare_class,
|
|
"dup_compare",
|
|
"(Lcom/sleepycat/db/Db;"
|
|
"Lcom/sleepycat/db/Dbt;"
|
|
"Lcom/sleepycat/db/Dbt;)I");
|
|
if (dbji->dup_compare_method_id == NULL) {
|
|
/*
|
|
* XXX
|
|
* We should really have a better way
|
|
* to translate this to a Java exception class.
|
|
* In theory, it shouldn't happen.
|
|
*/
|
|
report_exception(jnienv, "Cannot find callback method",
|
|
EFAULT, 0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (dbji->dup_compare != NULL)
|
|
DELETE_GLOBAL_REF(jnienv, dbji->dup_compare);
|
|
|
|
if (jcompare == NULL)
|
|
db->set_dup_compare(db, NULL);
|
|
else
|
|
db->set_dup_compare(db, Db_dup_compare_callback);
|
|
|
|
dbji->dup_compare = NEW_GLOBAL_REF(jnienv, jcompare);
|
|
}
|
|
|
|
int dbji_call_dup_compare(DB_JAVAINFO *dbji, DB *db, jobject jdb,
|
|
const DBT *dbt1, const DBT *dbt2)
|
|
{
|
|
JNIEnv *jnienv;
|
|
jobject jdbt1, jdbt2;
|
|
|
|
COMPQUIET(db, NULL);
|
|
jnienv = dbji_get_jnienv(dbji);
|
|
if (jnienv == NULL) {
|
|
fprintf(stderr, "Cannot attach to current thread!\n");
|
|
return (0);
|
|
}
|
|
|
|
jdbt1 = get_const_Dbt(jnienv, dbt1, NULL);
|
|
jdbt2 = get_const_Dbt(jnienv, dbt2, NULL);
|
|
|
|
DB_ASSERT(dbji->dup_compare_method_id != NULL);
|
|
return (*jnienv)->CallIntMethod(jnienv, dbji->dup_compare,
|
|
dbji->dup_compare_method_id,
|
|
jdb, jdbt1, jdbt2);
|
|
}
|
|
|
|
void dbji_set_h_hash_object(DB_JAVAINFO *dbji, JNIEnv *jnienv,
|
|
DB *db, jobject jhash)
|
|
{
|
|
jclass h_hash_class;
|
|
|
|
if (dbji->h_hash_method_id == NULL) {
|
|
if ((h_hash_class =
|
|
get_class(jnienv, name_DbHash)) == NULL)
|
|
return; /* An exception has been posted. */
|
|
dbji->h_hash_method_id =
|
|
(*jnienv)->GetMethodID(jnienv, h_hash_class,
|
|
"hash",
|
|
"(Lcom/sleepycat/db/Db;"
|
|
"[BI)I");
|
|
if (dbji->h_hash_method_id == NULL) {
|
|
/*
|
|
* XXX
|
|
* We should really have a better way
|
|
* to translate this to a Java exception class.
|
|
* In theory, it shouldn't happen.
|
|
*/
|
|
report_exception(jnienv, "Cannot find callback method",
|
|
EFAULT, 0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (dbji->h_hash != NULL)
|
|
DELETE_GLOBAL_REF(jnienv, dbji->h_hash);
|
|
|
|
if (jhash == NULL)
|
|
db->set_h_hash(db, NULL);
|
|
else
|
|
db->set_h_hash(db, Db_h_hash_callback);
|
|
|
|
dbji->h_hash = NEW_GLOBAL_REF(jnienv, jhash);
|
|
}
|
|
|
|
int dbji_call_h_hash(DB_JAVAINFO *dbji, DB *db, jobject jdb,
|
|
const void *data, int len)
|
|
{
|
|
JNIEnv *jnienv;
|
|
jbyteArray jdata;
|
|
|
|
COMPQUIET(db, NULL);
|
|
jnienv = dbji_get_jnienv(dbji);
|
|
if (jnienv == NULL) {
|
|
fprintf(stderr, "Cannot attach to current thread!\n");
|
|
return (0);
|
|
}
|
|
|
|
DB_ASSERT(dbji->h_hash_method_id != NULL);
|
|
|
|
if ((jdata = (*jnienv)->NewByteArray(jnienv, len)) == NULL)
|
|
return (0); /* An exception has been posted by the JVM */
|
|
(*jnienv)->SetByteArrayRegion(jnienv, jdata, 0, len, (void *)data);
|
|
return (*jnienv)->CallIntMethod(jnienv, dbji->h_hash,
|
|
dbji->h_hash_method_id,
|
|
jdb, jdata, len);
|
|
}
|