tdb:tdbtool: add transaction_start/_commit/_cancel commands.
[amitay/samba.git] / lib / tdb / tools / tdbtool.c
index d104ccd7c44994e9d0f8ba138cbf4584343983dc..193140b801dae1e8973955b32090f28419198be9 100644 (file)
@@ -40,6 +40,9 @@ static int disable_mmap;
 enum commands {
        CMD_CREATE_TDB,
        CMD_OPEN_TDB,
+       CMD_TRANSACTION_START,
+       CMD_TRANSACTION_COMMIT,
+       CMD_TRANSACTION_CANCEL,
        CMD_ERASE,
        CMD_DUMP,
        CMD_INSERT,
@@ -57,6 +60,7 @@ enum commands {
        CMD_FIRST,
        CMD_NEXT,
        CMD_SYSTEM,
+       CMD_CHECK,
        CMD_QUIT,
        CMD_HELP
 };
@@ -69,6 +73,9 @@ typedef struct {
 COMMAND_TABLE cmd_table[] = {
        {"create",      CMD_CREATE_TDB},
        {"open",        CMD_OPEN_TDB},
+       {"transaction_start",   CMD_TRANSACTION_START},
+       {"transaction_commit",  CMD_TRANSACTION_COMMIT},
+       {"transaction_cancel",  CMD_TRANSACTION_CANCEL},
        {"erase",       CMD_ERASE},
        {"dump",        CMD_DUMP},
        {"insert",      CMD_INSERT},
@@ -87,6 +94,7 @@ COMMAND_TABLE cmd_table[] = {
        {"1",           CMD_FIRST},
        {"next",        CMD_NEXT},
        {"n",           CMD_NEXT},
+       {"check",       CMD_CHECK},
        {"quit",        CMD_QUIT},
        {"q",           CMD_QUIT},
        {"!",           CMD_SYSTEM},
@@ -167,6 +175,9 @@ static void help(void)
 "tdbtool: \n"
 "  create    dbname     : create a database\n"
 "  open      dbname     : open an existing database\n"
+"  transaction_start    : start a transaction\n"
+"  transaction_commit   : commit a transaction\n"
+"  transaction_cancel   : cancel a transaction\n"
 "  erase                : erase the database\n"
 "  dump                 : dump the database as strings\n"
 "  keys                 : dump the database keys as strings\n"
@@ -179,7 +190,9 @@ static void help(void)
 "  delete    key        : delete a record by key\n"
 "  list                 : print the database hash table and freelist\n"
 "  free                 : print the database freelist\n"
-"  ! command            : execute system command\n"             
+"  check                : check the integrity of an opened database\n"
+"  speed                : perform speed tests on the database\n"
+"  ! command            : execute system command\n"
 "  1 | first            : print the first record\n"
 "  n | next             : print the next record\n"
 "  q | quit             : terminate\n"
@@ -389,15 +402,68 @@ static void speed_tdb(const char *tlimit)
 {
        unsigned timelimit = tlimit?atoi(tlimit):0;
        double t;
-       int ops=0;
-       if (timelimit == 0) timelimit = 10;
+       int ops;
+       if (timelimit == 0) timelimit = 5;
+
+       ops = 0;
+       printf("Testing store speed for %u seconds\n", timelimit);
+       _start_timer();
+       do {
+               long int r = random();
+               TDB_DATA key, dbuf;
+               key.dptr = (unsigned char *)"store test";
+               key.dsize = strlen((char *)key.dptr);
+               dbuf.dptr = (unsigned char *)&r;
+               dbuf.dsize = sizeof(r);
+               tdb_store(tdb, key, dbuf, TDB_REPLACE);
+               t = _end_timer();
+               ops++;
+       } while (t < timelimit);
+       printf("%10.3f ops/sec\n", ops/t);
+
+       ops = 0;
+       printf("Testing fetch speed for %u seconds\n", timelimit);
+       _start_timer();
+       do {
+               long int r = random();
+               TDB_DATA key, dbuf;
+               key.dptr = (unsigned char *)"store test";
+               key.dsize = strlen((char *)key.dptr);
+               dbuf.dptr = (unsigned char *)&r;
+               dbuf.dsize = sizeof(r);
+               tdb_fetch(tdb, key);
+               t = _end_timer();
+               ops++;
+       } while (t < timelimit);
+       printf("%10.3f ops/sec\n", ops/t);
+
+       ops = 0;
+       printf("Testing transaction speed for %u seconds\n", timelimit);
+       _start_timer();
+       do {
+               long int r = random();
+               TDB_DATA key, dbuf;
+               key.dptr = (unsigned char *)"transaction test";
+               key.dsize = strlen((char *)key.dptr);
+               dbuf.dptr = (unsigned char *)&r;
+               dbuf.dsize = sizeof(r);
+               tdb_transaction_start(tdb);
+               tdb_store(tdb, key, dbuf, TDB_REPLACE);
+               tdb_transaction_commit(tdb);
+               t = _end_timer();
+               ops++;
+       } while (t < timelimit);
+       printf("%10.3f ops/sec\n", ops/t);
+
+       ops = 0;
        printf("Testing traverse speed for %u seconds\n", timelimit);
        _start_timer();
-       while ((t=_end_timer()) < timelimit) {
+       do {
                tdb_traverse(tdb, traverse_fn, NULL);
-               printf("%10.3f ops/sec\r", (++ops)/t);
-       }
-       printf("\n");
+               t = _end_timer();
+               ops++;
+       } while (t < timelimit);
+       printf("%10.3f ops/sec\n", ops/t);
 }
 
 static void toggle_mmap(void)
@@ -452,6 +518,27 @@ static void next_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey)
                print_rec(the_tdb, *pkey, dbuf, NULL);
 }
 
+static int test_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+{
+       return 0;
+}
+
+static void check_db(TDB_CONTEXT *the_tdb)
+{
+       int tdbcount=-1;
+       if (the_tdb) {
+               tdbcount = tdb_traverse(the_tdb, test_fn, NULL);
+       } else {
+               printf("Error: No database opened!\n");
+       }
+
+       if (tdbcount<0) {
+               printf("Integrity check for the opened database failed.\n");
+       } else {
+               printf("Database integrity is OK and has %d records.\n", tdbcount);
+       }
+}
+
 static int do_command(void)
 {
        COMMAND_TABLE *ctp = cmd_table;
@@ -482,7 +569,9 @@ static int do_command(void)
             return 0;
        case CMD_SYSTEM:
            /* Shell command */
-           system(arg1);
+           if (system(arg1) == -1) {
+               terror("system() call failed\n");
+           }
            return 0;
        case CMD_QUIT:
            return 1;
@@ -495,6 +584,18 @@ static int do_command(void)
                return 0;
            }
            switch (mycmd) {
+           case CMD_TRANSACTION_START:
+               bIterate = 0;
+               tdb_transaction_start(tdb);
+               return 0;
+           case CMD_TRANSACTION_COMMIT:
+               bIterate = 0;
+               tdb_transaction_commit(tdb);
+               return 0;
+           case CMD_TRANSACTION_CANCEL:
+               bIterate = 0;
+               tdb_transaction_cancel(tdb);
+               return 0;
            case CMD_ERASE:
                bIterate = 0;
                tdb_traverse(tdb, do_delete_fn, NULL);
@@ -552,6 +653,9 @@ static int do_command(void)
               if (bIterate)
                  next_record(tdb, &iterate_kbuf);
                return 0;
+           case CMD_CHECK:
+               check_db(tdb);
+               return 0;
            case CMD_HELP:
                help();
                return 0;