UNPKG

orwelldb

Version:

Library, wich helps syncronize blockchain and any database use datascript protocol to write operations (can be wroten in blockchain transactions hex like scriptSig or scriptPubKey)

270 lines (226 loc) 9.33 kB
var util = require('util'); var base = require('./native') var bitPony = require('bitpony') var tools = require('./tools') function protocol(options, onloaded) { this.hash = bitPony.tool.sha256(new Buffer(options.public_key || "")).toString('hex') this.pubkey = options.public_key; this.options = options this.onInit = onloaded; } util.inherits(protocol, base); protocol.prototype.createDataSet = function (datasetname, data) { var f = this, scenario = { operation: 'create', dataset: datasetname, content: { owner_key: data.owner_key || this.pubkey, writeScript: (("" + data.writeScript) == '5560' || !data.writeScript) ? data.writeScript : "", privileges: data.privileges || [] } }; return this.getCollection(datasetname) .then(function (collection) { return f.setSettings(datasetname, data) }) .then(function (args) { return new Promise(function (resolve) { if (args.status == 0 || args.status == 'ok') args.scenario = scenario; else args.scenario = false; resolve(args) }) }) } protocol.prototype.writeData = function (datasetname, data) { var f = this, _args = [], _dataset, scenario = { operation: 'write', dataset: datasetname, content: data }, _canWrite = false return this.getSettings(datasetname) .then(function (settings) { return new Promise(function (r) { var script = settings.writeScript; //now only two rules maked for write script: //5560 mean check in privileges array and empty value, mean: read can every pusher if (script == "5560") {//0x55 0x60 mean PUSHDATA_PRIVKEYWRITER OP_CHECKDBPRIVILEGES var privileges = settings.privileges instanceof Array ? settings.privileges : []; if (privileges.indexOf(f.pubkey) >= 0 || settings.owner_key == f.pubkey || tools.generateAddressHash(f.pubkey) == f.name) r(true); else r(false) } else { r(true); } }); }) .then(function (canWrite) { _canWrite = canWrite return f.getItem(datasetname, data.oid); }) .then(function (item) { if (_canWrite) { var promise; if (item && data.oid && item.oid == data.oid) { for (var i in data) { if (i == 'meta' || i == '$loki') continue; item[i] = data[i]; } promise = f.updateItem(datasetname, item); } else { promise = f.insertItem(datasetname, data); } return promise; } else { return new Promise(function (resolve) { resolve({ operation: 'write', data: data, scenario: false, status: 'cantWrite', error: 'dataset settings do not accept writing for you key', }) }) } }) .then(function (args) { _args = args; return f.save(); }) .then(function () { if (_args.status == 0 || _args.status == 'ok') _args.scenario = scenario; else _args.scenario = false; return new Promise(function (resolve) { resolve(_args) }) }) } protocol.prototype.getSettings = function (datasetname) { var coll return this.getCollection(datasetname + "_settings") .then(function (collection) { coll = collection; return collection.getItem(1); }) .then(function (item) { if (!item) { var settings = {oid: 1, writeScript: '5560', owner_key: '', privileges: []}; item = coll.insertItem(settings); } return new Promise(function (resolve) { resolve(item) }) }) } protocol.prototype.setSettings = function (datasetname, data) { var coll, _args = [], _settings, _act, scenario = { operation: 'settings', dataset: datasetname, content: { writeScript: data.writeScript, privileges: data.privileges } }, f = this; return this.getCollection(datasetname + "_settings") .then(function (collection) { coll = collection; return collection.getItem(1); }) .then(function (item) { var act = 'settings', args = [] if (!item) { var settings = {oid: 1, writeScript: (("" + data.writeScript) == '5560' || !data.writeScript) ? data.writeScript : "", owner_key: data.owner_key || f.pubkey, privileges: data.privileges || []}; //item = coll.insertItem(settings); args = { operation: 'insert', data: settings, scenario: false, status: 0, } } else { item.writeScript = (("" + data.writeScript) == '5560' || !data.writeScript) ? data.writeScript : ""; item.privileges = data.privileges || []; if (!item.owner_key && data.owner_key)//only if not exist yet, cant be updated or changed item.owner_key = data.owner_key; args = { operation: 'update', data: item, scenario: false, status: 0, } //item = coll.updateItem(item) } return new Promise(function (resolve) { resolve(args) }) }) .then(function (args) { _args = args return new Promise(function (r) { if (!_args.data.owner_key || tools.generateAddressHash(f.pubkey) == f.name) r(0) else if (_args.data.owner_key == f.pubkey || _args.data.owner_key == f.hash) r(1); else r(-1); }); }) .then(function (canChange) { if (canChange == 0) { //add owner in script //init database at least scenario.content.owner_key = _args.data.owner_key = f.pubkey; if (_args.operation == 'insert') return coll.insertItem(_args.data) else { return coll.updateItem(_args.data); } } if (canChange == -1) return new Promise(function (resolve) { _args.status = 'cantChange'; _args.error = 'cant change settings for this dataset'; resolve(_args) }) if (canChange == 1) if (_args.operation == 'insert') return coll.insertItem(_args.data) else { return coll.updateItem(_args.data) } }) .then(function (args) { return f.save(); }) .then(function () { return new Promise(function (resolve) { if (_args.status == 0 || _args.status == 'ok') _args.scenario = scenario; else _args.scenario = false; resolve(_args) }) }) } var dbcache = {}; protocol.createDB = function (name, options) { return new Promise(function (resolve, reject) { if (dbcache[name]) resolve(dbcache[name]) else { if (!options) options = {}; options.name = name; new base(options, function () { dbcache[name] = this; resolve(this) }); } }) } module.exports = protocol