syncbase: Change db.createTable/deleteTable to table.create/destroy

As part of usability fixes documented on https://v.io/i/672

MultiPart: 3/8
Change-Id: Ib32d1b8f0e54e27a8334316ee555a3b179cdc06b
diff --git a/src/gen-vdl/v.io/v23/services/syncbase/nosql/index.js b/src/gen-vdl/v.io/v23/services/syncbase/nosql/index.js
index 2d12483..05cdcad 100644
--- a/src/gen-vdl/v.io/v23/services/syncbase/nosql/index.js
+++ b/src/gen-vdl/v.io/v23/services/syncbase/nosql/index.js
@@ -1847,8 +1847,8 @@
 };
     
       
-Table.prototype.delete = function(ctx, serverCall, schemaVersion) {
-  throw new Error('Method Delete not implemented');
+Table.prototype.destroy = function(ctx, serverCall, schemaVersion) {
+  throw new Error('Method Destroy not implemented');
 };
     
       
@@ -1913,8 +1913,8 @@
     
       
     {
-    name: 'Delete',
-    doc: "// Delete deletes this Table.",
+    name: 'Destroy',
+    doc: "// Destroy destroys this Table.",
     inArgs: [{
       name: 'schemaVersion',
       doc: "",
diff --git a/src/nosql/database.js b/src/nosql/database.js
index e141359..07f6b87 100644
--- a/src/nosql/database.js
+++ b/src/nosql/database.js
@@ -195,41 +195,6 @@
   return client.bindWithSignature(fullTableName, signature);
 };
 
-// TODO(nlacasse): It's strange that we create a Database with:
-//   var db = new Database();
-//   db.create();
-// But we create a Table with:
-//   db.createTable();
-// The .delete method is similarly confusing.  db.delete deletes a database,
-// but table.delete deletes a row (or row range).
-// Consider puting all 'create' and 'delete' methods on the parent class for
-// consistency.
-// TODO(aghassemi): If we keep this, it should return "table" in the CB instead
-// of being void.
-/**
- * Creates the specified Table.
- * If perms is nil, we inherit (copy) the Database perms.
- * @param {module:vanadium.context.Context} ctx Vanadium context.
- * @param {string} relativeName Table name.  Must not contain slashes.
- * @param {module:vanadium.security.access.Permissions} perms Permissions for
- * the new database.  If perms is null, we inherit (copy) the Database perms.
- * @param {function} cb Callback.
- */
-Database.prototype.createTable = function(ctx, relativeName, perms, cb) {
-  this._tableWire(ctx, relativeName).create(ctx, this.schemaVersion, perms, cb);
-};
-
-/**
- * Deletes the specified Table.
- * @param {module:vanadium.context.Context} ctx Vanadium context.
- * @param {string} relativeName Relative name of Table to delete.  Must not
- * contain slashes.
- * @param {function} cb Callback.
- */
-Database.prototype.deleteTable = function(ctx, relativeName, cb) {
-  this._tableWire(ctx, relativeName).delete(ctx, this.schemaVersion, cb);
-};
-
 /**
  * Watches for updates to the database. For each watch request, the client will
  * receive a reliable stream of watch events without re-ordering.
diff --git a/src/nosql/table.js b/src/nosql/table.js
index c050d14..77e5071 100644
--- a/src/nosql/table.js
+++ b/src/nosql/table.js
@@ -73,6 +73,29 @@
 };
 
 /**
+ * Creates this Table.
+ * If perms is nil, we inherit (copy) the Database perms.
+ * Create must not be called from within a batch.
+ * @param {module:vanadium.context.Context} ctx Vanadium context.
+ * @param {module:vanadium.security.access.Permissions} perms Permissions for
+ * the new database.  If perms is null, we inherit (copy) the Database perms.
+ * @param {function} cb Callback.
+ */
+Table.prototype.create = function(ctx, perms, cb) {
+  this._wire(ctx).create(ctx, this.schemaVersion, perms, cb);
+};
+
+/**
+ * Destroys this Table, permanently removing all of its data.
+ * Destroy must not be called from within a batch.
+ * @param {module:vanadium.context.Context} ctx Vanadium context.
+ * @param {function} cb Callback.
+ */
+Table.prototype.destroy = function(ctx, cb) {
+  this._wire(ctx).destroy(ctx, this.schemaVersion, cb);
+};
+
+/**
  * Creates a row the given primary key in this table.
  * @param {string} key Primary key for the row.
  * @return {module:syncbase.row.Row} Row object.
diff --git a/test/integration/test-database.js b/test/integration/test-database.js
index 98b1ee4..e07669f 100644
--- a/test/integration/test-database.js
+++ b/test/integration/test-database.js
@@ -245,119 +245,6 @@
   });
 });
 
-test('db.createTable() creates a table', function(t) {
-  setupDatabase(t, function(err, o) {
-    if (err) {
-      return t.end(err);
-    }
-
-    var db = o.database;
-    var table = db.table(uniqueName('table'));
-    var table2 = db.table(uniqueName('table'));
-
-    async.waterfall([
-      // Verify table does not exist yet.
-      table.exists.bind(table, o.ctx),
-      function(exists, cb) {
-        t.notok(exists, 'exists: table doesn\'t exist yet');
-        cb(null);
-      },
-
-      // Verify table list is empty.
-      db.listTables.bind(db, o.ctx),
-      function(tableList, cb) {
-        t.deepEqual(tableList, [],
-          'listTables: no tables exist');
-        cb(null);
-      },
-
-      // Create table.
-      db.createTable.bind(db, o.ctx, table.name, {}),
-
-      // Verify table exists.
-      table.exists.bind(table, o.ctx),
-      function(exists, cb) {
-        t.ok(exists, 'exists: table exists');
-        cb(null);
-      },
-
-      // Verify table list contains the table.
-      db.listTables.bind(db, o.ctx),
-      function(tableList, cb) {
-        t.deepEqual(tableList, [table.name],
-          'listTables: table exists');
-        cb(null);
-      },
-
-      // Create another table.
-      db.createTable.bind(db, o.ctx, table2.name, {}),
-
-      // Verify table list contains both tables.
-      db.listTables.bind(db, o.ctx),
-      function(tableList, cb) {
-        t.deepEqual(tableList.sort(), [table.name, table2.name].sort(),
-          'listTables: both tables exist');
-        cb(null);
-      },
-    ], function(err, arg) {
-      t.error(err);
-      o.teardown(t.end);
-    });
-  });
-});
-
-test('db.deleteTable() deletes a table', function(t) {
-  setupDatabase(t, function(err, o) {
-    if (err) {
-      return t.end(err);
-    }
-
-    var db = o.database;
-    var table = db.table(uniqueName('table'));
-
-    async.waterfall([
-      // Create table.
-      db.createTable.bind(db, o.ctx, table.name, {}),
-
-      // Verify table exists.
-      table.exists.bind(table, o.ctx),
-      function(exists, cb) {
-        t.ok(exists, 'table exists');
-        cb(null);
-      },
-
-      // Delete table.
-      db.deleteTable.bind(db, o.ctx, table.name),
-
-      // Verify table no longer exists.
-      table.exists.bind(table, o.ctx),
-      function(exists, cb) {
-        t.notok(exists, 'table no longer exists');
-        cb(null);
-      },
-    ], function(err, arg) {
-      t.error(err);
-      o.teardown(t.end);
-    });
-  });
-});
-
-test('deleting a table that does not exist should error', function(t) {
-  setupDatabase(t, function(err, o) {
-    if (err) {
-      return t.end(err);
-    }
-
-    var db = o.database;
-    var tableName = uniqueName('table');
-
-    db.deleteTable(o.ctx, tableName, function(err) {
-      t.error(err);
-      o.teardown(t.end);
-    });
-  });
-});
-
 test('Getting/Setting permissions of a database', function(t) {
   setupDatabase(t, function(err, o) {
     if (err) {
diff --git a/test/integration/test-table.js b/test/integration/test-table.js
index 7e924f8..02a9dbb 100644
--- a/test/integration/test-table.js
+++ b/test/integration/test-table.js
@@ -9,6 +9,7 @@
 
 var testUtil = require('./util');
 var assertScanRows = testUtil.assertScanRows;
+var setupDatabase = testUtil.setupDatabase;
 var setupTable = testUtil.setupTable;
 var uniqueName = testUtil.uniqueName;
 
@@ -18,6 +19,119 @@
 var ROW_KEY = 'row_key';
 var ROW_VAL = 'row value';
 
+test('table.create() creates a table', function(t) {
+  setupDatabase(t, function(err, o) {
+    if (err) {
+      return t.end(err);
+    }
+
+    var db = o.database;
+    var table = db.table(uniqueName('table'));
+    var table2 = db.table(uniqueName('table'));
+
+    async.waterfall([
+      // Verify table does not exist yet.
+      table.exists.bind(table, o.ctx),
+      function(exists, cb) {
+        t.notok(exists, 'exists: table doesn\'t exist yet');
+        cb(null);
+      },
+
+      // Verify table list is empty.
+      db.listTables.bind(db, o.ctx),
+      function(tableList, cb) {
+        t.deepEqual(tableList, [],
+          'listTables: no tables exist');
+        cb(null);
+      },
+
+      // Create table.
+      table.create.bind(table, o.ctx, {}),
+
+      // Verify table exists.
+      table.exists.bind(table, o.ctx),
+      function(exists, cb) {
+        t.ok(exists, 'exists: table exists');
+        cb(null);
+      },
+
+      // Verify table list contains the table.
+      db.listTables.bind(db, o.ctx),
+      function(tableList, cb) {
+        t.deepEqual(tableList, [table.name],
+          'listTables: table exists');
+        cb(null);
+      },
+
+      // Create another table.
+      table2.create.bind(table2, o.ctx, {}),
+
+      // Verify table list contains both tables.
+      db.listTables.bind(db, o.ctx),
+      function(tableList, cb) {
+        t.deepEqual(tableList.sort(), [table.name, table2.name].sort(),
+          'listTables: both tables exist');
+        cb(null);
+      },
+    ], function(err, arg) {
+      t.error(err);
+      o.teardown(t.end);
+    });
+  });
+});
+
+test('table.destroy() destroys a table', function(t) {
+  setupDatabase(t, function(err, o) {
+    if (err) {
+      return t.end(err);
+    }
+
+    var db = o.database;
+    var table = db.table(uniqueName('table'));
+
+    async.waterfall([
+      // Create table.
+      table.create.bind(table, o.ctx, {}),
+
+      // Verify table exists.
+      table.exists.bind(table, o.ctx),
+      function(exists, cb) {
+        t.ok(exists, 'table exists');
+        cb(null);
+      },
+
+      // Destroy table.
+      table.destroy.bind(table, o.ctx),
+
+      // Verify table no longer exists.
+      table.exists.bind(table, o.ctx),
+      function(exists, cb) {
+        t.notok(exists, 'table no longer exists');
+        cb(null);
+      },
+    ], function(err, arg) {
+      t.error(err);
+      o.teardown(t.end);
+    });
+  });
+});
+
+test('Destroying a table that does not exist should error', function(t) {
+  setupDatabase(t, function(err, o) {
+    if (err) {
+      return t.end(err);
+    }
+
+    var db = o.database;
+    var tableName = uniqueName('table');
+
+    db.table(tableName).destroy(o.ctx, function(err) {
+      t.error(err);
+      o.teardown(t.end);
+    });
+  });
+});
+
 test('Putting a string value in a row', function(t) {
   setupTable(t, function(err, o) {
     if (err) {
diff --git a/test/integration/util.js b/test/integration/util.js
index 7242f07..fecaa4b 100644
--- a/test/integration/util.js
+++ b/test/integration/util.js
@@ -148,7 +148,7 @@
     var db = o.database;
 
     var tableName = uniqueName('table');
-    db.createTable(o.ctx, tableName, {}, function(err) {
+    db.table(tableName).create(o.ctx, {}, function(err) {
       if (err) {
         o.rt.close(t.error);
         return cb(err);