PHP Classes

File: src/js/browser/adapters/UnicacheWebSql.js

Recommend this page to a friend!
  Classes of Nikos M.   Unicache   src/js/browser/adapters/UnicacheWebSql.js   Download  
File: src/js/browser/adapters/UnicacheWebSql.js
Role: Auxiliary data
Content typex: text/plain
Description: Auxiliary data
Class: Unicache
Store cached data in different storage types
Author: By
Last change:
Date: 2 months ago
Size: 8,975 bytes
 

Contents

Class file image Download
!function(UNICACHE){ "use strict"; var PROTO = 'prototype', DB_NAME = 'unicache_websql_db', DB_STORE_NAME = 'unicache_', DB_VER = '1.0', MAX_SIZE = 2 * 1024 * 1024 /* 2MB */, _ = UNICACHE._; var WebSqlCache = UNICACHE.WebSqlCache = function() { this.queue = []; }; function tryExecuteSql(t, sqlStatement, args, cb) { t.executeSql(sqlStatement, args, function(t, res) { if ('function' === typeof cb) cb(null, res); }, function(t, err) { if ('function' === typeof cb) cb(err, null); }); } function set(db, prefix, key, value, expires, cb) { db.transaction(function(t) { // insert or update, based if key exists already tryExecuteSql(t, 'SELECT * FROM "'+DB_STORE_NAME + prefix+'" WHERE key=? LIMIT 1', [key], function(err, res) { if (err) { if ('function' === typeof cb) cb(err, null); return; } if (!res || !res.rows.length) { tryExecuteSql(t, 'INSERT INTO "'+DB_STORE_NAME + prefix+'" (key,value,expires) VALUES(?,?,?)', [key,value,+expires], function(err, res) { if ('function' === typeof cb) cb(err, res); }); } else { tryExecuteSql(t, 'UPDATE "'+DB_STORE_NAME + prefix+'" SET value=?,expires=? WHERE key=?', [value,+expires,key], function(err, res) { if ('function' === typeof cb) cb(err, res); }); } }); }, function(err) { if ('function' === typeof cb) cb(err, null); }); } function get(db, prefix, key, expires, cb) { db.transaction(function(t) { if (null == expires) { tryExecuteSql(t, 'SELECT * FROM "'+DB_STORE_NAME + prefix+'" WHERE key = ?', [key], function(err, res) { if ('function' === typeof cb) cb(err, res && res.rows.length ? {value:res.rows.item(0).value, expires:res.rows.item(0).expires} : null); }); } else { tryExecuteSql(t, 'SELECT * FROM "'+DB_STORE_NAME + prefix+'" WHERE key = ? AND expires >= ?', [key,+expires], function(err, res) { if ('function' === typeof cb) cb(err, res && res.rows.length ? {value:res.rows.item(0).value, expires:res.rows.item(0).expires} : null); }); } }, function(err) { if ('function' === typeof cb) cb(err, null); }); } function del(db, prefix, key, cb) { db.transaction(function(t) { // insert or update, based if key exists already tryExecuteSql(t, 'DELETE FROM "'+DB_STORE_NAME + prefix+'" WHERE key=?', [key], function(err, res) { if ('function' === typeof cb) cb(err, res); }); }, function(err) { if ('function' === typeof cb) cb(err, null); }); } function clear(db, prefix, cb) { db.transaction(function(t) { // insert or update, based if key exists already tryExecuteSql(t, 'DELETE FROM "'+DB_STORE_NAME + prefix+'"', [], function(err, res) { if ('function' === typeof cb) cb(err, res); }); }, function(err) { if ('function' === typeof cb) cb(err, null); }); } function gc(db, prefix, maxlifetime, currenttime, cb) { if (null == currenttime) currenttime = _.time(); db.transaction(function(t) { // insert or update, based if key exists already tryExecuteSql(t, 'DELETE FROM "'+DB_STORE_NAME + prefix+'" WHERE expires < ?', [currenttime-maxlifetime], function(err, res) { if ('function' === typeof cb) cb(err, res); }); }, function(err) { if ('function' === typeof cb) cb(err, null); }); } // extend UNICACHE.Cache class WebSqlCache[PROTO] = Object.create(UNICACHE.Cache[PROTO]); WebSqlCache.isSupported = function() { return 'function' === typeof openDatabase; }; WebSqlCache[PROTO].db = null; WebSqlCache[PROTO].err = null; WebSqlCache[PROTO].queue = null; WebSqlCache[PROTO].open = function(cb) { var self = this; if (null == self.db) { if ('function' === typeof cb) self.queue.push(cb); try{ self.db = openDatabase(DB_NAME, DB_VER, 'UNICACHE Cache Database', MAX_SIZE); } catch(e) { self.err = e; self.db = false; } if (self.db) { self.db.transaction(function(t) { // create db table related to passed cache prefix // NOTE: cannot change prefix in the middle of operations // need to instantiate new instance of WebSqlCache with new prefix // this is done to avoid having to run create table on every sql query, in case prefix has changed tryExecuteSql(t, 'CREATE TABLE IF NOT EXISTS "'+DB_STORE_NAME + self.prefix+'" (id INTEGER PRIMARY KEY, key unique, value, expires INTEGER)', [], function(err, res) { if (err) self.err = err; var queue = self.queue; self.queue = null; queue.map(function(cb) {cb(self.err, self.db);}); }); }, function(err) { self.err = err; var queue = self.queue; self.queue = null; queue.map(function(cb) {cb(self.err, self.db);}); }); } else { var queue = self.queue; self.queue = null; queue.map(function(cb) {cb(self.err, self.db);}); } } else if (self.queue) { if ('function' === typeof cb) self.queue.push(cb); } else { if ('function' === typeof cb) cb(self.err, self.db); } return this; }; WebSqlCache[PROTO].close = function() { var self = this; if (self.db) { self.db = null; } return this; }; WebSqlCache[PROTO].drop = function(prefix, cb) { var self = this; if (self.db) { if (null == prefix) prefix = self.prefix; self.open(function(err, db) { if (err) { if ('function' === typeof cb) cb(err, null); return; } db.transaction(function(t) { tryExecuteSql(t, 'DROP TABLE IF EXISTS "'+DB_STORE_NAME + prefix+'"', [], function(err, res) { if ('function' === typeof cb) cb(err, res); }); },function(err) { if ('function' === typeof cb) cb(err, null); }); }); } }; WebSqlCache[PROTO].dispose = function() { this.close(); this.db = null; this.err = null; this.queue = null; return UNICACHE.Cache[PROTO].dispose.call(this); }; WebSqlCache[PROTO].put = function(key, value, ttl, cb) { var self = this; self.open(function(err, db) { if (err) { if ('function' === typeof cb) cb(err, null); return; } ttl = +ttl; set(db, self.prefix, key, _.serialize(value), _.time() + ttl, cb); }); }; WebSqlCache[PROTO].get = function(key, cb) { var self = this; self.open(function(err, db) { if (err) { if ('function' === typeof cb) cb(err, null); return; } var currenttime = _.time(); get(db, self.prefix, key, currenttime, function(err, res) { if (err) { if ('function' === typeof cb) cb(err, null); return; } if (res && (res.expires < currenttime)) { del(db, self.prefix, key); } if ('function' === typeof cb) { if (!res || (res.expires < currenttime)) { cb(null, false); } else { cb(null, _.unserialize(res.value)); } } }); }); }; WebSqlCache[PROTO].remove = function(key, cb) { var self = this; self.open(function(err, db) { if (err) { if ('function' === typeof cb) cb(err, null); return; } del(db, self.prefix, key, cb); }); }; WebSqlCache[PROTO].clear = function(cb) { var self = this; self.open(function(err, db) { if (err) { if ('function' === typeof cb) cb(err, null); return; } clear(db, self.prefix, cb); }); }; WebSqlCache[PROTO].gc = function(maxlifetime, cb) { var self = this; self.open(function(err, db) { if (err) { if ('function' === typeof cb) cb(err, null); return; } maxlifetime = +maxlifetime; var currenttime = _.time(); gc(db, self.prefix, maxlifetime, currenttime, cb); }); }; return WebSqlCache; }(UNICACHE);