mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 21:12:26 +01:00
288 lines
6.9 KiB
C
288 lines
6.9 KiB
C
/*-
|
|
* 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 11.6 2002/08/06 05:19:06 bostic Exp $";
|
|
#endif /* not lint */
|
|
|
|
#include <jni.h>
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#ifdef DIAGNOSTIC
|
|
#include <stdio.h>
|
|
#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, "<init>",
|
|
"(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, "<init>",
|
|
"(Lcom/sleepycat/db/DbEnv;Lcom/sleepycat/db/DbTxn;)V");
|
|
return (*jnienv)->NewObject(jnienv, cl, mid, jenv, jtxn);
|
|
}
|