mirror of
https://github.com/moparisthebest/mail
synced 2024-11-22 08:52:15 -05:00
use spaces in all daos and cleanup keystorage dao to use prototype style
This commit is contained in:
parent
66e0d5341b
commit
7f42722699
@ -5,67 +5,67 @@
|
||||
* used to encrypt data on the fly before persisting via a JSON store.
|
||||
*/
|
||||
define(['cryptoLib/util', 'js/crypto/crypto', 'js/dao/lawnchair-dao'], function(util, crypto, jsonDao) {
|
||||
'use strict';
|
||||
'use strict';
|
||||
|
||||
var self = {};
|
||||
var self = {};
|
||||
|
||||
/**
|
||||
* Stores a list of encrypted items in the object store
|
||||
* @param list [Array] The list of items to be persisted
|
||||
* @param type [String] The type of item to be persisted e.g. 'email'
|
||||
*/
|
||||
self.storeEcryptedList = function(list, type, callback) {
|
||||
var date, key, items = [];
|
||||
/**
|
||||
* Stores a list of encrypted items in the object store
|
||||
* @param list [Array] The list of items to be persisted
|
||||
* @param type [String] The type of item to be persisted e.g. 'email'
|
||||
*/
|
||||
self.storeEcryptedList = function(list, type, callback) {
|
||||
var date, key, items = [];
|
||||
|
||||
// nothing to store
|
||||
if (list.length === 0) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
// nothing to store
|
||||
if (list.length === 0) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
// format items for batch storing in dao
|
||||
list.forEach(function(i) {
|
||||
// format items for batch storing in dao
|
||||
list.forEach(function(i) {
|
||||
|
||||
// put date in key if available... for easy querying
|
||||
if (i.sentDate) {
|
||||
date = util.parseDate(i.sentDate);
|
||||
key = type + '_' + i.sentDate + '_' + i.id;
|
||||
} else {
|
||||
key = type + '_' + i.id;
|
||||
}
|
||||
// put date in key if available... for easy querying
|
||||
if (i.sentDate) {
|
||||
date = util.parseDate(i.sentDate);
|
||||
key = type + '_' + i.sentDate + '_' + i.id;
|
||||
} else {
|
||||
key = type + '_' + i.id;
|
||||
}
|
||||
|
||||
items.push({
|
||||
key: key,
|
||||
object: i
|
||||
});
|
||||
items.push({
|
||||
key: key,
|
||||
object: i
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
jsonDao.batch(items, function() {
|
||||
callback();
|
||||
});
|
||||
};
|
||||
jsonDao.batch(items, function() {
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* List stored items of a given type
|
||||
* @param type [String] The type of item e.g. 'email'
|
||||
* @param offset [Number] The offset of items to fetch (0 is the last stored item)
|
||||
* @param num [Number] The number of items to fetch (null means fetch all)
|
||||
*/
|
||||
self.listEncryptedItems = function(type, offset, num, callback) {
|
||||
// fetch all items of a certain type from the data-store
|
||||
jsonDao.list(type, offset, num, function(encryptedList) {
|
||||
/**
|
||||
* List stored items of a given type
|
||||
* @param type [String] The type of item e.g. 'email'
|
||||
* @param offset [Number] The offset of items to fetch (0 is the last stored item)
|
||||
* @param num [Number] The number of items to fetch (null means fetch all)
|
||||
*/
|
||||
self.listEncryptedItems = function(type, offset, num, callback) {
|
||||
// fetch all items of a certain type from the data-store
|
||||
jsonDao.list(type, offset, num, function(encryptedList) {
|
||||
|
||||
callback(null, encryptedList);
|
||||
});
|
||||
};
|
||||
callback(null, encryptedList);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the whole device data-store
|
||||
*/
|
||||
self.clear = function(callback) {
|
||||
jsonDao.clear(callback);
|
||||
};
|
||||
/**
|
||||
* Clear the whole device data-store
|
||||
*/
|
||||
self.clear = function(callback) {
|
||||
jsonDao.clear(callback);
|
||||
};
|
||||
|
||||
return self;
|
||||
return self;
|
||||
});
|
@ -3,314 +3,326 @@
|
||||
* between the cloud service and the device's local storage
|
||||
*/
|
||||
define(['underscore', 'js/dao/lawnchair-dao'], function(_, jsonDao) {
|
||||
'use strict';
|
||||
'use strict';
|
||||
|
||||
var KeychainDAO = function(cloudstorage) {
|
||||
var self = this;
|
||||
var KeychainDAO = function(cloudstorage) {
|
||||
var self = this;
|
||||
|
||||
/**
|
||||
* Get an array of public keys by looking in local storage and
|
||||
* fetching missing keys from the cloud service.
|
||||
* @param ids [Array] the key ids as [{_id, userId}]
|
||||
* @return [PublicKeyCollection] The requiested public keys
|
||||
*/
|
||||
self.getPublicKeys = function(ids, callback) {
|
||||
var already, pubkeys = [];
|
||||
self._cloudstorage = cloudstorage;
|
||||
};
|
||||
|
||||
var after = _.after(ids.length, function() {
|
||||
callback(null, pubkeys);
|
||||
});
|
||||
/**
|
||||
* Get an array of public keys by looking in local storage and
|
||||
* fetching missing keys from the cloud service.
|
||||
* @param ids [Array] the key ids as [{_id, userId}]
|
||||
* @return [PublicKeyCollection] The requiested public keys
|
||||
*/
|
||||
KeychainDAO.prototype.getPublicKeys = function(ids, callback) {
|
||||
var self = this,
|
||||
after, already, pubkeys = [];
|
||||
|
||||
_.each(ids, function(i) {
|
||||
// lookup locally and in storage
|
||||
lookupPublicKey(i._id, function(err, pubkey) {
|
||||
if (err || !pubkey) {
|
||||
callback({
|
||||
errMsg: 'Error looking up public key!',
|
||||
err: err
|
||||
});
|
||||
return;
|
||||
}
|
||||
after = _.after(ids.length, function() {
|
||||
callback(null, pubkeys);
|
||||
});
|
||||
|
||||
// check if public key with that id has already been fetched
|
||||
already = null;
|
||||
already = _.findWhere(pubkeys, {
|
||||
_id: i._id
|
||||
});
|
||||
if (!already) {
|
||||
pubkeys.push(pubkey);
|
||||
}
|
||||
_.each(ids, function(i) {
|
||||
// lookup locally and in storage
|
||||
self.lookupPublicKey(i._id, function(err, pubkey) {
|
||||
if (err || !pubkey) {
|
||||
callback({
|
||||
errMsg: 'Error looking up public key!',
|
||||
err: err
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
after(); // asynchronously iterate through objects
|
||||
});
|
||||
});
|
||||
};
|
||||
// check if public key with that id has already been fetched
|
||||
already = null;
|
||||
already = _.findWhere(pubkeys, {
|
||||
_id: i._id
|
||||
});
|
||||
if (!already) {
|
||||
pubkeys.push(pubkey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up a reveiver's public key by user id
|
||||
* @param userId [String] the receiver's email address
|
||||
*/
|
||||
self.getReveiverPublicKey = function(userId, callback) {
|
||||
// search local keyring for public key
|
||||
jsonDao.list('publickey', 0, null, function(allPubkeys) {
|
||||
var pubkey = _.findWhere(allPubkeys, {
|
||||
userId: userId
|
||||
});
|
||||
after(); // asynchronously iterate through objects
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if (!pubkey || !pubkey._id) {
|
||||
// no public key by that user id in storage
|
||||
// find from cloud by email address
|
||||
cloudstorage.getPublicKeyByUserId(userId, function(err, cloudPubkey) {
|
||||
if (err || !cloudPubkey) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Look up a reveiver's public key by user id
|
||||
* @param userId [String] the receiver's email address
|
||||
*/
|
||||
KeychainDAO.prototype.getReveiverPublicKey = function(userId, callback) {
|
||||
var self = this;
|
||||
|
||||
if (cloudPubkey && cloudPubkey._id) {
|
||||
// there is a public key for that user already in the cloud...
|
||||
// save to local storage
|
||||
saveLocalPublicKey(cloudPubkey, function(err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
// search local keyring for public key
|
||||
jsonDao.list('publickey', 0, null, function(allPubkeys) {
|
||||
var pubkey = _.findWhere(allPubkeys, {
|
||||
userId: userId
|
||||
});
|
||||
|
||||
callback(null, cloudPubkey);
|
||||
});
|
||||
} else {
|
||||
// no public key for that user
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
});
|
||||
if (!pubkey || !pubkey._id) {
|
||||
// no public key by that user id in storage
|
||||
// find from cloud by email address
|
||||
self._cloudstorage.getPublicKeyByUserId(userId, function(err, cloudPubkey) {
|
||||
if (err || !cloudPubkey) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
// that user's public key is already in local storage
|
||||
callback(null, pubkey);
|
||||
}
|
||||
});
|
||||
};
|
||||
if (cloudPubkey && cloudPubkey._id) {
|
||||
// there is a public key for that user already in the cloud...
|
||||
// save to local storage
|
||||
self.saveLocalPublicKey(cloudPubkey, function(err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the local user's key either from local storage
|
||||
* or fetches it from the cloud. The private key is encrypted.
|
||||
* If no key pair exists, null is returned.
|
||||
* return [Object] The user's key pair {publicKey, privateKey}
|
||||
*/
|
||||
self.getUserKeyPair = function(userId, callback) {
|
||||
// search for user's public key locally
|
||||
jsonDao.list('publickey', 0, null, function(allPubkeys) {
|
||||
var pubkey = _.findWhere(allPubkeys, {
|
||||
userId: userId
|
||||
});
|
||||
callback(null, cloudPubkey);
|
||||
});
|
||||
} else {
|
||||
// no public key for that user
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if (!pubkey || !pubkey._id) {
|
||||
// no public key by that user id in storage
|
||||
// find from cloud by email address
|
||||
cloudstorage.getPublicKeyByUserId(userId, function(err, cloudPubkey) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// that user's public key is already in local storage
|
||||
callback(null, pubkey);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (cloudPubkey && cloudPubkey._id) {
|
||||
// there is a public key for that user already in the cloud...
|
||||
// sync keypair to local storage
|
||||
syncKeypair(cloudPubkey._id);
|
||||
} else {
|
||||
// continue without keypair... generate in crypto.js
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Gets the local user's key either from local storage
|
||||
* or fetches it from the cloud. The private key is encrypted.
|
||||
* If no key pair exists, null is returned.
|
||||
* return [Object] The user's key pair {publicKey, privateKey}
|
||||
*/
|
||||
KeychainDAO.prototype.getUserKeyPair = function(userId, callback) {
|
||||
var self = this;
|
||||
|
||||
} else {
|
||||
// that user's public key is already in local storage...
|
||||
// sync keypair to the cloud
|
||||
syncKeypair(pubkey._id);
|
||||
}
|
||||
});
|
||||
// search for user's public key locally
|
||||
jsonDao.list('publickey', 0, null, function(allPubkeys) {
|
||||
var pubkey = _.findWhere(allPubkeys, {
|
||||
userId: userId
|
||||
});
|
||||
|
||||
function syncKeypair(keypairId) {
|
||||
// persist key pair in local storage
|
||||
lookupPublicKey(keypairId, function(err, savedPubkey) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
if (!pubkey || !pubkey._id) {
|
||||
// no public key by that user id in storage
|
||||
// find from cloud by email address
|
||||
self._cloudstorage.getPublicKeyByUserId(userId, function(err, cloudPubkey) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// persist private key in local storage
|
||||
lookupPrivateKey(keypairId, function(err, savedPrivkey) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
if (cloudPubkey && cloudPubkey._id) {
|
||||
// there is a public key for that user already in the cloud...
|
||||
// sync keypair to local storage
|
||||
syncKeypair(cloudPubkey._id);
|
||||
} else {
|
||||
// continue without keypair... generate in crypto.js
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
// validate fetched key
|
||||
if (savedPubkey && savedPubkey.publicKey && savedPrivkey && savedPrivkey.encryptedKey) {
|
||||
callback(null, {
|
||||
publicKey: savedPubkey,
|
||||
privateKey: savedPrivkey
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
// that user's public key is already in local storage...
|
||||
// sync keypair to the cloud
|
||||
syncKeypair(pubkey._id);
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
// continue without keypair... generate in crypto.js
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
function syncKeypair(keypairId) {
|
||||
// persist key pair in local storage
|
||||
self.lookupPublicKey(keypairId, function(err, savedPubkey) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the user's key pair is stored both
|
||||
* locally and in the cloud and persist arccordingly
|
||||
* @param [Object] The user's key pair {publicKey, privateKey}
|
||||
*/
|
||||
self.putUserKeyPair = function(keypair, callback) {
|
||||
// validate input
|
||||
if (!keypair || !keypair.publicKey || !keypair.privateKey || !keypair.publicKey.userId || keypair.publicKey.userId !== keypair.privateKey.userId) {
|
||||
callback({
|
||||
errMsg: 'Incorrect input!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
// persist private key in local storage
|
||||
self.lookupPrivateKey(keypairId, function(err, savedPrivkey) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// store public key locally
|
||||
saveLocalPublicKey(keypair.publicKey, function(err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
// validate fetched key
|
||||
if (savedPubkey && savedPubkey.publicKey && savedPrivkey && savedPrivkey.encryptedKey) {
|
||||
callback(null, {
|
||||
publicKey: savedPubkey,
|
||||
privateKey: savedPrivkey
|
||||
});
|
||||
return;
|
||||
|
||||
// persist public key in cloud storage
|
||||
cloudstorage.putPublicKey(keypair.publicKey, function(err) {
|
||||
// validate result
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// continue without keypair... generate in crypto.js
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// store private key locally
|
||||
saveLocalPrivateKey(keypair.privateKey, function(err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Checks to see if the user's key pair is stored both
|
||||
* locally and in the cloud and persist arccordingly
|
||||
* @param [Object] The user's key pair {publicKey, privateKey}
|
||||
*/
|
||||
KeychainDAO.prototype.putUserKeyPair = function(keypair, callback) {
|
||||
var self = this;
|
||||
|
||||
// persist private key in cloud storage
|
||||
cloudstorage.putPrivateKey(keypair.privateKey, function(err) {
|
||||
// validate result
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
// validate input
|
||||
if (!keypair || !keypair.publicKey || !keypair.privateKey || !keypair.publicKey.userId || keypair.publicKey.userId !== keypair.privateKey.userId) {
|
||||
callback({
|
||||
errMsg: 'Incorrect input!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
// store public key locally
|
||||
self.saveLocalPublicKey(keypair.publicKey, function(err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Helper functions
|
||||
//
|
||||
// persist public key in cloud storage
|
||||
self._cloudstorage.putPublicKey(keypair.publicKey, function(err) {
|
||||
// validate result
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
function lookupPublicKey(id, callback) {
|
||||
// lookup in local storage
|
||||
jsonDao.read('publickey_' + id, function(pubkey) {
|
||||
if (!pubkey) {
|
||||
// fetch from cloud storage
|
||||
cloudstorage.getPublicKey(id, function(err, cloudPubkey) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
// store private key locally
|
||||
self.saveLocalPrivateKey(keypair.privateKey, function(err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// cache public key in cache
|
||||
saveLocalPublicKey(cloudPubkey, function(err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
// persist private key in cloud storage
|
||||
self._cloudstorage.putPrivateKey(keypair.privateKey, function(err) {
|
||||
// validate result
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, cloudPubkey);
|
||||
});
|
||||
});
|
||||
callback(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
} else {
|
||||
callback(null, pubkey);
|
||||
}
|
||||
});
|
||||
}
|
||||
//
|
||||
// Helper functions
|
||||
//
|
||||
|
||||
function lookupPrivateKey(id, callback) {
|
||||
// lookup in local storage
|
||||
jsonDao.read('privatekey_' + id, function(privkey) {
|
||||
if (!privkey) {
|
||||
// fetch from cloud storage
|
||||
cloudstorage.getPrivateKey(id, function(err, cloudPrivkey) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
KeychainDAO.prototype.lookupPublicKey = function(id, callback) {
|
||||
var self = this;
|
||||
|
||||
// cache private key in cache
|
||||
saveLocalPrivateKey(cloudPrivkey, function(err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
// lookup in local storage
|
||||
jsonDao.read('publickey_' + id, function(pubkey) {
|
||||
if (!pubkey) {
|
||||
// fetch from cloud storage
|
||||
self._cloudstorage.getPublicKey(id, function(err, cloudPubkey) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, cloudPrivkey);
|
||||
});
|
||||
// cache public key in cache
|
||||
self.saveLocalPublicKey(cloudPubkey, function(err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
});
|
||||
callback(null, cloudPubkey);
|
||||
});
|
||||
});
|
||||
|
||||
} else {
|
||||
callback(null, privkey);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
callback(null, pubkey);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function saveLocalPublicKey(pubkey, callback) {
|
||||
// persist public key (email, _id)
|
||||
var pkLookupKey = 'publickey_' + pubkey._id;
|
||||
KeychainDAO.prototype.lookupPrivateKey = function(id, callback) {
|
||||
var self = this;
|
||||
|
||||
jsonDao.persist(pkLookupKey, pubkey, function(res1) {
|
||||
// validate result
|
||||
if (res1.key !== pkLookupKey) {
|
||||
callback({
|
||||
errMsg: 'Persisting public key in local storage went wrong!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
// lookup in local storage
|
||||
jsonDao.read('privatekey_' + id, function(privkey) {
|
||||
if (!privkey) {
|
||||
// fetch from cloud storage
|
||||
self._cloudstorage.getPrivateKey(id, function(err, cloudPrivkey) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
callback();
|
||||
});
|
||||
}
|
||||
// cache private key in cache
|
||||
self.saveLocalPrivateKey(cloudPrivkey, function(err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
function saveLocalPrivateKey(privkey, callback) {
|
||||
// persist private key (email, _id)
|
||||
var prkLookupKey = 'privatekey_' + privkey._id;
|
||||
callback(null, cloudPrivkey);
|
||||
});
|
||||
|
||||
jsonDao.persist(prkLookupKey, privkey, function(res1) {
|
||||
// validate result
|
||||
if (res1.key !== prkLookupKey) {
|
||||
callback({
|
||||
errMsg: 'Persisting private key in local storage went wrong!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
callback();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
callback(null, privkey);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
};
|
||||
KeychainDAO.prototype.saveLocalPublicKey = function(pubkey, callback) {
|
||||
// persist public key (email, _id)
|
||||
var pkLookupKey = 'publickey_' + pubkey._id;
|
||||
|
||||
return KeychainDAO;
|
||||
jsonDao.persist(pkLookupKey, pubkey, function(res1) {
|
||||
// validate result
|
||||
if (res1.key !== pkLookupKey) {
|
||||
callback({
|
||||
errMsg: 'Persisting public key in local storage went wrong!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
KeychainDAO.prototype.saveLocalPrivateKey = function(privkey, callback) {
|
||||
// persist private key (email, _id)
|
||||
var prkLookupKey = 'privatekey_' + privkey._id;
|
||||
|
||||
jsonDao.persist(prkLookupKey, privkey, function(res1) {
|
||||
// validate result
|
||||
if (res1.key !== prkLookupKey) {
|
||||
callback({
|
||||
errMsg: 'Persisting private key in local storage went wrong!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
return KeychainDAO;
|
||||
});
|
@ -2,124 +2,123 @@
|
||||
* Handles generic caching of JSON objects in a lawnchair adapter
|
||||
*/
|
||||
define(['lawnchair', 'lawnchairSQL', 'lawnchairIDB'], function(Lawnchair) {
|
||||
'use strict';
|
||||
'use strict';
|
||||
|
||||
var self = {};
|
||||
var self = {},
|
||||
db;
|
||||
|
||||
var db;
|
||||
self.init = function(dbName) {
|
||||
if (!dbName) {
|
||||
throw new Error('Lawnchair DB name must be specified!');
|
||||
}
|
||||
|
||||
self.init = function(dbName) {
|
||||
if (!dbName) {
|
||||
throw new Error('Lawnchair DB name must be specified!');
|
||||
}
|
||||
db = new Lawnchair({
|
||||
name: dbName
|
||||
}, function(lc) {
|
||||
if (!lc) {
|
||||
throw new Error('Lawnchair init failed!');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
db = new Lawnchair({
|
||||
name: dbName
|
||||
}, function(lc) {
|
||||
if (!lc) {
|
||||
throw new Error('Lawnchair init failed!');
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Create or update an object
|
||||
*/
|
||||
self.persist = function(key, object, callback) {
|
||||
db.save({
|
||||
key: key,
|
||||
object: object
|
||||
}, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create or update an object
|
||||
*/
|
||||
self.persist = function(key, object, callback) {
|
||||
db.save({
|
||||
key: key,
|
||||
object: object
|
||||
}, callback);
|
||||
};
|
||||
/**
|
||||
* Persist a bunch of items at once
|
||||
*/
|
||||
self.batch = function(list, callback) {
|
||||
db.batch(list, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Persist a bunch of items at once
|
||||
*/
|
||||
self.batch = function(list, callback) {
|
||||
db.batch(list, callback);
|
||||
};
|
||||
/**
|
||||
* Read a single item by its key
|
||||
*/
|
||||
self.read = function(key, callback) {
|
||||
db.get(key, function(o) {
|
||||
if (o) {
|
||||
callback(o.object);
|
||||
} else {
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Read a single item by its key
|
||||
*/
|
||||
self.read = function(key, callback) {
|
||||
db.get(key, function(o) {
|
||||
if (o) {
|
||||
callback(o.object);
|
||||
} else {
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* List all the items of a certain type
|
||||
* @param type [String] The type of item e.g. 'email'
|
||||
* @param offset [Number] The offset of items to fetch (0 is the last stored item)
|
||||
* @param num [Number] The number of items to fetch (null means fetch all)
|
||||
*/
|
||||
self.list = function(type, offset, num, callback) {
|
||||
var i, from, to,
|
||||
matchingKeys = [],
|
||||
intervalKeys = [],
|
||||
list = [];
|
||||
|
||||
/**
|
||||
* List all the items of a certain type
|
||||
* @param type [String] The type of item e.g. 'email'
|
||||
* @param offset [Number] The offset of items to fetch (0 is the last stored item)
|
||||
* @param num [Number] The number of items to fetch (null means fetch all)
|
||||
*/
|
||||
self.list = function(type, offset, num, callback) {
|
||||
var i, from, to,
|
||||
matchingKeys = [],
|
||||
intervalKeys = [],
|
||||
list = [];
|
||||
// get all keys
|
||||
db.keys(function(keys) {
|
||||
|
||||
// get all keys
|
||||
db.keys(function(keys) {
|
||||
// check if key begins with type
|
||||
keys.forEach(function(key) {
|
||||
if (key.indexOf(type) === 0) {
|
||||
matchingKeys.push(key);
|
||||
}
|
||||
});
|
||||
|
||||
// check if key begins with type
|
||||
keys.forEach(function(key) {
|
||||
if (key.indexOf(type) === 0) {
|
||||
matchingKeys.push(key);
|
||||
}
|
||||
});
|
||||
// sort keys
|
||||
matchingKeys.sort();
|
||||
|
||||
// sort keys
|
||||
matchingKeys.sort();
|
||||
// set window of items to fetch
|
||||
// if num is null, list all items
|
||||
from = (num) ? matchingKeys.length - offset - num : 0;
|
||||
to = matchingKeys.length - 1 - offset;
|
||||
// filter items within requested interval
|
||||
for (i = 0; i < matchingKeys.length; i++) {
|
||||
if (i >= from && i <= to) {
|
||||
intervalKeys.push(matchingKeys[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// set window of items to fetch
|
||||
// if num is null, list all items
|
||||
from = (num) ? matchingKeys.length - offset - num : 0;
|
||||
to = matchingKeys.length - 1 - offset;
|
||||
// filter items within requested interval
|
||||
for (i = 0; i < matchingKeys.length; i++) {
|
||||
if (i >= from && i <= to) {
|
||||
intervalKeys.push(matchingKeys[i]);
|
||||
}
|
||||
}
|
||||
// return if there are no matching keys
|
||||
if (intervalKeys.length === 0) {
|
||||
callback(list);
|
||||
return;
|
||||
}
|
||||
|
||||
// return if there are no matching keys
|
||||
if (intervalKeys.length === 0) {
|
||||
callback(list);
|
||||
return;
|
||||
}
|
||||
// fetch all items from data-store with matching key
|
||||
db.get(intervalKeys, function(intervalList) {
|
||||
intervalList.forEach(function(item) {
|
||||
list.push(item.object);
|
||||
});
|
||||
|
||||
// fetch all items from data-store with matching key
|
||||
db.get(intervalKeys, function(intervalList) {
|
||||
intervalList.forEach(function(item) {
|
||||
list.push(item.object);
|
||||
});
|
||||
// return only the interval between offset and num
|
||||
callback(list);
|
||||
});
|
||||
|
||||
// return only the interval between offset and num
|
||||
callback(list);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Removes an object liter from local storage by its key (delete)
|
||||
*/
|
||||
self.remove = function(key, callback) {
|
||||
db.remove(key, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes an object liter from local storage by its key (delete)
|
||||
*/
|
||||
self.remove = function(key, callback) {
|
||||
db.remove(key, callback);
|
||||
};
|
||||
/**
|
||||
* Clears the whole local storage cache
|
||||
*/
|
||||
self.clear = function(callback) {
|
||||
db.nuke(callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the whole local storage cache
|
||||
*/
|
||||
self.clear = function(callback) {
|
||||
db.nuke(callback);
|
||||
};
|
||||
|
||||
return self;
|
||||
return self;
|
||||
});
|
Loading…
Reference in New Issue
Block a user