00001
00002
00003
00004
00005
00006
00007
00008 #include "config.h"
00009
00010 #ifndef lint
00011 static const char revid[] = "$Id: db__iface_8c-source.html,v 1.1 2008/06/08 10:17:40 sebdiaz Exp $";
00012 #endif
00013
00014 #ifndef NO_SYSTEM_INCLUDES
00015 #include <sys/types.h>
00016
00017 #include <errno.h>
00018 #endif
00019
00020 #include "db_int.h"
00021 #include "db_page.h"
00022 #include "db_am.h"
00023 #include "btree.h"
00024
00025 static int __db_curinval __P((const DB_ENV *));
00026 static int __db_rdonly __P((const DB_ENV *, const char *));
00027 static int __dbt_ferr __P((const DB *, const char *, const DBT *, int));
00028
00029
00030
00031
00032
00033
00034
00035 int
00036 CDB___db_cursorchk(dbp, flags, isrdonly)
00037 const DB *dbp;
00038 u_int32_t flags;
00039 int isrdonly;
00040 {
00041
00042 switch (flags) {
00043 case 0:
00044 break;
00045 case DB_WRITECURSOR:
00046 if (isrdonly)
00047 return (__db_rdonly(dbp->dbenv, "DB->cursor"));
00048 if (!LOCKING(dbp->dbenv))
00049 return (CDB___db_ferr(dbp->dbenv, "DB->cursor", 0));
00050 break;
00051 case DB_WRITELOCK:
00052 if (isrdonly)
00053 return (__db_rdonly(dbp->dbenv, "DB->cursor"));
00054 break;
00055 default:
00056 return (CDB___db_ferr(dbp->dbenv, "DB->cursor", 0));
00057 }
00058
00059 return (0);
00060 }
00061
00062
00063
00064
00065
00066
00067
00068 int
00069 CDB___db_ccountchk(dbp, flags, isvalid)
00070 const DB *dbp;
00071 u_int32_t flags;
00072 int isvalid;
00073 {
00074
00075 switch (flags) {
00076 case 0:
00077 break;
00078 default:
00079 return (CDB___db_ferr(dbp->dbenv, "DBcursor->c_count", 0));
00080 }
00081
00082
00083
00084
00085
00086 return (isvalid ? 0 : __db_curinval(dbp->dbenv));
00087 }
00088
00089
00090
00091
00092
00093
00094
00095 int
00096 CDB___db_cdelchk(dbp, flags, isrdonly, isvalid)
00097 const DB *dbp;
00098 u_int32_t flags;
00099 int isrdonly, isvalid;
00100 {
00101
00102 if (isrdonly)
00103 return (__db_rdonly(dbp->dbenv, "c_del"));
00104
00105
00106 switch (flags) {
00107 case 0:
00108 break;
00109 default:
00110 return (CDB___db_ferr(dbp->dbenv, "DBcursor->c_del", 0));
00111 }
00112
00113
00114
00115
00116
00117 return (isvalid ? 0 : __db_curinval(dbp->dbenv));
00118 }
00119
00120
00121
00122
00123
00124
00125
00126 int
00127 CDB___db_cgetchk(dbp, key, data, flags, isvalid)
00128 const DB *dbp;
00129 DBT *key, *data;
00130 u_int32_t flags;
00131 int isvalid;
00132 {
00133 int key_einval, ret;
00134
00135 key_einval = 0;
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 if (LF_ISSET(DB_RMW)) {
00146 if (!LOCKING_ON(dbp->dbenv)) {
00147 CDB___db_err(dbp->dbenv,
00148 "the DB_RMW flag requires locking");
00149 return (EINVAL);
00150 }
00151 LF_CLR(DB_RMW);
00152 }
00153
00154
00155 switch (flags) {
00156 case DB_CONSUME:
00157 if (dbp->type != DB_QUEUE)
00158 goto err;
00159 break;
00160 case DB_CURRENT:
00161 case DB_FIRST:
00162 case DB_LAST:
00163 case DB_NEXT:
00164 case DB_NEXT_DUP:
00165 case DB_NEXT_NODUP:
00166 case DB_PREV:
00167 case DB_PREV_NODUP:
00168 break;
00169 case DB_GET_BOTHC:
00170 if (dbp->type == DB_QUEUE)
00171 goto err;
00172
00173 case DB_GET_BOTH:
00174 case DB_SET:
00175 case DB_SET_RANGE:
00176 key_einval = 1;
00177 break;
00178 case DB_GET_RECNO:
00179 if (!F_ISSET(dbp, DB_BT_RECNUM))
00180 goto err;
00181 break;
00182 case DB_SET_RECNO:
00183 if (!F_ISSET(dbp, DB_BT_RECNUM))
00184 goto err;
00185 key_einval = 1;
00186 break;
00187 default:
00188 err: return (CDB___db_ferr(dbp->dbenv, "DBcursor->c_get", 0));
00189 }
00190
00191
00192 if ((ret = __dbt_ferr(dbp, "key", key, 0)) != 0)
00193 return (ret);
00194 if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0)
00195 return (ret);
00196
00197
00198
00199
00200
00201 if (isvalid || (flags != DB_CURRENT && flags != DB_NEXT_DUP))
00202 return (0);
00203
00204 return(__db_curinval(dbp->dbenv));
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214 int
00215 CDB___db_cputchk(dbp, key, data, flags, isrdonly, isvalid)
00216 const DB *dbp;
00217 const DBT *key;
00218 DBT *data;
00219 u_int32_t flags;
00220 int isrdonly, isvalid;
00221 {
00222 int key_einval, key_flags, ret;
00223
00224 key_einval = key_flags = 0;
00225
00226
00227 if (isrdonly)
00228 return (__db_rdonly(dbp->dbenv, "c_put"));
00229
00230
00231 switch (flags) {
00232 case DB_AFTER:
00233 case DB_BEFORE:
00234 switch (dbp->type) {
00235 case DB_BTREE:
00236 case DB_HASH:
00237 if (!F_ISSET(dbp, DB_AM_DUP))
00238 goto err;
00239 if (dbp->dup_compare != NULL)
00240 goto err;
00241 break;
00242 case DB_QUEUE:
00243 goto err;
00244 case DB_RECNO:
00245 if (!F_ISSET(dbp, DB_RE_RENUMBER))
00246 goto err;
00247 key_flags = 1;
00248 break;
00249 default:
00250 goto err;
00251 }
00252 break;
00253 case DB_CURRENT:
00254
00255
00256
00257
00258
00259 break;
00260 case DB_NODUPDATA:
00261 if (!F_ISSET(dbp, DB_AM_DUPSORT))
00262 goto err;
00263
00264 case DB_KEYFIRST:
00265 case DB_KEYLAST:
00266 if (dbp->type == DB_QUEUE || dbp->type == DB_RECNO)
00267 goto err;
00268 key_einval = key_flags = 1;
00269 break;
00270 default:
00271 err: return (CDB___db_ferr(dbp->dbenv, "DBcursor->c_put", 0));
00272 }
00273
00274
00275 if (key_flags && (ret = __dbt_ferr(dbp, "key", key, 0)) != 0)
00276 return (ret);
00277 if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0)
00278 return (ret);
00279
00280
00281
00282
00283
00284 if (isvalid || flags == DB_KEYFIRST ||
00285 flags == DB_KEYLAST || flags == DB_NODUPDATA)
00286 return (0);
00287
00288 return (__db_curinval(dbp->dbenv));
00289 }
00290
00291
00292
00293
00294
00295
00296
00297 int
00298 CDB___db_closechk(dbp, flags)
00299 const DB *dbp;
00300 u_int32_t flags;
00301 {
00302
00303 switch (flags) {
00304 case 0:
00305 case DB_NOSYNC:
00306 break;
00307 default:
00308 return (CDB___db_ferr(dbp->dbenv, "DB->close", 0));
00309 }
00310
00311 return (0);
00312 }
00313
00314
00315
00316
00317
00318
00319
00320 int
00321 CDB___db_delchk(dbp, key, flags, isrdonly)
00322 const DB *dbp;
00323 DBT *key;
00324 u_int32_t flags;
00325 int isrdonly;
00326 {
00327 COMPQUIET(key, NULL);
00328
00329
00330 if (isrdonly)
00331 return (__db_rdonly(dbp->dbenv, "delete"));
00332
00333
00334 switch (flags) {
00335 case 0:
00336 break;
00337 default:
00338 return (CDB___db_ferr(dbp->dbenv, "DB->del", 0));
00339 }
00340
00341 return (0);
00342 }
00343
00344
00345
00346
00347
00348
00349
00350 int
00351 CDB___db_getchk(dbp, key, data, flags)
00352 const DB *dbp;
00353 const DBT *key;
00354 DBT *data;
00355 u_int32_t flags;
00356 {
00357 int ret;
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 if (LF_ISSET(DB_RMW)) {
00368 if (!LOCKING_ON(dbp->dbenv)) {
00369 CDB___db_err(dbp->dbenv,
00370 "the DB_RMW flag requires locking");
00371 return (EINVAL);
00372 }
00373 LF_CLR(DB_RMW);
00374 }
00375
00376
00377 switch (flags) {
00378 case 0:
00379 case DB_GET_BOTH:
00380 break;
00381 case DB_SET_RECNO:
00382 if (!F_ISSET(dbp, DB_BT_RECNUM))
00383 goto err;
00384 break;
00385 default:
00386 err: return (CDB___db_ferr(dbp->dbenv, "DB->get", 0));
00387 }
00388
00389
00390 if ((ret = __dbt_ferr(dbp, "key", key, flags == DB_SET_RECNO)) != 0)
00391 return (ret);
00392 if ((ret = __dbt_ferr(dbp, "data", data, 1)) != 0)
00393 return (ret);
00394
00395 return (0);
00396 }
00397
00398
00399
00400
00401
00402
00403
00404 int
00405 CDB___db_joinchk(dbp, flags)
00406 const DB *dbp;
00407 u_int32_t flags;
00408 {
00409 switch (flags) {
00410 case 0:
00411 case DB_JOIN_NOSORT:
00412 break;
00413 default:
00414 return (CDB___db_ferr(dbp->dbenv, "DB->join", 0));
00415 }
00416
00417 return (0);
00418 }
00419
00420
00421
00422
00423
00424
00425
00426 int
00427 CDB___db_joingetchk(dbp, key, flags)
00428 const DB *dbp;
00429 DBT *key;
00430 u_int32_t flags;
00431 {
00432
00433 if (LF_ISSET(DB_RMW)) {
00434 if (!LOCKING_ON(dbp->dbenv)) {
00435 CDB___db_err(dbp->dbenv,
00436 "the DB_RMW flag requires locking");
00437 return (EINVAL);
00438 }
00439 LF_CLR(DB_RMW);
00440 }
00441
00442 switch (flags) {
00443 case 0:
00444 case DB_JOIN_ITEM:
00445 break;
00446 default:
00447 return (CDB___db_ferr(dbp->dbenv, "DBcursor->c_get", 0));
00448 }
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 if (F_ISSET(key, DB_DBT_PARTIAL)) {
00462 CDB___db_err(dbp->dbenv,
00463 "DB_DBT_PARTIAL may not be set on key during join_get");
00464 return (EINVAL);
00465 }
00466
00467 return (0);
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477 int
00478 CDB___db_putchk(dbp, key, data, flags, isrdonly, isdup)
00479 const DB *dbp;
00480 DBT *key;
00481 const DBT *data;
00482 u_int32_t flags;
00483 int isrdonly, isdup;
00484 {
00485 int key_einval, key_flags, ret;
00486
00487 key_einval = key_flags = 0;
00488
00489
00490 if (isrdonly)
00491 return (__db_rdonly(dbp->dbenv, "put"));
00492
00493
00494 switch (flags) {
00495 case 0:
00496 case DB_NOOVERWRITE:
00497 key_einval = key_flags = 1;
00498 break;
00499 case DB_APPEND:
00500 if (dbp->type != DB_RECNO && dbp->type != DB_QUEUE)
00501 goto err;
00502 key_flags = 1;
00503 break;
00504 case DB_NODUPDATA:
00505 if (F_ISSET(dbp, DB_AM_DUPSORT))
00506 break;
00507
00508 default:
00509 err: return (CDB___db_ferr(dbp->dbenv, "DB->put", 0));
00510 }
00511
00512
00513 if (key_flags && (ret = __dbt_ferr(dbp, "key", key, 0)) != 0)
00514 return (ret);
00515 if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0)
00516 return (ret);
00517
00518
00519 if (isdup && F_ISSET(data, DB_DBT_PARTIAL)) {
00520 CDB___db_err(dbp->dbenv,
00521 "a partial put in the presence of duplicates requires a cursor operation");
00522 return (EINVAL);
00523 }
00524
00525 return (0);
00526 }
00527
00528
00529
00530
00531
00532
00533
00534 int
00535 CDB___db_removechk(dbp, flags)
00536 const DB *dbp;
00537 u_int32_t flags;
00538 {
00539
00540 switch (flags) {
00541 case 0:
00542 break;
00543 default:
00544 return (CDB___db_ferr(dbp->dbenv, "DB->remove", 0));
00545 }
00546
00547 return (0);
00548 }
00549
00550
00551
00552
00553
00554
00555
00556 int
00557 CDB___db_statchk(dbp, flags)
00558 const DB *dbp;
00559 u_int32_t flags;
00560 {
00561
00562 switch (flags) {
00563 case 0:
00564 case DB_CACHED_COUNTS:
00565 break;
00566 case DB_RECORDCOUNT:
00567 if (dbp->type == DB_RECNO)
00568 break;
00569 if (dbp->type == DB_BTREE && F_ISSET(dbp, DB_BT_RECNUM))
00570 break;
00571 goto err;
00572 default:
00573 err: return (CDB___db_ferr(dbp->dbenv, "DB->stat", 0));
00574 }
00575
00576 return (0);
00577 }
00578
00579
00580
00581
00582
00583
00584
00585 int
00586 CDB___db_syncchk(dbp, flags)
00587 const DB *dbp;
00588 u_int32_t flags;
00589 {
00590
00591 switch (flags) {
00592 case 0:
00593 break;
00594 default:
00595 return (CDB___db_ferr(dbp->dbenv, "DB->sync", 0));
00596 }
00597
00598 return (0);
00599 }
00600
00601
00602
00603
00604
00605 static int
00606 __dbt_ferr(dbp, name, dbt, check_thread)
00607 const DB *dbp;
00608 const char *name;
00609 const DBT *dbt;
00610 int check_thread;
00611 {
00612 DB_ENV *dbenv;
00613 int ret;
00614
00615 dbenv = dbp->dbenv;
00616
00617
00618
00619
00620
00621
00622
00623
00624 if ((ret = CDB___db_fchk(dbenv, name, dbt->flags,
00625 DB_DBT_MALLOC | DB_DBT_DUPOK |
00626 DB_DBT_REALLOC | DB_DBT_USERMEM | DB_DBT_PARTIAL)) != 0)
00627 return (ret);
00628 switch (F_ISSET(dbt, DB_DBT_MALLOC | DB_DBT_REALLOC | DB_DBT_USERMEM)) {
00629 case 0:
00630 case DB_DBT_MALLOC:
00631 case DB_DBT_REALLOC:
00632 case DB_DBT_USERMEM:
00633 break;
00634 default:
00635 return (CDB___db_ferr(dbenv, name, 1));
00636 }
00637
00638 if (check_thread && DB_IS_THREADED(dbp) &&
00639 !F_ISSET(dbt, DB_DBT_MALLOC | DB_DBT_REALLOC | DB_DBT_USERMEM)) {
00640 CDB___db_err(dbenv,
00641 "DB_THREAD mandates memory allocation flag on DBT %s",
00642 name);
00643 return (EINVAL);
00644 }
00645 return (0);
00646 }
00647
00648
00649
00650
00651
00652 static int
00653 __db_rdonly(dbenv, name)
00654 const DB_ENV *dbenv;
00655 const char *name;
00656 {
00657 CDB___db_err(dbenv, "%s: attempt to modify a read-only tree", name);
00658 return (EACCES);
00659 }
00660
00661
00662
00663
00664
00665 static int
00666 __db_curinval(dbenv)
00667 const DB_ENV *dbenv;
00668 {
00669 CDB___db_err(dbenv,
00670 "Cursor position must be set before performing this operation");
00671 return (EINVAL);
00672 }