summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2000-04-25 01:17:45 +0000
committerAndrew Tridgell <tridge@samba.org>2000-04-25 01:17:45 +0000
commitdce954d275977d14326249e07e20d988ad1d91f4 (patch)
tree6dcd1c596683f4298a75e7a102af171b8b83bbbf
parent59c8a608c2c6fa5fc1d342787cf28d5e00075664 (diff)
downloadsamba-dce954d275977d14326249e07e20d988ad1d91f4.tar.gz
samba-dce954d275977d14326249e07e20d988ad1d91f4.tar.bz2
samba-dce954d275977d14326249e07e20d988ad1d91f4.zip
added TDB_MODIFY flag - patch from from luke
(This used to be commit 90b574296e06cd6ed4fedc1e5a8ae412a5e78b45)
-rw-r--r--source3/tdb/README3
-rw-r--r--source3/tdb/tdb.c29
-rw-r--r--source3/tdb/tdb.h3
3 files changed, 30 insertions, 5 deletions
diff --git a/source3/tdb/README b/source3/tdb/README
index 9eef521075..96fdcf5c99 100644
--- a/source3/tdb/README
+++ b/source3/tdb/README
@@ -137,6 +137,9 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag);
store an element in the database, replacing any existing element
with the same key
+ If flag==TDB_INSERT then don't overwrite an existing entry
+ If flag==TDB_MODIFY then don't create a new entry
+
return 0 on success, -1 on failure
----------------------------------------------------------------------
diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c
index 5f30db21e4..3b85b71217 100644
--- a/source3/tdb/tdb.c
+++ b/source3/tdb/tdb.c
@@ -2,7 +2,8 @@
Unix SMB/Netbios implementation.
Version 3.0
Samba database functions
- Copyright (C) Andrew Tridgell 1999
+ Copyright (C) Andrew Tridgell 1999-2000
+ Copyright (C) Luke Kenneth Casson Leighton 2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -600,6 +601,7 @@ char *tdb_error(TDB_CONTEXT *tdb)
{TDB_ERR_LOCK, "Locking error"},
{TDB_ERR_OOM, "Out of memory"},
{TDB_ERR_EXISTS, "Record exists"},
+ {TDB_ERR_NOEXIST, "Record does not exist"},
{-1, NULL}};
if (tdb != NULL) {
for (i=0;emap[i].estring;i++) {
@@ -630,14 +632,19 @@ int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf)
return -1;
}
+ /* initialise error code to ok, first */
+ tdb->ecode = 0;
+
/* find which hash bucket it is in */
hash = tdb_hash(&key);
tdb_lock(tdb, BUCKET(hash));
rec_ptr = tdb_find(tdb, key, hash, &rec);
- if (!rec_ptr)
+ if (!rec_ptr) {
+ tdb->ecode = TDB_ERR_NOEXIST;
goto out;
+ }
/* must be long enough */
if (rec.rec_len < key.dsize + dbuf.dsize)
@@ -1025,17 +1032,31 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
/* find which hash bucket it is in */
hash = tdb_hash(&key);
- /* check for it existing */
+ /* check for it existing, on insert. */
if (flag == TDB_INSERT && tdb_exists(tdb, key)) {
tdb->ecode = TDB_ERR_EXISTS;
return -1;
}
- /* first try in-place update */
+ /* first try in-place update, on modify or replace. */
if (flag != TDB_INSERT && tdb_update(tdb, key, dbuf) == 0) {
return 0;
}
+ /* check for it _not_ existing, from error code of the update. */
+ if (flag == TDB_MODIFY && tdb->ecode == TDB_ERR_NOEXIST) {
+ return -1;
+ }
+
+ /* reset the error code potentially set by the tdb_update() */
+ tdb->ecode = 0;
+
+ /*
+ * now we're into insert / modify / replace of a record
+ * which we know could not be optimised by an in-place
+ * store (for various reasons).
+ */
+
rec_ptr = tdb_allocate(tdb, key.dsize + dbuf.dsize);
if (rec_ptr == 0) {
return -1;
diff --git a/source3/tdb/tdb.h b/source3/tdb/tdb.h
index 949a843e8a..90a1cccfac 100644
--- a/source3/tdb/tdb.h
+++ b/source3/tdb/tdb.h
@@ -51,13 +51,14 @@ typedef struct {
/* flags to tdb_store() */
#define TDB_REPLACE 1
#define TDB_INSERT 2
+#define TDB_MODIFY 3
/* flags for tdb_open() */
#define TDB_CLEAR_IF_FIRST 1
/* error codes */
enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK,
- TDB_ERR_OOM, TDB_ERR_EXISTS};
+ TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOEXIST };
typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *);