/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1997-2001 * Sleepycat Software. All rights reserved. */ #include "db_config.h" #ifndef lint static const char revid[] = "$Id: java_DbXAResource.c,v 1.1.1.1 2003/02/15 04:56:08 zarzycki Exp $"; #endif /* not lint */ #include #include #include #include #ifdef DIAGNOSTIC #include #endif #include "db_int.h" #include "java_util.h" #include "dbinc/xa.h" #include "dbinc_auto/xa_ext.h" #include "com_sleepycat_db_xa_DbXAResource.h" JNIEXPORT void JNICALL Java_com_sleepycat_db_xa_DbXAResource__1init (JNIEnv *jnienv, jobject jthis, jstring home, jint rmid, jint flags) { int err; LOCKED_STRING ls_home; jclass cl; jmethodID mid; COMPQUIET(jthis, NULL); if (locked_string_get(&ls_home, jnienv, home) != 0) goto out; if ((err = __db_xa_open((char *)ls_home.string, rmid, flags)) != XA_OK) { verify_return(jnienv, err, EXCEPTION_XA); } /* * Now create the DbEnv object, it will get attached * to the DB_ENV just made in __db_xa_open. */ if ((cl = get_class(jnienv, name_DB_ENV)) == NULL) goto out; mid = (*jnienv)->GetStaticMethodID(jnienv, cl, "_create_DbEnv_for_XA", "(II)V"); (*jnienv)->CallStaticVoidMethod(jnienv, cl, mid, 0, rmid); out: locked_string_put(&ls_home, jnienv); } JNIEXPORT void JNICALL Java_com_sleepycat_db_xa_DbXAResource__1close (JNIEnv *jnienv, jobject jthis, jstring home, jint rmid, jint flags) { int err; LOCKED_STRING ls_home; COMPQUIET(jthis, NULL); if (locked_string_get(&ls_home, jnienv, home) != 0) goto out; if ((err = __db_xa_close((char *)ls_home.string, rmid, flags)) != XA_OK) verify_return(jnienv, err, EXCEPTION_XA); out: locked_string_put(&ls_home, jnienv); } JNIEXPORT void JNICALL Java_com_sleepycat_db_xa_DbXAResource__1commit (JNIEnv *jnienv, jobject jthis, jobject jxid, jint rmid, jboolean onePhase) { XID xid; long flags; int err; COMPQUIET(jthis, NULL); if (!get_XID(jnienv, jxid, &xid)) return; flags = 0; if (onePhase == JNI_TRUE) flags |= TMONEPHASE; if ((err = __db_xa_commit(&xid, rmid, flags)) != XA_OK) verify_return(jnienv, err, EXCEPTION_XA); } JNIEXPORT void JNICALL Java_com_sleepycat_db_xa_DbXAResource__1end (JNIEnv *jnienv, jobject jthis, jobject jxid, jint rmid, jint flags) { XID xid; int err; COMPQUIET(jthis, NULL); if (!get_XID(jnienv, jxid, &xid)) return; if ((err = __db_xa_end(&xid, rmid, flags)) != XA_OK) verify_return(jnienv, err, EXCEPTION_XA); } JNIEXPORT void JNICALL Java_com_sleepycat_db_xa_DbXAResource__1forget (JNIEnv *jnienv, jobject jthis, jobject jxid, jint rmid) { XID xid; int err; COMPQUIET(jthis, NULL); if (!get_XID(jnienv, jxid, &xid)) return; if ((err = __db_xa_forget(&xid, rmid, 0)) != XA_OK) verify_return(jnienv, err, EXCEPTION_XA); } JNIEXPORT jint JNICALL Java_com_sleepycat_db_xa_DbXAResource__1prepare (JNIEnv *jnienv, jobject jthis, jobject jxid, jint rmid) { XID xid; int err; COMPQUIET(jthis, NULL); if (!get_XID(jnienv, jxid, &xid)) return (0); err = __db_xa_prepare(&xid, rmid, 0); if (err != XA_OK && err != XA_RDONLY) verify_return(jnienv, err, EXCEPTION_XA); return (err); } JNIEXPORT jobjectArray JNICALL Java_com_sleepycat_db_xa_DbXAResource__1recover (JNIEnv *jnienv, jobject jthis, jint rmid, jint flags) { XID *xids; int err; int total; int cnt; int i; int curflags; size_t nbytes; jclass xid_class; jmethodID mid; jobject obj; jobjectArray retval; COMPQUIET(jthis, NULL); total = 0; cnt = 0; xids = NULL; flags &= ~(DB_FIRST | DB_LAST | DB_NEXT); /* Repeatedly call __db_xa_recover to fill up an array of XIDs */ curflags = flags | DB_FIRST; do { total += cnt; nbytes = sizeof(XID) * (total + 10); if ((err = __os_realloc(NULL, nbytes, &xids)) != 0) { if (xids != NULL) __os_free(NULL, xids); verify_return(jnienv, XAER_NOTA, EXCEPTION_XA); return (NULL); } cnt = __db_xa_recover(&xids[total], 10, rmid, curflags); curflags = flags | DB_NEXT; } while (cnt > 0); if (xids != NULL) __os_free(NULL, xids); if (cnt < 0) { verify_return(jnienv, cnt, EXCEPTION_XA); return (NULL); } /* Create the java DbXid array and fill it up */ if ((xid_class = get_class(jnienv, name_DB_XID)) == NULL) return (NULL); mid = (*jnienv)->GetMethodID(jnienv, xid_class, "", "(I[B[B)V"); if ((retval = (*jnienv)->NewObjectArray(jnienv, total, xid_class, 0)) == NULL) goto out; for (i = 0; i < total; i++) { jobject gtrid; jobject bqual; jsize gtrid_len; jsize bqual_len; gtrid_len = (jsize)xids[i].gtrid_length; bqual_len = (jsize)xids[i].bqual_length; gtrid = (*jnienv)->NewByteArray(jnienv, gtrid_len); bqual = (*jnienv)->NewByteArray(jnienv, bqual_len); if (gtrid == NULL || bqual == NULL) goto out; (*jnienv)->SetByteArrayRegion(jnienv, gtrid, 0, gtrid_len, (jbyte *)&xids[i].data[0]); (*jnienv)->SetByteArrayRegion(jnienv, bqual, 0, bqual_len, (jbyte *)&xids[i].data[gtrid_len]); if ((obj = (*jnienv)->NewObject(jnienv, xid_class, mid, (jint)xids[i].formatID, gtrid, bqual)) == NULL) goto out; (*jnienv)->SetObjectArrayElement(jnienv, retval, i, obj); } out: return (retval); } JNIEXPORT void JNICALL Java_com_sleepycat_db_xa_DbXAResource__1rollback (JNIEnv *jnienv, jobject jthis, jobject jxid, jint rmid) { XID xid; int err; COMPQUIET(jthis, NULL); if (!get_XID(jnienv, jxid, &xid)) return; if ((err = __db_xa_rollback(&xid, rmid, 0)) != XA_OK) verify_return(jnienv, err, EXCEPTION_XA); } JNIEXPORT void JNICALL Java_com_sleepycat_db_xa_DbXAResource__1start (JNIEnv *jnienv, jobject jthis, jobject jxid, jint rmid, jint flags) { XID xid; int err; COMPQUIET(jthis, NULL); if (!get_XID(jnienv, jxid, &xid)) return; if ((err = __db_xa_start(&xid, rmid, flags)) != XA_OK) verify_return(jnienv, err, EXCEPTION_XA); } JNIEXPORT jobject JNICALL Java_com_sleepycat_db_xa_DbXAResource_xa_1attach (JNIEnv *jnienv, jclass jthisclass, jobject jxid, jobject jrmid) { XID xid; XID *xidp; int ret; DB_ENV *env; DB_TXN *txn; int rmid; int *rmidp; jobject jtxn; jobject jenv; jclass cl; jmethodID mid; COMPQUIET(jthisclass, NULL); if (jxid == NULL) { xidp = NULL; } else { xidp = &xid; if (!get_XID(jnienv, jxid, &xid)) return (NULL); } if (jrmid == NULL) { rmidp = NULL; } else { rmidp = &rmid; rmid = (int)(*jnienv)->CallIntMethod(jnienv, jrmid, mid_Integer_intValue); } if ((ret = db_env_xa_attach(rmidp, xidp, &env, &txn)) != 0) { /* * DB_NOTFOUND is a normal return, it means we * have no current transaction, */ if (ret != DB_NOTFOUND) verify_return(jnienv, ret, 0); return (NULL); } jenv = ((DB_ENV_JAVAINFO *)env->api2_internal)->jenvref; jtxn = get_DbTxn(jnienv, txn); if ((cl = get_class(jnienv, name_DB_XAATTACH)) == NULL) return (NULL); mid = (*jnienv)->GetMethodID(jnienv, cl, "", "(Lcom/sleepycat/db/DbEnv;Lcom/sleepycat/db/DbTxn;)V"); return (*jnienv)->NewObject(jnienv, cl, mid, jenv, jtxn); }