UNPKG

edudb

Version:
234 lines (213 loc) 7.79 kB
const fs = require('fs'); const path = require('path'); class db { // Set default config constructor() { this.root = '.\\db\\'; this.encoding = 'utf8'; } // DONE /** * Set initial configuration for the database to work. * @param {object} options How to config the database. * @param {string} options.root Root directory path. Default is '.\db' * @param {string} options.encoding Encoding for the files to save and open. Default is 'utf-8' * @returns {void} */ config(options) { // Config aren't stored localy /** options = { * root: path, * encoding: string * } */ if(options != undefined && typeof options == 'object') { // For root if(options.root == undefined) { if(!fs.existsSync('.\\db')) { fs.mkdir('.\\db\\', function(err) {if(err) throw "Error to create db root directory. Please create it manually at "+path.normalize(__dirname + '\\db\\')}); this.root = '.\\db\\'; } } else { options.root = path.normalize(options.root + "\\"); this.root = options.root; if(!fs.existsSync(options.root)) { fs.mkdir(options.root, function(err) {if(err) throw("Error to create db root directory. Pleace create it manually at "+options.root)}); } } // For encoding options.encoding == undefined ? this.encoding = 'utf8' : this.encoding = options.encoding; } else if(typeof options != 'object' && options != undefined) { throw "Options to define db class must be an object."; } else { // options == undefined this.root = '.\\db\\'; this.encoding = 'utf8'; } } // DONE ///// IN functions: to directories /** * To create a table in the database that will hold the information you want to put. Only works with objects. * @param {string} name Name for the table. This is the name you will use to get the table. (see get()) * @param {object} options Options to create the table. At version 1.2.0, it only can read options.structure. * @param {object} options.structure Index 0 in the table and works as guide for you while setting the next row. * @returns {boolean} Returns true if file was created and false if it already existed. */ createTable(name, options) { var path = this.root + name + '.json'; var data = []; if(options != undefined) { if(typeof options == 'object') { if(options.structure != undefined && typeof options.structure == 'object') { data[0] = options.structure; } else { throw "Structure in options must be an object!"; } } else { throw "Options must be an object to create a table!"; } } // Check if exists if(!this.exists(name)) { // Write file data = JSON.stringify(data); fs.writeFileSync(path, data, this.encoding); return true; } else { return false; } } // DONE /** * Saves the table you indicated in the root directory for the database. * @param {string} table Name of the table to save. * @param {object} obj After you did get(), for this argument you must set that object. * @returns {void} Will throw an error if there's no obj specified. */ save(table, obj) { if(typeof obj == 'object' || typeof obj == 'array') { obj = JSON.stringify(obj); fs.writeFileSync(this.root + table + '.json', obj); } else { throw "Obj argument must be an object or an array."; } } // DONE ///// OUT functions: to client /** * To get access to a table and get the information, you must use this method. EduDB works with JSON files so you will get an easy to use object. * @param {string} table Name of the table to get. * @returns {object|undefined} Returns an array with all the rows of the table. */ get(table) { var path = this.root + table + '.json'; if(this.exists(table)) { return JSON.parse(fs.readFileSync(path, this.encoding)); } else { //throw("Table \""+table+"\" doesn't exist!"); return undefined; } } // DONE /** * Get an array of all the tables created sorted by name. This is useful for automating your program working only with index. * @returns {object} An array with the names of the tables. */ list() { var result = []; var files = fs.readdirSync(this.root, this.encoding); for (var i = 0; i < files.length; i++) { result.push(path.parse(files[i]).name); } return result; } // DONE /** * Useful method for finding information in the whole database. The first parameter works in a strict way where the first index is the proporty and the next stands for its value. * db.find([property1, whichValue1, property2, value2, ...propertyN, ...valueN]); * @param {object} args Array indicating first the property to find and then the value. i.e.: ["name", "lasangreesroja", "id", 0] * @param {string} [table] Optional. If indicated, will only search in the specifed table. * @returns {object|undefined} If there's no property with that value, will return undefined. If found, will return an object with the table name where found (find().table), the entire row object (find().row) and the index of the row in the table (find().index). */ find(args, table) { // Check syntax for args if(args != undefined) { if(typeof args == 'object') { if(args.length != 0) { if(args.length % 2 == 0) { // Check 'table' argument if(table != undefined && typeof table == 'string') { var file = JSON.parse(fs.readFileSync(this.root + table + '.json', this.encoding)); if(typeof file == 'object') { // Check every index of the array for (var j = 0; j < file.length; j++) { var paramSucceed = false; // Check if has every property properties: for (var param = 0; param < args.length / 2; param++) { if(file[j].hasOwnProperty(args[2 * param]) && file[j][args[2 * param]] == args[2 * param + 1]) { paramSucceed = true; } else { // If hasn't property, try next row paramSucceed = false; break properties; } if(param == args.length/2 - 1 && paramSucceed) { return { table: table, row: file[j], index: j } } } } } } else { var dir = this.list(); // Check every file in root for (var i = 0; i < dir.length; i++) { var file = JSON.parse(fs.readFileSync(this.root + dir[i] + '.json', this.encoding)); if(typeof file == 'object') { // Check every index of the array for (var j = 0; j < file.length; j++) { var paramSucceed = false; // Check if has every property properties: for (var param = 0; param < args.length / 2; param++) { if(file[j].hasOwnProperty(args[2 * param]) && file[j][args[2 * param]] == args[2 * param + 1]) { paramSucceed = true; } else { // If hasn't property, try next row paramSucceed = false; break properties; } if(param == args.length/2 - 1 && paramSucceed) { return { table: dir[i], row: file[j], index: j } } } } } } } } else { throw "Array's length in find() must be pair for [attr, value, attr, value, ...]!"; } } } else { throw "First argument in find() must be an array!"; } } } // DONE /** * Check if a table exists in the root directory. * @param {string} table Name of the table to check */ exists(table) { var path = this.root + table + '.json'; if(fs.existsSync(path)) { return true; } else { return false; } } // DONE } // To import: const db = require('db'); // and that should be applying new db(); module.exports = new db();