From d7e324c9a2ea609a0f216a37077ed8e7b8ba1cc9 Mon Sep 17 00:00:00 2001 From: John Wright Date: Sat, 29 May 2010 12:26:13 -0600 Subject: [PATCH] moving ahead --- lib/nosqlite.js | 73 ++++++++++++++++++--------------------- lib/nsl_sync.js | 48 +++++++++---------------- src/nosqlite.coffee | 52 ++++++++++++++-------------- src/nsl_sync.coffee | 36 ++++++++----------- test/test_nosqlite.coffee | 4 +-- test/test_nosqlite.js | 4 ++- 6 files changed, 96 insertions(+), 121 deletions(-) diff --git a/lib/nosqlite.js b/lib/nosqlite.js index 0c72bd5..9420956 100644 --- a/lib/nosqlite.js +++ b/lib/nosqlite.js @@ -1,5 +1,5 @@ (function(){ - var NoSQLite, _a, nsl_console, nsl_debug, sys, webdb_provider; + var NSLCore, _a, nosqlite, nsl_console, nsl_debug, sys, webdb_provider; var __hasProp = Object.prototype.hasOwnProperty; // NoSQLite - SQLite for Javascript // (c) 2010 John J. Wright @@ -29,13 +29,12 @@ throw Error("Unsupported browser. Does not support HTML5 Web DB API."); } } - NoSQLite = function(options) { + NSLCore = function(options) { this.options = { core_data_mode: false, // whether to check if String columns are JSON // that start with nsl_json: - check_for_json: true, - sync_mode: false + check_for_json: true }; // setup some of the default filters this.filters = []; @@ -56,32 +55,9 @@ // Pass in an optional Core Data compatible mode flag. // params: // * (optional) If set to `true` will create a core data compatible schema. - // Opens a database - // name: the name of a db, or the full path to a db file - // options: (optional) the NoSQLite options - // callback: (optional) a callback method to use if the call succeeded - NoSQLite.prototype.open = function(name, options, callback) { - callback = _.isFunction(options) ? options : null; - if ((typeof options !== "undefined" && options !== null) && (typeof callback !== "undefined" && callback !== null)) { - this.options = _.extend(this.options, options); - } - this.openDatabase(name, null, null, null, callback); - return this; - }; - // Opens the database - // Name to be the complete path to the db if it makes sense - // Also providers can ignore the version attribute - NoSQLite.prototype.openDatabase = function(name, version, displayName, estimatedSize, callback) { - this.db = webdb_provider.openDatabase(name, version, displayName, estimatedSize, function() { - if ((typeof callback !== "undefined" && callback !== null)) { - return callback(); - } - }); - return this; - }; // A poss through to the underly db transaction // in case the user wants to execute their own transactions - NoSQLite.prototype.transaction = function(start, failure, success) { + NSLCore.prototype.transaction = function(start, failure, success) { return this.db.transaction(start, failure, success); }; //# Core Methods ################################# @@ -103,7 +79,7 @@ // the same way you put it in. You can turn this off by setting // the nosqlite option: nosqlite.options.check_for_json = false // As always, we will call you back when everything is ready! - NoSQLite.prototype.find = function(table, predicate, the_callback) { + NSLCore.prototype.find = function(table, predicate, the_callback) { var callback, select, self; select = this.sql.select(table, predicate); self = this; @@ -140,7 +116,7 @@ }; // Saves an object or objects in SQLite. // A convenience method that wraps save_objs - NoSQLite.prototype.save = function(table, obj, after, callback) { + NSLCore.prototype.save = function(table, obj, after, callback) { var obj_desc; obj_desc = { table: table, @@ -163,7 +139,7 @@ // * Dates are stored ISO 8601 date strings // * Other objects (arrays, complex objects) are simply stored as JSON.stringify text // As always, we'll call you back when everything is ready! - NoSQLite.prototype.save_objs = function(obj_desc, callback) { + NSLCore.prototype.save_objs = function(obj_desc, callback) { var current_err, current_obj_desc, db, obj_descs, res, save_args, self; // we accept an array or a single obj_desc obj_descs = _.isArray(obj_desc) ? obj_desc : [obj_desc]; @@ -213,7 +189,6 @@ }, function(transaction, err) { // we want the transaction error handler to be called current_err = err; - sys.debug(sys.inspect(i)); // so we can try to fix the error current_obj_desc = obj_descs[i]; return false; @@ -246,7 +221,7 @@ // If the error was fixed successfully retries the current // failed transaction. // Else notifies the callback - NoSQLite.prototype.fixSave = function(err, obj_desc, callback, save_args) { + NSLCore.prototype.fixSave = function(err, obj_desc, callback, save_args) { var _b, _c, errobj, fix_sql, self; if (!(typeof err !== "undefined" && err !== null)) { return null; @@ -284,7 +259,7 @@ // go through a key of an object and checks for String // attributes that start with "json: " and calls // JSON.parse on them - NoSQLite.prototype.json_text_to_obj = function(obj) { + NSLCore.prototype.json_text_to_obj = function(obj) { var _b, key, val; _b = obj; for (key in _b) { if (__hasProp.call(_b, key)) { @@ -301,7 +276,7 @@ // Error Handling // ------------------------ // Parses error into an internal error code - NoSQLite.prototype.parse_error = function(err) { + NSLCore.prototype.parse_error = function(err) { var errobj; errobj = {}; if (err.indexOf("no such table") !== -1) { @@ -322,12 +297,32 @@ String.prototype.startsWith = function(str) { return this.indexOf(str) === 0; }; + nosqlite = { + // Opens a database + // name: the name of a db, or the full path to a db file + // options: (optional) the NoSQLite options + // callback: (optional) a callback method to use if the call succeeded + open: function(name, options, callback) { + var nsl, nsl_sync; + callback = _.isFunction(options) ? options : callback; + if (options.sync_mode === true) { + nsl_sync = require("./nsl_sync"); + nsl = new nsl_sync.NSLSync(options); + } else { + nsl = new NSLCore(options); + } + nsl.db = webdb_provider.openDatabase(name, options.version, options.displayName, options.estimatedSize, callback); + return nsl; + } + }; if ((typeof window !== "undefined" && window !== null)) { - NoSQLite.prototype.sql = sqlite_sql; - window.nosqlite = new NoSQLite(); + NSLCore.prototype.sql = sqlite_sql; + window.nosqlite = nosqlite; + window.NSLCore = NSLCore; } else { - NoSQLite.prototype.sql = (require("./sqlite_sql")).sqlite_sql; - exports.nosqlite = new NoSQLite(); + NSLCore.prototype.sql = (require("./sqlite_sql")).sqlite_sql; + exports.nosqlite = nosqlite; + exports.NSLCore = NSLCore; } // In a browser enviroment, the rest of the NoSQLite functions are // bundled below here in a single JS file diff --git a/lib/nsl_sync.js b/lib/nsl_sync.js index 2680ce4..2cb1341 100644 --- a/lib/nsl_sync.js +++ b/lib/nsl_sync.js @@ -1,30 +1,31 @@ (function(){ - var NSLSync, blowup_objs_in_bucket, create_phantom, hash_object, make_cluster, objs_in_bucket, pull, pull_response, push_local, send_objs_in_bucket, send_requested_objs, store_objs, sys, uuid, uuid_to_obj; + var NSLSync, blowup_objs_in_bucket, create_phantom, hashlib, make_cluster, nosqlite, objs_in_bucket, pull, pull_response, push_local, send_objs_in_bucket, send_requested_objs, store_objs, sys, uuid_to_obj; var __extends = function(child, parent) { var ctor = function(){ }; ctor.prototype = parent.prototype; child.__superClass__ = parent.prototype; child.prototype = new ctor(); child.prototype.constructor = child; - }, __hasProp = Object.prototype.hasOwnProperty; + }; // Syncing module if (!(typeof window !== "undefined" && window !== null)) { sys = require("sys"); - uuid = require("Math.uuid"); + hashlib = require("hashlib"); + nosqlite = require("./nosqlite"); } NSLSync = function() { - return NoSQLite.apply(this, arguments); + return nosqlite.NSLCore.apply(this, arguments); }; - __extends(NSLSync, NoSQLite); - // Extends the core NoSQLite save_ojb functions + __extends(NSLSync, nosqlite.NSLCore); + // Extends the core NoSQLite save_obj functions // Creates a nsl_obj entry for each user obj // Stores an attribue called oid in the user table // that references the nsl_obj // Also stores auxilary objs needed for syncing - NSLSync.prototype.save_obj = function(obj_desc, callback) { - var _a, _b, _c, i, nsl_obj_descs, obj_descs; + NSLSync.prototype.save_objs = function(the_obj_desc, callback) { + var _a, _b, _c, i, nsl_obj_descs, obj_desc, obj_descs; // we accept an array or a single object - obj_descs = _.isArray(obj_desc) ? obj_desc : [obj_desc]; + obj_descs = _.isArray(the_obj_desc) ? the_obj_desc : [the_obj_desc]; // store a nsl_obj for each user obj nsl_obj_descs = []; i = 0; @@ -35,9 +36,10 @@ var _d, _e, _f, after, nsl_obj_desc, obj, objs; after = function(obj_desc, obj, oid) { // we always put an entry in unclustered. - i += 1; + sys.debug(sys.inspect(obj_descs)); obj_desc = obj_descs[i]; - obj_desc.oid = oid; + i += 1; + obj_desc.obj.oid = oid; return [ obj_desc, { table: "nsl_unclustered", @@ -68,10 +70,10 @@ after: after }; } - return nsl_objs_descs.push(nsl_obj_desc); + return nsl_obj_descs.push(nsl_obj_desc); })(); } - return NSLSync.__superClass__.save_obj.call(this, save_obj(nsl_obj_descs, callback)); + return NSLSync.__superClass__.save_objs.call(this, nsl_obj_descs, callback); }; // Returns nsl_objs in buckets not in another bucket. @@ -82,7 +84,7 @@ sql = ("SELECT * FROM " + (bucket) + " JOIN nsl_obj USING(oid)"); if ((typeof exclude_bucket !== "undefined" && exclude_bucket !== null)) { sql += ("WHERE NOT EXISTS (SELECT 1 FROM " + (exclude_bucket) + " WHERE oid=nsl_obj.oid)"); - return self.nosqlite.query(sql, function(err, res) { + return self.execute(sql, function(err, res) { if ((typeof err !== "undefined" && err !== null)) { return callback(err); } @@ -304,21 +306,5 @@ return req.send(this); }, function(err, res) { }); }; - // Creates a SHA-1 hash of the object's contents - // in the piped export format of SQLite. - hash_object = function(object) { - var _a, i, key, keys_length, value, values; - values = ""; - i = 0; - keys_length = Object.keys(object).length - 1; - _a = object; - for (key in _a) { if (__hasProp.call(_a, key)) { - value = _a[key]; - values += value; - if (i++ < keys_length) { - values += "|"; - } - }} - return hashlib.sha1(values); - }; + !(typeof window !== "undefined" && window !== null) ? (exports.NSLSync = NSLSync) : null; })(); diff --git a/src/nosqlite.coffee b/src/nosqlite.coffee index 58b504d..3f9c368 100644 --- a/src/nosqlite.coffee +++ b/src/nosqlite.coffee @@ -26,7 +26,7 @@ else if window? webdb_provider: window else throw Error("Unsupported browser. Does not support HTML5 Web DB API.") -class NoSQLite +class NSLCore # Creates a NoSQLite object # Pass in an optional Core Data compatible mode flag. @@ -38,7 +38,6 @@ class NoSQLite # whether to check if String columns are JSON # that start with nsl_json: check_for_json: true - sync_mode: false } # setup some of the default filters @@ -58,25 +57,6 @@ class NoSQLite @sync: new require("./nsl_sync").NSLSync(this) else @sync: new NSLSync(this) - - # Opens a database - # - # name: the name of a db, or the full path to a db file - # options: (optional) the NoSQLite options - # callback: (optional) a callback method to use if the call succeeded - open: (name, options, callback) -> - callback: if _.isFunction(options) then options - @options = _.extend(@options, options) if options? and callback? - @openDatabase(name, null, null, null, callback) - return this - - # Opens the database - # Name to be the complete path to the db if it makes sense - # Also providers can ignore the version attribute - openDatabase: (name, version, displayName, estimatedSize, callback) -> - @db: webdb_provider.openDatabase name, version, displayName, estimatedSize, -> - return callback() if callback? - return this # A poss through to the underly db transaction # in case the user wants to execute their own transactions @@ -202,7 +182,6 @@ class NoSQLite (transaction, err) -> # we want the transaction error handler to be called current_err: err - sys.debug(sys.inspect(i)) # so we can try to fix the error current_obj_desc: obj_descs[i] return false @@ -289,12 +268,33 @@ String.prototype.trim: -> String.prototype.startsWith: (str) -> return this.indexOf(str) is 0 + +nosqlite: { + + # Opens a database + # + # name: the name of a db, or the full path to a db file + # options: (optional) the NoSQLite options + # callback: (optional) a callback method to use if the call succeeded + open: (name, options, callback) -> + callback: if _.isFunction(options) then options else callback + if options.sync_mode is true + nsl_sync: require("./nsl_sync") + nsl: new nsl_sync.NSLSync(options) + else + nsl: new NSLCore(options) + nsl.db: webdb_provider.openDatabase name, options.version, options.displayName, options.estimatedSize, callback + return nsl +} + if window? - NoSQLite.prototype.sql: sqlite_sql - window.nosqlite: new NoSQLite() + NSLCore.prototype.sql: sqlite_sql + window.nosqlite: nosqlite + window.NSLCore: NSLCore else - NoSQLite.prototype.sql: (require "./sqlite_sql").sqlite_sql - exports.nosqlite: new NoSQLite() + NSLCore.prototype.sql: (require "./sqlite_sql").sqlite_sql + exports.nosqlite: nosqlite + exports.NSLCore: NSLCore # In a browser enviroment, the rest of the NoSQLite functions are # bundled below here in a single JS file \ No newline at end of file diff --git a/src/nsl_sync.coffee b/src/nsl_sync.coffee index 8d4c38e..d11759a 100644 --- a/src/nsl_sync.coffee +++ b/src/nsl_sync.coffee @@ -1,19 +1,20 @@ # Syncing module if not window? sys: require "sys" - uuid: require "Math.uuid" - -class NSLSync extends NoSQLite + hashlib: require "hashlib" + nosqlite: require "./nosqlite" + +class NSLSync extends nosqlite.NSLCore - # Extends the core NoSQLite save_ojb functions + # Extends the core NoSQLite save_obj functions # Creates a nsl_obj entry for each user obj # # Stores an attribue called oid in the user table # that references the nsl_obj # Also stores auxilary objs needed for syncing - save_obj: (obj_desc, callback) -> + save_objs: (the_obj_desc, callback) -> # we accept an array or a single object - obj_descs = if _.isArray(obj_desc) then obj_desc else [obj_desc] + obj_descs = if _.isArray(the_obj_desc) then the_obj_desc else [the_obj_desc] # store a nsl_obj for each user obj nsl_obj_descs: [] @@ -21,9 +22,10 @@ class NSLSync extends NoSQLite for obj_desc in obj_descs after: (obj_desc, obj, oid) -> # we always put an entry in unclustered. - i += 1 + sys.debug(sys.inspect(obj_descs)) obj_desc: obj_descs[i] - obj_desc.oid: oid + i += 1 + obj_desc.obj.oid: oid return [ obj_desc, { table: "nsl_unclustered", obj: {oid: oid}}, @@ -42,8 +44,8 @@ class NSLSync extends NoSQLite }, after: after } - nsl_objs_descs.push(nsl_obj_desc) - super save_obj(nsl_obj_descs, callback) + nsl_obj_descs.push(nsl_obj_desc) + super(nsl_obj_descs, callback) # Returns nsl_objs in buckets not in another bucket. @@ -53,7 +55,7 @@ class NSLSync extends NoSQLite sql: "SELECT * FROM ${bucket} JOIN nsl_obj USING(oid)" if exclude_bucket? sql += "WHERE NOT EXISTS (SELECT 1 FROM ${exclude_bucket} WHERE oid=nsl_obj.oid)" - self.nosqlite.query sql, (err, res) -> + self.execute sql, (err, res) -> if err? then return callback(err) return callback(null, res) @@ -251,13 +253,5 @@ class NSLSync extends NoSQLite ) - # Creates a SHA-1 hash of the object's contents - # in the piped export format of SQLite. - hash_object: (object) -> - values: "" - i: 0 - keys_length: Object.keys(object).length - 1 - for key, value of object - values += value - values += "|" if i++ < keys_length - return hashlib.sha1(values) +if not window? + exports.NSLSync: NSLSync \ No newline at end of file diff --git a/test/test_nosqlite.coffee b/test/test_nosqlite.coffee index 9cc4b25..8d1a73b 100644 --- a/test/test_nosqlite.coffee +++ b/test/test_nosqlite.coffee @@ -44,8 +44,7 @@ test_find: -> test_sync: -> db_file: "./test/test_sync.db" remove_file(db_file) - - db: nosqlite.open db_file, -> + db: nosqlite.open db_file, {sync_mode: true}, -> log: { text: "hello", occurred_at: new Date().getTime(), @@ -62,7 +61,6 @@ test_sync: -> facts: ["hello", "hello", "hello1"], original: {id: 1, text: "some crazy object"} } - db.save "log", log, null, (err, res) -> throw err if err? db.find "log", {text: "hello"}, (err, result) -> diff --git a/test/test_nosqlite.js b/test/test_nosqlite.js index 832c774..c422144 100644 --- a/test/test_nosqlite.js +++ b/test/test_nosqlite.js @@ -62,7 +62,9 @@ var db, db_file; db_file = "./test/test_sync.db"; remove_file(db_file); - db = nosqlite.open(db_file, function() { + db = nosqlite.open(db_file, { + sync_mode: true + }, function() { var log; log = { text: "hello",