2 * See the file LICENSE for redistribution information.
4 * Copyright (c) 1996, 1997, 1998
5 * Sleepycat Software. All rights reserved.
11 static const char copyright
[] =
12 "@(#) Copyright (c) 1996, 1997, 1998\n\
13 Sleepycat Software Inc. All rights reserved.\n";
14 static const char sccsid
[] = "@(#)db185.c 8.17 (Sleepycat) 5/7/98";
17 #ifndef NO_SYSTEM_INCLUDES
18 #include <sys/types.h>
28 #include "db185_int.h"
29 #include "common_ext.h"
31 static int db185_close
__P((DB185
*));
32 static int db185_del
__P((const DB185
*, const DBT185
*, u_int
));
33 static int db185_fd
__P((const DB185
*));
34 static int db185_get
__P((const DB185
*, const DBT185
*, DBT185
*, u_int
));
35 static int db185_put
__P((const DB185
*, DBT185
*, const DBT185
*, u_int
));
36 static int db185_seq
__P((const DB185
*, DBT185
*, DBT185
*, u_int
));
37 static int db185_sync
__P((const DB185
*, u_int
));
40 __dbopen(file
, oflags
, mode
, type
, openinfo
)
51 DB_INFO dbinfo
, *dbinfop
;
54 if ((db185p
= (DB185
*)__db_calloc(1, sizeof(DB185
))) == NULL
)
57 memset(&dbinfo
, 0, sizeof(dbinfo
));
61 * The DBTYPE enum wasn't initialized in DB 185, so it's off-by-one
65 case 0: /* DB_BTREE */
67 if ((bi
= openinfo
) != NULL
) {
69 if (bi
->flags
& ~R_DUP
)
71 if (bi
->flags
& R_DUP
)
72 dbinfop
->flags
|= DB_DUP
;
73 dbinfop
->db_cachesize
= bi
->cachesize
;
74 dbinfop
->bt_maxkey
= bi
->maxkeypage
;
75 dbinfop
->bt_minkey
= bi
->minkeypage
;
76 dbinfop
->db_pagesize
= bi
->psize
;
79 * Comparisons and prefix calls work because the DBT
80 * structures in 1.85 and 2.0 have the same initial
83 dbinfop
->bt_compare
= bi
->compare
;
84 dbinfop
->bt_prefix
= bi
->prefix
;
85 dbinfop
->db_lorder
= bi
->lorder
;
90 if ((hi
= openinfo
) != NULL
) {
92 dbinfop
->db_pagesize
= hi
->bsize
;
93 dbinfop
->h_ffactor
= hi
->ffactor
;
94 dbinfop
->h_nelem
= hi
->nelem
;
95 dbinfop
->db_cachesize
= hi
->cachesize
;
96 dbinfop
->h_hash
= hi
->hash
;
97 dbinfop
->db_lorder
= hi
->lorder
;
101 case 2: /* DB_RECNO */
105 /* DB 1.85 did renumbering by default. */
106 dbinfop
->flags
|= DB_RENUMBER
;
110 * The file name given to DB 1.85 recno is the name of the DB
111 * 2.0 backing file. If the file doesn't exist, create it if
112 * the user has the O_CREAT flag set, DB 1.85 did it for you,
113 * and DB 2.0 doesn't.
116 * Setting the file name to NULL specifies that we're creating
117 * a temporary backing file, in DB 2.X. If we're opening the
118 * DB file read-only, change the flags to read-write, because
119 * temporary backing files cannot be opened read-only, and DB
120 * 2.X will return an error. We are cheating here -- if the
121 * application does a put on the database, it will succeed --
122 * although that would be a stupid thing for the application
126 * Note, the file name in DB 1.85 was a const -- we don't do
127 * that in DB 2.0, so do that cast.
130 if (oflags
& O_CREAT
&& __db_exists(file
, NULL
) != 0)
131 (void)__os_close(__os_open(file
, oflags
, mode
));
132 dbinfop
->re_source
= (char *)file
;
140 if ((ri
= openinfo
) != NULL
) {
143 * We can't support the bfname field.
145 #define BFMSG "DB: DB 1.85's recno bfname field is not supported.\n"
146 if (ri
->bfname
!= NULL
) {
147 (void)__os_write(2, BFMSG
, sizeof(BFMSG
) - 1);
151 if (ri
->flags
& ~(R_FIXEDLEN
| R_NOKEY
| R_SNAPSHOT
))
153 if (ri
->flags
& R_FIXEDLEN
) {
154 dbinfop
->flags
|= DB_FIXEDLEN
;
156 dbinfop
->flags
|= DB_PAD
;
157 dbinfop
->re_pad
= ri
->bval
;
161 dbinfop
->flags
|= DB_DELIMITER
;
162 dbinfop
->re_delim
= ri
->bval
;
167 * We ignore the R_NOKEY flag, but that's okay, it was
168 * only an optimization that was never implemented.
171 if (ri
->flags
& R_SNAPSHOT
)
172 dbinfop
->flags
|= DB_SNAPSHOT
;
174 dbinfop
->db_cachesize
= ri
->cachesize
;
175 dbinfop
->db_pagesize
= ri
->psize
;
176 dbinfop
->db_lorder
= ri
->lorder
;
177 dbinfop
->re_len
= ri
->reclen
;
184 db185p
->close
= db185_close
;
185 db185p
->del
= db185_del
;
186 db185p
->fd
= db185_fd
;
187 db185p
->get
= db185_get
;
188 db185p
->put
= db185_put
;
189 db185p
->seq
= db185_seq
;
190 db185p
->sync
= db185_sync
;
194 * Store the returned pointer to the real DB 2.0 structure in the
195 * internal pointer. Ugly, but we're not going for pretty, here.
197 if ((errno
= db_open(file
,
198 type
, __db_oflags(oflags
), mode
, NULL
, dbinfop
, &dbp
)) != 0) {
203 /* Create the cursor used for sequential ops. */
204 if ((errno
= dbp
->cursor(dbp
, NULL
, &((DB185
*)db185p
)->dbc
)) != 0) {
206 (void)dbp
->close(dbp
, 0);
208 __set_errno(s_errno
);
212 db185p
->internal
= dbp
;
215 einval
: __db_free(db185p
);
219 weak_alias (__dbopen
, dbopen
)
227 dbp
= (DB
*)db185p
->internal
;
229 __set_errno(dbp
->close(dbp
, 0));
233 return (errno
== 0 ? 0 : -1);
237 db185_del(db185p
, key185
, flags
)
239 const DBT185
*key185
;
245 dbp
= (DB
*)db185p
->internal
;
247 memset(&key
, 0, sizeof(key
));
248 key
.data
= key185
->data
;
249 key
.size
= key185
->size
;
251 if (flags
& ~R_CURSOR
)
253 if (flags
& R_CURSOR
)
254 __set_errno(db185p
->dbc
->c_del(db185p
->dbc
, 0));
256 __set_errno(dbp
->del(dbp
, NULL
, &key
, 0));
266 einval
: __set_errno(EINVAL
);
277 dbp
= (DB
*)db185p
->internal
;
279 return ((__set_errno(dbp
->fd(dbp
, &fd
))) == 0 ? fd
: -1);
283 db185_get(db185p
, key185
, data185
, flags
)
285 const DBT185
*key185
;
292 dbp
= (DB
*)db185p
->internal
;
294 memset(&key
, 0, sizeof(key
));
295 key
.data
= key185
->data
;
296 key
.size
= key185
->size
;
297 memset(&data
, 0, sizeof(data
));
298 data
.data
= data185
->data
;
299 data
.size
= data185
->size
;
304 switch (__set_errno(dbp
->get(dbp
, NULL
, &key
, &data
, 0))) {
306 data185
->data
= data
.data
;
307 data185
->size
= data
.size
;
314 einval
: __set_errno(EINVAL
);
319 db185_put(db185p
, key185
, data185
, flags
)
322 const DBT185
*data185
;
330 dbp
= (DB
*)db185p
->internal
;
332 memset(&key
, 0, sizeof(key
));
333 key
.data
= key185
->data
;
334 key
.size
= key185
->size
;
335 memset(&data
, 0, sizeof(data
));
336 data
.data
= data185
->data
;
337 data
.size
= data185
->size
;
341 __set_errno(dbp
->put(dbp
, NULL
, &key
, &data
, 0));
345 db185p
->dbc
->c_put(db185p
->dbc
, &key
, &data
, DB_CURRENT
));
349 if (dbp
->type
!= DB_RECNO
)
352 if ((__set_errno(dbp
->cursor(dbp
, NULL
, &dbcp_put
))) != 0)
355 dbcp_put
->c_get(dbcp_put
, &key
, &data
, DB_SET
))) != 0) {
357 (void)dbcp_put
->c_close(dbcp_put
);
358 __set_errno(s_errno
);
361 memset(&data
, 0, sizeof(data
));
362 data
.data
= data185
->data
;
363 data
.size
= data185
->size
;
364 __set_errno(dbcp_put
->c_put(dbcp_put
,
365 &key
, &data
, flags
== R_IAFTER
? DB_AFTER
: DB_BEFORE
));
367 (void)dbcp_put
->c_close(dbcp_put
);
368 __set_errno(s_errno
);
371 __set_errno(dbp
->put(dbp
, NULL
, &key
, &data
, DB_NOOVERWRITE
));
374 if (dbp
->type
!= DB_BTREE
&& dbp
->type
!= DB_RECNO
)
377 if ((__set_errno(dbp
->put(dbp
, NULL
, &key
, &data
, 0))) != 0)
379 __set_errno(db185p
->dbc
->c_get(db185p
->dbc
,
380 &key
, &data
, DB_SET_RANGE
));
388 key185
->data
= key
.data
;
389 key185
->size
= key
.size
;
396 einval
: __set_errno(EINVAL
);
401 db185_seq(db185p
, key185
, data185
, flags
)
403 DBT185
*key185
, *data185
;
409 dbp
= (DB
*)db185p
->internal
;
411 memset(&key
, 0, sizeof(key
));
412 key
.data
= key185
->data
;
413 key
.size
= key185
->size
;
414 memset(&data
, 0, sizeof(data
));
415 data
.data
= data185
->data
;
416 data
.size
= data185
->size
;
420 flags
= DB_SET_RANGE
;
426 if (dbp
->type
!= DB_BTREE
&& dbp
->type
!= DB_RECNO
)
434 if (dbp
->type
!= DB_BTREE
&& dbp
->type
!= DB_RECNO
)
441 switch (__set_errno(db185p
->dbc
->c_get(db185p
->dbc
,
442 &key
, &data
, flags
))) {
444 key185
->data
= key
.data
;
445 key185
->size
= key
.size
;
446 data185
->data
= data
.data
;
447 data185
->size
= data
.size
;
454 einval
: __set_errno(EINVAL
);
459 db185_sync(db185p
, flags
)
465 dbp
= (DB
*)db185p
->internal
;
473 * We can't support the R_RECNOSYNC flag.
475 #define RSMSG "DB: DB 1.85's R_RECNOSYNC sync flag is not supported.\n"
476 (void)__os_write(2, RSMSG
, sizeof(RSMSG
) - 1);
482 return ((__set_errno(dbp
->sync(dbp
, 0))) == 0 ? 0 : -1);
484 einval
: __set_errno(EINVAL
);