Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Indexed db adapter - allow multiple records #175

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/adapters/indexed-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,17 @@ Lawnchair.adapter('indexed-db', (function(){
// ok, create object store.
var params = {};
if (self.useAutoIncrement) { params.autoIncrement = true; }
self.db.createObjectStore(self.record, params);

if ( options.records ) {
// create multiple records or objectStores
// option object = {..., records:['objectStore1', 'objectStore2']}
for ( i=options.records.length; i--; ) {
self.db.createObjectStore(options.records[i], params);
}
} else {
// single record
self.db.createObjectStore(self.record, params);
}
self.store = true;
};
request.onupgradeneeded = function(event) {
Expand Down
211 changes: 115 additions & 96 deletions src/adapters/webkit-sqlite.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ Lawnchair.adapter('webkit-sqlite', (function () {
// private methods
var fail = function (e, i) { console.error('error in sqlite adaptor!', e, i) }
, now = function () { return new Date() } // FIXME need to use better date fn
, convertInt2String = function(args) {
// converts array's integer value to string
return args.map(function(value, index, arr){
return '' + value
});
}
// not entirely sure if this is needed...
if (!Function.prototype.bind) {
Function.prototype.bind = function( obj ) {
Expand Down Expand Up @@ -63,7 +69,6 @@ Lawnchair.adapter('webkit-sqlite', (function () {
save: function (obj, callback, error) {
var that = this
, objs = (this.isArray(obj) ? obj : [obj]).map(function(o){if(!o.key) { o.key = that.uuid()} return o})
, ins = "INSERT OR REPLACE INTO " + this.record + " (value, timestamp, id) VALUES (?,?,?)"
, win = function () { if (callback) { that.lambda(callback).call(that, that.isArray(obj)?objs:objs[0]) }}
, error= error || function() {}
, insvals = []
Expand All @@ -78,10 +83,16 @@ Lawnchair.adapter('webkit-sqlite', (function () {
throw e;
}

that.db.transaction(function(t) {
for (var i = 0, l = objs.length; i < l; i++)
t.executeSql(ins, insvals[i])
}, function(e,i){fail(e,i)}, win)
that.db.transaction(function(t) {
for (var i = 0, l = objs.length; i < l; i++) {
// Fixed the issue on id field.
// Numeric id will now save as Integer. Otherwise, it will be saved as String.
ins = "INSERT OR REPLACE INTO " + that.record + " (value, timestamp, id) VALUES (?,?,";
ins += /\D/.test(insvals[i][2]) ? "'" + insvals[i][2] + "'" : insvals[i][2];
ins += ")";
t.executeSql(ins, [insvals[i][0], insvals[i][1]])
}
}, function(e,i){fail(e,i)}, win)

return this
},
Expand All @@ -92,96 +103,104 @@ Lawnchair.adapter('webkit-sqlite', (function () {
},

get: function (keyOrArray, cb) {
var that = this
, sql = ''
, args = this.isArray(keyOrArray) ? keyOrArray : [keyOrArray];
// batch selects support
sql = 'SELECT id, value FROM ' + this.record + " WHERE id IN (" +
args.map(function(){return '?'}).join(",") + ")"
// FIXME
// will always loop the results but cleans it up if not a batch return at the end..
// in other words, this could be faster
var win = function (xxx, results) {
var o
, r
, lookup = {}
// map from results to keys
for (var i = 0, l = results.rows.length; i < l; i++) {
o = JSON.parse(results.rows.item(i).value)
o.key = results.rows.item(i).id
lookup[o.key] = o;
}
r = args.map(function(key) { return lookup[key]; });
if (!that.isArray(keyOrArray)) r = r.length ? r[0] : null
if (cb) that.lambda(cb).call(that, r)
var that = this
, sql = ''
, args = this.isArray(keyOrArray) ? keyOrArray : [keyOrArray];
// batch selects support
sql = 'SELECT id, value FROM ' + this.record + " WHERE id IN (" +
args.map(function(){return '?'}).join(",") + ")"

// converts integer value to string
args = convertInt2String(args);

// FIXME
// will always loop the results but cleans it up if not a batch return at the end..
// in other words, this could be faster
var win = function (xxx, results) {
var o
, r
, lookup = {}
// map from results to keys
for (var i = 0, l = results.rows.length; i < l; i++) {
o = JSON.parse(results.rows.item(i).value)
o.key = results.rows.item(i).id
lookup[o.key] = o;
}
this.db.readTransaction(function(t){ t.executeSql(sql, args, win, fail) })
return this
},

exists: function (key, cb) {
var is = "SELECT * FROM " + this.record + " WHERE id = ?"
, that = this
, win = function(xxx, results) { if (cb) that.fn('exists', cb).call(that, (results.rows.length > 0)) }
this.db.readTransaction(function(t){ t.executeSql(is, [key], win, fail) })
return this
},

all: function (callback) {
var that = this
, all = "SELECT * FROM " + this.record
, r = []
, cb = this.fn(this.name, callback) || undefined
, win = function (xxx, results) {
if (results.rows.length != 0) {
for (var i = 0, l = results.rows.length; i < l; i++) {
var obj = JSON.parse(results.rows.item(i).value)
obj.key = results.rows.item(i).id
r.push(obj)
}
}
if (cb) cb.call(that, r)
}

this.db.readTransaction(function (t) {
t.executeSql(all, [], win, fail)
})
return this
},

remove: function (keyOrArray, cb) {
var that = this
, args
, sql = "DELETE FROM " + this.record + " WHERE id "
, win = function () { if (cb) that.lambda(cb).call(that) }
if (!this.isArray(keyOrArray)) {
sql += '= ?';
args = [keyOrArray];
} else {
args = keyOrArray;
sql += "IN (" +
args.map(function(){return '?'}).join(',') +
")";
}
args = args.map(function(obj) {
return obj.key ? obj.key : obj;
});

this.db.transaction( function (t) {
t.executeSql(sql, args, win, fail);
});

return this;
},

nuke: function (cb) {
var nuke = "DELETE FROM " + this.record
, that = this
, win = cb ? function() { that.lambda(cb).call(that) } : function(){}
this.db.transaction(function (t) {
t.executeSql(nuke, [], win, fail)
})
return this
}
r = args.map(function(key) { return lookup[key]; });
if (!that.isArray(keyOrArray)) r = r.length ? r[0] : null
if (cb) that.lambda(cb).call(that, r)
}

this.db.readTransaction(function(t){ t.executeSql(sql, args, win, fail) })
return this
},

exists: function (key, cb) {
var is = "SELECT * FROM " + this.record + " WHERE id = ?"
, that = this
, win = function(xxx, results) { if (cb) that.fn('exists', cb).call(that, (results.rows.length > 0)) }
this.db.readTransaction(function(t){ t.executeSql(is, [''+key], win, fail) })
return this
},

all: function (callback) {
var that = this
, all = "SELECT * FROM " + this.record
, r = []
, cb = this.fn(this.name, callback) || undefined
, win = function (xxx, results) {
if (results.rows.length != 0) {
for (var i = 0, l = results.rows.length; i < l; i++) {
var obj = JSON.parse(results.rows.item(i).value)
obj.key = results.rows.item(i).id
r.push(obj)
}
}
if (cb) cb.call(that, r)
}

this.db.readTransaction(function (t) {
t.executeSql(all, [], win, fail)
})
return this
},

remove: function (keyOrArray, cb) {
var that = this
, args = this.isArray(keyOrArray) ? keyOrArray : [keyOrArray]
, sql = "DELETE FROM " + this.record + " WHERE id "
, win = function () { if (cb) that.lambda(cb).call(that) }

if (!this.isArray(keyOrArray)) {
sql += '= ?';
} else {
sql += "IN (" +
args.map(function(){return '?'}).join(',') +
")";
}

args = args.map(function(obj) {
return obj.key ? obj.key : obj;
});

// converts integer value to string
args = convertInt2String(args);

this.db.transaction( function (t) {
t.executeSql(sql, args, win, fail);
});

return this;
},

nuke: function (cb) {
var nuke = "DELETE FROM " + this.record
, that = this
, win = cb ? function() { that.lambda(cb).call(that) } : function(){}
this.db.transaction(function (t) {
t.executeSql(nuke, [], win, fail)
})
return this
}
//////
}})());
}})())