s3-talloc Change TALLOC_ZERO_P() to talloc_zero()
[nivanova/samba-autobuild/.git] / source3 / lib / dbwrap_tdb.c
index 83a0d111aa7926fd0e77cb6393788e77a8fc5f36..f8baa0aeca8ff6a67c407c1ad72626fcb25386b7 100644 (file)
@@ -18,6 +18,8 @@
 */
 
 #include "includes.h"
+#include "dbwrap.h"
+#include "lib/util/tdb_wrap.h"
 
 struct db_tdb_ctx {
        struct tdb_wrap *wtdb;
@@ -31,9 +33,14 @@ static int db_tdb_record_destr(struct db_record* data)
        struct db_tdb_ctx *ctx =
                talloc_get_type_abort(data->private_data, struct db_tdb_ctx);
 
+       /* This hex_encode_talloc() call allocates memory on data context. By way how current 
+          __talloc_free() code works, it is OK to allocate in the destructor as 
+          the children of data will be freed after call to the destructor and this 
+          new 'child' will be caught and freed correctly.
+        */
        DEBUG(10, (DEBUGLEVEL > 10
                   ? "Unlocking key %s\n" : "Unlocking key %.20s\n",
-                  hex_encode(data, (unsigned char *)data->key.dptr,
+                  hex_encode_talloc(data, (unsigned char *)data->key.dptr,
                              data->key.dsize)));
 
        if (tdb_chainunlock(ctx->wtdb->tdb, data->key) != 0) {
@@ -86,10 +93,10 @@ static struct db_record *db_tdb_fetch_locked(struct db_context *db,
        struct db_tdb_ctx *ctx = talloc_get_type_abort(db->private_data,
                                                       struct db_tdb_ctx);
        struct tdb_fetch_locked_state state;
-       int res;
 
-       if (DEBUGLEVEL >= 10) {
-               char *keystr = hex_encode(NULL, key.dptr, key.dsize);
+       /* Do not accidently allocate/deallocate w/o need when debug level is lower than needed */
+       if(DEBUGLEVEL >= 10) {
+               char *keystr = hex_encode_talloc(talloc_tos(), (unsigned char*)key.dptr, key.dsize);
                DEBUG(10, (DEBUGLEVEL > 10
                           ? "Locking key %s\n" : "Locking key %.20s\n",
                           keystr));
@@ -104,8 +111,7 @@ static struct db_record *db_tdb_fetch_locked(struct db_context *db,
        state.mem_ctx = mem_ctx;
        state.result = NULL;
 
-       res = tdb_parse_record(ctx->wtdb->tdb, key, db_tdb_fetchlock_parse,
-                              &state);
+       tdb_parse_record(ctx->wtdb->tdb, key, db_tdb_fetchlock_parse, &state);
 
        if (state.result == NULL) {
                db_tdb_fetchlock_parse(key, tdb_null, &state);
@@ -160,8 +166,7 @@ static int db_tdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
 
        state.mem_ctx = mem_ctx;
        state.result = 0;
-       state.data.dptr = NULL;
-       state.data.dsize = 0;
+       state.data = tdb_null;
 
        tdb_parse_record(ctx->wtdb->tdb, key, db_tdb_fetch_parse, &state);
 
@@ -173,6 +178,17 @@ static int db_tdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
        return 0;
 }
 
+static int db_tdb_parse(struct db_context *db, TDB_DATA key,
+                       int (*parser)(TDB_DATA key, TDB_DATA data,
+                                     void *private_data),
+                       void *private_data)
+{
+       struct db_tdb_ctx *ctx = talloc_get_type_abort(
+               db->private_data, struct db_tdb_ctx);
+
+       return tdb_parse_record(ctx->wtdb->tdb, key, parser, private_data);
+}
+
 static NTSTATUS db_tdb_store(struct db_record *rec, TDB_DATA data, int flag)
 {
        struct db_tdb_ctx *ctx = talloc_get_type_abort(rec->private_data,
@@ -192,15 +208,16 @@ static NTSTATUS db_tdb_delete(struct db_record *rec)
 {
        struct db_tdb_ctx *ctx = talloc_get_type_abort(rec->private_data,
                                                       struct db_tdb_ctx);
-       int res;
-       
-       res = tdb_delete(ctx->wtdb->tdb, rec->key);
 
-       if (res == 0) {
+       if (tdb_delete(ctx->wtdb->tdb, rec->key) == 0) {
                return NT_STATUS_OK;
        }
 
-       return map_nt_error_from_tdb(tdb_error(ctx->wtdb->tdb));
+       if (tdb_error(ctx->wtdb->tdb) == TDB_ERR_NOEXIST) {
+               return NT_STATUS_NOT_FOUND;
+       }
+
+       return NT_STATUS_UNSUCCESSFUL;
 }
 
 struct db_tdb_traverse_ctx {
@@ -287,6 +304,35 @@ static int db_tdb_get_seqnum(struct db_context *db)
        return tdb_get_seqnum(db_ctx->wtdb->tdb);
 }
 
+static int db_tdb_get_flags(struct db_context *db)
+
+{
+       struct db_tdb_ctx *db_ctx =
+               talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
+       return tdb_get_flags(db_ctx->wtdb->tdb);
+}
+
+static int db_tdb_transaction_start(struct db_context *db)
+{
+       struct db_tdb_ctx *db_ctx =
+               talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
+       return tdb_transaction_start(db_ctx->wtdb->tdb);
+}
+
+static int db_tdb_transaction_commit(struct db_context *db)
+{
+       struct db_tdb_ctx *db_ctx =
+               talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
+       return tdb_transaction_commit(db_ctx->wtdb->tdb);
+}
+
+static int db_tdb_transaction_cancel(struct db_context *db)
+{
+       struct db_tdb_ctx *db_ctx =
+               talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
+       return tdb_transaction_cancel(db_ctx->wtdb->tdb);
+}
+
 struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
                               const char *name,
                               int hash_size, int tdb_flags,
@@ -295,13 +341,13 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
        struct db_context *result = NULL;
        struct db_tdb_ctx *db_tdb;
 
-       result = TALLOC_ZERO_P(mem_ctx, struct db_context);
+       result = talloc_zero(mem_ctx, struct db_context);
        if (result == NULL) {
                DEBUG(0, ("talloc failed\n"));
                goto fail;
        }
 
-       result->private_data = db_tdb = TALLOC_P(result, struct db_tdb_ctx);
+       result->private_data = db_tdb = talloc(result, struct db_tdb_ctx);
        if (db_tdb == NULL) {
                DEBUG(0, ("talloc failed\n"));
                goto fail;
@@ -318,7 +364,13 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
        result->fetch = db_tdb_fetch;
        result->traverse = db_tdb_traverse;
        result->traverse_read = db_tdb_traverse_read;
+       result->parse_record = db_tdb_parse;
        result->get_seqnum = db_tdb_get_seqnum;
+       result->get_flags = db_tdb_get_flags;
+       result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
+       result->transaction_start = db_tdb_transaction_start;
+       result->transaction_commit = db_tdb_transaction_commit;
+       result->transaction_cancel = db_tdb_transaction_cancel;
        return result;
 
  fail: