已在github上建立项目:https://github.com/ThinkerCodeChina/jsonDB
/**
+-----------------------------------------
* jsonDB 基于json数据格式构建的数据模型
+-----------------------------------------
* @description 对json数据检索,删除,查询和更新
* @author 戚银(web程序员) [email protected]
* @date 2014年6月28日
* @version 0.1
* @blog http://blog.csdn.net/thinkercode/
+-----------------------------------------
* 简单介绍:
* jsonDB是js的一个类库,是基于json数据格式构建的数据
* 模型实现对json数据增删改查。 jsonDB的构建源自于HTML5
* 本地存储的一个应用需求,能够通过sql对json数据进行增
* 删改查,同一时候该类库提供强大的where检索条件,数据排序,
* limit查询条件限制等数据库基本功能。 通过jsonDB能够轻
* 松维护一个库/表或多个库/表。而无需额外实现json的数据
* 的维护等,在该类库完好以后为简化sql操作,基于jsonDB核
* 心模块扩展了连贯操作模型,简化对jsonDB的操作以及sql语
* 句出错的概率。
+-----------------------------------------
* 当前版本号的不足:
* 1.无法支持查询字段运算
* 2.不支持对没有选取的查询字段排序
* 3.仅仅支持单个字段排序,无法进行组合排序操作
* 4.update、delete语句不支持order by子句。导致limit子句功能弱化
* 5.编写where条件是必须使用()包括where条件
* 6.无法选取深层次的字段作为返回字段
* 7.没有错误或异常解决方式
* 8.不支持外部扩展
+-----------------------------------------
* jsonDB的使用:
* jsonDB会提供一个具体的使用手冊,当中包括大量演示样例
* jsonDB还有非常多能够使用的技巧并没有一一包括在手冊中
* 期望强大的网友一起挖掘jsonDB的潜在使用技巧。并分享给大家
* 假设使用中发现问题能够随时发送邮件,或者通过博客留言等方式一起探讨
* 同一时候鉴于自己实力有限,期望发动网友一起扩展jsonDB。
* 能在未来前端应用中奉献一份力量
+-----------------------------------------
*/
(function(window,undefined){
_jsonDB = window.jsonDB,
_history = null,
DBCore = {},
Database = {},
DBExpand = {}; /**
* [jsonDB 初始化模型。支持定义本地数据库和数据表]
* @param mixed data 数据
* @param string dbName 数据库名字
* @return jsonDB
*/
var jsonDB = function(data,dbName){ //创建数据库或者数据表
if(data){
dbName = dbName || 'json_db';
eval('Database.'+ dbName +'= data');
} return jsonDB.fn.init();
} jsonDB.fn = jsonDB.prototype = {
//初始化插件
init : function (alias){
if(alias){
_history = window[alias];
window[alias] = jsonDB();
}
return this;
}, query : function(sql){
var type = sql.match(/^(\w+)/);
switch(type[0]){
case 'select' :
case 'delete' :
case 'update' :
return eval('DBCore.fn.'+ type[0] +'(sql+" ")');
break;
default :
return false;
break;
}
}, insert : function(data,dbName){
if(data){
dbName = dbName || 'json_db';
eval('Database.'+ dbName +'.push(data)');
}
return this;
}, findAll : function(dbName){
if(dbName){
return eval('Database.'+ dbName);
}
return Database;
}
}; /**
* [DBExpand 数据库核心功能扩展]
*/
DBExpand = DBExpand.prototype = {
sqlParam : {
fields : '*',
table : 'json_db',
where : null,
order : null,
limit : null,
}, add : function(data){
return this.insert(data,this.sqlParam.table);
}, select : function(){
var sql = 'select '+this.sqlParam.fields+' from '+this.sqlParam.table;
if(this.sqlParam.where){
sql += ' where '+this.sqlParam.where;
}
if(this.sqlParam.order){
sql += ' order by '+this.sqlParam.order;
}
if(this.sqlParam.limit){
sql += ' limit '+this.sqlParam.limit;
} this.clear();
return this.query(sql);
}, update : function(data){
if(data.length<1){
return false;
} var sql = 'update '+this.sqlParam.table+' set '+data;
if(this.sqlParam.where){
sql += ' where '+this.sqlParam.where;
}
if(this.sqlParam.limit){
sql += ' limit '+this.sqlParam.limit;
}
this.clear();
return this.query(sql);
}, delete : function(){
if(this.sqlParam.where.length<1){
return false;
} var sql = 'delete from '+this.sqlParam.table;
if(this.sqlParam.where){
sql += ' where '+this.sqlParam.where;
}
if(this.sqlParam.limit){
sql += ' limit '+this.sqlParam.limit;
}
this.clear();
return this.query(sql);
}, drop : function(dbName){
//创建数据库或者数据表
if(data){
dbName = dbName || 'json_db';
eval('Database.'+ dbName +'= null');
}
return this;
}, field : function(fields){
if(typeof fields == 'object'){
this.sqlParam.fields = fields.join(',');
}else{
this.sqlParam.fields = fields;
}
return this;
}, table : function(table){
this.sqlParam.table = table;
return this;
}, where : function(where){
this.sqlParam.where = '('+where+')';
return this;
}, order : function(order){
this.sqlParam.order = order;
return this;
}, limit : function(limit){
this.sqlParam.limit = limit;
return this;
}, clear : function(){
this.sqlParam.fields = '*';
this.sqlParam.where = null;
this.sqlParam.order = null;
this.sqlParam.limit = null;
}
} /**
* [DBCore 数据库核心]
*/
DBCore.fn = DBCore.prototype = {
SqlRegExp : {
fields: '([a-z0-9_\\,\\.\\s\\*]*?\\s+)',
from : '(from\\s+([a-z0-9_\\.]+)\\s*)?',
where : '(?:where\\s+(\\(.*\\))\\s*)? ',
order : '(?:order\\s+by\\s+([a-z0-9_\\,\\.]+))? \\s+(asc|desc|ascnum|descnum)?\\s*',
limit : '(?:limit\\s+([0-9\\,]+))?',
set : '(set\\s+(.*?)\\s+)',
table : '(([a-z0-9_\\.]*?)\\s*)?',
}, select : function(sql){
var params = {fields:["*"], from:"json_db", where:"", orderby:[], order: "asc", limit:[]},
SqlRegExp = this.SqlRegExp,
reg = '^(select)\\s+'+SqlRegExp.fields + SqlRegExp.from + SqlRegExp.where + SqlRegExp.order + SqlRegExp.limit,
sqlReg = new RegExp(reg,'i'),
sqlFields = sql.match(sqlReg),
options = {
fields: sqlFields[2].replace(' ','').split(','),
from: (sqlFields[4] == undefined) ? 'json_db' : sqlFields[4],
where: (sqlFields[5] == undefined) ? "true" : sqlFields[5].replace(/([^\>\<\!\=])=([^\>\<\!\=])/gi,'$1 == $2').replace(/\sand\s/gi,' && ').replace(/\sor\s/gi,' || ').replace(/`/gi,''),
orderby: (sqlFields[6] == undefined) ? []:sqlFields[6].replace(' ','').split(','),
order: (sqlFields[7] == undefined) ? "asc" : sqlFields[7],
limit: (sqlFields[8] == undefined) ? [] : sqlFields[8].replace(' ','').split(',')
}; for(i in options){
params[i] = options[i];
} var result = [];
result = this.filter(params,function(data){
if(options.fields.length == 0 || options.fields[0] == "*"){
return data;
} var result = {};
for(var i in options.fields){
result[options.fields[i]] = data[options.fields[i]];
}
return result;
});
result = this.orderBy(result,options);
result = this.limit(result,options);
return result;
}, update : function(sql){
var params = {from:"json_db", where:"", limit:[], set:[]},
SqlRegExp = this.SqlRegExp,
reg = '^(update)\\s+'+ SqlRegExp.table + SqlRegExp.set + SqlRegExp.where + SqlRegExp.limit,
sqlReg = new RegExp(reg,'i'),
sqlFields = sql.match(sqlReg),
options = {
from: (sqlFields[3] == undefined) ? 'json_db' : sqlFields[3],
set: (sqlFields[5] == undefined) ? [] : sqlFields[5].replace(' ','').split(','),
where: (sqlFields[6] == undefined) ? "true" : sqlFields[6].replace(/([^\>\<\!\=])=([^\>\<\!\=])/gi,'$1 == $2').replace(/\sand\s/gi,' && ').replace(/\sor\s/gi,' || ').replace(/`/gi,''),
limit: (sqlFields[7] == undefined) ? [] : sqlFields[7].replace(' ','').split(',')
}; for(i in options){
params[i] = options[i];
}
var jsonData = eval('Database.' + options.from),
tally = 0,
extent = this.extent(params),
setLen = options.set.length,
affected_rows = 0; if(setLen<1){
return false;
} options.where = options.where || "true";
for(var i in jsonData){
with(jsonData[i]){
if(eval(options.where)){
if(affected_rows >= extent.start && tally < extent.stop){
for(var j=0;j<setLen;++j){
eval(options.set[j]);
}
++tally;
}else if(tally == extent.stop){
return tally;
}
++affected_rows;
}
}
}
return tally;
}, delete : function(sql){
var params = {from:"json_db", where:"", limit:[]},
SqlRegExp = this.SqlRegExp,
reg = '^(delete)\\s+'+ SqlRegExp.from + SqlRegExp.where + SqlRegExp.limit,
sqlReg = new RegExp(reg,'i'),
sqlFields = sql.match(sqlReg),
options = {
from: (sqlFields[3] == undefined) ? 'json_db' : sqlFields[3],
where: (sqlFields[4] == undefined) ? "true" : sqlFields[4].replace(/([^\>\<\!\=])=([^\>\<\!\=])/gi,'$1 == $2').replace(/\sand\s/gi,' && ').replace(/\sor\s/gi,' || ').replace(/`/gi,''),
limit: (sqlFields[5] == undefined) ? [] : sqlFields[5].replace(' ','').split(',')
}; for(i in options){
params[i] = options[i];
} var jsonData = eval('Database.' + options.from + '.concat()'),
tally = 0,
extent = this.extent(params),
affected_rows = 0; options.where = options.where || "true";
for(var i in jsonData){
with(jsonData[i]){
if(eval(options.where)){
if(affected_rows >= extent.start && tally < extent.stop){
eval('Database.'+options.from+'.splice(i-tally,1)');
++tally;
}else if(tally == extent.stop){
return tally;
}
++affected_rows;
}
}
}
return tally;
}, filter : function(options, callback){
var jsonData = eval('Database.' + options.from),
result = [],
index = 0; options.where = options.where || "true";
for(var i in jsonData){
with(jsonData[i]){
if(eval(options.where)){
if(callback){
result[index++] = callback(jsonData[i]);
}else{
result[index++] = jsonData[i];
}
}
}
} return result;
}, orderBy : function(result,options){
if(options.orderby.length == 0){
return result;
} result.sort(function(a,b){
switch(options.order.toLowerCase()){
case "desc": return (eval('a.'+ options.orderby[0] +' < b.'+ options.orderby[0]))? 1:-1;
case "asc": return (eval('a.'+ options.orderby[0] +' > b.'+ options.orderby[0]))? 1:-1;
case "descnum": return (eval('a.'+ options.orderby[0] +' - b.'+ options.orderby[0]));
case "ascnum": return (eval('b.'+ options.orderby[0] +' - a.'+ options.orderby[0]));
}
}); return result;
}, limit : function(result,options){
switch(options.limit.length){
case 0:
return result;
case 1:
return result.splice(0,options.limit[0]);
case 2:
return result.splice(options.limit[0],options.limit[1]);
}
}, extent : function(options){
switch(options.limit.length){
case 0:
return {start:0, stop:9e+99};
case 1:
return {start:0, stop:options.limit[0]};
case 2:
return {start:options.limit[0], stop:options.limit[1]};
}
}
} window.jsonDB = jsonDB; //追加扩展功能
jsonDB.fn = jsonDB.prototype =extend(jsonDB.fn,DBExpand); //合并对象方法
function extend(){
var paramsLen = arguments.length;
if(paramsLen<1){
return false;
} var target = arguments[0];
for(var i=1;i<paramsLen;++i){
for(var j in arguments[i]){
target[j] = arguments[i][j];
}
} return target;
}
})(window);
源代码与演示样例下载:jsonDB.rar