00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "db_config.h"
00011
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014 #endif
00015
00016 #include "db_int.h"
00017 #include "dbinc/txn.h"
00018
00019 static int __xa_close __P((DB *, u_int32_t));
00020 static int __xa_cursor __P((DB *, DB_TXN *, DBC **, u_int32_t));
00021 static int __xa_del __P((DB *, DB_TXN *, DBT *, u_int32_t));
00022 static int __xa_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
00023 static int __xa_open __P((DB *, DB_TXN *,
00024 const char *, const char *, DBTYPE, u_int32_t, int));
00025 static int __xa_put __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
00026 static int __xa_set_txn __P((DB *, DB_TXN **, int));
00027 static int __xa_truncate __P((DB *, DB_TXN *, u_int32_t *, u_int32_t));
00028
00029 typedef struct __xa_methods {
00030 int (*close) __P((DB *, u_int32_t));
00031 int (*cursor) __P((DB *, DB_TXN *, DBC **, u_int32_t));
00032 int (*del) __P((DB *, DB_TXN *, DBT *, u_int32_t));
00033 int (*get) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
00034 int (*open) __P((DB *, DB_TXN *,
00035 const char *, const char *, DBTYPE, u_int32_t, int));
00036 int (*put) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
00037 int (*truncate) __P((DB *, DB_TXN *, u_int32_t *, u_int32_t));
00038 } XA_METHODS;
00039
00040
00041
00042
00043
00044 static int
00045 __xa_set_txn(dbp, txnpp, no_xa_txn)
00046 DB *dbp;
00047 DB_TXN **txnpp;
00048 int no_xa_txn;
00049 {
00050 DB_ENV *dbenv;
00051 int ret;
00052
00053 dbenv = dbp->dbenv;
00054
00055
00056
00057
00058
00059
00060
00061
00062 if (*txnpp != NULL) {
00063 __db_err(dbenv,
00064 "transaction handles should not be directly specified to XA interfaces");
00065 return (EINVAL);
00066 }
00067
00068
00069 if ((ret = __xa_get_txn(dbenv, txnpp, 0)) != 0)
00070 return (ret);
00071 if ((*txnpp)->txnid != TXN_INVALID)
00072 return (0);
00073
00074
00075
00076
00077
00078
00079
00080 if (no_xa_txn) {
00081 *txnpp = NULL;
00082 return (0);
00083 }
00084
00085 __db_err(dbenv, "no XA transaction declared");
00086 return (EINVAL);
00087 }
00088
00089
00090
00091
00092
00093
00094
00095 int
00096 __db_xa_create(dbp)
00097 DB *dbp;
00098 {
00099 XA_METHODS *xam;
00100 int ret;
00101
00102
00103
00104
00105
00106 if ((ret = __os_calloc(dbp->dbenv, 1, sizeof(XA_METHODS), &xam)) != 0)
00107 return (ret);
00108
00109 dbp->xa_internal = xam;
00110 xam->open = dbp->open;
00111 dbp->open = __xa_open;
00112 xam->close = dbp->close;
00113 dbp->close = __xa_close;
00114
00115 return (0);
00116 }
00117
00118
00119
00120
00121
00122 static int
00123 __xa_open(dbp, txn, name, subdb, type, flags, mode)
00124 DB *dbp;
00125 DB_TXN *txn;
00126 const char *name, *subdb;
00127 DBTYPE type;
00128 u_int32_t flags;
00129 int mode;
00130 {
00131 XA_METHODS *xam;
00132 int ret;
00133
00134 xam = (XA_METHODS *)dbp->xa_internal;
00135
00136 if ((ret =
00137 __xa_set_txn(dbp, &txn, LF_ISSET(DB_AUTO_COMMIT) ? 1 : 0)) != 0)
00138 return (ret);
00139 if ((ret = xam->open(dbp, txn, name, subdb, type, flags, mode)) != 0)
00140 return (ret);
00141
00142
00143 xam->cursor = dbp->cursor;
00144 xam->del = dbp->del;
00145 xam->get = dbp->get;
00146 xam->put = dbp->put;
00147 xam->truncate = dbp->truncate;
00148 dbp->cursor = __xa_cursor;
00149 dbp->del = __xa_del;
00150 dbp->get = __xa_get;
00151 dbp->put = __xa_put;
00152 dbp->truncate = __xa_truncate;
00153
00154 return (0);
00155 }
00156
00157 static int
00158 __xa_cursor(dbp, txn, dbcp, flags)
00159 DB *dbp;
00160 DB_TXN *txn;
00161 DBC **dbcp;
00162 u_int32_t flags;
00163 {
00164 int ret;
00165
00166 if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0)
00167 return (ret);
00168 return (((XA_METHODS *)
00169 dbp->xa_internal)->cursor(dbp, txn, dbcp, flags));
00170 }
00171
00172 static int
00173 __xa_del(dbp, txn, key, flags)
00174 DB *dbp;
00175 DB_TXN *txn;
00176 DBT *key;
00177 u_int32_t flags;
00178 {
00179 int ret;
00180
00181 if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0)
00182 return (ret);
00183 return (((XA_METHODS *)dbp->xa_internal)->del(dbp, txn, key, flags));
00184 }
00185
00186 static int
00187 __xa_close(dbp, flags)
00188 DB *dbp;
00189 u_int32_t flags;
00190 {
00191 int (*real_close) __P((DB *, u_int32_t));
00192
00193 real_close = ((XA_METHODS *)dbp->xa_internal)->close;
00194
00195 __os_free(dbp->dbenv, dbp->xa_internal);
00196 dbp->xa_internal = NULL;
00197
00198 return (real_close(dbp, flags));
00199 }
00200
00201 static int
00202 __xa_get(dbp, txn, key, data, flags)
00203 DB *dbp;
00204 DB_TXN *txn;
00205 DBT *key, *data;
00206 u_int32_t flags;
00207 {
00208 int ret;
00209
00210 if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0)
00211 return (ret);
00212 return (((XA_METHODS *)
00213 dbp->xa_internal)->get(dbp, txn, key, data, flags));
00214 }
00215
00216 static int
00217 __xa_put(dbp, txn, key, data, flags)
00218 DB *dbp;
00219 DB_TXN *txn;
00220 DBT *key, *data;
00221 u_int32_t flags;
00222 {
00223 int ret;
00224
00225 if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0)
00226 return (ret);
00227 return (((XA_METHODS *)
00228 dbp->xa_internal)->put(dbp, txn, key, data, flags));
00229 }
00230
00231 static int
00232 __xa_truncate(dbp, txn, countp, flags)
00233 DB *dbp;
00234 DB_TXN *txn;
00235 u_int32_t *countp, flags;
00236 {
00237 int ret;
00238
00239 if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0)
00240 return (ret);
00241 return (((XA_METHODS *)
00242 dbp->xa_internal)->truncate(dbp, txn, countp, flags));
00243 }