I'm curious if there is a library or a project out there to provide a generic interface to IndexedDB or to WebSQL, depending on user's browser's support. If they're using Chrome/Safari, use WebSQL, if they're using Firefox or Internet Explorer, use IndexedDB.
The poster of this question appears to have homegrown a solution, but did not provide any source 开发者_Go百科code.
JasonCasden has shared a huge list of libraries/wrappers at his presentation In-browser storage and me. Here is the list:
lawnchair
persistence.js
persistJS
amplify.store
localStorageDB
https://github.com/axemclion/IndexedDB
realStorage
YUI3 CacheOffline
dojox.storage
DomSQL
Impel
ActiveJS ActiveRecord
JazzRecord
picnet.data.DataManager
ShinyCar
lscache
Kizzy
Artemia
microcache.js
Store.js
You might want to go with Lawnchair, which is quite well known, as mentioned by Guido Tapia in the question that you link to.
Either that, or use his picnet.data.DataManager solution.
Also take a look at persistence.js.
I have written YDN-DB for the exact purpose. It is database wrapper for IndexedDB, WebSql and localStorage, build on the top of closure library.
Goal
Beautiful API for secure robust high-performance large-scale web app.
Features
- Support IndexedDB, Web SQL and localStorage storage mechanisms.
- Well tested closure library module.
- Support version migration, encryption, query and transaction.
- Each method call is an atomic transaction. All methods are asynchronous.
- Follow usual javascript etiquette like: single namespace, no global, no error globbing (unless we told you so in doc), no eval, parameterized query, this is this, coding error throw error.
- JQuery plugin available (see download section).
Basic usage
Import lastest minified JS script (see download section) to your HTML files. This will create single object in the global scope, call ydn.db.Storage.
var db = new ydn.db.Storage('db name');
db.setItem('x', 'some value')
db.getItem('x').success(function(value) {
console.log('x = ' + value);
}
Query
Calculate average by using query
q = db.query('customer').average('age');
avg = q.fetch()
Key query
q = db.query('customer', 'age').bound(18, 25, true).where('sex', '=', 'FEMALE').select('full_name')
young_girl_names = q.fetch()
Transaction
p1 = db.key('player', 1);
db.transaction(function() {
p1.get().success(function(p1_obj) {
p1_obj.health += 10;
p1.put(p123_obj);
});
}, [p1]);
Encryption
String value data can be optionally encrypted using SHA-1 cipher.
db = new ydn.db.Store('store name')
db.setSecret(passphase); // generally send from server side upon login
db.setItem(key, value, 3600*1000); // data expire on one hour
db.getItem(key); // data will be decrypted using the provided passphase
Take a look at this: https://github.com/axemclion/IndexedDBShim
It's a polyfill to enable IndexedDB using WebSql. I use it and I think it's quite good, but as every solution, it has some limitations, although you can develop it almost whatever you want without big problems.
The question is answered, I just want to share the updates.
In May 2012 JayData has been released, which is the unified data access library for JavaScript and helps to manage data in IndexedDB, WebSQL, SQLite, MongoDB, HTML5 localStorage databases and Facebook, OData, WebAPI, YQL data services with the same JavaScript Language Query syntax.
Changing to IndexedDB from WebSQL means only changing type of the storage provider:
var todoDB = new TodoDatabase({
provider: 'webSql', databaseName: 'MyTodoDatabase' });
var todoDB = new TodoDatabase({
provider: 'indexedDB', databaseName: 'MyTodoDatabase' });
If you don't specify the provider, the library detects the available storage of the browser/device in the following priority order (WebSQL, IndexedDB, HTML5 localStorage).
Disclaimer: I'm member of the developer team of the open-source JayData project
I hope you (OP) are happy with the solutions suggested in the answer you've accepted.
For those who are still on the hunt for a capable solution (a group which may or may not include OP), check out BakedGoods.
It's a library which establishes a uniform interface that can be used to conduct storage operations in all native, and some non-native client storage facilities. It also maintains the flexibility and options afforded to the user by each.
With it, conducting storage operations in whichever of the database types is supported is a matter of...
... specifying the appropriate operation options and equivalent configs for both database types:
//If the operation is a set(), and the referenced structures
//don't exist, they will be created automatically.
var webSQLOptionsObj = {
databaseName: "Example_DB",
databaseDisplayName: "Example DB",
databaseVersion: "",
estimatedDatabaseSize: 1024 * 1024,
tableData: {
name: "Main",
keyColumnName: "lastName",
columnDefinitions: "(lastName TEXT PRIMARY KEY, firstName TEXT)"
},
tableIndexDataArray: [name: "First_Name_Index", columnNames: "(firstName)"]
};
var indexedDBOptionsObj = {
databaseName: "Example_DB",
databaseVersion: 1,
objectStoreData: {
name: "Main",
keyPath: lastName,
autoIncrement: false
},
objectStoreIndexDataArray: [
{name: "First_Name_Index", keyPath: "firstName", unique: false, multiEntry: false}
],
};
var optionsObj = {
conductDisjointly: false,
webSQL: webSQLOptionsObj,
indexedDB: indexedDBOptionsObj
};
... and conducting the operation:
bakedGoods.set({
data: [
{value: {lastName: "Obama", firstName: "Barack"}},
{value: {lastName: "Biden", firstName: "Joe"}}
],
storageTypes: ["indexedDB", "webSQL"],
options: optionsObj,
complete: function(byStorageTypeStoredItemRangeDataObj, byStorageTypeErrorObj){}
});
Its simple interface and unmatched storage facility support comes at the cost of lack of support for some storage facility-specific configurations. For instance, it does not support the conduction of storage operations in WebSQL tables with multi-column primary keys.
So if you make heavy use of those types of features, you may want to look elsewhere.
Oh, and for the sake of complete transparency, BakedGoods is maintained by yours truly :) .
精彩评论