IPAD的localstorage上限只有5M,不够用,现在想用websql替代,最初设计又没考虑到回调的方式,结果代码修改很多——我个人十分不喜欢html5 websql/file api的调用方式,phonegap的插件使用callback指针,这点还可以理解,至于纯js为什么要设计成这样,不解——抱怨下,下面贴下代码
/**
* Begin class defination XDB : Web sql辅助方法
*/
var XDB = {
db: null,
init: function(dbName, version, dbDisplayName, size){
if(window.openDatabase)
this.db = openDatabase(dbName, version, dbDisplayName, size);
},
exe: function(sql, args, callback){
if(!this.db){
X.log('Web sql not support!');
return;
}
this.db.transaction(function(tx){
if(!sql.contains('t_key_val'))
X.log('Web sql exe : ' + sql + ' || ' + (args ? args.join(',') : 'null'));
tx.executeSql(sql, args, function(tx, results){
if(callback)
callback(results);
}, function(tx, err){
// SQLError
X.log('Web sql execute error: ' + err.message);
});
});
},
exeSqlLl: function(sqlLl, pre, suf){
if(!this.db){
X.log('Web sql not support!');
return;
}
pre = pre || '';
suf = suf || '';
this.db.transaction(function(tx){
X.log('Web sql exe : ' + sqlLl.length);
var savedLog = false;
var i = 0;
for (; i < sqlLl.length; i++){
var sql = sqlLl[i];
if(sql.trim()){
sql = pre + sql + suf;
tx.executeSql(sql, null, null, function(tx, err){
// SQLError
X.log('Web sql execute error: ' + err.message);
if(!savedLog){
X.logDb('Web sql execute error: ' + err.message);
X.logDb('Web sql sql: ' + sql);
savedLog = true;
}
});
}
}
});
},
trans: function(fn){
if(!this.db){
X.log('Web sql not support!');
return;
}
this.db.transaction(fn);
},
// crud
add: function(data, table){
var keys = _.keys(data);
var str1 = keys.join(',');
var str2 = _.map(keys, function(it){return '?';}).join(',');
var sql = 'insert into {0} ({1}) values ({2})';
sql = sql.format(table, str1, str2);
var args = _.values(data);
this.exe(sql, args)
},
del: function(data, table){
var keys = _.keys(data);
var strClause = _.map(keys, function(it){
return it + ' = ?';
}).join(' and ');
var sql = 'delete from {0} where {1}';
sql = sql.format(table, strClause);
var args = _.values(data);
this.exe(sql, args)
},
update: function(data, dataClause, table){
var strSet = _.map(_.keys(data), function(it){
return it + ' = ?';
}).join(', ');
var argsSet = _.values(data);
var strClause = _.map(_.keys(dataClause), function(it){
return it + ' = ?';
}).join(' and ');
var argsClause = _.values(dataClause);
var sql = 'update {0} set {1} where {2}';
sql = sql.format(table, strSet, strClause);
this.exe(sql, argsSet.merge(argsClause))
},
queryItem: function(sql, args, callback){
this.exe(sql, args, function(results){
if(callback){
if(results.rows.length > 0){
var item = results.rows.item(0);
if(!sql.contains('t_key_val'))
X.log('Query resultset item : ' + JSON.stringify(item));
callback(item);
}else{
callback(null);
}
}
});
},
query: function(sql, args, callback){
this.exe(sql, args, function(results){
X.log('Query resultset size : ' + results.rows.length);
if(callback)
callback(results.rows);
});
},
queryAndMap: function(sql, args, callback, callback2){
this.query(sql, args, function(rows){
if(callback){
var i = 0;
for (; i < rows.length; i++){
var record = rows.item(i);
callback(record, i);
}
}
if(callback2)
callback2(rows);
});
},
pi: function(sql, args, cp, npp, callback){
var pager = new XPager(cp, npp, 0);
var countSql = 'select count(1) as rowCount from ({0})'.format(sql);
var subSql = 'select * from ({0}) limit {1}, {2}'.format(sql, pager.getStart(), npp);
var _this = this;
this.query(countSql, args, function(rows){
pager.rowCount = rows.item(0)['rowCount'];
_this.query(subSql, args, function(rows){
if(callback)
callback(pager, rows);
});
});
},
piAndMap: function(sql, args, cp, npp, callback, callback2){
this.pi(sql, args, cp, npp, function(pager, rows){
if(callback){
var i = 0;
for (; i < rows.length; i++){
var record = rows.item(i);
callback(record, i);
}
if(callback2)
callback2(pager);
}
});
},
dump : ''
};
// HTML5本地存储只能存字符串
// 当本地存储受限时候,使用db
var XLocal = {
storage: null,
keyGlobal: null,
init: function(key){
if(window.localStorage){
this.storage = window.localStorage;
if(key){
this.keyGlobal = key;
}
}else{
X.log('Web localStorage api not support!');
}
},
clear: function(){
if(!this.storage){
X.log('Web localStorage api not support!');
return;
}
if(this.keyGlobal){
this.storage.removeItem(this.keyGlobal);
}else{
this.storage.clear();
}
},
get: function(key, unpack){
if(!this.storage){
X.log('Web localStorage api not support!');
return;
}
if(!this.keyGlobal){
var str = this.storage[key];
if(!str || 'undefined' == str || 'null' == str)
return null
if(unpack)
str = LzwCN.unpack(str);
return JSON.parse(str);
}else{
var str = this.storage[this.keyGlobal];
if(str){
var item = JSON.parse(str);
return item ? item[key] : null;
}
}
},
put: function(key, val, pack){
if(!this.storage){
X.log('Web localStorage api not support!');
return;
}
X.log('Web localStorage put ' + key);
if(!this.keyGlobal){
// 先删除,ipad localstorage不删除会有问题?
// http://stackoverflow.com/questions/5887326/is-localstorage-reliable-on-an-ipad
this.remove(key);
var str = JSON.stringify(val);
if(pack)
str = LzwCN.pack(str);
this.storage[key] = str;
}else{
this.remove(key);
var item = {};
var str = this.storage[this.keyGlobal];
if(str)
item = JSON.parse(str);
item[key] = val;
this.storage[this.keyGlobal] = JSON.stringify(item);
}
},
remove: function(key){
if(!this.storage){
X.log('Web localStorage api not support!');
return;
}
X.log('Web localStorage remove ' + key);
if(!this.keyGlobal){
this.storage.removeItem(key);
}else{
var str = this.storage[this.keyGlobal];
if(str){
var item = JSON.parse(str);
if(item){
item[key] = null;
this.storage[this.keyGlobal] = JSON.stringify(item);
}
}
}
},
dump: ''
};
var XLocalDB = {
init: function(){
XDB.exe('create table if not exists t_key_val(k varchar,v varchar)');
},
clear: function(){
var sql = 'delete from t_key_val';
setTimeout(function(){
XDB.exe(sql);
}, 100);
},
/*
XLocalDB.clear()
XLocalDB.put('y', {a: 'xx'})
XLocalDB.get('y', function(item){
X.log(item);
});
*/
get: function(key, fn){
var sql = 'select v from t_key_val where k = ?';
var sqlArgs = [key];
XDB.queryItem(sql, sqlArgs, function(item){
if(!item){
if(fn)
fn(null);
}else{
var src = item.v;
if(src){
src = LzwCN.unpack(src);
var val = JSON.parse(src);
if(fn)
fn(val);
}else{
if(fn)
fn(null);
}
}
});
},
put: function(key, val){
X.log('Web DB put ' + key);
var src = JSON.stringify(val);
src = LzwCN.pack(src);
var item = {k: key, v: src};
setTimeout(function(){
XDB.add(item, 't_key_val');
}, 100);
},
remove: function(key){
X.log('Web DB remove ' + key);
var item = {k: key};
setTimeout(function(){
XDB.del(item, 't_key_val');
}, 100);
},
dump: ''
};
注意:调用XDB方法时候,加上setTimeout,这点算是个hack,在使用web sql之前,还想到一个思路是进行字符串压缩,效果也很好,压缩率在50%以上,js的压缩类,我也贴下:
var LzwCN = {};
LzwCN.compress = function(text){
var result = [];
for(var n = 0; n < text.length; n++){
var c = text.charCodeAt(n);
if (c < 128){
result.push(String.fromCharCode(c));
}else if (c > 127 && c < 2048){
result.push(String.fromCharCode((c >> 6) | 192));
result.push(String.fromCharCode((c & 63) | 128));
}else{
result.push(String.fromCharCode((c >> 12) | 224));
result.push(String.fromCharCode(((c >> 6) & 63) | 128));
result.push(String.fromCharCode((c & 63) | 128));
}
}
return result.join('');
};
LzwCN.decompress = function(text){
var result = [];
var i = 0, c1 = 0, c2 = 0, c3 = 0;
while(i < text.length){
c1 = text.charCodeAt(i);
if (c1 < 128){
result.push(String.fromCharCode(c1));
i++;
}else if (c1 > 191 && c1 < 224){
c2 = text.charCodeAt(i + 1);
result.push(String.fromCharCode(((c1 & 31) << 6) | (c2 & 63)));
i += 2;
}else{
c2 = text.charCodeAt(i + 1);
c3 = text.charCodeAt(i + 2);
result.push(String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)));
i += 3;
}
}
return result.join('');
};
LzwCN.pack = function(str){
var result = [];
var rstr = this.compress(str);
var i = 0,
size = 0,
xstr = '',
chars = 256,
dict = [];
for(i = 0; i < chars; i++){
dict[String(i)] = i;
}
var splitted = rstr.split('');
var buffer = [];
var current = '';
for(i = 0; i <= splitted.length; i++){
current = new String(splitted[i]);
xstr = (buffer.length == 0) ? String(current.charCodeAt(0)) : (buffer.join('-') + '-' + String(current.charCodeAt(0)));
if (dict[xstr] !== undefined){
buffer.push(current.charCodeAt(0));
}else{
result.push(String.fromCharCode(dict[buffer.join('-')]));
dict[xstr] = chars;
chars++;
buffer = [current.charCodeAt(0)];
}
}
return result.join('');
};
LzwCN.unpack = function(str){
var i,
chars = 256,
dict = [];
for(i = 0; i < chars; i++){
dict[i] = String.fromCharCode(i);
}
var original = new String(str);
var splitted = original.split('');
var buffer = '';
var chain = '';
var result = [];
for(i = 0; i < splitted.length; i++){
var code = original.charCodeAt(i);
var current = dict[code];
if(buffer == ''){
buffer = current;
result.push(current);
}else{
if(code <= 255){
result.push(current);
chain = buffer + current;
dict[chars] = chain;
chars++;
buffer = current;
}else{
chain = dict[code];
if(chain == null){
chain = buffer + buffer.slice(0, 1);
}
result.push(chain);
dict[chars] = buffer + chain.slice(0, 1);
chars++;
buffer = chain;
}
}
}
return this.decompress(result.join(''));
};
最后一句:苹果在ios设备上对html5的支持,我个人表示不信任。
本文深入探讨了WebSQL在iOS设备上的局限性,并提出了使用本地存储和压缩技术作为替代方案。文章详细介绍了如何通过本地存储和WebSQL结合使用,以及在不同场景下的操作方法和优化策略,旨在解决iOS设备上资源受限导致的功能不足问题。
495

被折叠的 条评论
为什么被折叠?



