UNPKG

sjdb

Version:

The simple lightweight (2.75Kb) with 0 depencies embedded/persistant JSON database to Node.js, made for little projects.

18 lines (17 loc) 8.57 kB
var fs=require("fs"),readline=require("readline"),JDatabase=function(l,k){var a=this;this.dir={path:l};this.file={path:k};this.db={isCompressed:!1,isCompacted:!1};this.core={secureMod:!1,handleEx:!1,log:{active:!1,dir:(this.dir.path+this.file.path+"/log").toString()},sjdbfy:function(d){return a.db.isCompacted?JSON.stringify(d):JSON.stringify(d,null,4)},compress:function(){var d=fs.readFileSync(a.dir.path+"/"+a.file.path+".json"),d=JSON.parse(d),d=JSON.stringify(d);fs.writeFileSync(a.dir.path+"/"+ a.file.path+".json",d)},fancify:function(){var d=fs.readFileSync(a.dir.path+"/"+a.file.path+".json"),d=JSON.parse(d),d=JSON.stringify(d,null,4);fs.writeFileSync(a.dir.path+"/"+a.file.path+".json",d)}};if(1==this.core.handleEx)process.on("uncaughtException",function(d){a.log.write("An exeption occured, SJDB handle every exeptions for data security, if you want that SJDB stop handling exeptions, set 'db.core.handleEx = false', error: \n"+d,"danger")});this.tables={};this.create=function(d){var f=!0, c=!0;a.dir.path.substring(2,a.length)==a.file.path&&(a.file.path+=Math.random().toString().substring(2,3));if(1!=d){try{fs.accessSync(a.dir.path)}catch(b){f=!1,fs.mkdirSync(a.dir.path),a.log.log("Creating directory..","info")}try{fs.accessSync(a.file.path)}catch(b){c=!1}if(f&&1==a.core.secureMod){a.log.log(a.dir.path+" directory already exists! For security reasons, to overwrite your databases, please delete them manualy (/!\\ or give true as argument /!\\).","danger");return}if(c){a.log.log(a.file.path+ " database already exists! For security reasons, to overwrite your database, please delete it manualy (/!\\or give true as argument /!\\).","danger");return}}fs.writeFileSync(a.dir.path+"/"+a.file.path+".json",a.core.sjdbfy({}));1==a.core.log.active&&(fs.writeFileSync(a.dir.path+"/"+a.file.path+"_log.log",""),fs.writeFileSync(a.dir.path+"/"+a.file.path+"_log.html",""))};this.table=function(d){var f=a.dir.path+"/"+a.file.path+".json";a.tables[d]={name:d,create:function(c){void 0==c&&(c={});var b=fs.readFileSync(f, "utf8"),b=JSON.parse(b);b[d]?a.log.write('table "'+d+'" already exists! For security reasons, to overwrite it, please delete this table manualy.',"danger"):(b[d]=c,fs.writeFileSync(f,a.core.sjdbfy(b)))},put:function(c,b){var e=fs.readFileSync(f,"utf8"),e=JSON.parse(e);e[d][c]?a.log.log('key "'+c+'" already exists! For security reasons, to overwrite it, please delete this key manualy.',"danger"):(e[d][c]=b,fs.writeFileSync(f,a.core.sjdbfy(e)),a.log.log("Put "+b+" as "+c+" in "+f))},get:function(c, b){var e=fs.readFileSync(f,"utf8"),e=JSON.parse(e);if(!c)return e[d];if(e[d][c])return b?a.core.sjdbfy(e[d][c]):e[d][c];a.log.log('key "'+c+"\" doesn' exists!","danger")},update:function(c,b){var e=fs.readFileSync(f,"utf8"),e=JSON.parse(e);e[d][c]?(void 0==c?e[d]=b:e[d][c]=b,fs.writeFileSync(f,a.core.sjdbfy(e))):a.log.log('key "'+c+"\" doesn' exists!","danger")},"delete":function(c){var b=fs.readFileSync(f,"utf8"),b=JSON.parse(b);c?b[d][c]?(delete b[d][c],fs.writeFileSync(f,a.core.sjdbfy(b)),a.log.log("Key "+ c+" of table "+d+" was deleted!")):a.log.log('key "'+c+"\" doesn' exists!","danger"):b[d]?(delete b[d],fs.writeFileSync(f,a.core.sjdbfy(b)),a.log.log("Table "+d+" deleted!")):a.log.log("table "+d+" doesn't exists!","danger")}};return a.tables[d]};this.log={log:function(d,f){a.core.log.active&&("danger"==f?console.error(d):console.log("[SJDB]",d))},write:function(d,f){if(a.core.log.active){void 0==f&&(f="log");var c=new Date,c=(c.toLocaleDateString()+"|"+c.toLocaleTimeString()).toString(),b,e;"info"== f&&(b="color: blue;",e="color: white");"log"==f&&(b="color: #888888;",e="color: white;");"danger"==f&&(b="color: red;",e="font-weight: 600; color: red;");"success"==f&&(b="color: green;",e="font-weight: 100; color: #2ecc71;");fs.appendFile(a.dir.path+a.file.path+"/log.log",c+" ["+f+"] >> "+d+"\n");fs.appendFile(a.dir.path+a.file.path+"/log.html",'<span style="color:grey;">'+c+'</span><span style="'+b+'"> ['+f+']</span> >> <span style="'+e+'">'+d+"</span><br/>");console.log("[SJDB]",d)}},open:function(){var a= require("child_process").exec,f=process.platform;"win32"==f||"win64"==f?a("cd database & log.html",function(a,b,d){a&&console.log("[SJDB]",a)}):"linux"==f&&a("cd database & xdg-open log.html",function(a,b,d){this.log.write(b)})},clear:function(){fs.writeFileSync(a.dir.path+a.file.path+"/log.log","");fs.writeFileSync(a.dir.path+a.file.path+"/log.html",'<link href="https://fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet"> <style>html {font-family: "Inconsolata", monospace; background: black; color: white;}</style>')}}; this.QueryCLI=function(d){void 0==d&&(d="-/");var f=require("querystring");console.log("[SJDB]","< SJDB Query CLI started >");readline.createInterface({input:process.stdin,output:process.stdout}).on("line",function(c){if(c.substring(0,d.length).toString()==d){c=c.substring(d.length,c.length);c=f.parse(c,".");var b=[],e;for(e in c)b.push(e);if("db"==b[0])if("create()"==b[1])a.create();else if("table"==b[1].substring(0,5)){e="";c=b[1].substring(6,b[1].lenght);for(var g in c)"'"!=c[g]&&")"!=c[g]&&" "!= c[g]&&(e+=c[g]);if("get"==b[2].substring(0,3)){c=b[2].substring(4,b[2].lenght);var h="";for(g in c)"'"!=c[g]&&")"!=c[g]&&(h+=c[g]);a.log.write(a.table(""+e).get(""+h),"info")}else if("put"==b[2].substring(0,3)){c=b[2].substring(4,b[2].lenght);g={};c=f.parse(c,",");b=0;for(h in c)g[b]=h,b++;g[1]=g[1].toString().slice(1,-1);g[0]=g[0].replace(/[\"\']+/g,"");g[1]=g[1].replace(/[\"\']+/g,"");a.table(e).put(g[0],g[1])}else if("update"==b[2].substring(0,6)){c=b[2].substring(7,b[2].lenght);g={};c=f.parse(c, ",");b=0;for(h in c)g[b]=h,b++;g[1]=g[1].toString().slice(1,-1);a.table(e).update(g[0],g[1])}else"create()"==b[2].substring(0,8)?a.table(""+e).create():"delete"==b[2].substring(0,6)?"delete()"==b[2]?a.table(e)["delete"]():(h=b[2].substring(8,b[2].lenght).toString(),h=h.slice(0,-2),a.table(e)["delete"](h)):a.log.write("Invalid SJDB CLI command!","danger")}else"log"==b[1]?"open()"==b[2]?a.log.open():"clear()"==b[2]&&a.log.clear():"core"==b[1]?"compress()"==b[2]?a.core.compress():"fancify()"==b[2]?a.core.fancify(): a.log.write("Invalid SJDB CLI command!","danger"):a.log.write("Invalid SJDB CLI command!","danger");else"help"==b[0]?console.log("[SJDB]","< SJDB Query CLI help >\n\n"+d+"db\n .create(force[true||false@default]): Create a new database. Overwrite if true gived as arg.\n .table('tableName'): Select table as target.\n .create(): Create new table as '.table()' argument.\n\t.put('key', 'value'): Insert string or int as key into db, don't support objects. Use real editor.\n .update('key', 'newValue'): Update key.\n .get('key', 'value'): Get value from key.\n .delete('key'): Remove key and he's value.\n .get(): Get table.\n .delete(): Delete table.\n .log\n .open(): Open logs in HTML file.\n .clear(): Clear logs.\n .core\n .compress(): Improve database's speed by compressing data, use only for production.\n .fancify(): Fancify database for humain readability, less faster, use this command only for reading.\n .makeBenchmark(ops): Run a benchmark on a new db with arg Put, Update, Delete operations.\n"): "makeBenchmark"==b[0].substring(0,13)?(h=b[0].substring(14,a.length),h=h.substring(0,h.length-1),makeBenchmark(h)):a.log.write("Invalid SJDB CLI command!","danger")}})}}; function makeBenchmark(l){if(void 0==l)console.error("Need number of operations in argument.");else{"linux"!=process.platform&&console.warn("Starting benchmark for "+l+" ops, keep in mind that your OS can slow down nodejs process, for this reason, you should benchmark on a real server.");var k=new JDatabase("./~BENCHMARK~",Math.random().toString().substring(14));k.create();k.table("Benchmark").create();console.time("Put");k.table("Benchmark").create();for(var a=0;a<l;a++)k.table("Benchmark").put(a, a);console.timeEnd("Put");console.time("Update");for(a=0;a<l;a++)k.table("Benchmark").update(a,"klj");console.timeEnd("Update");console.time("Delete");for(a=0;a<l;a++)k.table("Benchmark")["delete"](a.toString());fs.existsSync(k.dir.path)&&(fs.readdirSync(k.dir.path).forEach(function(a,f){var c=k.dir.path+"/"+a;fs.lstatSync(c).isDirectory()?deleteFolderRecursive(c):fs.unlinkSync(c)}),fs.rmdirSync(k.dir.path));console.timeEnd("Delete");console.log("[SJDB]","When there is more than 1 000 keys in the same file, we recommand you to split a big database into smallers databases.")}} module.exports={JDatabase:JDatabase,makeBenchmark:makeBenchmark};