`

使用web sql适配local storage存储

 
阅读更多

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的支持,我个人表示不信任。

分享到:
评论

相关推荐

    HTML5本地存储——Web SQL Database

    然而,理解Web SQL的概念对于理解现代Web存储机制仍然很有帮助,尤其是当面临需要支持旧版浏览器的项目时。 在提供的压缩包文件`test`中,可能包含了实现上述操作的示例代码,读者可以查阅以加深理解。通过学习和...

    使用Web SQL数据库.pptx

    使用 Web SQL 数据库 Web SQL 数据库是 HTML5 中的一种存储机制,它...使用 Web SQL 数据库可以实现客户端存储数据,并提供了一个类似于关系型数据库的存储机制。但是,需要注意浏览器的支持性、数据安全性等问题。

    jquery+easyui+websql.rar

    在本项目中,"jquery+easyui+web...虽然WebSQL已经过时,但其背后的思想——即在客户端存储数据以提高性能和用户体验——在现代Web开发中仍然非常重要,现在通常使用IndexedDB或者LocalStorage+Service Worker来实现。

    WebSQL例子、webSQL 增删改查

    总之,WebSQL提供了一种在浏览器中存储结构化数据的方法,尽管不再推荐使用,但在一些老项目或特定场景下,理解并掌握WebSQL的使用仍然很重要。通过了解如何创建数据库、表,以及执行增删改查操作,开发者可以有效地...

    vue+element-ui+websql

    在“vue+element-ui+websql”这个项目中,开发者选择使用 Vue.js 作为基础框架来构建应用的逻辑和视图层。Vue.js 提供了双向数据绑定、虚拟DOM、指令系统等特性,使得开发者可以轻松地管理应用程序的状态和视图更新...

    解析HTML5的存储功能和web SQL的相关操作方法

    本文将详细解析HTML5的存储机制,包括session storage和local storage,并介绍如何利用JavaScript进行Web SQL数据库操作。 首先,HTML5引入了session storage和local storage两种存储方式,以解决HTTP cookies存在...

    HTML 5离线存储之Web SQL

    Web SQL是一种基于客户端的数据库存储技术,允许开发者在用户的浏览器中存储数据。它提供了一个简单的API来执行SQL命令,可以用来创建表、插入数据、查询数据等。尽管目前Web SQL已被弃用,但其概念和技术仍然被广泛...

    Web SQL数据库概述.pptx

    2. Web SQL Database使用SQL语言来操作客户端数据库的API。 3. Web SQL Database的API包括openDatabase、transaction和executeSql三个核心方法。 4. Web SQL Database已经被广泛实现在不同的浏览器中,尤其是在...

    Microsoft SQL Server 2012 Express LocalDB.zip

    在Visual Studio (VS) 2017中,如果你尝试打开一个依赖于数据库的.NET项目,可能会遇到错误提示,指出"web项目需要安装SQL Server 2012 Express LocalDB"。这个提示意味着你的开发环境缺少SQL Server的一个轻量级...

    websql使用

    WebSQL是旧版的Web数据库标准,主要用于在浏览器中存储大量结构化数据,尤其是在移动设备上。它提供了一个类似于SQLite的关系型数据库系统,允许开发者通过JavaScript进行操作。尽管WebSQL已被弃用,但它在一些老...

    webSql/LocalStorage

    例如,你可以使用JavaScript的AJAX技术从服务器获取数据,然后将其存储到LocalStorage或WebSQL中;当用户操作时,JavaScript可以读取这些数据并更新界面。 在文件名"01"中,可能包含了实现WebSQL或LocalStorage的...

    前端开源库-anysql-websql

    anysql-websql库的目标是提供与MySQL类似的API接口,使得开发者可以更方便地在Web应用中使用SQL语句进行数据管理。 **二、anysql API** anysql是一个轻量级的JavaScript库,致力于简化Node.js和浏览器中的SQL查询...

    WebSql 学习实例

    WebSQL是Web应用程序本地存储数据的一种机制,尤其适用于离线应用。它是一个内置于浏览器中的SQLite数据库,允许JavaScript在客户端进行复杂的数据操作,无需服务器的交互。本学习实例将深入探讨WebSQL的基本概念、...

    webSQL基础JS库

    将Web SQL基本操作封装成一个类

    [其他类别]WEB SQL数据库管理工具_web_sql_manager.zip

    【标题解析】 标题中的"[其他类别]WEB SQL数据库管理工具_web_sql_manager...了解并掌握这样一个Web SQL数据库管理工具,对于Web开发者来说,不仅可以提升开发效率,也有助于更好地理解和维护使用Web SQL数据库的应用。

    WEB页面执行SQL

    WEB页面执行SQLWEB页面执行SQLWEB页面执行SQLWEB页面执行SQLWEB页面执行SQLWEB页面执行SQLWEB页面执行SQLWEB页面执行SQLWEB页面执行SQLWEB页面执行SQLWEB页面执行SQLWEB页面执行SQLWEB页面执行SQLWEB页面执行SQLWEB...

    前端开源库-websql

    websql 是一个前端开源库,它允许在浏览器环境中使用 SQL 数据库技术进行本地数据存储。在 Web 应用程序中,特别是在离线应用或者需要大量数据存储的场景下,WebSQL 提供了一个非常实用的解决方案。尽管现在更多的...

    .NET6WebAPI使用Sqlserver+JWT增删改查

    在本项目中,".NET6WebAPI使用Sqlserver+JWT增删改查"是一个基于最新.NET框架.NET6构建的Web应用程序示例,主要用于演示如何利用ASP.NET Core Web API与SQL Server数据库进行数据操作,以及结合JWT(JSON Web Tokens...

    Web_SQL_Manage

    7. **未来发展趋势**:由于Web SQL的局限性和不再更新,开发者更倾向于使用更现代的Web存储技术,如IndexedDB和Web Storage(Local Storage和Session Storage)。然而,理解Web SQL的概念和技术仍然是了解Web存储...

Global site tag (gtag.js) - Google Analytics