UNPKG

jsonq-js

Version:

JSON Query Javascript Libiary

1,030 lines (1,001 loc) 28.6 kB
(function(){ function _checkString(arg){ if(arg.constructor==String){ return arg.split(","); } return arg } function _hasStr(s,str){ return s.indexOf(str)!==-1 } function _cloneArray(arr) { var a=new Array(); arr.forEach(function(item){ a.push(_clone(item)); }); return a; }; function _sortByAttr(arr,a,type, b) { var c = arr.length; var d, current; for (var i = 1; i < c; i++) { d = i - 1; current = arr[i]; while (d >= 0 && _compareValue(arr[d][a],current[a],type) ) { arr[d + 1] = arr[d]; d-- } arr[d + 1] = current } if (type == false||b==false) { arr.reverse() } return arr }; function _compareValue(a,b,type){ if(_getSortValue(a,type)>_getSortValue(b,type)){ return true; } return false; }; function _getSortValue(value,type){ if(type==undefined||_type(type)=="boolean"){ return value; }else{ var res=null; switch(type){ case "date": if(_type(value)=="date"){ res=value; }else{ var arr; if(_hasStr(value,'-')){ arr=value.split("-"); }else{ arr=value.split("/"); } res=new Date(arr[0],arr[1],arr[2]); }break; case "length":res=value.length;break; case "headLetter":res=value.toLowerCase().charCodeAt(0);break; case "number":res=value;break; default:res=value;break; } return res; } }; function _type(obj){ if(arguments.length==0){ throw new Error("This function need a argument"); }else{ var type=typeof obj; if(type=="object"){ if(obj===null){ return "null"; }else{ var con = obj.constructor; switch(con){ case Object:type="json";break; case Array:type="array";break; case HTMLCollection:type="htmlcollection";break; case NodeList:type="nodelist";break; case FormData:type="formdata";break; case Error:type="error";break; case Date:type="date";break; default:if(_hasStr(con.toString(),'HTML')){ type="htmlelement"; }else{ type="object"; };break; } } } return type; } }; function _clone(obj){ if(obj==undefined){ return null; } var type=_type(obj); if(type=="array"){ return _cloneArray(obj); }else if(type=="json"||type=="object"){ var a=new Object(); for(var attr in obj){ if(obj[attr]==null||obj[attr]==undefined){ a[attr]=obj[attr]; }else if(_type(obj[attr])=="array"){ a[attr]=_cloneArray(obj[attr]); }else if(_type(obj[attr])=="json"||_type(obj[attr])=="object"){ a[attr]=_clone(obj[attr]); }else{ a[attr]=obj[attr]; } } return a; }else if(type=="number"||type=="boolean"||type=="string"||type=="function"){ return obj; }else{ return obj; } }; //var arg=1; var TYPE={ update:"update", select:"select", delete:"delete", insert:"insert", add:"add", remove:"remove", clear:"clear", groupBy:"groupBy", desc:"desc", asc:"asc", all:"*" }; var FUN={ //avg count first last max min sum:"sum", count:"count", avg:"avg", distinct:"distinct", first:"first", last:"last", max:"max", min:"min", array:["sum","count","avg","distinct","first","last","max","min"] } function _jqlSetAttrAndValue(data,set){ var attra=[]; var valuea=[]; for(var attr in data){ attra.push(attr); valuea.push(data[attr]); } set.attr(attra); set.value(valuea); } function _jqlSelect(get,set,arg,run){ if(arg==undefined||arg.constructor==Boolean){ if(run===true||arg===true){ return _jqlCheckReturn(get.data(),get); } arg=TYPE.all; } if(get.canQuery()){ set.type(TYPE.select); set.attr(_checkString(arg)); return _jqlCheckRun.call(this,run); } return this; }; function _jqlUpdate(get,set,data,value,run){ return _addAndUpdateCom.call(this,get,set,data,value,run,TYPE.update); }; function _jqlAdd(get,set,data,value,run){ return _addAndUpdateCom.call(this,get,set,data,value,run,TYPE.add); } function _addAndUpdateCom(get,set,data,value,run,type){ if(get.canQuery()){ set.type(type); if(data.constructor==Object){ _jqlSetAttrAndValue(data,set); run=value; }else{ set.attr(_checkString(data)); set.value(_checkString(value)); } return _jqlCheckRun.call(this,value,run); } return this; } function _jqlRemove(get,set,arg,run){ set.type(TYPE.remove); if(arg!=undefined&&arg.constructor!=Boolean){ set.attr(_checkString(arg)); return _jqlCheckRun.call(this,run); }else { set.attr(TYPE.all); if(arg.constructor==Boolean){ return _jqlCheckRun.call(this,run); } } return this; } function _jqlDelete(get,set,index,run){ set.type(TYPE.delete); if(index!=undefined&&index.constructor==Number){ set.index(index); return _jqlCheckRun.call(this,run); } return _jqlCheckRun.call(this,index); } function _jqlInsert(get,set,a1,a2,a3,a4){//(arg,value,i,run) set.type(TYPE.insert); if(a1.constructor==Object){ set.attr(a1); if(a2!=undefined){ if(a2.constructor==Number){ set.index(a2); return _jqlCheckRun.call(this,a3); }else{ return _jqlCheckRun.call(this,a2); } } }else{ set.attr(_checkString(a1)); set.value(_checkString(a2)); if(a3!=undefined){ if(a3.constructor==Number){ set.index(a3); return _jqlCheckRun.call(this,a4); }else{ return _jqlCheckRun.call(this,a3); } } } return this; } function _jqlSetCondAttrAndValue(data,set){ var attra=[]; var valuea=[]; for(var attr in data){ attra.push(attr); valuea.push(data[attr]); } set.condAttr(attra); set.condValue(valuea); } function _jqlWhere(get,set,attr,value,run){ if(get.type()===""){ _throw("where:使用where之前必须使用select、update、add、remove、insert、delete方法之一"); }else{ if(attr.constructor==Object){ _jqlSetCondAttrAndValue(attr,set); run=value; }else{ if(value!=undefined&&value.constructor==String){ set.condAttr(_checkString(attr)); set.condValue(_checkString(value)); }else{//复杂模式 bool表达式 set.condAttr(attr); run=value; } } set.cond(true); return _jqlCheckRun.call(this,value,run); } } function _jqlCheckWhere(index,get,realI){ if(get.cond()){ var data=get.data()[index]; var attr=get.condAttr(); if(get.condValue().length>0){ for(var i=0;i<attr.length;i++){ if(data[attr[i]]!=get.condValue()[i]){ return false; } } }else{//bool表达式 var attrs=_getObjectAttr(data); eval("var "+attrs); var $index=index; var $i=index; if(realI!=undefined){ $index=realI; } for(var i=0;i<attrs.length;i++){ if(_hasStr(attr,attrs[i])){ var item=data[attrs[i]]; if(item==undefined){ _throw("where:"+attrs[i]+"属性不存在"); }else{ eval(attrs[i]+"="+JSON.stringify(item)); } } } return eval(attr); } } return true; } function _getObjectAttr(obj){ var arr=[]; for(attr in obj){ arr.push(attr); } return arr; } function _jqlGroupBy(get,set,attr,run){ if(attr==undefined||attr.constructor!=String){ _throw("groupBy属性参数必须非空且为字符串"); }else{ set.groupAttr(attr); return _jqlCheckRun.call(this,run); } }; function _throw(str){ str=str||"未知异常"; throw new Error(str); } function _jqlOrderBy(get,set,attr,order,orderType,run){ if(attr==undefined||attr.constructor!=String){ _throw("orderBy属性参数必须非空且为字符串"); }else{ set.orderAttr(attr); if(order!=undefined){ if(order.constructor==String){ order=order.toLowerCase(); if(order=="desc"||order=="asc"){ set.order(order); if(orderType!=undefined&&orderType.constructor==String){ set.orderType(orderType); } }else{ set.orderType(order); } return _jqlCheckRun.call(this,order,orderType,run); } return _jqlCheckRun.call(this,order); } return this; } }; function _getRunGroupBySelect(obj,sel,as){ if(sel){ if(as[0]==TYPE.all||as[0]==""){ return obj; } var d={}; if(as!=TYPE.all&&as.length>0){ as.forEach(function(a){ d[a]=obj[a]; }); } return d; } return obj; } function _checkSelectAttr(attr){ for(var i=0;i<attr.length;i++){ if(_hasStr(attr[i],"(")){ return false; } } return true; } function _jqlCheckReturn(res,get){ if(get.single()){ return _clone(res[0]); } return _clone(res); } function _checkRunOrderBy(get,res){ var attr=get.orderAttr(); if(attr!=""){ if(get.order()=="desc"){ _sortByAttr(res,attr,get.orderType(),false); }else{ _sortByAttr(res,attr,get.orderType()); } } return res; } function _checkRunGroupBy(get,data){ //avg count count(DISTINCT ) first last max min //实现函数 var attr=get.groupAttr(); var as=get.attr(); var gres=[]; var vs=[]; var norSel=_checkSelectAttr(as); if(attr!=""){ data.forEach(function(item){ if(item.hasOwnProperty(attr)){ var index=vs.index(item[attr]); if(index==-1){ vs.push(item[attr]); gres.push([_getRunGroupBySelect(item,norSel,as)]); }else{ gres[index].push(_getRunGroupBySelect(item,norSel,as)); } }else{ _throw("groupBy:元素中没有"+attr+"属性"); } }); if(!norSel){ var funs=get.groupFuns(); if(funs.length>0){ var funRes=[]; gres.forEach(function(items){ var newobj={}; var names=[]; funs.forEach(function(fun){ if(fun.fun==undefined){ if(fun.attr!=attr){ _throw(fun.attr+" 没有groupBy"); }else{ newobj[attr]=items[0][attr]; } }else{ if(fun.name==TYPE.all){ if(fun.fun!=FUN.count){ _throw("* 不能用于"+fun.fun+"方法"); } fun.name=FUN.count; } if(!_hasStr(names,fun.name)){ names.push(fun.name); }else{ _throw(fun.name+"列名不能相同"); } if(fun.name==fun.attr){ fun.name=fun.fun; } switch(fun.fun){ case FUN.sum:{ newobj[fun.name]=_getGroupAttrArr(items,fun.attr).sum(); };break; case FUN.count:{ newobj[fun.name]=items.length; };break; case FUN.avg:{ newobj[fun.name]=_getGroupAttrArr(items,fun.attr).avg(); };break; case FUN.first:{ newobj[fun.name]=items.first()[fun.attr]; };break; case FUN.last:{ newobj[fun.name]=items.last()[fun.attr]; };break; case FUN.max:{ newobj[fun.name]=_getGroupAttrArr(items,fun.attr).max(); };break; case FUN.min:{ newobj[fun.name]=_getGroupAttrArr(items,fun.attr).min(); };break; default:{ newobj[fun.name]=items[0][fun.attr]; };break; } } }); funRes.push(newobj); }); return funRes; } } return gres; }else{ _throw("groupBy属性参数必须非空且为字符串"); } } function _getGroupAttrArr(arr,attr){ var res=[]; arr.forEach(function(item){ res.push(item[attr]); }); return res; } function _geneGroupFuns(attr){ if(attr.timeOf(" ")>2){ _throw("参数错误:select 参数空格不能多于2个"); }else{ var res={}; if(_hasStr(attr,"(")&&_hasStr(attr,")")){ var arr=attr.split(")"); if(arr[1]!=""){ res.name=arr[1].substring(1); } attr=arr[0]; arr=attr.split("("); res.attr=arr[1].toLowerCase(); if(_hasStr(arr[1]," ")){ arr[1]=arr[1].split(" ")[1]; } if(!res.hasOwnProperty("name")){ res.name=arr[1]; } res.fun=arr[0].toLowerCase(); }else{ if(_hasStr(attr," ")){ res.name=attr.split(" ")[1]; res.attr=attr.split(" ")[0]; }else{ res.attr=res.name=attr; } } return res; } } function _selectCount(get,attr,data){ if(attr.length>1){ _throw("使用count函数时select最多只能选择一列"); } var obj=_geneGroupFuns(attr[0]); var sum=0; var result; if(get.cond()===true){ result=[]; for(var i=0;i<data.length;i++){ if(_jqlCheckWhere(i,get)){ result.push(data[i]); } } }else{ result=data; } if(_hasStr(obj.attr,FUN.distinct)){ var at=obj.attr.split(" ")[1]; var vs=[]; result.forEach(function(item){ if(!_hasStr(vs,item[at])){ vs.push(item[at]); sum++; } }); }else{ if(obj.attr!=TYPE.all&&obj.attr!=""&&!result[0].hasOwnProperty(obj.attr)){ _throw("select:"+obj.attr+"属性不存在"); } sum=result.length; } if(obj.name==TYPE.all||obj.name==""||obj.name==obj.attr){ obj.name=FUN.count; } var r={}; r[obj.name]=sum; return r; } function _jqlRun(get,set){ var data=get.data(); var attr=get.attr(); var value=get.value(); var cond=get.cond(); switch(get.type()){ case TYPE.select:{ var result=[]; var dist=false; var distArr=[]; var sum=0; if(get.groupAttr()==""){//没使用groupBy for(var i=0;i<data.length;i++){ if(_jqlCheckWhere(i,get)){ var r={}; if(attr==TYPE.all){ r=_clone(data[i]); result.push(r); }else{ if(_hasStr(attr[0],FUN.count)){//count 函数 result=_selectCount(get,attr,data); break; }else{ attr.forEach(function(a,j){ var name=a;//别名 if(_hasStr(a,FUN.count)){ _throw("使用count函数时select最多只能选择一列"); } if(_hasStr(a," ")){//别名 var arr=a.split(" "); if(arr.length>3){ _throw("select参数格式错误"); }else if(arr.length==3){ if(arr[0]!=FUN.distinct||j!=0){ _throw("distinct必须放在第一个参数前"); } dist=true; name=arr[2]; a=arr[1]; }else{ if(arr[0]==FUN.distinct){ if(j!=0){ _throw("distinct必须放在第一个参数前"); } dist=true; name=a=arr[1]; }else{ name=arr[1]; a=arr[0]; } } } if(a in data[i]){ if(name in r){ _throw("select:["+name+"]列名不能重复"); } r[name]=data[i][a]; }else{ if(_hasStr(a,"(")){ _throw("select:"+a.split("(")[0]+"函数要与groupBy配合使用"); }else{ _throw("select参数错误,对象不包含"+a+"属性"); } } }); if(dist){ var str=JSON.stringify(r); if(!_hasStr(distArr,str)){ distArr.push(str); result.push(r); } }else{ result.push(r); } } } } } _checkRunOrderBy(get,result);//对select结果order }else{//使用groupBy var funs=[]; attr.forEach(function(a){ if(_hasStr(a,FUN.distinct)){ _throw("groupBy与distinct不能共用"); } funs.push(_geneGroupFuns(a)); }); if(funs.length>0){ set.groupFuns(funs); } result=_checkRunOrderBy(get,_clone(data)); result=_checkRunGroupBy(get,result); } _jqlReset(set); return _jqlCheckReturn(result,get); };break; case TYPE.update:{ for(var i=0;i<data.length;i++){ if(_jqlCheckWhere(i,get)){ attr.forEach(function(item,j){ if(data[i].hasOwnProperty(item)){ data[i][item]=value[j]; }else{ _throw("属性不存在,若要添加新属性,请使用add方法"); } }); } } _jqlReset(set); return _jqlCheckReturn(data,get); };break; case TYPE.add:{ for(var i=0;i<data.length;i++){ if(_jqlCheckWhere(i,get)){ attr.forEach(function(item,j){ if(!data[i].hasOwnProperty(item)){ data[i][item]=value[j] }else{ _throw("属性已存在,若要更新属性,请使用update方法"); } }); } } _jqlReset(set); return _jqlCheckReturn(data,get); };break; case TYPE.remove:{ for(var i=0;i<data.length;i++){ if(_jqlCheckWhere(i,get)){ if(attr==TYPE.all){ data[i]={}; }else{ for(var j=0;j<attr.length;j++){ delete data[i][attr[j]]; } } } } _jqlReset(set); return _jqlCheckReturn(data,get); };break; case TYPE.insert:{ var obj={}; if(attr.constructor==Object){ obj=attr; }else{ for(var i=0;i<attr.length;i++){ obj[attr[i]]=value[i]; } } if(get.index()>=0){ if(get.index()>=data.length){ set.index(data.length-1); } data.insert(obj,get.index()); }else{ data.push(obj); } _jqlReset(set); return _clone(data); };break; case TYPE.delete:{ if(get.index()>=0){ if(_jqlCheckWhere(get.index(),get)){ data.removeByIndex(get.index()); } }else{ var realI=0; for(var i=0;i<data.length;i++){ if(_jqlCheckWhere(i,get,realI)){ data.removeByIndex(i); i--; } realI++; } } _jqlReset(set); return _clone(data); };break; default:{ var res; if(get.cond()===true){ res=[]; for(var i=0;i<data.length;i++){ if(_jqlCheckWhere(i,get)){ res.push(_clone(data[i])); } } }else{ res=_clone(data); } if(get.orderAttr()!=""){//没有sele的order res = _checkRunOrderBy(get,res); } if(get.groupAttr()!=""){//没有sele的group res = _checkRunGroupBy(get,res); } _jqlReset(set); return res; };break; } } function _jqlInitData(data,set){ if(data!=null){ if(data.constructor!=Object&&data.constructor!=Array){ set.canQuery(false); } } } function _jqlCheckRun(){ if(_checkArg.apply(null,arguments)&&this.run!=undefined){ return this.run(); } return this; } function _checkArg(){ if(arguments.length==1){ return (arguments[0]===true); }else{ for(var i=0;i<arguments.length;i++){ if(arguments[i]===true){ return true; } } return false; } } function _jqlReset(set){ set.attr([]); set.value([]); set.cond(false); set.condAttr([]); set.condValue([]); set.index(-1); set.sort(""); set.type(""); set.order(""); set.orderAttr(""); set.orderType("number"); set.groupAttr(""); set.groupFuns([]); } function _jqlCheckData(data){ if(this.data==undefined){ this.canQuery=false; return true; }else if(this.data.constructor==Object||this.data.constructor==Array){ if(data.constructor==String){ this.canQuery=true; return false; }else if(data.constructor==Object||data.constructor==Array){ this.canQuery=true; return true; }else{ this.canQuery=false; _throw("参数错误"); } }else{ if(data.constructor==Object||data.constructor==Array){ this.canQuery=true; }else{ this.canQuery=false; } return true; } }; Jql=function(data){ return new JQL(data); } JQL=function(data){ var _canQuery=true; var _data; var _single=false; if(data.constructor==Object){ _data=[data]; _single=true; }else{ _data=data; } var _attr=[]; var _value=[]; var _cond=false; var _cond_attr=[]; var _cond_value=[]; var _index=-1; var _sort=""; var _type=""; var _order=""; var _order_attr=""; var _order_type="number"; var _group_attr=""; var _group_funs=[]; var set={ canQuery:function(val){ _canQuery=val; },data:function(val){ _data = val; },attr:function(val){ _attr =val; },value:function(val){ _value =val; },cond:function(val){ _cond =val; },condAttr:function(val){ _cond_attr =val; },condValue:function(val){ _cond_value =val; },index:function(val){ _index =val; },sort:function(val){ _sort =val; },type:function(val){ _type =val; },order:function(val){ _order =val; },orderAttr:function(val){ _order_attr =val; },orderType:function(val){ _order_type =val; },groupAttr:function(val){ _group_attr =val; },groupFuns:function(val){ _group_funs =val; } }; var get={ canQuery:function(){ return _canQuery; },data:function(){ return _data; },attr:function(){ return _attr; },value:function(){ return _value; },cond:function(){ return _cond; },condAttr:function(){ return _cond_attr; },condValue:function(){ return _cond_value; },index:function(){ return _index; },sort:function(){ return _sort; },type:function(){ return _type; },single:function(){ return _single; },order:function(){ return _order; },orderAttr:function(){ return _order_attr; },orderType:function(){ return _order_type; },groupAttr:function(){ return _group_attr; },groupFuns:function(){ return _group_funs; } } _jqlInitData(data,set); if(data.constructor==Object){ this.add=function(attr,value){ _jqlAdd.call(this,get,set,attr,value); return _jqlRun.call(this,get,set); }; this.remove=function(attr){ _jqlRemove.call(this,get,set,attr,true); return _jqlRun.call(this,get,set); }; this.select=function(attr){ _jqlSelect.call(this,get,set,attr,true); return _jqlRun.call(this,get,set); }; this.update=function(attr,value){ _jqlUpdate.call(this,get,set,attr,value,true); return _jqlRun.call(this,get,set); }; }else if(data.constructor==Array){ this.add=function(attr,value,run){ return _jqlAdd.call(this,get,set,attr,value,run); }; this.remove=function(attr,run){ return _jqlRemove.call(this,get,set,attr,run); }; this.insert=function(attr,value,index,run){ return _jqlInsert.call(this,get,set,attr,value,index,run); }; this.delete=function(index,run){ return _jqlDelete.call(this,get,set,index,run); }; this.select=function(attr,run){ return _jqlSelect.call(this,get,set,attr,run); }; this.update=function(attr,value,run){ return _jqlUpdate.call(this,get,set,attr,value,run); }; this.run=function(){ return _jqlRun.call(this,get,set); }; this.where=function(attr,value,run){ return _jqlWhere.call(this,get,set,attr,value,run); }; this.orderBy=function(attr,order,type,run){ return _jqlOrderBy.call(this,get,set,attr,order,type,run); }; this.groupBy=function(attr,run){ return _jqlGroupBy.call(this,get,set,attr,run); }; } this.set=function(data){ var datac=_clone(data); if(datac.constructor==Object){ datac=[datac]; } if(_data.constructor!=datac.constructor){ _throw("数据类型不同,无法执行set"); }else{ _data=datac; return data; } }; this.get=function(){ if(_single){ return _clone(_data[0]); } return _clone(_data); }; this.data=function(){ if(_single){ return _data[0]; } return _data; }; this.clear=function(){ _data=null; return null; } }; var Jql; var JQL; if (typeof module !== 'undefined') { module.exports = Jql; } else { if(typeof window.Jql!=='undefined'){ window.Jql = Jql }else{ window.$Jql = Jql } } })();