📄 db_iface.c
字号:
if (IS_READONLY(dbp)) return (__db_rdonly(dbp->dbenv, "delete")); /* Check for invalid function flags. */ LF_CLR(DB_AUTO_COMMIT); switch (flags) { case 0: break; default: return (__db_ferr(dbp->dbenv, "DB->del", 0)); } return (0);}/* * __db_getchk -- * Common get argument checking routine. * * PUBLIC: int __db_getchk __P((const DB *, const DBT *, DBT *, u_int32_t)); */int__db_getchk(dbp, key, data, flags) const DB *dbp; const DBT *key; DBT *data; u_int32_t flags;{ int dirty, multi, ret; /* * Check for read-modify-write validity. DB_RMW doesn't make sense * with CDB cursors since if you're going to write the cursor, you * had to create it with DB_WRITECURSOR. Regardless, we check for * LOCKING_ON and not STD_LOCKING, as we don't want to disallow it. * If this changes, confirm that DB does not itself set the DB_RMW * flag in a path where CDB may have been configured. */ dirty = 0; if (LF_ISSET(DB_DIRTY_READ | DB_RMW)) { if (!LOCKING_ON(dbp->dbenv)) return (__db_fnl(dbp->dbenv, "DB->get")); if (LF_ISSET(DB_DIRTY_READ)) dirty = 1; LF_CLR(DB_DIRTY_READ | DB_RMW); } multi = 0; if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) { if (LF_ISSET(DB_MULTIPLE_KEY)) goto multi_err; multi = LF_ISSET(DB_MULTIPLE) ? 1 : 0; LF_CLR(DB_MULTIPLE); } /* Check for invalid function flags. */ switch (flags) { case 0: case DB_GET_BOTH: break; case DB_SET_RECNO: if (!F_ISSET(dbp, DB_AM_RECNUM)) goto err; break; case DB_CONSUME: case DB_CONSUME_WAIT: if (dirty) { __db_err(dbp->dbenv, "DB_DIRTY_READ is not supported with DB_CONSUME or DB_CONSUME_WAIT"); return (EINVAL); } if (multi)multi_err: return (__db_ferr(dbp->dbenv, "DB->get", 1)); if (dbp->type == DB_QUEUE) break; /* FALLTHROUGH */ default:err: return (__db_ferr(dbp->dbenv, "DB->get", 0)); } /* * Check for invalid key/data flags. * * XXX: Dave Krinsky * Remember to modify this when we fix the flag-returning problem. */ if ((ret = __dbt_ferr(dbp, "key", key, flags == DB_SET_RECNO)) != 0) return (ret); if ((ret = __dbt_ferr(dbp, "data", data, 1)) != 0) return (ret); if (multi && !F_ISSET(data, DB_DBT_USERMEM)) { __db_err(dbp->dbenv, "DB_MULTIPLE requires that DB_DBT_USERMEM be set"); return (EINVAL); } if (multi && (F_ISSET(key, DB_DBT_PARTIAL) || F_ISSET(data, DB_DBT_PARTIAL))) { __db_err(dbp->dbenv, "DB_DBT_PARTIAL forbidden with DB_MULTIPLE(_KEY)"); return (EINVAL); } return (0);}/* * __db_joinchk -- * Common join argument checking routine. * * PUBLIC: int __db_joinchk __P((const DB *, DBC * const *, u_int32_t)); */int__db_joinchk(dbp, curslist, flags) const DB *dbp; DBC * const *curslist; u_int32_t flags;{ DB_TXN *txn; int i; switch (flags) { case 0: case DB_JOIN_NOSORT: break; default: return (__db_ferr(dbp->dbenv, "DB->join", 0)); } if (curslist == NULL || curslist[0] == NULL) { __db_err(dbp->dbenv, "At least one secondary cursor must be specified to DB->join"); return (EINVAL); } txn = curslist[0]->txn; for (i = 1; curslist[i] != NULL; i++) if (curslist[i]->txn != txn) { __db_err(dbp->dbenv, "All secondary cursors must share the same transaction"); return (EINVAL); } return (0);}/* * __db_joingetchk -- * Common join_get argument checking routine. * * PUBLIC: int __db_joingetchk __P((const DB *, DBT *, u_int32_t)); */int__db_joingetchk(dbp, key, flags) const DB *dbp; DBT *key; u_int32_t flags;{ if (LF_ISSET(DB_DIRTY_READ | DB_RMW)) { if (!LOCKING_ON(dbp->dbenv)) return (__db_fnl(dbp->dbenv, "DBcursor->c_get")); LF_CLR(DB_DIRTY_READ | DB_RMW); } switch (flags) { case 0: case DB_JOIN_ITEM: break; default: return (__db_ferr(dbp->dbenv, "DBcursor->c_get", 0)); } /* * A partial get of the key of a join cursor don't make much sense; * the entire key is necessary to query the primary database * and find the datum, and so regardless of the size of the key * it would not be a performance improvement. Since it would require * special handling, we simply disallow it. * * A partial get of the data, however, potentially makes sense (if * all possible data are a predictable large structure, for instance) * and causes us no headaches, so we permit it. */ if (F_ISSET(key, DB_DBT_PARTIAL)) { __db_err(dbp->dbenv, "DB_DBT_PARTIAL may not be set on key during join_get"); return (EINVAL); } return (0);}/* * __db_putchk -- * Common put argument checking routine. * * PUBLIC: int __db_putchk * PUBLIC: __P((const DB *, DBT *, const DBT *, u_int32_t, int)); */int__db_putchk(dbp, key, data, flags, isdup) const DB *dbp; DBT *key; const DBT *data; u_int32_t flags; int isdup;{ int ret, returnkey; returnkey = 0; /* Check for changes to a read-only tree. */ if (IS_READONLY(dbp)) return (__db_rdonly(dbp->dbenv, "put")); /* Check for puts on a secondary. */ if (F_ISSET(dbp, DB_AM_SECONDARY)) { __db_err(dbp->dbenv, "DB->put forbidden on secondary indices"); return (EINVAL); } /* Check for invalid function flags. */ LF_CLR(DB_AUTO_COMMIT); switch (flags) { case 0: case DB_NOOVERWRITE: break; case DB_APPEND: if (dbp->type != DB_RECNO && dbp->type != DB_QUEUE) goto err; returnkey = 1; break; case DB_NODUPDATA: if (F_ISSET(dbp, DB_AM_DUPSORT)) break; /* FALLTHROUGH */ default:err: return (__db_ferr(dbp->dbenv, "DB->put", 0)); } /* Check for invalid key/data flags. */ if ((ret = __dbt_ferr(dbp, "key", key, returnkey)) != 0) return (ret); if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0) return (ret); /* Check for partial puts in the presence of duplicates. */ if (isdup && F_ISSET(data, DB_DBT_PARTIAL)) { __db_err(dbp->dbenv,"a partial put in the presence of duplicates requires a cursor operation"); return (EINVAL); } return (0);}/* * __db_statchk -- * Common stat argument checking routine. * * PUBLIC: int __db_statchk __P((const DB *, u_int32_t)); */int__db_statchk(dbp, flags) const DB *dbp; u_int32_t flags;{ /* Check for invalid function flags. */ switch (flags) { case 0: case DB_FAST_STAT: case DB_CACHED_COUNTS: /* Deprecated and undocumented. */ break; case DB_RECORDCOUNT: /* Deprecated and undocumented. */ if (dbp->type == DB_RECNO) break; if (dbp->type == DB_BTREE && F_ISSET(dbp, DB_AM_RECNUM)) break; goto err; default:err: return (__db_ferr(dbp->dbenv, "DB->stat", 0)); } return (0);}/* * __db_syncchk -- * Common sync argument checking routine. * * PUBLIC: int __db_syncchk __P((const DB *, u_int32_t)); */int__db_syncchk(dbp, flags) const DB *dbp; u_int32_t flags;{ /* Check for invalid function flags. */ switch (flags) { case 0: break; default: return (__db_ferr(dbp->dbenv, "DB->sync", 0)); } return (0);}/* * __dbt_ferr -- * Check a DBT for flag errors. */static int__dbt_ferr(dbp, name, dbt, check_thread) const DB *dbp; const char *name; const DBT *dbt; int check_thread;{ DB_ENV *dbenv; int ret; dbenv = dbp->dbenv; /* * Check for invalid DBT flags. We allow any of the flags to be * specified to any DB or DBcursor call so that applications can * set DB_DBT_MALLOC when retrieving a data item from a secondary * database and then specify that same DBT as a key to a primary * database, without having to clear flags. */ if ((ret = __db_fchk(dbenv, name, dbt->flags, DB_DBT_APPMALLOC | DB_DBT_MALLOC | DB_DBT_DUPOK | DB_DBT_REALLOC | DB_DBT_USERMEM | DB_DBT_PARTIAL)) != 0) return (ret); switch (F_ISSET(dbt, DB_DBT_MALLOC | DB_DBT_REALLOC | DB_DBT_USERMEM)) { case 0: case DB_DBT_MALLOC: case DB_DBT_REALLOC: case DB_DBT_USERMEM: break; default: return (__db_ferr(dbenv, name, 1)); } if (check_thread && DB_IS_THREADED(dbp) && !F_ISSET(dbt, DB_DBT_MALLOC | DB_DBT_REALLOC | DB_DBT_USERMEM)) { __db_err(dbenv, "DB_THREAD mandates memory allocation flag on DBT %s", name); return (EINVAL); } return (0);}/* * __db_rdonly -- * Common readonly message. */static int__db_rdonly(dbenv, name) const DB_ENV *dbenv; const char *name;{ __db_err(dbenv, "%s: attempt to modify a read-only tree", name); return (EACCES);}/* * __db_fnl -- * Common flag-needs-locking message. */static int__db_fnl(dbenv, name) const DB_ENV *dbenv; const char *name;{ __db_err(dbenv, "%s: the DB_DIRTY_READ and DB_RMW flags require locking", name); return (EINVAL);}/* * __db_curinval * Report that a cursor is in an invalid state. */static int__db_curinval(dbenv) const DB_ENV *dbenv;{ __db_err(dbenv, "Cursor position must be set before performing this operation"); return (EINVAL);}/* * __db_secondary_corrupt -- * Report that a secondary index appears corrupt, as it has a record * that does not correspond to a record in the primary. * * PUBLIC: int __db_secondary_corrupt __P((DB *)); */int__db_secondary_corrupt(dbp) DB *dbp;{ __db_err(dbp->dbenv, "Secondary index corrupt: item in secondary not found in primary"); return (DB_SECONDARY_BAD);}/* * __db_associatechk -- * Argument checking routine for DB->associate(). * * PUBLIC: int __db_associatechk __P((DB *, DB *, * PUBLIC: int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t)); */int__db_associatechk(dbp, sdbp, callback, flags) DB *dbp, *sdbp; int (*callback) __P((DB *, const DBT *, const DBT *, DBT *)); u_int32_t flags;{ DB_ENV *dbenv; dbenv = dbp->dbenv; if (F_ISSET(sdbp, DB_AM_SECONDARY)) { __db_err(dbenv, "Secondary index handles may not be re-associated"); return (EINVAL); } if (F_ISSET(dbp, DB_AM_SECONDARY)) { __db_err(dbenv, "Secondary indices may not be used as primary databases"); return (EINVAL); } if (F_ISSET(dbp, DB_AM_DUP)) { __db_err(dbenv, "Primary databases may not be configured with duplicates"); return (EINVAL); } if (F_ISSET(dbp, DB_AM_RENUMBER)) { __db_err(dbenv, "Renumbering recno databases may not be used as primary databases"); return (EINVAL); } if (callback == NULL && (!F_ISSET(dbp, DB_AM_RDONLY) || !F_ISSET(sdbp, DB_AM_RDONLY))) { __db_err(dbenv, "Callback function may be NULL only when database handles are read-only"); return (EINVAL); } return (__db_fchk(dbenv, "DB->associate", flags, DB_CREATE | DB_AUTO_COMMIT));}/* * __db_txn_auto -- * Handle DB_AUTO_COMMIT initialization. * * PUBLIC: int __db_txn_auto __P((DB *, DB_TXN **)); */int__db_txn_auto(dbp, txnidp) DB *dbp; DB_TXN **txnidp;{ DB_ENV *dbenv; dbenv = dbp->dbenv; if (*txnidp != NULL) { __db_err(dbenv, "DB_AUTO_COMMIT may not be specified along with a transaction handle"); return (EINVAL); } if (!TXN_ON(dbenv)) { __db_err(dbenv, "DB_AUTO_COMMIT may not be specified in non-transactional environment"); return (EINVAL); } return (dbenv->txn_begin(dbenv, NULL, txnidp, 0));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -