2 * DB1->3 compatibility layer
14 #include "../common/db.h"
15 #include "../common/dbinternal.h"
21 static int db1_dbenv_close(DB_ENV
*, u_int32_t
);
22 static int db1_dbenv_open(DB_ENV
*, char *, u_int32_t
, int);
23 static int db1_dbenv_remove(DB_ENV
*, char *, u_int32_t
);
26 db_env_create(DB_ENV
**dbenvp
, u_int32_t flags
) {
31 dbenv
= malloc(sizeof *dbenv
);
35 dbenv
->close
= db1_dbenv_close
;
36 dbenv
->open
= db1_dbenv_open
;
37 dbenv
->remove
= db1_dbenv_remove
;
39 dbenv
->base_path
= NULL
;
47 db1_dbenv_close(DB_ENV
*dbenv
, u_int32_t flags
) {
50 if (dbenv
->base_path
!= NULL
)
51 free(dbenv
->base_path
);
58 db1_dbenv_open(DB_ENV
*dbenv
, char *base_path
, u_int32_t flags
, int mode
) {
60 /* We ignore flags on purpose */
62 dbenv
->base_path
= strdup(base_path
);
63 if (dbenv
->base_path
== NULL
)
66 dbenv
->mode
= mode
!= 0? mode
: 0660;
71 db1_dbenv_remove(DB_ENV
*dbenv_fake
, char *base_path
, u_int32_t flags
) {
72 /* dbenv_fake is not a useful environment */
73 /* XXX check if we have to remove files here */
81 static int db1_db_close(DB
*, u_int32_t
);
82 static int db1_db_open(DB
*, const char *, const char *, DBTYPE
, u_int32_t
, int);
83 static int db1_db_sync(DB
*, u_int32_t
);
84 static int db1_db_get(DB
*, DB_TXN
*, DBT
*, DBT
*, u_int32_t
);
85 static int db1_db_put(DB
*, DB_TXN
*, DBT
*, DBT
*, u_int32_t
);
86 static int db1_db_del(DB
*, DB_TXN
*, DBT
*, u_int32_t
);
87 static int db1_db_set_flags(DB
*, u_int32_t
);
88 static int db1_db_set_pagesize(DB
*, u_int32_t
);
89 static int db1_db_set_re_delim(DB
*, int);
90 static int db1_db_set_re_source(DB
*, const char *);
91 static int db1_db_cursor(DB
*, DB_TXN
*, DBC
**, u_int32_t
);
94 db_create(DB
**dbp
, DB_ENV
*dbenv
, u_int32_t flags
) {
97 *dbp
= malloc(sizeof **dbp
);
101 (*dbp
)->type
= DB_UNKNOWN
;
102 (*dbp
)->actual_db
= NULL
;
103 (*dbp
)->_pagesize
= 0;
105 memset(&(*dbp
)->_recno_info
, 0, sizeof (RECNOINFO
));
107 (*dbp
)->close
= db1_db_close
;
108 (*dbp
)->open
= db1_db_open
;
109 (*dbp
)->sync
= db1_db_sync
;
110 (*dbp
)->get
= db1_db_get
;
111 (*dbp
)->put
= db1_db_put
;
112 (*dbp
)->del
= db1_db_del
;
113 (*dbp
)->set_flags
= db1_db_set_flags
;
114 (*dbp
)->set_pagesize
= db1_db_set_pagesize
;
115 (*dbp
)->set_re_delim
= db1_db_set_re_delim
;
116 (*dbp
)->set_re_source
= db1_db_set_re_source
;
117 (*dbp
)->cursor
= db1_db_cursor
;
123 db_strerror(int error
) {
124 return error
> 0? strerror(error
) : "record not found";
128 db1_db_close(DB
*db
, u_int32_t flags
) {
129 if (flags
& DB_NOSYNC
) {
132 db
->actual_db
->close(db
->actual_db
);
134 db
->type
= DB_UNKNOWN
;
135 db
->actual_db
= NULL
;
138 memset(&db
->_recno_info
, 0, sizeof (RECNOINFO
));
144 db1_db_open(DB
*db
, const char *file
, const char *database
, DBTYPE type
,
145 u_int32_t flags
, int mode
) {
148 assert(database
== NULL
&& !(flags
& ~(DB_CREATE
| DB_TRUNCATE
)));
152 if (flags
& DB_CREATE
)
154 if (flags
& DB_TRUNCATE
)
157 if (type
== DB_RECNO
) {
158 const char *tmp
= file
;
160 /* The interface is reversed in DB3 */
161 file
= db
->_recno_info
.bfname
;
162 db
->_recno_info
.bfname
= __UNCONST(tmp
);
164 /* ... and so, we should avoid to truncate the main file! */
165 oldflags
&= ~O_TRUNC
;
167 db
->_recno_info
.flags
=
168 db
->_flags
& DB_SNAPSHOT
? R_SNAPSHOT
: 0;
169 db
->_recno_info
.psize
= db
->_pagesize
;
172 db
->actual_db
= dbopen(file
, oldflags
, mode
, type
,
173 type
== DB_RECNO
? &db
->_recno_info
: NULL
);
175 return db
->actual_db
== NULL
? errno
: 0;
179 db1_db_sync(DB
*db
, u_int32_t flags
) {
182 return db
->actual_db
->sync(db
->actual_db
, db
->type
== DB_UNKNOWN
?
183 R_RECNOSYNC
: 0) == 0? 0 : errno
;
187 db1_db_get(DB
*db
, DB_TXN
*txnid
, DBT
*key
, DBT
*data
, u_int32_t flags
) {
191 assert(flags
== 0 && txnid
== NULL
);
193 err
= db
->actual_db
->get(db
->actual_db
, (DBT_v1
*) key
, &data1
, flags
);
199 if (data
->flags
& DB_DBT_USERMEM
) {
200 data
->size
= data1
.size
;
201 if (data1
.size
> data
->ulen
)
202 return DB_BUFFER_SMALL
;
204 memcpy(data
->data
, data1
.data
, data1
.size
);
211 db1_db_put(DB
*db
, DB_TXN
*txnid
, DBT
*key
, DBT
*data
, u_int32_t flags
) {
213 DB_old
*db_v1
= db
->actual_db
;
218 assert((flags
& ~DB_APPEND
) == 0 && txnid
== NULL
);
222 if (flags
& DB_APPEND
) {
223 if (db_v1
->seq(db_v1
, (DBT_v1
*)(void *)key
,
224 (DBT_v1
*)(void *)&data1
, R_LAST
) == 1) {
226 key1
.size
= sizeof recno
;
229 err
= db_v1
->put(db_v1
, (DBT_v1
*)(void *)&key1
, (DBT_v1
*)(void *)data
,
232 return err
== -1? errno
: err
;
236 db1_db_del(DB
*db
, DB_TXN
*txnid
, DBT
*key
, u_int32_t flags
) {
238 DB_old
*db_v1
= db
->actual_db
;
240 assert(txnid
== NULL
&& flags
== 0);
242 err
= db_v1
->del(db_v1
, (DBT_v1
*) key
, 0);
243 return err
== -1? errno
: err
;
247 db1_db_set_flags(DB
*db
, u_int32_t flags
) {
248 assert((flags
& ~(DB_RENUMBER
| DB_SNAPSHOT
)) == 0);
250 /* Can't prevent renumbering from happening with DB1 */
251 assert((flags
| db
->_flags
) & DB_RENUMBER
);
260 db1_db_set_pagesize(DB
*db
, u_int32_t pagesize
) {
261 db
->_pagesize
= pagesize
;
267 db1_db_set_re_delim(DB
*db
, int re_delim
) {
268 db
->_recno_info
.bval
= re_delim
;
274 db1_db_set_re_source(DB
*db
, const char *re_source
) {
275 db
->_recno_info
.bfname
= __UNCONST(re_source
);
280 /* DBC emulation. Very basic, only one cursor at a time, enough for vi */
282 static int db1_dbc_close(DBC
*);
283 static int db1_dbc_get(DBC
*, DBT
*, DBT
*, u_int32_t
);
284 static int db1_dbc_put(DBC
*, DBT
*, DBT
*, u_int32_t
);
287 db1_db_cursor(DB
*db
, DB_TXN
*txn
, DBC
**cursorp
, u_int32_t flags
) {
290 assert(txn
== NULL
&& flags
== 0);
292 cursor
= malloc(sizeof *cursor
);
297 cursor
->pos_key
.data
= &cursor
->pos
;
298 cursor
->pos_key
.size
= sizeof cursor
->pos
;
299 cursor
->c_close
= db1_dbc_close
;
300 cursor
->c_get
= db1_dbc_get
;
301 cursor
->c_put
= db1_dbc_put
;
309 db1_dbc_close(DBC
*cursor
) {
315 db1_dbc_get(DBC
*cursor
, DBT
*key
, DBT
*data
, u_int32_t flags
) {
317 DB_old
*db_v1
= db
->actual_db
;
323 ret
= db_v1
->seq(db_v1
, (DBT_v1
*) key
, (DBT_v1
*) data
,
325 cursor
->pos
= * (db_recno_t
*) key
->data
;
328 ret
= db_v1
->seq(db_v1
, (DBT_v1
*) key
, (DBT_v1
*) data
,
332 cursor
->pos
= * (db_recno_t
*) key
->data
;
335 ret
= db_v1
->seq(db_v1
, (DBT_v1
*) key
, (DBT_v1
*) data
,
339 cursor
->pos
= * (db_recno_t
*) key
->data
;
349 db1_dbc_put(DBC
*cursor
, DBT
*key
, DBT
*data
, u_int32_t flags
) {
351 DB_old
*db_v1
= db
->actual_db
;
354 assert((flags
& ~(DB_BEFORE
| DB_AFTER
)) == 0);
356 ret
= db_v1
->put(db_v1
, &cursor
->pos_key
, (DBT_v1
*) data
,
357 flags
== DB_BEFORE
? R_IBEFORE
: R_IAFTER
);
359 return ret
== -1? errno
: ret
;