UNPKG

zetabasejs

Version:

A NoSQL database for quick deployment.

370 lines (299 loc) 9.5 kB
# ZetabaseJS ## A NoSQL database for quick deployment * [Get started](#get-started) * [Installation](#installation) * [Hello World](#hello-world) * [Structure](#structure) * [Operations](#operations) * [Write](#write) * [Read](#read) * [Append](#append) * [List](#list) * [Wipe](#wipe) * [Query](#query) &nbsp;&nbsp;⭐ <strong>Updated 1.1.73<strong> * [Monitor](#monitor) * [Modules](#modules) * [ORM](#orm) ## Get started ### Installation ```bash npm install --save zetabasejs ``` ### Hello World ```javascript const Zetabase = require("zetabasejs") const db = new Zetabase("database.json") //Specify a filename. db.write('/', 'Hello World !!') let data = db.read('/') console.log("Read DB: ", data) // Read DB: Hello World !! ``` ### Structure A data node contains 2 parts, `data` & `childNodes`. `Write` operation will update the value in `data`, which can be retrieved by `Read` function. `Append` operation will update the value in `childNodes`, which can be retrieved by `List` function. ## Operations > All operations are synchronized. ### Write ```javascript db.write('/path', data); let retrieve = db.read('/path'); console.log(retrieve) //The data is retrieved already. db.write('/path/notExistFolder/subFolder', data); //The missing path will be created automatically. db.write('/wallet', {balance: 351.5, timestamp: 1565485663}) //Just write the object into db. ``` ### Read ```javascript let balance = db.read('/wallet') //Retrieve the value in data part. Output: { balance: 351.5, timestamp: 1565485663 } // The value will be null if empty. ``` ### Append ```javascript db.append('/cart', {productCode: '#704FV4', price: 30, timestamp: 1565485663}) db.append('/cart', {productCode: '#604PG4', price: 20.9, timestamp: 1565485703}) db.append('/cart', {productCode: '#204KJ4', price: 70.4, timestamp: 1565485710}) db.append('/cart', {productCode: '#304TI2', price: 3.9, timestamp: 1565485716}) //The objects will be added to the childNodes with an unique key. ``` ### List ```javascript //List all appended objects. db.list('/cart', (product, key)=>{ console.log(` Product: ${JSON.stringify(product)} Key: ${key} `) }) Product: {"productCode":"#704FV4","price":30,"timestamp":1565485663,"key":"2b0941aab466211b1c0752719c3d693b"} Key: 2b0941aab466211b1c0752719c3d693b Product: {"productCode":"#604PG4","price":20.9,"timestamp":1565485703,"key":"0c0381d3010fa7197d1658733cf2002a"} Key: 0c0381d3010fa7197d1658733cf2002a ... //Nested list. let receiptKey = db.append('/receipts', {customerId: '#c001', totalPrice: 53.6, timestamp: 1565485716}) db.append('/receipts/'+receiptKey, {productCode: '#704FV4', price: 30, timestamp: 1565485663}) db.append('/receipts/'+receiptKey, {productCode: '#604PG4', price: 20.9, timestamp: 1565485703}) db.append('/receipts/'+receiptKey, {productCode: '#204KJ4', price: 70.4, timestamp: 1565485710}) db.append('/receipts/'+receiptKey, {productCode: '#304TI2', price: 3.9, timestamp: 1565485716}) db.list('/receipts', (receipt, key, products_dataNode)=>{ products_dataNode.list(product=>console.log(` 'Product code:', ${product.productCode}, 'Price:', ${product.price}, 'Timestamp:', ${product.timestamp} `)) }) ``` ### Wipe ```javascript //The empty folder will be removed automatically. db.write('/A/B', 'Content in B') db.write('/A/B/C/D', 'Content in D') // In memory { "data": null, "childNodes": { "A": { "id": "A", "data": null, "childNodes": { "B": { "id": "B", "data": "Content in B", "childNodes": { "C": { "id": "C", "data": null, "childNodes": { "D": { "id": "D", "data": "Content in D", "childNodes": {} } } } } } } } } } db.wipe('/A/B/C/D') // In memory, folder C is removed automatically { "data": null, "childNodes": { "A": { "id": "A", "data": null, "childNodes": { "B": { "id": "B", "data": "Content in B", "childNodes": {} } } } } } ``` ### Query ```javascript let aliceId = db.append("/Customers", { name: "Alice", gender: "F" }) let katyId = db.append("/Customers", { name: "Katy", gender: "F" }) let bobId = db.append("/Customers", { name: "Bob", gender: "M" }) let tomId = db.append("/Customers", { name: "Tom", gender: "-" }) let waterId = db.append("/Product/drinks", { name: "Water", description: "300ml" }) let breadId = db.append("/Product/foods", { name: "Bread" }) db.append("/Transactions", { customerId: aliceId, products: [ { productCode: waterId, quantity: 10 }, { productCode: breadId, quantity: 6 }, ] }) db.append("/Transactions", { customerId: bobId, products: [ { productCode: breadId, quantity: 40 } ] }) // Query all female/not gender specified customers let customers = db.query("/Customers/:key/@{name, gender}", { gender: val => ['F', '-'].includes(val) }) // Output // [ { name: 'Alice', gender: 'F' }, // { name: 'Katy', gender: 'F' }, // { name: 'Tom', gender: '-' } ] // Query all transactions for Alice and Katy let transactions = db.query("/Transactions/:key/@{}", { customerId: val => [aliceId, katyId].includes(val) }) // Output // [ { customerId: '6a7b5c84159b2e05837a2c4a3fcf5a6b', // products: [ [Object], [Object] ], // key: '9d705f589d16f6e69067679f479bab2f' } ] // Query all transactions that contains water. transactions = db.query("/Transactions/:key/@{}", { products: val => val.filter(v => v.productCode == waterId).length > 0 }) transactions.map(trans => { let cust = db.read("/Customers/" + trans.customerId) console.log(`Customer:\t${cust.name}`) console.log(`Product:\t${JSON.stringify(trans.products, null, 2)}`) }) // Output // Customer: Alice // Product: [ // { // "productCode": "17978e7bdb1b9eb1deffa6e37883c34a8DEbA", // "quantity": 10 // }, // { // "productCode": "fd08c2ebcef2c7243017a058ad650f898DEbA", // "quantity": 6 // } // ] ``` ### Monitor > Monitor changes in that level only. ```javascript // There are 3 action codes, WRITE, APPEND and WIPE db.monitor('/Supermarket/status', status=>console.log("Supermarket's status is changed: ", status)) db.monitor('/Supermarket/purchaseOrder', (order, actCode) => { if (actCode === "APPEND") { console.log(` An order is made.\n orderId:, ${order.id}, totalAmount:, ${order.totalAmount} `) } else if (actCode === "WIPE") { console.log(` This order is cancelled.\n orderId:, ${order.id}, totalAmount:, ${order.totalAmount} `) } }) let orderKey = db.append('/Supermarket/purchaseOrder', { id: '#o001', totalAmount: 100 }) // Output // An order is made. // orderId:, #o001, // totalAmount:, 100 db.wipe('/Supermarket/purchaseOrder/'+orderKey) // Output // This order is cancelled. // orderId:, #o001, // totalAmount:, 100 db.write('/Supermarket/status', 'Closed'); // Output // Supermarket's status is changed: Closed ``` ## Modules ### ORM ```javascript const Zetabase = require("zetabasejs") const crypto = require('crypto') // Require the Model class, which contains 3 properties // __ctime__: creation time // __mtime__: last modify time // __key__: entity's key const { Model } = require("zetabasejs/orm") // Pass option { orm: true } to Zetabase constructor // Default is false const db = new Zetabase('./ormDemo.json', { orm: true }) // class Product extends Model { constructor(name, productCode, price) { super() this.name = name; this.productCode = productCode; this.price = price; } description() { console.log(`Product name: ${this.name}, Product Code: ${this.productCode}, Price: ${this.price}`) } } db.wipe('/') for (let i = 0; i < 5; i++) { let name = { en: crypto.randomBytes(2).toString('hex'), zh: crypto.randomBytes(4).toString('hex') } new Product(name, crypto.randomBytes(8).toString('hex'), Math.floor(Math.random() * 100) + 1).put() } let options = { filters: { price: v => v > 50 }, //Filter fields: '{__key__, name, name.zh, productCode, price}', // Select the response value, default is all. get: false //Default is true, which return an instance. Set to false to return the object contains the selected fields only. } let prods = Product.query(options); //Pass options object as params // prods [ { __key__: '350295370a6b98fb63cc0c8495f00984', name: { en: 'b3ca', zh: 'c3700382' }, 'name.zh': 'c3700382', productCode: '2bc6fb0714f2585e', price: 95 }, { __key__: 'eba710dc0a6185b6512ba0dfad2d75a3', name: { en: '55ab', zh: '206a6a6e' }, 'name.zh': '206a6a6e', productCode: '52ac26b1796b657d', price: 93 } ] let firstProd = prods[0] //The query result is an object. firstProd.description() // firstProd Product { __ctime__: 1574498716475000, __mtime__: 1574498716475000, __key__: '350295370a6b98fb63cc0c8495f00984', name: { en: 'b3ca', zh: 'c3700382' }, productCode: '2bc6fb0714f2585e', price: 95 } //Output Product name: [object Object], Product Code: 8b81f7f2d494d061, Price: 90 ```