1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 1998, 1999, 2000
5  *	Sleepycat Software.  All rights reserved.
6  */
7 
8 #include "config.h"
9 
10 #ifndef lint
11 static const char revid[] = "$Id: xa_db.c,v 1.3 2000/06/28 16:47:03 loic Exp $";
12 #endif /* not lint */
13 
14 #ifndef NO_SYSTEM_INCLUDES
15 #include <sys/types.h>
16 #endif
17 
18 #include "db_int.h"
19 #include "xa.h"
20 #include "xa_ext.h"
21 #include "txn.h"
22 
23 static int __xa_close __P((DB *, u_int32_t));
24 static int __xa_cursor __P((DB *, DB_TXN *, DBC **, u_int32_t));
25 static int __xa_del __P((DB *, DB_TXN *, DBT *, u_int32_t));
26 static int __xa_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
27 static int __xa_put __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
28 
29 typedef struct __xa_methods {
30 	int (*close) __P((DB *, u_int32_t));
31 	int (*cursor) __P((DB *, DB_TXN *, DBC **, u_int32_t));
32 	int (*del) __P((DB *, DB_TXN *, DBT *, u_int32_t));
33 	int (*get) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
34 	int (*put) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
35 } XA_METHODS;
36 
37 /*
38  * CDB___db_xa_create --
39  *	DB XA constructor.
40  *
41  * PUBLIC: int CDB___db_xa_create __P((DB *));
42  */
43 int
CDB___db_xa_create(dbp)44 CDB___db_xa_create(dbp)
45 	DB *dbp;
46 {
47 	XA_METHODS *xam;
48 	int ret;
49 
50 	/*
51 	 * Interpose XA routines in front of any method that takes a TXN
52 	 * ID as an argument.
53 	 */
54 	if ((ret = CDB___os_calloc(dbp->dbenv, 1, sizeof(XA_METHODS), &xam)) != 0)
55 		return (ret);
56 
57 	dbp->xa_internal = xam;
58 	xam->close = dbp->close;
59 	xam->cursor = dbp->cursor;
60 	xam->del = dbp->del;
61 	xam->get = dbp->get;
62 	xam->put = dbp->put;
63 	dbp->close = __xa_close;
64 	dbp->cursor = __xa_cursor;
65 	dbp->del = __xa_del;
66 	dbp->get = __xa_get;
67 	dbp->put = __xa_put;
68 
69 	return (0);
70 }
71 
72 static int
__xa_cursor(dbp,txn,dbcp,flags)73 __xa_cursor(dbp, txn, dbcp, flags)
74 	DB *dbp;
75 	DB_TXN *txn;
76 	DBC **dbcp;
77 	u_int32_t flags;
78 {
79 	DB_TXN *t;
80 
81 	t = txn != NULL && txn == dbp->open_txn ? txn : dbp->dbenv->xa_txn;
82 	if (t->txnid == TXN_INVALID)
83 		t = NULL;
84 
85 	return (((XA_METHODS *)dbp->xa_internal)->cursor (dbp, t, dbcp, flags));
86 }
87 
88 static int
__xa_del(dbp,txn,key,flags)89 __xa_del(dbp, txn, key, flags)
90 	DB *dbp;
91 	DB_TXN *txn;
92 	DBT *key;
93 	u_int32_t flags;
94 {
95 	DB_TXN *t;
96 
97 	t = txn != NULL && txn == dbp->open_txn ? txn : dbp->dbenv->xa_txn;
98 	if (t->txnid == TXN_INVALID)
99 		t = NULL;
100 
101 	return (((XA_METHODS *)dbp->xa_internal)->del(dbp, t, key, flags));
102 }
103 
104 static int
__xa_close(dbp,flags)105 __xa_close(dbp, flags)
106 	DB *dbp;
107 	u_int32_t flags;
108 {
109 	int (*real_close) __P((DB *, u_int32_t));
110 
111 	real_close = ((XA_METHODS *)dbp->xa_internal)->close;
112 
113 	CDB___os_free(dbp->xa_internal, sizeof(XA_METHODS));
114 	dbp->xa_internal = NULL;
115 
116 	return (real_close(dbp, flags));
117 }
118 
119 static int
__xa_get(dbp,txn,key,data,flags)120 __xa_get(dbp, txn, key, data, flags)
121 	DB *dbp;
122 	DB_TXN *txn;
123 	DBT *key, *data;
124 	u_int32_t flags;
125 {
126 	DB_TXN *t;
127 
128 	t = txn != NULL && txn == dbp->open_txn ? txn : dbp->dbenv->xa_txn;
129 	if (t->txnid == TXN_INVALID)
130 		t = NULL;
131 
132 	return (((XA_METHODS *)dbp->xa_internal)->get
133 	    (dbp, t, key, data, flags));
134 }
135 
136 static int
__xa_put(dbp,txn,key,data,flags)137 __xa_put(dbp, txn, key, data, flags)
138 	DB *dbp;
139 	DB_TXN *txn;
140 	DBT *key, *data;
141 	u_int32_t flags;
142 {
143 	DB_TXN *t;
144 
145 	t = txn != NULL && txn == dbp->open_txn ? txn : dbp->dbenv->xa_txn;
146 	if (t->txnid == TXN_INVALID)
147 		t = NULL;
148 
149 	return (((XA_METHODS *)dbp->xa_internal)->put
150 	    (dbp, t, key, data, flags));
151 }
152