-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheasyStorage.min.js
5 lines (5 loc) · 12.6 KB
/
easyStorage.min.js
1
2
3
4
5
/*!
* easyStorage 0.5 (experimental)
* (c) 2020 Richard Franklin Chinedu
*/
class EasyStorage{constructor(database){this.init(database),this.createEventSpace(),window.addEventListener("storage",e=>{"__$easyStorage"==e.key&&(this.updateEasystorage(),Object.keys(this.dbEvents[this.db.name].events.tabupdate.values).forEach(el=>{this.dbEvents[this.db.name].events.tabupdate.values[el].callback()},this))})}init(database){localStorage.__$easyStorage?(this.__$easyStorage=JSON.parse(localStorage.__$easyStorage),this.__$easyStorage.databaseHolder[database]?(this.db=this.__$easyStorage.databaseHolder[database],this.addMethods()):(this.__$easyStorage.databaseHolder[database]={name:database,tables:{}},localStorage.__$easyStorage=JSON.stringify(this.__$easyStorage),this.db=this.__$easyStorage.databaseHolder[database],this.addMethods())):(localStorage.__$easyStorage=JSON.stringify({databaseHolder:{[database]:{name:database,tables:{}}}}),this.__$easyStorage=JSON.parse(localStorage.__$easyStorage),this.db=this.__$easyStorage.databaseHolder[database],this.addMethods())}createEventSpace(){this.dbEvents={[this.db.name]:{events:{tabupdate:{lastInsertId:0,values:{}}}}}}addMethods(){let that=this;Object.defineProperty(Object.prototype,"getAll",{configurable:!0,value:function(){let tablename;return this.tablename?this:that.db.tables}}),Object.defineProperty(Object.prototype,"getFirst",{configurable:!0,value:function(){let tablename;return this.tablename?this[0]:that.db.tables}}),Object.defineProperty(Object.prototype,"getLast",{configurable:!0,value:function(){let tablename=this.tablename,len=this.length;return tablename?this[len-1]:that.db.tables}}),Object.defineProperty(Object.prototype,"batch",{configurable:!0,value:function(start,stop){let tablename;return this.tablename?this.slice(start,stop):that.db.tables}}),Object.defineProperty(Object.prototype,"from",{configurable:!0,value:function(tablename){let selectFrom=JSON.parse(this.selectFrom),result=that.db.tables[tablename].records.map((el,i)=>{let resObj={};return"*"!=selectFrom?selectFrom.forEach(item=>{item in el&&(resObj[item]=el[item])}):resObj=el,resObj});return result=that.removeFalsy(result),that.addProperties([{target:result,key:"tablename",value:tablename},{target:result,key:"selectFrom",value:this.selectFrom},{target:result,key:"type",value:this.type}]),result}}),Object.defineProperty(Object.prototype,"like",{configurable:!0,value:function(value,isInclude){let tablename=this.tablename,expression=JSON.parse(this.expression),type=this.type,likeValue=value,isDelete="delete"==type;if(expression in that.db.tables[tablename].fields){if(!value)throw new Error("argument for like cant be empty");let valIndex=value.indexOf("%"),isExact=value.indexOf("%")!=value.lastIndexOf("%")&&value.length-1==value.lastIndexOf("%")||-1==value.indexOf("%"),realVal=value.replace(/%/gi,""),keyword=isInclude?"includes":0==valIndex?"startsWith":"endsWith",result;if(isExact&&!isInclude)result=that.db.tables[tablename].records.filter((el,i)=>{let passed=el[expression]==realVal;return isDelete&&passed&&that.db.tables[tablename].records.splice(i,1,!1),passed}),that.db.tables[tablename].records=that.removeFalsy(result),that.updateLocalStorage(type);else{let tableValue=that.db.tables[tablename].records;result=that.db.tables[tablename].records.filter((el,i)=>{let passed=String(el[expression])[keyword](realVal);return isDelete&&passed&&that.db.tables[tablename].records.splice(i,1,!1),passed}),that.db.tables[tablename].records=that.removeFalsy(tableValue),that.updateLocalStorage(type)}return that.addProperties([{target:result,key:"tablename",value:tablename},{target:result,key:"type",value:type},{target:result,key:"likeValue",value:likeValue},{target:result,key:"expression",value:JSON.stringify(expression)},{target:result,key:"like",value:!0}]),result}{let tableValue=that.db.tables[tablename].records,columnArr=expression.split(" "),column=columnArr[0],operator=columnArr[1];operator="="==operator?"==":operator,operator=">"==operator?"<":"<"==operator?">":operator;let operand=columnArr[2],result=that.db.tables[tablename].records.filter((el,i)=>{let passed=eval(operand+" "+operator+" "+el[column]);return isDelete&&passed&&that.db.tables[tablename].records.splice(i,1,!1),passed});return that.db.tables[tablename].records=that.removeFalsy(tableValue),that.updateLocalStorage(type),that.addProperties([{target:result,key:"tablename",value:tablename},{target:result,key:"type",value:type},{target:result,key:"likeValue",value:likeValue},{target:result,key:"expression",value:JSON.stringify(expression)},{target:result,key:"like",value:!0}]),result}}}),Object.defineProperty(Array.prototype,"values",{configurable:!0,value:function(obj){let tablename=this.tablename,expressionArr=this.expression?JSON.parse(this.expression):[],like=this.like,likeValue=this.likeValue,type=this.type,expressObj=that.expressionObject(that.formatExpression(expressionArr));if(!likeValue)return that.db.tables[tablename].records.forEach(el=>{eval(el[expressObj.firstOperand]+" "+expressObj.operator+" "+expressObj.secondOperand)&&Object.keys(obj).forEach(userEl=>{el[userEl]=obj[userEl],that.updateLocalStorage(type)},that)});{if(!likeValue)throw new Error("argument for like cant be empty");let valIndex=likeValue.indexOf("%"),isExact=likeValue.indexOf("%")!=likeValue.lastIndexOf("%")&&likeValue.length-1==likeValue.lastIndexOf("%")||-1==likeValue.indexOf("%"),realVal=likeValue.replace(/%/gi,""),keyword=0==valIndex?"startsWith":"endsWith";isExact?that.db.tables[tablename].records.forEach(el=>{eval(expressObj.secondOperand+" "+expressObj.operator+" "+el[expressObj.firstOperand])&&Object.keys(obj).forEach(userEl=>{el[userEl]=obj[userEl],that.updateLocalStorage(type)},that)}):that.db.tables[tablename].records.forEach(el=>{String(el[expressionArr])[keyword](realVal)&&Object.keys(obj).forEach(userEl=>{el[userEl]=obj[userEl],that.updateLocalStorage(type)},that)})}}}),Object.defineProperty(Object.prototype,"all",{configurable:!0,value:function(){let tablename=this.tablename,type;if("delete"==this.type&&(that.db.tables[tablename].records=[],!that.db.tables[tablename].records.length))return that.updateLocalStorage("delete"),!0}}),Object.defineProperty(Object.prototype,"where",{configurable:!0,value:function(expressionArr){let tablename=this.tablename,type=this.type,selectFrom=!!this.selectFrom&&JSON.parse(this.selectFrom),expression="Array"==that.typeOf(expressionArr)?JSON.stringify(expressionArr):JSON.stringify([expressionArr]);if(expressionArr in that.db.tables[tablename].fields){let tablename=this.tablename,where=that.db.tables[tablename].records;return that.addProperties([{target:where,key:"expression",value:expression},{target:where,key:"tablename",value:tablename},{target:where,key:"type",value:type}]),where}{let expressObj=that.expressionObject(that.formatExpression(expressionArr)),tableValue=that.db.tables[tablename].records,result=that.db.tables[tablename].records.map((el,i)=>{let e1=JSON.stringify(el[expressObj.firstOperand]),e2=JSON.stringify(expressObj.secondOperand),expressionStr=`${e1} ${expressObj.operator} ${e2}`,passed=eval(expressionStr.toString()),resObj={};return passed&&("delete"==type&&that.db.tables[tablename].records.splice(i,1,!1),selectFrom&&"*"!=selectFrom?selectFrom.forEach(item=>{item in el&&(resObj[item]=el[item])}):resObj=el),resObj});return that.db.tables[tablename].records=that.removeFalsy(tableValue),that.updateLocalStorage(type),result=that.removeFalsy(result),that.addProperties([{target:result,key:"expression",value:expression},{target:result,key:"tablename",value:tablename},{target:result,key:"type",value:type}]),result}}})}expressionObject(expressionArr){return{firstOperand:expressionArr[0],operator:expressionArr[1],secondOperand:expressionArr[2]}}tableExist(tablename){return!!this.db.tables[tablename]}dropTable(tablename){delete this.db.tables[tablename],that.updateLocalStorage("delete")}formatExpression(expressionArr){return expressionArr.map(el=>"="==el?"==":el)}getLastInsertId(tablename){let field=this.db.tables[tablename].fields;for(let record in field)if(field[record].key)return field[record].lastInsertId}create(tablename,fields){this.db.tables[tablename]={records:[]},this.db.tables[tablename].fields="Array"==this.typeOf(fields)?this.validateField(this.ArrayColumnObject(fields)):this.validateField(fields),this.updateLocalStorage("create")}insert(tablename,records){if(!tablename)throw new Error("Invalid Tablename");if(!this.db.tables[tablename])throw new Error(`Inserting into ${tablename} failed. Reason : Table does not exist`);return this.db.tables[tablename].records.push(this.ArrayToRecordObject(tablename,records)),this.updateLocalStorage("insert"),this.addProperties([{target:{},key:"lastInsertId",value:this.getLastInsertId(tablename)}])[0]}convertToObj(arr){let obj={};arr.forEach(el=>{obj[el]=""})}ArrayToRecordObject(tablename,records){let obj={};if("Array"==this.typeOf(records)){let recordsLen,fieldsLen;return records.length==Object.keys(this.db.tables[tablename].fields).length-1&&(records=[1,...records]),Object.keys(this.db.tables[tablename].fields).forEach((element,i)=>{let currentEl=this.db.tables[tablename].fields[element];currentEl.key?(currentEl.lastInsertId=currentEl.lastInsertId?currentEl.lastInsertId+1:1,obj[element]=currentEl.lastInsertId):obj[element]=records[i]>=0||records[i]?records[i]:currentEl.default?currentEl.default:null}),this.validateType(tablename,obj),obj}{let recordsLen,fieldsLen;return Object.keys(records).length==Object.keys(this.db.tables[tablename].fields).length-1&&(records={id:1,...records}),Object.keys(this.db.tables[tablename].fields).forEach((element,i)=>{let currentEl=this.db.tables[tablename].fields[element];currentEl.key?(currentEl.lastInsertId=currentEl.lastInsertId?currentEl.lastInsertId+1:1,obj[element]=currentEl.lastInsertId):obj[element]=records[element]>=0||records[element]?records[element]:currentEl.default?currentEl.default:null}),this.validateType(tablename,obj),obj}}isEmptyArray(arr){return arr.every(el=>!el)}removeFalsy(arr){return arr.filter(el=>Object.keys(el).length&&el)}validateType(tablename,records){return Object.keys(this.db.tables[tablename].fields).forEach((key,i)=>{let type=this.db.tables[tablename].fields[key].type;if(records[key]&&type!=this.typeOf(records[key]))throw new Error(`cant insert ${this.typeOf(records[key])} into ${key} with type : ${type}`)})}validateField(fields){for(let field in fields)if(!("type"in fields[field]))throw new Error(`type not specified for column : ${field}`);return fields}typeOf(input){return input?input.constructor.name:null}ArrayColumnObject(arr){let type=this.typeOf(arr),obj={};return arr.forEach(element=>{obj[element]=""}),obj}updateEasystorage(){let __$easyStorage,storage;JSON.stringify(this.__$easyStorage)!=localStorage.__$easyStorage&&this.init(this.db.name)}updateLocalStorage(type){let __$easyStorage=JSON.stringify(this.__$easyStorage);try{localStorage.__$easyStorage=__$easyStorage}catch(e){throw new Error(e.message)}}getFromLocalStorage(db){return JSON.parse(localStorage.__$easyStorage.databaseHolder[database])}createTrack(tablename,type){if(!tablename)throw new Error("Invalid Tablename");if(!this.db.tables[tablename])throw new Error(`update to ${tablename} failed. Reason : Table does not exist`);let holder=this.db.tables[tablename].records,properties=[{target:holder,key:"tablename",value:tablename},{target:holder,key:"type",value:type}];return this.addProperties(properties)[properties.length-1]}createColumnTrack(column,type){let holder=[],properties=[{target:holder,key:"type",value:type},{target:holder,key:"selectFrom",value:column}];return this.addProperties(properties)[properties.length-1]}select(column){return column="String"==this.typeOf(column)?[column]:column,this.createColumnTrack(JSON.stringify(column),"select")}update(tablename){return this.createTrack(tablename,"update")}delete(tablename){return this.createTrack(tablename,"delete")}addProperties(properties){return properties.map(property=>{let target=property.target,key=property.key,value=property.value;return Object.defineProperty(target,key,{enumerable:!1,configurable:!0,writable:!1,value:value}),target})}on(event,callback,thisValue){this.addEventListener(event,callback,thisValue)}addEventListener(event,callback,thisValue){if(this.dbEvents[this.db.name].events[event])return this.dbEvents[this.db.name].events[event].lastInsertId+=1,this.dbEvents[this.db.name].events[event].values["event"+this.dbEvents[this.db.name].events[event].lastInsertId]={callback:thisValue?callback.bind(thisValue):callback},this.dbEvents[this.db.name].events[event].lastInsertId}removeEventListener(event,eventId,callback,thisValue){if(eventId){let eventKey="event"+eventId;return!!this.dbEvents[this.db.name].events[event].values[eventKey]&&(delete this.dbEvents[this.db.name].events[event].values[eventKey],!callback||(thisValue?callback.bind(thisValue)():callback()))}return null}}