java_Db.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:24k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1997-2002
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char revid[] = "$Id: java_Db.c,v 11.80 2002/08/29 14:22:23 margo Exp $";
  10. #endif /* not lint */
  11. #include <jni.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include "db_int.h"
  15. #include "dbinc/db_page.h"
  16. #include "dbinc/btree.h"
  17. #include "dbinc_auto/db_ext.h"
  18. #include "java_util.h"
  19. #include "java_stat_auto.h"
  20. #include "com_sleepycat_db_Db.h"
  21. /* This struct is used in Db.verify and its callback */
  22. struct verify_callback_struct {
  23. JNIEnv *env;
  24. jobject streamobj;
  25. jbyteArray bytes;
  26. int nbytes;
  27. jmethodID writemid;
  28. };
  29. JAVADB_GET_FLD(Db, jint, flags_1raw, DB, flags)
  30. JAVADB_SET_METH(Db, jint, flags, DB, flags)
  31. JAVADB_SET_METH(Db, jint, h_1ffactor, DB, h_ffactor)
  32. JAVADB_SET_METH(Db, jint, h_1nelem, DB, h_nelem)
  33. JAVADB_SET_METH(Db, jint, lorder, DB, lorder)
  34. JAVADB_SET_METH(Db, jint, re_1delim, DB, re_delim)
  35. JAVADB_SET_METH(Db, jint, re_1len, DB, re_len)
  36. JAVADB_SET_METH(Db, jint, re_1pad, DB, re_pad)
  37. JAVADB_SET_METH(Db, jint, q_1extentsize, DB, q_extentsize)
  38. JAVADB_SET_METH(Db, jint, bt_1maxkey, DB, bt_maxkey)
  39. JAVADB_SET_METH(Db, jint, bt_1minkey, DB, bt_minkey)
  40. /*
  41.  * This only gets called once ever, at the beginning of execution
  42.  * and can be used to initialize unchanging methodIds, fieldIds, etc.
  43.  */
  44. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_one_1time_1init
  45.   (JNIEnv *jnienv,  /*Db.class*/ jclass jthisclass)
  46. {
  47. COMPQUIET(jthisclass, NULL);
  48. one_time_init(jnienv);
  49. }
  50. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db__1init
  51.   (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbEnv*/ jobject jdbenv, jint flags)
  52. {
  53. int err;
  54. DB *db;
  55. DB_JAVAINFO *dbinfo;
  56. DB_ENV *dbenv;
  57. dbenv = get_DB_ENV(jnienv, jdbenv);
  58. dbinfo = get_DB_JAVAINFO(jnienv, jthis);
  59. DB_ASSERT(dbinfo == NULL);
  60. err = db_create(&db, dbenv, flags);
  61. if (verify_return(jnienv, err, 0)) {
  62. set_private_dbobj(jnienv, name_DB, jthis, db);
  63. dbinfo = dbji_construct(jnienv, jthis, flags);
  64. set_private_info(jnienv, name_DB, jthis, dbinfo);
  65. db->api_internal = dbinfo;
  66. }
  67. }
  68. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db__1associate
  69.     (JNIEnv *jnienv, /*Db*/ jobject jthis, /* DbTxn */ jobject jtxn,
  70.      /*Db*/ jobject jsecondary, /*DbSecondaryKeyCreate*/ jobject jcallback,
  71.      jint flags)
  72. {
  73. DB *db, *secondary;
  74. DB_JAVAINFO *second_info;
  75. DB_TXN *txn;
  76. db = get_DB(jnienv, jthis);
  77. txn = get_DB_TXN(jnienv, jtxn);
  78. secondary = get_DB(jnienv, jsecondary);
  79. second_info = (DB_JAVAINFO*)secondary->api_internal;
  80. dbji_set_assoc_object(second_info, jnienv, db, txn, secondary,
  81.       jcallback, flags);
  82. }
  83. JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db__1close
  84.   (JNIEnv *jnienv, /*Db*/ jobject jthis, jint flags)
  85. {
  86. int err;
  87. DB *db;
  88. DB_JAVAINFO *dbinfo;
  89. db = get_DB(jnienv, jthis);
  90. dbinfo = get_DB_JAVAINFO(jnienv, jthis);
  91. if (!verify_non_null(jnienv, db))
  92. return (0);
  93. /*
  94.  * Null out the private data to indicate the DB is invalid.
  95.  * We do this in advance to help guard against multithreading
  96.  * issues.
  97.  */
  98. set_private_dbobj(jnienv, name_DB, jthis, 0);
  99. err = db->close(db, flags);
  100. verify_return(jnienv, err, 0);
  101. dbji_dealloc(dbinfo, jnienv);
  102. return (err);
  103. }
  104. /*
  105.  * We are being notified that the parent DbEnv has closed.
  106.  * Zero out the pointer to the DB, since it is no longer
  107.  * valid, to prevent mistakes.  The user will get a null
  108.  * pointer exception if they try to use this Db again.
  109.  */
  110. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db__1notify_1internal
  111.   (JNIEnv *jnienv, /*Db*/ jobject jthis)
  112. {
  113. set_private_dbobj(jnienv, name_DB, jthis, 0);
  114. }
  115. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_append_1recno_1changed
  116.   (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbAppendRecno*/ jobject jcallback)
  117. {
  118. DB *db;
  119. DB_JAVAINFO *dbinfo;
  120. db = get_DB(jnienv, jthis);
  121. if (!verify_non_null(jnienv, db))
  122. return;
  123. dbinfo = (DB_JAVAINFO*)db->api_internal;
  124. dbji_set_append_recno_object(dbinfo, jnienv, db, jcallback);
  125. }
  126. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_bt_1compare_1changed
  127.   (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbBtreeCompare*/ jobject jbtcompare)
  128. {
  129. DB *db;
  130. DB_JAVAINFO *dbinfo;
  131. db = get_DB(jnienv, jthis);
  132. if (!verify_non_null(jnienv, db))
  133. return;
  134. dbinfo = (DB_JAVAINFO*)db->api_internal;
  135. dbji_set_bt_compare_object(dbinfo, jnienv, db, jbtcompare);
  136. }
  137. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_bt_1prefix_1changed
  138.   (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbBtreePrefix*/ jobject jbtprefix)
  139. {
  140. DB *db;
  141. DB_JAVAINFO *dbinfo;
  142. db = get_DB(jnienv, jthis);
  143. if (!verify_non_null(jnienv, db))
  144. return;
  145. dbinfo = (DB_JAVAINFO*)db->api_internal;
  146. dbji_set_bt_prefix_object(dbinfo, jnienv, db, jbtprefix);
  147. }
  148. JNIEXPORT jobject JNICALL Java_com_sleepycat_db_Db_cursor
  149.   (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbTxn*/ jobject txnid, jint flags)
  150. {
  151. int err;
  152. DBC *dbc;
  153. DB *db = get_DB(jnienv, jthis);
  154. DB_TXN *dbtxnid = get_DB_TXN(jnienv, txnid);
  155. if (!verify_non_null(jnienv, db))
  156. return (NULL);
  157. err = db->cursor(db, dbtxnid, &dbc, flags);
  158. verify_return(jnienv, err, 0);
  159. return (get_Dbc(jnienv, dbc));
  160. }
  161. JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_del
  162.   (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbTxn*/ jobject txnid,
  163.    /*Dbt*/ jobject key, jint dbflags)
  164. {
  165. int err;
  166. DB_TXN *dbtxnid;
  167. DB *db;
  168. LOCKED_DBT lkey;
  169. err = 0;
  170. db = get_DB(jnienv, jthis);
  171. if (!verify_non_null(jnienv, db))
  172. return (0);
  173. dbtxnid = get_DB_TXN(jnienv, txnid);
  174. if (locked_dbt_get(&lkey, jnienv, db->dbenv, key, inOp) != 0)
  175. goto out;
  176. err = db->del(db, dbtxnid, &lkey.javainfo->dbt, dbflags);
  177. if (!DB_RETOK_DBDEL(err))
  178. verify_return(jnienv, err, 0);
  179.  out:
  180. locked_dbt_put(&lkey, jnienv, db->dbenv);
  181. return (err);
  182. }
  183. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_dup_1compare_1changed
  184.   (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbDupCompare*/ jobject jdupcompare)
  185. {
  186. DB *db;
  187. DB_JAVAINFO *dbinfo;
  188. db = get_DB(jnienv, jthis);
  189. if (!verify_non_null(jnienv, db))
  190. return;
  191. dbinfo = (DB_JAVAINFO*)db->api_internal;
  192. dbji_set_dup_compare_object(dbinfo, jnienv, db, jdupcompare);
  193. }
  194. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_err
  195.   (JNIEnv *jnienv, /*Db*/ jobject jthis, jint ecode, jstring msg)
  196. {
  197. DB *db;
  198. LOCKED_STRING ls_msg;
  199. if (locked_string_get(&ls_msg, jnienv, msg) != 0)
  200. goto out;
  201. db = get_DB(jnienv, jthis);
  202. if (!verify_non_null(jnienv, db))
  203. goto out;
  204. db->err(db, ecode, "%s", ls_msg.string);
  205.  out:
  206. locked_string_put(&ls_msg, jnienv);
  207. }
  208. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_errx
  209.   (JNIEnv *jnienv, /*Db*/ jobject jthis, jstring msg)
  210. {
  211. LOCKED_STRING ls_msg;
  212. DB *db = get_DB(jnienv, jthis);
  213. if (locked_string_get(&ls_msg, jnienv, msg) != 0)
  214. goto out;
  215. if (!verify_non_null(jnienv, db))
  216. goto out;
  217. db->errx(db, "%s", ls_msg.string);
  218.  out:
  219. locked_string_put(&ls_msg, jnienv);
  220. }
  221. JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_fd
  222.   (JNIEnv *jnienv, /*Db*/ jobject jthis)
  223. {
  224. int err;
  225. int return_value = 0;
  226. DB *db = get_DB(jnienv, jthis);
  227. if (!verify_non_null(jnienv, db))
  228. return (0);
  229. err = db->fd(db, &return_value);
  230. verify_return(jnienv, err, 0);
  231. return (return_value);
  232. }
  233. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_set_1encrypt
  234.   (JNIEnv *jnienv, /*Db*/ jobject jthis, jstring jpasswd, jint flags)
  235. {
  236. int err;
  237. DB *db;
  238. LOCKED_STRING ls_passwd;
  239. db = get_DB(jnienv, jthis);
  240. if (!verify_non_null(jnienv, db))
  241. return;
  242. if (locked_string_get(&ls_passwd, jnienv, jpasswd) != 0)
  243. goto out;
  244. err = db->set_encrypt(db, ls_passwd.string, flags);
  245. verify_return(jnienv, err, 0);
  246. out: locked_string_put(&ls_passwd, jnienv);
  247. }
  248. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_feedback_1changed
  249.   (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbFeedback*/ jobject jfeedback)
  250. {
  251. DB *db;
  252. DB_JAVAINFO *dbinfo;
  253. db = get_DB(jnienv, jthis);
  254. if (!verify_non_null(jnienv, db))
  255. return;
  256. dbinfo = (DB_JAVAINFO*)db->api_internal;
  257. dbji_set_feedback_object(dbinfo, jnienv, db, jfeedback);
  258. }
  259. JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_get
  260.   (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbTxn*/ jobject txnid,
  261.    /*Dbt*/ jobject key, /*Dbt*/ jobject data, jint flags)
  262. {
  263. int err, op_flags, retry;
  264. DB *db;
  265. DB_ENV *dbenv;
  266. OpKind keyop, dataop;
  267. DB_TXN *dbtxnid;
  268. LOCKED_DBT lkey, ldata;
  269. err = 0;
  270. db = get_DB(jnienv, jthis);
  271. if (!verify_non_null(jnienv, db))
  272. goto out3;
  273. dbenv = db->dbenv;
  274. /* Depending on flags, the key may be input/output. */
  275. keyop = inOp;
  276. dataop = outOp;
  277. op_flags = flags & DB_OPFLAGS_MASK;
  278. if (op_flags == DB_SET_RECNO) {
  279. keyop = inOutOp;
  280. }
  281. else if (op_flags == DB_GET_BOTH) {
  282. keyop = inOutOp;
  283. dataop = inOutOp;
  284. }
  285. dbtxnid = get_DB_TXN(jnienv, txnid);
  286. if (locked_dbt_get(&lkey, jnienv, dbenv, key, keyop) != 0)
  287. goto out2;
  288. if (locked_dbt_get(&ldata, jnienv, dbenv, data, dataop) != 0)
  289. goto out1;
  290. for (retry = 0; retry < 3; retry++) {
  291. err = db->get(db,
  292.     dbtxnid, &lkey.javainfo->dbt, &ldata.javainfo->dbt, flags);
  293. /*
  294.  * If we failed due to lack of memory in our DBT arrays,
  295.  * retry.
  296.  */
  297. if (err != ENOMEM)
  298. break;
  299. if (!locked_dbt_realloc(&lkey, jnienv, dbenv) &&
  300.     !locked_dbt_realloc(&ldata, jnienv, dbenv))
  301. break;
  302. }
  303.  out1:
  304. locked_dbt_put(&ldata, jnienv, dbenv);
  305.  out2:
  306. locked_dbt_put(&lkey, jnienv, dbenv);
  307.  out3:
  308. if (!DB_RETOK_DBGET(err)) {
  309. if (verify_dbt(jnienv, err, &lkey) &&
  310.     verify_dbt(jnienv, err, &ldata))
  311. verify_return(jnienv, err, 0);
  312. }
  313. return (err);
  314. }
  315. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_hash_1changed
  316.   (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbHash*/ jobject jhash)
  317. {
  318. DB *db;
  319. DB_JAVAINFO *dbinfo;
  320. db = get_DB(jnienv, jthis);
  321. if (!verify_non_null(jnienv, db))
  322. return;
  323. dbinfo = (DB_JAVAINFO*)db->api_internal;
  324. dbji_set_h_hash_object(dbinfo, jnienv, db, jhash);
  325. }
  326. JNIEXPORT jobject JNICALL Java_com_sleepycat_db_Db_join
  327.   (JNIEnv *jnienv, /*Db*/ jobject jthis, /*Dbc[]*/ jobjectArray curslist,
  328.    jint flags)
  329. {
  330. int err;
  331. DB *db;
  332. int count;
  333. DBC **newlist;
  334. DBC *dbc;
  335. int i;
  336. int size;
  337. db = get_DB(jnienv, jthis);
  338. count = (*jnienv)->GetArrayLength(jnienv, curslist);
  339. size = sizeof(DBC *) * (count+1);
  340. if ((err = __os_malloc(db->dbenv, size, &newlist)) != 0) {
  341. if (!verify_return(jnienv, err, 0))
  342. return (NULL);
  343. }
  344. /* Convert the java array of Dbc's to a C array of DBC's. */
  345. for (i = 0; i < count; i++) {
  346. jobject jobj =
  347.     (*jnienv)->GetObjectArrayElement(jnienv, curslist, i);
  348. if (jobj == 0) {
  349. /*
  350.  * An embedded null in the array is treated
  351.  * as an endpoint.
  352.  */
  353. newlist[i] = 0;
  354. break;
  355. }
  356. else {
  357. newlist[i] = get_DBC(jnienv, jobj);
  358. }
  359. }
  360. newlist[count] = 0;
  361. if (!verify_non_null(jnienv, db))
  362. return (NULL);
  363. err = db->join(db, newlist, &dbc, flags);
  364. verify_return(jnienv, err, 0);
  365. __os_free(db->dbenv, newlist);
  366. return (get_Dbc(jnienv, dbc));
  367. }
  368. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_key_1range
  369.   (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbTxn*/ jobject txnid,
  370.    /*Dbt*/ jobject jkey, jobject /*DbKeyRange*/ range, jint flags)
  371. {
  372. int err;
  373. DB *db;
  374. DB_TXN *dbtxnid;
  375. LOCKED_DBT lkey;
  376. DB_KEY_RANGE result;
  377. jfieldID fid;
  378. jclass krclass;
  379. db = get_DB(jnienv, jthis);
  380. dbtxnid = get_DB_TXN(jnienv, txnid);
  381. if (!verify_non_null(jnienv, db))
  382. return;
  383. if (!verify_non_null(jnienv, range))
  384. return;
  385. if (locked_dbt_get(&lkey, jnienv, db->dbenv, jkey, inOp) != 0)
  386. goto out;
  387. err = db->key_range(db, dbtxnid, &lkey.javainfo->dbt, &result, flags);
  388. if (verify_return(jnienv, err, 0)) {
  389. /* fill in the values of the DbKeyRange structure */
  390. if ((krclass = get_class(jnienv, "DbKeyRange")) == NULL)
  391. return; /* An exception has been posted. */
  392. fid = (*jnienv)->GetFieldID(jnienv, krclass, "less", "D");
  393. (*jnienv)->SetDoubleField(jnienv, range, fid, result.less);
  394. fid = (*jnienv)->GetFieldID(jnienv, krclass, "equal", "D");
  395. (*jnienv)->SetDoubleField(jnienv, range, fid, result.equal);
  396. fid = (*jnienv)->GetFieldID(jnienv, krclass, "greater", "D");
  397. (*jnienv)->SetDoubleField(jnienv, range, fid, result.greater);
  398. }
  399.  out:
  400. locked_dbt_put(&lkey, jnienv, db->dbenv);
  401. }
  402. JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_pget
  403.   (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbTxn*/ jobject txnid,
  404.    /*Dbt*/ jobject key, /*Dbt*/ jobject rkey, /*Dbt*/ jobject data, jint flags)
  405. {
  406. int err, op_flags, retry;
  407. DB *db;
  408. DB_ENV *dbenv;
  409. OpKind keyop, rkeyop, dataop;
  410. DB_TXN *dbtxnid;
  411. LOCKED_DBT lkey, lrkey, ldata;
  412. err = 0;
  413. db = get_DB(jnienv, jthis);
  414. if (!verify_non_null(jnienv, db))
  415. goto out4;
  416. dbenv = db->dbenv;
  417. /* Depending on flags, the key may be input/output. */
  418. keyop = inOp;
  419. rkeyop = outOp;
  420. dataop = outOp;
  421. op_flags = flags & DB_OPFLAGS_MASK;
  422. if (op_flags == DB_SET_RECNO) {
  423. keyop = inOutOp;
  424. }
  425. else if (op_flags == DB_GET_BOTH) {
  426. keyop = inOutOp;
  427. rkeyop = inOutOp;
  428. dataop = inOutOp;
  429. }
  430. dbtxnid = get_DB_TXN(jnienv, txnid);
  431. if (locked_dbt_get(&lkey, jnienv, dbenv, key, keyop) != 0)
  432. goto out3;
  433. if (locked_dbt_get(&lrkey, jnienv, dbenv, rkey, rkeyop) != 0)
  434. goto out2;
  435. if (locked_dbt_get(&ldata, jnienv, dbenv, data, dataop) != 0)
  436. goto out1;
  437. for (retry = 0; retry < 3; retry++) {
  438. err = db->pget(db, dbtxnid, &lkey.javainfo->dbt,
  439.     &lrkey.javainfo->dbt, &ldata.javainfo->dbt, flags);
  440. /*
  441.  * If we failed due to lack of memory in our DBT arrays,
  442.  * retry.
  443.  */
  444. if (err != ENOMEM)
  445. break;
  446. if (!locked_dbt_realloc(&lkey, jnienv, dbenv) &&
  447.     !locked_dbt_realloc(&lrkey, jnienv, dbenv) &&
  448.     !locked_dbt_realloc(&ldata, jnienv, dbenv))
  449. break;
  450. }
  451.  out1:
  452. locked_dbt_put(&ldata, jnienv, dbenv);
  453.  out2:
  454. locked_dbt_put(&lrkey, jnienv, dbenv);
  455.  out3:
  456. locked_dbt_put(&lkey, jnienv, dbenv);
  457.  out4:
  458. if (!DB_RETOK_DBGET(err)) {
  459. if (verify_dbt(jnienv, err, &lkey) &&
  460.     verify_dbt(jnienv, err, &lrkey) &&
  461.     verify_dbt(jnienv, err, &ldata))
  462. verify_return(jnienv, err, 0);
  463. }
  464. return (err);
  465. }
  466. JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_put
  467.   (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbTxn*/ jobject txnid,
  468.    /*Dbt*/ jobject key, /*Dbt*/ jobject data, jint flags)
  469. {
  470. int err;
  471. DB *db;
  472. DB_ENV *dbenv;
  473. DB_TXN *dbtxnid;
  474. LOCKED_DBT lkey, ldata;
  475. OpKind keyop;
  476. err = 0;
  477. db = get_DB(jnienv, jthis);
  478. dbtxnid = get_DB_TXN(jnienv, txnid);
  479. if (!verify_non_null(jnienv, db))
  480. return (0);   /* error will be thrown, retval doesn't matter */
  481. dbenv = db->dbenv;
  482. /*
  483.  * For DB_APPEND, the key may be output-only;  for all other flags,
  484.  * it's input-only.
  485.  */
  486. if ((flags & DB_OPFLAGS_MASK) == DB_APPEND)
  487. keyop = outOp;
  488. else
  489. keyop = inOp;
  490. if (locked_dbt_get(&lkey, jnienv, dbenv, key, keyop) != 0)
  491. goto out2;
  492. if (locked_dbt_get(&ldata, jnienv, dbenv, data, inOp) != 0)
  493. goto out1;
  494. if (!verify_non_null(jnienv, db))
  495. goto out1;
  496. err = db->put(db,
  497.     dbtxnid, &lkey.javainfo->dbt, &ldata.javainfo->dbt, flags);
  498. if (!DB_RETOK_DBPUT(err))
  499. verify_return(jnienv, err, 0);
  500.  out1:
  501. locked_dbt_put(&ldata, jnienv, dbenv);
  502.  out2:
  503. locked_dbt_put(&lkey, jnienv, dbenv);
  504. return (err);
  505. }
  506. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db__1remove
  507.   (JNIEnv *jnienv, /*Db*/ jobject jthis,
  508.    jstring file, jstring database, jint flags)
  509. {
  510. int err;
  511. DB *db;
  512. DB_JAVAINFO *dbinfo;
  513. LOCKED_STRING ls_file;
  514. LOCKED_STRING ls_database;
  515. db = get_DB(jnienv, jthis);
  516. dbinfo = get_DB_JAVAINFO(jnienv, jthis);
  517. if (!verify_non_null(jnienv, db))
  518. return;
  519. if (locked_string_get(&ls_file, jnienv, file) != 0)
  520. goto out2;
  521. if (locked_string_get(&ls_database, jnienv, database) != 0)
  522. goto out1;
  523. err = db->remove(db, ls_file.string, ls_database.string, flags);
  524. set_private_dbobj(jnienv, name_DB, jthis, 0);
  525. verify_return(jnienv, err, EXCEPTION_FILE_NOT_FOUND);
  526.  out1:
  527. locked_string_put(&ls_database, jnienv);
  528.  out2:
  529. locked_string_put(&ls_file, jnienv);
  530. dbji_dealloc(dbinfo, jnienv);
  531. }
  532. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db__1rename
  533.   (JNIEnv *jnienv, /*Db*/ jobject jthis,
  534.    jstring file, jstring database, jstring newname, jint flags)
  535. {
  536. int err;
  537. DB *db;
  538. DB_JAVAINFO *dbinfo;
  539. LOCKED_STRING ls_file;
  540. LOCKED_STRING ls_database;
  541. LOCKED_STRING ls_newname;
  542. db = get_DB(jnienv, jthis);
  543. dbinfo = get_DB_JAVAINFO(jnienv, jthis);
  544. if (!verify_non_null(jnienv, db))
  545. return;
  546. if (locked_string_get(&ls_file, jnienv, file) != 0)
  547. goto out3;
  548. if (locked_string_get(&ls_database, jnienv, database) != 0)
  549. goto out2;
  550. if (locked_string_get(&ls_newname, jnienv, newname) != 0)
  551. goto out1;
  552. err = db->rename(db, ls_file.string, ls_database.string,
  553.  ls_newname.string, flags);
  554. verify_return(jnienv, err, EXCEPTION_FILE_NOT_FOUND);
  555. set_private_dbobj(jnienv, name_DB, jthis, 0);
  556.  out1:
  557. locked_string_put(&ls_newname, jnienv);
  558.  out2:
  559. locked_string_put(&ls_database, jnienv);
  560.  out3:
  561. locked_string_put(&ls_file, jnienv);
  562. dbji_dealloc(dbinfo, jnienv);
  563. }
  564. JAVADB_METHOD(Db_set_1pagesize, (JAVADB_ARGS, jlong pagesize), DB,
  565.     set_pagesize, (c_this, (u_int32_t)pagesize))
  566. JAVADB_METHOD(Db_set_1cachesize,
  567.     (JAVADB_ARGS, jint gbytes, jint bytes, jint ncaches), DB,
  568.     set_cachesize, (c_this, gbytes, bytes, ncaches))
  569. JAVADB_METHOD(Db_set_1cache_1priority, (JAVADB_ARGS, jint priority), DB,
  570.     set_cache_priority, (c_this, (DB_CACHE_PRIORITY)priority))
  571. JNIEXPORT void JNICALL
  572.   Java_com_sleepycat_db_Db_set_1re_1source
  573.   (JNIEnv *jnienv, /*Db*/ jobject jthis, jstring re_source)
  574. {
  575. int err;
  576. DB *db;
  577. db = get_DB(jnienv, jthis);
  578. if (verify_non_null(jnienv, db)) {
  579. /* XXX does the string from get_c_string ever get freed? */
  580. if (re_source != NULL)
  581. err = db->set_re_source(db,
  582.     get_c_string(jnienv, re_source));
  583. else
  584. err = db->set_re_source(db, 0);
  585. verify_return(jnienv, err, 0);
  586. }
  587. }
  588. JNIEXPORT jobject JNICALL Java_com_sleepycat_db_Db_stat
  589.   (JNIEnv *jnienv, jobject jthis, jint flags)
  590. {
  591. DB *db;
  592. DB_BTREE_STAT *bstp;
  593. DB_HASH_STAT *hstp;
  594. DB_QUEUE_STAT *qstp;
  595. DBTYPE dbtype;
  596. jobject retval;
  597. jclass dbclass;
  598. size_t bytesize;
  599. void *statp;
  600. bytesize = 0;
  601. retval = NULL;
  602. statp = NULL;
  603. db = get_DB(jnienv, jthis);
  604. if (!verify_non_null(jnienv, db))
  605. return (NULL);
  606. if (verify_return(jnienv, db->stat(db, &statp, flags), 0) &&
  607.     verify_return(jnienv, db->get_type(db, &dbtype), 0)) {
  608. switch (dbtype) {
  609. /* Btree and recno share the same stat structure */
  610. case DB_BTREE:
  611. case DB_RECNO:
  612. bstp = (DB_BTREE_STAT *)statp;
  613. bytesize = sizeof(DB_BTREE_STAT);
  614. retval = create_default_object(jnienv,
  615.        name_DB_BTREE_STAT);
  616. if ((dbclass =
  617.     get_class(jnienv, name_DB_BTREE_STAT)) == NULL)
  618. break; /* An exception has been posted. */
  619. __jv_fill_bt_stat(jnienv, dbclass, retval, bstp);
  620. break;
  621. /* Hash stat structure */
  622. case DB_HASH:
  623. hstp = (DB_HASH_STAT *)statp;
  624. bytesize = sizeof(DB_HASH_STAT);
  625. retval = create_default_object(jnienv,
  626.        name_DB_HASH_STAT);
  627. if ((dbclass =
  628.     get_class(jnienv, name_DB_HASH_STAT)) == NULL)
  629. break; /* An exception has been posted. */
  630. __jv_fill_h_stat(jnienv, dbclass, retval, hstp);
  631. break;
  632. case DB_QUEUE:
  633. qstp = (DB_QUEUE_STAT *)statp;
  634. bytesize = sizeof(DB_QUEUE_STAT);
  635. retval = create_default_object(jnienv,
  636.        name_DB_QUEUE_STAT);
  637. if ((dbclass =
  638.     get_class(jnienv, name_DB_QUEUE_STAT)) == NULL)
  639. break; /* An exception has been posted. */
  640. __jv_fill_qam_stat(jnienv, dbclass, retval, qstp);
  641. break;
  642. /* That's all the database types we're aware of! */
  643. default:
  644. report_exception(jnienv,
  645.  "Db.stat not implemented for types"
  646.  " other than BTREE, HASH, QUEUE,"
  647.  " and RECNO",
  648.  EINVAL, 0);
  649. break;
  650. }
  651. if (bytesize != 0)
  652. __os_ufree(db->dbenv, statp);
  653. }
  654. return (retval);
  655. }
  656. JAVADB_METHOD(Db_sync, (JAVADB_ARGS, jint flags), DB,
  657.     sync, (c_this, flags))
  658. JNIEXPORT jboolean JNICALL Java_com_sleepycat_db_Db_get_1byteswapped
  659.   (JNIEnv *jnienv, /*Db*/ jobject jthis)
  660. {
  661. DB *db;
  662. int err, isbyteswapped;
  663. /* This value should never be seen, because of the exception. */
  664. isbyteswapped = 0;
  665. db = get_DB(jnienv, jthis);
  666. if (!verify_non_null(jnienv, db))
  667. return (0);
  668. err = db->get_byteswapped(db, &isbyteswapped);
  669. (void)verify_return(jnienv, err, 0);
  670. return ((jboolean)isbyteswapped);
  671. }
  672. JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_get_1type
  673.   (JNIEnv *jnienv, /*Db*/ jobject jthis)
  674. {
  675. DB *db;
  676. int err;
  677. DBTYPE dbtype;
  678. /* This value should never be seen, because of the exception. */
  679. dbtype = DB_UNKNOWN;
  680. db = get_DB(jnienv, jthis);
  681. if (!verify_non_null(jnienv, db))
  682. return (0);
  683. err = db->get_type(db, &dbtype);
  684. (void)verify_return(jnienv, err, 0);
  685. return ((jint)dbtype);
  686. }
  687. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db__1open
  688.   (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbTxn*/ jobject txnid,
  689.    jstring file, jstring database, jint type, jint flags, jint mode)
  690. {
  691. int err;
  692. DB *db;
  693. DB_TXN *dbtxnid;
  694. LOCKED_STRING ls_file;
  695. LOCKED_STRING ls_database;
  696. /* Java is assumed to be threaded */
  697. flags |= DB_THREAD;
  698. db = get_DB(jnienv, jthis);
  699. dbtxnid = get_DB_TXN(jnienv, txnid);
  700. if (locked_string_get(&ls_file, jnienv, file) != 0)
  701. goto out2;
  702. if (locked_string_get(&ls_database, jnienv, database) != 0)
  703. goto out1;
  704. if (verify_non_null(jnienv, db)) {
  705. err = db->open(db, dbtxnid, ls_file.string, ls_database.string,
  706.        (DBTYPE)type, flags, mode);
  707. verify_return(jnienv, err, EXCEPTION_FILE_NOT_FOUND);
  708. }
  709.  out1:
  710. locked_string_put(&ls_database, jnienv);
  711.  out2:
  712. locked_string_put(&ls_file, jnienv);
  713. }
  714. JNIEXPORT jint JNICALL Java_com_sleepycat_db_Db_truncate
  715.   (JNIEnv *jnienv, /*Db*/ jobject jthis, /*DbTxn*/ jobject jtxnid, jint flags)
  716. {
  717. int err;
  718. DB *db;
  719. u_int32_t count;
  720. DB_TXN *dbtxnid;
  721. db = get_DB(jnienv, jthis);
  722. dbtxnid = get_DB_TXN(jnienv, jtxnid);
  723. count = 0;
  724. if (verify_non_null(jnienv, db)) {
  725. err = db->truncate(db, dbtxnid, &count, flags);
  726. verify_return(jnienv, err, 0);
  727. }
  728. return (jint)count;
  729. }
  730. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_upgrade
  731.   (JNIEnv *jnienv, /*Db*/ jobject jthis, jstring name,
  732.    jint flags)
  733. {
  734. int err;
  735. DB *db = get_DB(jnienv, jthis);
  736. LOCKED_STRING ls_name;
  737. if (verify_non_null(jnienv, db)) {
  738. if (locked_string_get(&ls_name, jnienv, name) != 0)
  739. goto out;
  740. err = db->upgrade(db, ls_name.string, flags);
  741. verify_return(jnienv, err, 0);
  742. }
  743.  out:
  744. locked_string_put(&ls_name, jnienv);
  745. }
  746. static int java_verify_callback(void *handle, const void *str_arg)
  747. {
  748. char *str;
  749. struct verify_callback_struct *vc;
  750. int len;
  751. JNIEnv *jnienv;
  752. str = (char *)str_arg;
  753. vc = (struct verify_callback_struct *)handle;
  754. jnienv = vc->env;
  755. len = strlen(str)+1;
  756. if (len > vc->nbytes) {
  757. vc->nbytes = len;
  758. vc->bytes = (*jnienv)->NewByteArray(jnienv, len);
  759. }
  760. if (vc->bytes != NULL) {
  761. (*jnienv)->SetByteArrayRegion(jnienv, vc->bytes, 0, len,
  762.     (jbyte*)str);
  763. (*jnienv)->CallVoidMethod(jnienv, vc->streamobj,
  764.     vc->writemid, vc->bytes, 0, len-1);
  765. }
  766. if ((*jnienv)->ExceptionOccurred(jnienv) != NULL)
  767. return (EIO);
  768. return (0);
  769. }
  770. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db_verify
  771.   (JNIEnv *jnienv, /*Db*/ jobject jthis, jstring name,
  772.    jstring subdb, jobject stream, jint flags)
  773. {
  774. int err;
  775. DB *db;
  776. LOCKED_STRING ls_name;
  777. LOCKED_STRING ls_subdb;
  778. struct verify_callback_struct vcs;
  779. jclass streamclass;
  780. db = get_DB(jnienv, jthis);
  781. if (!verify_non_null(jnienv, db))
  782. return;
  783. if (locked_string_get(&ls_name, jnienv, name) != 0)
  784. goto out2;
  785. if (locked_string_get(&ls_subdb, jnienv, subdb) != 0)
  786. goto out1;
  787. /* set up everything we need for the callbacks */
  788. vcs.env = jnienv;
  789. vcs.streamobj = stream;
  790. vcs.nbytes = 100;
  791. if ((vcs.bytes = (*jnienv)->NewByteArray(jnienv, vcs.nbytes)) == NULL)
  792. goto out1;
  793. /* get the method ID for OutputStream.write(byte[], int, int); */
  794. streamclass = (*jnienv)->FindClass(jnienv, "java/io/OutputStream");
  795. vcs.writemid = (*jnienv)->GetMethodID(jnienv, streamclass,
  796.       "write", "([BII)V");
  797. /* invoke verify - this will invoke the callback repeatedly. */
  798. err = __db_verify_internal(db, ls_name.string, ls_subdb.string,
  799.    &vcs, java_verify_callback, flags);
  800. verify_return(jnienv, err, 0);
  801. out1:
  802. locked_string_put(&ls_subdb, jnienv);
  803. out2:
  804. locked_string_put(&ls_name, jnienv);
  805. }
  806. JNIEXPORT void JNICALL Java_com_sleepycat_db_Db__1finalize
  807.     (JNIEnv *jnienv, jobject jthis,
  808.      jobject /*DbErrcall*/ errcall, jstring errpfx)
  809. {
  810. DB_JAVAINFO *dbinfo;
  811. DB *db;
  812. dbinfo = get_DB_JAVAINFO(jnienv, jthis);
  813. db = get_DB(jnienv, jthis);
  814. DB_ASSERT(dbinfo != NULL);
  815. /*
  816.  * Note: We can never be sure if the underlying DB is attached to
  817.  * a DB_ENV that was already closed.  Sure, that's a user error,
  818.  * but it shouldn't crash the VM.  Therefore, we cannot just
  819.  * automatically close if the handle indicates we are not yet
  820.  * closed.  The best we can do is detect this and report it.
  821.  */
  822. if (db != NULL) {
  823. /* If this error occurs, this object was never closed. */
  824. report_errcall(jnienv, errcall, errpfx,
  825.        "Db.finalize: open Db object destroyed");
  826. }
  827. /* Shouldn't see this object again, but just in case */
  828. set_private_dbobj(jnienv, name_DB, jthis, 0);
  829. set_private_info(jnienv, name_DB, jthis, 0);
  830. dbji_destroy(dbinfo, jnienv);
  831. }