Comparing version 0.0.17-alpha to 0.0.18-alpha
@@ -1,1 +0,1 @@ | ||
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var r in n)("object"==typeof exports?exports:e)[r]=n[r]}}(global,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(r,a,function(t){return e[t]}.bind(null,a));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=9)}([function(e,t){e.exports=require("fast-json-stable-stringify")},function(e,t){e.exports=require("immutable-sorted")},function(e,t){e.exports=require("it-all")},function(e,t){e.exports=require("core-js/stable")},function(e,t){e.exports=require("regenerator-runtime/runtime")},function(e,t){e.exports=require("it-to-buffer")},function(e,t){e.exports=require("uint8arrays/from-string")},function(e,t){e.exports=require("uint8arrays/to-string")},function(e,t){e.exports=require("uint8arrays/concat")},function(e,t,n){"use strict";n.r(t),n.d(t,"MFdb",(function(){return N})),n.d(t,"SortDirection",(function(){return c}));n(3),n(4);function r(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return a(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return a(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,i=function(){};return{s:i,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var s,o=!0,c=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return o=e.done,e},e:function(e){c=!0,s=e},f:function(){try{o||null==n.return||n.return()}finally{if(c)throw s}}}}function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function i(e,t,n,r,a,i,s){try{var o=e[i](s),c=o.value}catch(e){return void n(e)}o.done?t(c):Promise.resolve(c).then(r,a)}function s(e){return function(){var t=this,n=arguments;return new Promise((function(r,a){var s=e.apply(t,n);function o(e){i(s,r,a,o,c,"next",e)}function c(e){i(s,r,a,o,c,"throw",e)}o(void 0)}))}}function o(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}var c,u=n(0),f=n(1).SortedMap,l=function(){function e(t,n,r,a){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.definitionService=t,this.ioService=n,this.ipfs=r,this.mfdb=a}var t,n,a,i,c,l,p;return t=e,(n=[{key:"cacheIndexMap",value:function(e,t,n){this.indexMaps[e]||(this.indexMaps[e]={}),this.indexMaps[e][t]=n}},{key:"getCachedIndexMap",value:function(e,t){if(this.indexMaps&&this.indexMaps[e])return this.indexMaps[e][t]}},{key:"updateIndex",value:(p=s(regeneratorRuntime.mark((function e(t){var n,r,a,i,s,o,c;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.getIndexMap(t.table,t.index);case 2:return n=e.sent,e.next=5,this.getDefinitionForIndex(t.table,t.index);case 5:if(r=e.sent,n&&r){e.next=8;break}return e.abrupt("return");case 8:r.unique?t.mapKey?n=n.set(t.mapKey.toString(),t.mapValue):t.mapExistingKey&&(n=n.delete(t.mapExistingKey.toString())):(a=Boolean(!t.mapExistingKey)&&Boolean(t.mapKey),i=!a&&t.mapKey!=t.mapExistingKey,t.mapExistingKey&&i&&(s=n.get(t.mapExistingKey.toString()),(o=s.indexOf(t.mapValue))>=0&&(s.splice(o,1),n=n.set(t.mapExistingKey,s))),t.mapKey&&(i||a)&&((c=n.get(t.mapKey.toString()))||(c=[],n=n.set(t.mapKey.toString(),c)),c.push(t.mapValue))),this.cacheIndexMap(t.table,t.index,n);case 10:case"end":return e.stop()}}),e,this)}))),function(e){return p.apply(this,arguments)})},{key:"flushIndexes",value:(l=s(regeneratorRuntime.mark((function e(t){var n,a,i,s,o,c,f;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.definitionService.getTableDefinition(t);case 2:n=e.sent,a=r(n.columns),e.prev=4,a.s();case 6:if((i=a.n()).done){e.next=21;break}if(s=i.value,o="".concat(this.ioService.getTableDirectoryName(this.mfdb.selectedDatabase,t),"/indexMaps/").concat(s.name),!(c=this.getCachedIndexMap(t,s.name))){e.next=19;break}return e.next=13,this.ioService.fileExists(o);case 13:if(!e.sent){e.next=16;break}return e.next=16,this.ipfs.files.rm(o,{flush:!0});case 16:return f=c.toJSON(),e.next=19,this.ipfs.files.write(o,u(f),{create:!0,parents:!0,flush:!0});case 19:e.next=6;break;case 21:e.next=26;break;case 23:e.prev=23,e.t0=e.catch(4),a.e(e.t0);case 26:return e.prev=26,a.f(),e.finish(26);case 29:case"end":return e.stop()}}),e,this,[[4,23,26,29]])}))),function(e){return l.apply(this,arguments)})},{key:"getDefinitionForIndex",value:(c=s(regeneratorRuntime.mark((function e(t,n){var r;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.definitionService.getTableDefinition(t);case 2:return r=e.sent,e.abrupt("return",r.columns.filter((function(e){return e.name==n}))[0]);case 4:case"end":return e.stop()}}),e,this)}))),function(e,t){return c.apply(this,arguments)})},{key:"getIndexMap",value:(i=s(regeneratorRuntime.mark((function e(t,n){var r,a,i,s;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(!(r=this.getCachedIndexMap(t,n))){e.next=3;break}return e.abrupt("return",r);case 3:return e.prev=3,i="".concat(this.ioService.getTableDirectoryName(this.mfdb.selectedDatabase,t),"/indexMaps/").concat(n),e.next=7,this.ipfs.files.stat(i);case 7:return e.next=9,this.ioService.getFileContent(i);case 9:s=e.sent,a=f(s),e.next=15;break;case 13:e.prev=13,e.t0=e.catch(3);case 15:return a||(a=f()),this.cacheIndexMap(t,n,a),e.abrupt("return",a);case 18:case"end":return e.stop()}}),e,this,[[3,13]])}))),function(e,t){return i.apply(this,arguments)})},{key:"clearCache",value:function(){this.indexMaps={}}}])&&o(t.prototype,n),a&&o(t,a),e}();function p(e,t,n,r,a,i,s){try{var o=e[i](s),c=o.value}catch(e){return void n(e)}o.done?t(c):Promise.resolve(c).then(r,a)}function h(e){return function(){var t=this,n=arguments;return new Promise((function(r,a){var i=e.apply(t,n);function s(e){p(i,r,a,s,o,"next",e)}function o(e){p(i,r,a,s,o,"throw",e)}s(void 0)}))}}function v(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}!function(e){e.DESC="desc",e.ASC="asc"}(c||(c={}));var d=n(5),m=n(0),b=n(2),x=(n(6),n(7)),y=n(8),g=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.ipfs=t}var t,n,r,a,i,s,o,c,u,f,l;return t=e,(n=[{key:"databaseExists",value:(l=h(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.fileExists(this.getDatabasePath(t)));case 1:case"end":return e.stop()}}),e,this)}))),function(e){return l.apply(this,arguments)})},{key:"tableExists",value:(f=h(regeneratorRuntime.mark((function e(t,n){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.fileExists(this.getTableDirectoryName(t,n)));case 1:case"end":return e.stop()}}),e,this)}))),function(e,t){return f.apply(this,arguments)})},{key:"rowExists",value:(u=h(regeneratorRuntime.mark((function e(t,n,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.fileExists("".concat(this.getTableDirectoryName(t,n),"/").concat(r)));case 1:case"end":return e.stop()}}),e,this)}))),function(e,t,n){return u.apply(this,arguments)})},{key:"getDatabasePath",value:function(t){return"/".concat(e.MFS_DB,"/").concat(t)}},{key:"getTableDirectoryName",value:function(e,t){return"".concat(this.getDatabasePath(e),"/").concat(t)}},{key:"fileExists",value:(c=h(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,this.ipfs.files.stat(t);case 3:return e.abrupt("return",!0);case 6:return e.prev=6,e.t0=e.catch(0),e.abrupt("return",!1);case 9:case"end":return e.stop()}}),e,this,[[0,6]])}))),function(e){return c.apply(this,arguments)})},{key:"getFileContent",value:(o=h(regeneratorRuntime.mark((function e(t){var n,r;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,d(this.ipfs.files.read(t));case 2:return n=e.sent,r=n.toString(),e.abrupt("return",JSON.parse(r));case 5:case"end":return e.stop()}}),e,this)}))),function(e){return o.apply(this,arguments)})},{key:"write",value:(s=h(regeneratorRuntime.mark((function e(t){var n;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.ipfs.add({content:m(t)});case 2:return n=e.sent,e.abrupt("return",n.cid);case 4:case"end":return e.stop()}}),e,this)}))),function(e){return s.apply(this,arguments)})},{key:"read",value:(i=h(regeneratorRuntime.mark((function e(t){var n;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,b(this.ipfs.get(t));case 2:return n=e.sent,e.t0=JSON,e.t1=x,e.t2=y,e.next=8,b(n[0].content);case 8:return e.t3=e.sent,e.t4=(0,e.t2)(e.t3),e.t5=(0,e.t1)(e.t4),e.abrupt("return",e.t0.parse.call(e.t0,e.t5));case 12:case"end":return e.stop()}}),e,this)}))),function(e){return i.apply(this,arguments)})},{key:"removeFile",value:(a=h(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.fileExists(t);case 2:if(!e.sent){e.next=5;break}return e.next=5,this.ipfs.files.rm(t);case 5:case"end":return e.stop()}}),e,this)}))),function(e){return a.apply(this,arguments)})}])&&v(t.prototype,n),r&&v(t,r),e}();function k(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return w(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return w(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,a=function(){};return{s:a,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,s=!0,o=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return s=e.done,e},e:function(e){o=!0,i=e},f:function(){try{s||null==n.return||n.return()}finally{if(o)throw i}}}}function w(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function S(e,t,n,r,a,i,s){try{var o=e[i](s),c=o.value}catch(e){return void n(e)}o.done?t(c):Promise.resolve(c).then(r,a)}function D(e){return function(){var t=this,n=arguments;return new Promise((function(r,a){var i=e.apply(t,n);function s(e){S(i,r,a,s,o,"next",e)}function o(e){S(i,r,a,s,o,"throw",e)}s(void 0)}))}}function R(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}g.MFS_DB="mfdb";var E=n(0),I=function(){function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.ioService=t,this.ipfs=n}var t,n,r,a,i;return t=e,(n=[{key:"saveDefinition",value:(i=D(regeneratorRuntime.mark((function t(n){var r;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return r="".concat(this.ioService.getDatabasePath(n.name),"/definition/").concat(e.DEFINITION_FILENAME),console.debug("Saving definition for database ".concat(n.name," (").concat(r,")")),t.next=4,this.ipfs.files.write(r,E(n),{create:!0,parents:!0,flush:!0});case 4:case"end":return t.stop()}}),t,this)}))),function(e){return i.apply(this,arguments)})},{key:"loadDefinition",value:(a=D(regeneratorRuntime.mark((function t(n){var r;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return r="".concat(this.ioService.getDatabasePath(n),"/definition/").concat(e.DEFINITION_FILENAME),t.next=3,this.ioService.getFileContent(r);case 3:this.activeDefinition=t.sent;case 4:case"end":return t.stop()}}),t,this)}))),function(e){return a.apply(this,arguments)})},{key:"validateTableDefinition",value:function(e){var t,n=0,r=k(e.columns);try{for(r.s();!(t=r.n()).done;)t.value.primary&&n++}catch(e){r.e(e)}finally{r.f()}if(0==n)throw Error("Invalid schema. Table ".concat(e.name," has no primary key."));if(n>1)throw Error("Invalid schema. Table ".concat(e.name," has multiple primary keys."))}},{key:"getTableDefinition",value:function(e){return this.activeDefinition.tables.filter((function(t){return t.name==e}))[0]}},{key:"getPrimaryKeyDefinition",value:function(e){return this.getTableDefinition(e).columns.filter((function(e){return 1==e.primary}))[0]}},{key:"clearCache",value:function(){delete this.activeDefinition}}])&&R(t.prototype,n),r&&R(t,r),e}();function T(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return M(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return M(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,a=function(){};return{s:a,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,s=!0,o=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return s=e.done,e},e:function(e){o=!0,i=e},f:function(){try{s||null==n.return||n.return()}finally{if(o)throw i}}}}function M(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function P(e,t,n,r,a,i,s){try{var o=e[i](s),c=o.value}catch(e){return void n(e)}o.done?t(c):Promise.resolve(c).then(r,a)}function C(e){return function(){var t=this,n=arguments;return new Promise((function(r,a){var i=e.apply(t,n);function s(e){P(i,r,a,s,o,"next",e)}function o(e){P(i,r,a,s,o,"throw",e)}s(void 0)}))}}function j(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}I.DEFINITION_FILENAME="definition.json";n(1).SortedMap,n(0),n(2);var N=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.ipfs=t,this.ioService=new g(this.ipfs),this.definitionService=new I(this.ioService,this.ipfs),this.indexService=new l(this.definitionService,this.ioService,this.ipfs,this)}var t,n,r,a,i,s,o,u,f,p,h,v,d,m;return t=e,(n=[{key:"createDatabase",value:(m=C(regeneratorRuntime.mark((function e(t){var n,r,a;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(null!=t.name){e.next=2;break}throw Error("Must give database a name");case 2:return e.next=4,this.ioService.databaseExists(t.name);case 4:if(!e.sent){e.next=6;break}throw Error("Database already exists");case 6:return console.debug("Creating database ".concat(t.name," at ").concat(this.ioService.getDatabasePath(t.name))),e.next=9,this.ipfs.files.mkdir(this.ioService.getDatabasePath(t.name),{parents:!0});case 9:n=T(t.tables);try{for(n.s();!(r=n.n()).done;)a=r.value,this.definitionService.validateTableDefinition(a)}catch(e){n.e(e)}finally{n.f()}return e.next=13,this.definitionService.saveDefinition(t);case 13:case"end":return e.stop()}}),e,this)}))),function(e){return m.apply(this,arguments)})},{key:"dropDatabase",value:(d=C(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,this.ipfs.files.rm(this.ioService.getDatabasePath(t),{recursive:!0});case 3:e.next=7;break;case 5:e.prev=5,e.t0=e.catch(0);case 7:case"end":return e.stop()}}),e,this,[[0,5]])}))),function(e){return d.apply(this,arguments)})},{key:"useDatabase",value:(v=C(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return console.debug("Using database ".concat(t)),this.selectedDatabase=t,delete this.activeTransaction,e.next=5,this.definitionService.loadDefinition(t);case 5:return e.next=7,this.indexService.clearCache();case 7:case"end":return e.stop()}}),e,this)}))),function(e){return v.apply(this,arguments)})},{key:"startTransaction",value:function(){console.debug("Starting new transaction"),this.activeTransaction={changes:[],tables:[]}}},{key:"commit",value:(h=C(regeneratorRuntime.mark((function e(){var t,n,r,a,i,s;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:console.debug("Commiting ".concat(this.activeTransaction.changes.length," changes to: ").concat(this.activeTransaction.tables)),t=T(this.activeTransaction.changes),e.prev=2,t.s();case 4:if((n=t.n()).done){e.next=10;break}return r=n.value,e.next=8,r();case 8:e.next=4;break;case 10:e.next=15;break;case 12:e.prev=12,e.t0=e.catch(2),t.e(e.t0);case 15:return e.prev=15,t.f(),e.finish(15);case 18:a=T(this.activeTransaction.tables),e.prev=19,a.s();case 21:if((i=a.n()).done){e.next=27;break}return s=i.value,e.next=25,this.indexService.flushIndexes(s);case 25:e.next=21;break;case 27:e.next=32;break;case 29:e.prev=29,e.t1=e.catch(19),a.e(e.t1);case 32:return e.prev=32,a.f(),e.finish(32);case 35:delete this.activeTransaction;case 36:case"end":return e.stop()}}),e,this,[[2,12,15,18],[19,29,32,35]])}))),function(){return h.apply(this,arguments)})},{key:"insert",value:function(e,t){var n=this;if(!this.selectedDatabase)throw Error("No database selected");if(!this.activeTransaction)throw Error("No transaction started");this.queueChange(e,C(regeneratorRuntime.mark((function r(){var a,i,s,o,c,u;return regeneratorRuntime.wrap((function(r){for(;;)switch(r.prev=r.next){case 0:return r.next=2,n.definitionService.getPrimaryKeyDefinition(e);case 2:if(a=r.sent,void 0!==t[a.name]){r.next=5;break}throw Error("Insert failed: Record does not contain primary key field ".concat(a.name));case 5:return r.next=7,n.get(e,t[a.name]);case 7:if(!r.sent){r.next=10;break}throw Error("Insert failed: Primary key ".concat(t[a.name]," already exists in ").concat(e," table"));case 10:return r.next=12,n.ioService.write(t);case 12:return i=r.sent,r.next=15,n.definitionService.getTableDefinition(e);case 15:s=r.sent,o=T(s.columns),r.prev=17,o.s();case 19:if((c=o.n()).done){r.next=25;break}return u=c.value,r.next=23,n.indexService.updateIndex({table:e,index:u.name,mapKey:u.primary?t[a.name]:t[u.name],mapValue:u.primary?i.toString():t[a.name]});case 23:r.next=19;break;case 25:r.next=30;break;case 27:r.prev=27,r.t0=r.catch(17),o.e(r.t0);case 30:return r.prev=30,o.f(),r.finish(30);case 33:case"end":return r.stop()}}),r,null,[[17,27,30,33]])}))))}},{key:"update",value:function(e,t){var n=this;if(!this.selectedDatabase)throw Error("No database selected");if(!this.activeTransaction)throw Error("No transaction started");this.queueChange(e,C(regeneratorRuntime.mark((function r(){var a,i,s,o,c,u;return regeneratorRuntime.wrap((function(r){for(;;)switch(r.prev=r.next){case 0:return r.next=2,n.definitionService.getPrimaryKeyDefinition(e);case 2:if(a=r.sent,void 0!==t[a.name]){r.next=5;break}throw Error("Update failed: Record does not contain primary key field ".concat(a.name));case 5:return r.next=7,n.get(e,t[a.name]);case 7:if(void 0!==(i=r.sent)){r.next=10;break}throw Error("Update failed: Primary key ".concat(t[a.name]," does not exist in ").concat(e," table"));case 10:return r.next=12,n.ioService.write(t);case 12:return r.sent,r.next=15,n.definitionService.getTableDefinition(e);case 15:s=r.sent,o=T(s.columns.filter((function(e){return!e.primary}))),r.prev=17,o.s();case 19:if((c=o.n()).done){r.next=25;break}return u=c.value,r.next=23,n.indexService.updateIndex({table:e,index:u.name,mapKey:t[u.name],mapExistingKey:i[u.name],mapValue:t[a.name]});case 23:r.next=19;break;case 25:r.next=30;break;case 27:r.prev=27,r.t0=r.catch(17),o.e(r.t0);case 30:return r.prev=30,o.f(),r.finish(30);case 33:case"end":return r.stop()}}),r,null,[[17,27,30,33]])}))))}},{key:"getCID",value:(p=C(regeneratorRuntime.mark((function e(t,n){var r,a,i;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(this.selectedDatabase){e.next=2;break}throw Error("No database selected");case 2:return e.next=4,this.definitionService.getPrimaryKeyDefinition(t);case 4:return r=e.sent,e.next=7,this.indexService.getIndexMap(t,r.name);case 7:return a=e.sent,i=a.get(n.toString()),e.abrupt("return",i);case 10:case"end":return e.stop()}}),e,this)}))),function(e,t){return p.apply(this,arguments)})},{key:"get",value:(f=C(regeneratorRuntime.mark((function e(t,n){var r,a;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(this.selectedDatabase){e.next=2;break}throw Error("No database selected");case 2:return e.next=4,this.getCID(t,n);case 4:if(!(r=e.sent)){e.next=10;break}return e.next=8,this.ioService.read(r.toString());case 8:return a=e.sent,e.abrupt("return",a);case 10:case"end":return e.stop()}}),e,this)}))),function(e,t){return f.apply(this,arguments)})},{key:"searchIndex",value:(u=C(regeneratorRuntime.mark((function e(t){var n,r,a,i,s,o,u,f,l,p,h,v,d,m;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.definitionService.getTableDefinition(t.table);case 2:return n=e.sent,r=n.columns.filter((function(e){return e.name==t.index}))[0],e.next=6,this.indexService.getIndexMap(t.table,t.index);case 6:if(a=e.sent,n&&r&&a){e.next=9;break}return e.abrupt("return",[]);case 9:if(i=[],s=[],t.value){if(r.unique)(o=a.get(t.value))&&s.push(o);else if(u=a.get(t.value)){f=T(u);try{for(f.s();!(l=f.n()).done;)p=l.value,s.push(p)}catch(e){f.e(e)}finally{f.f()}}}else s=Object.keys(a.toSeq().toJS());s.sort(),t.sortDirection==c.ASC&&s.reverse(),h=0,v=T(s),e.prev=16,v.s();case 18:if((d=v.n()).done){e.next=35;break}if(m=d.value,!(i.length>=t.limit)){e.next=22;break}return e.abrupt("break",35);case 22:if(!(h<t.offset)){e.next=27;break}return h++,e.abrupt("continue",33);case 27:h++;case 28:return e.t0=i,e.next=31,this.get(t.table,m);case 31:e.t1=e.sent,e.t0.push.call(e.t0,e.t1);case 33:e.next=18;break;case 35:e.next=40;break;case 37:e.prev=37,e.t2=e.catch(16),v.e(e.t2);case 40:return e.prev=40,v.f(),e.finish(40);case 43:return e.abrupt("return",i);case 44:case"end":return e.stop()}}),e,this,[[16,37,40,43]])}))),function(e){return u.apply(this,arguments)})},{key:"count",value:(o=C(regeneratorRuntime.mark((function e(t){var n,r;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(this.selectedDatabase){e.next=2;break}throw Error("No database selected");case 2:return e.next=4,this.definitionService.getPrimaryKeyDefinition(t);case 4:return n=e.sent,e.next=7,this.indexService.getIndexMap(t,n.name);case 7:return r=e.sent,e.abrupt("return",r.size);case 9:case"end":return e.stop()}}),e,this)}))),function(e){return o.apply(this,arguments)})},{key:"delete",value:function(e,t){var n=this;if(!this.selectedDatabase)throw Error("No database selected");if(!this.activeTransaction)throw Error("No transaction started");this.queueChange(e,C(regeneratorRuntime.mark((function r(){var a,i,s,o,c;return regeneratorRuntime.wrap((function(r){for(;;)switch(r.prev=r.next){case 0:return r.next=2,n.definitionService.getPrimaryKeyDefinition(e);case 2:return r.sent,r.next=5,n.get(e,t);case 5:return a=r.sent,r.next=8,n.definitionService.getTableDefinition(e);case 8:i=r.sent,s=T(i.columns),r.prev=10,s.s();case 12:if((o=s.n()).done){r.next=18;break}return c=o.value,r.next=16,n.indexService.updateIndex({table:e,index:c.name,mapKey:void 0,mapExistingKey:a[c.name],mapValue:t});case 16:r.next=12;break;case 18:r.next=23;break;case 20:r.prev=20,r.t0=r.catch(10),s.e(r.t0);case 23:return r.prev=23,s.f(),r.finish(23);case 26:case"end":return r.stop()}}),r,null,[[10,20,23,26]])}))))}},{key:"flushToMFS",value:(s=C(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:case"end":return e.stop()}}),e)}))),function(){return s.apply(this,arguments)})},{key:"getDatabaseCid",value:(i=C(regeneratorRuntime.mark((function e(t){var n;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(this.ioService.databaseExists(t)){e.next=2;break}throw Error("Database does not exist");case 2:return e.next=4,this.ipfs.files.stat(this.ioService.getDatabasePath(t));case 4:return n=e.sent,e.abrupt("return",n.cid);case 6:case"end":return e.stop()}}),e,this)}))),function(e){return i.apply(this,arguments)})},{key:"updateFromCid",value:(a=C(regeneratorRuntime.mark((function e(t,n){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return console.log("Updating ".concat(t," from ").concat(n)),e.next=3,this.ioService.databaseExists(t);case 3:if(!e.sent){e.next=6;break}return e.next=6,this.ipfs.files.rm(this.ioService.getDatabasePath(t),{recursive:!0});case 6:return e.next=8,this.ipfs.files.cp("/ipfs/".concat(n),this.ioService.getDatabasePath(t));case 8:return e.next=10,this.useDatabase(t);case 10:case"end":return e.stop()}}),e,this)}))),function(e,t){return a.apply(this,arguments)})},{key:"queueChange",value:function(e,t){this.activeTransaction.changes.push(t),0==this.activeTransaction.tables.filter((function(t){return t==e})).length&&this.activeTransaction.tables.push(e)}}])&&j(t.prototype,n),r&&j(t,r),e}()}])})); | ||
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var r in n)("object"==typeof exports?exports:e)[r]=n[r]}}(global,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(r,a,function(t){return e[t]}.bind(null,a));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=9)}([function(e,t){e.exports=require("fast-json-stable-stringify")},function(e,t){e.exports=require("immutable-sorted")},function(e,t){e.exports=require("it-all")},function(e,t){e.exports=require("core-js/stable")},function(e,t){e.exports=require("regenerator-runtime/runtime")},function(e,t){e.exports=require("it-to-buffer")},function(e,t){e.exports=require("uint8arrays/from-string")},function(e,t){e.exports=require("uint8arrays/to-string")},function(e,t){e.exports=require("uint8arrays/concat")},function(e,t,n){"use strict";n.r(t),n.d(t,"MFdb",(function(){return j})),n.d(t,"SortDirection",(function(){return c}));n(3),n(4);function r(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return a(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return a(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,i=function(){};return{s:i,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var s,o=!0,c=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return o=e.done,e},e:function(e){c=!0,s=e},f:function(){try{o||null==n.return||n.return()}finally{if(c)throw s}}}}function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function i(e,t,n,r,a,i,s){try{var o=e[i](s),c=o.value}catch(e){return void n(e)}o.done?t(c):Promise.resolve(c).then(r,a)}function s(e){return function(){var t=this,n=arguments;return new Promise((function(r,a){var s=e.apply(t,n);function o(e){i(s,r,a,o,c,"next",e)}function c(e){i(s,r,a,o,c,"throw",e)}o(void 0)}))}}function o(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}var c,u=n(0),f=n(1).SortedMap,l=function(){function e(t,n,r,a){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.definitionService=t,this.ioService=n,this.ipfs=r,this.mfdb=a}var t,n,a,i,c,l,p;return t=e,(n=[{key:"cacheIndexMap",value:function(e,t,n){this.indexMaps[e]||(this.indexMaps[e]={}),this.indexMaps[e][t]=n}},{key:"getCachedIndexMap",value:function(e,t){if(this.indexMaps&&this.indexMaps[e])return this.indexMaps[e][t]}},{key:"updateIndex",value:(p=s(regeneratorRuntime.mark((function e(t){var n,r,a,i,s,o,c;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.getIndexMap(t.table,t.index);case 2:return n=e.sent,e.next=5,this.getDefinitionForIndex(t.table,t.index);case 5:if(r=e.sent,n&&r){e.next=8;break}return e.abrupt("return");case 8:r.unique?t.mapKey?n=n.set(t.mapKey.toString(),t.mapValue):t.mapExistingKey&&(n=n.delete(t.mapExistingKey.toString())):(a=Boolean(!t.mapExistingKey)&&Boolean(t.mapKey),i=!a&&t.mapKey!=t.mapExistingKey,t.mapExistingKey&&i&&(s=n.get(t.mapExistingKey.toString()),(o=s.indexOf(t.mapValue))>=0&&(s.splice(o,1),n=n.set(t.mapExistingKey,s))),t.mapKey&&(i||a)&&((c=n.get(t.mapKey.toString()))||(c=[],n=n.set(t.mapKey.toString(),c)),c.push(t.mapValue))),this.cacheIndexMap(t.table,t.index,n);case 10:case"end":return e.stop()}}),e,this)}))),function(e){return p.apply(this,arguments)})},{key:"flushIndexes",value:(l=s(regeneratorRuntime.mark((function e(t){var n,a,i,s,o,c,f;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.definitionService.getTableDefinition(t);case 2:n=e.sent,a=r(n.columns),e.prev=4,a.s();case 6:if((i=a.n()).done){e.next=21;break}if(s=i.value,o="".concat(this.ioService.getTableDirectoryName(this.mfdb.selectedDatabase,t),"/indexMaps/").concat(s.name),!(c=this.getCachedIndexMap(t,s.name))){e.next=19;break}return e.next=13,this.ioService.fileExists(o);case 13:if(!e.sent){e.next=16;break}return e.next=16,this.ipfs.files.rm(o,{flush:!0});case 16:return f=c.toJSON(),e.next=19,this.ipfs.files.write(o,u(f),{create:!0,parents:!0,flush:!0});case 19:e.next=6;break;case 21:e.next=26;break;case 23:e.prev=23,e.t0=e.catch(4),a.e(e.t0);case 26:return e.prev=26,a.f(),e.finish(26);case 29:case"end":return e.stop()}}),e,this,[[4,23,26,29]])}))),function(e){return l.apply(this,arguments)})},{key:"getDefinitionForIndex",value:(c=s(regeneratorRuntime.mark((function e(t,n){var r;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.definitionService.getTableDefinition(t);case 2:return r=e.sent,e.abrupt("return",r.columns.filter((function(e){return e.name==n}))[0]);case 4:case"end":return e.stop()}}),e,this)}))),function(e,t){return c.apply(this,arguments)})},{key:"getIndexMap",value:(i=s(regeneratorRuntime.mark((function e(t,n){var r,a,i,s;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(!(r=this.getCachedIndexMap(t,n))){e.next=3;break}return e.abrupt("return",r);case 3:return e.prev=3,i="".concat(this.ioService.getTableDirectoryName(this.mfdb.selectedDatabase,t),"/indexMaps/").concat(n),e.next=7,this.ipfs.files.stat(i);case 7:return e.next=9,this.ioService.getFileContent(i);case 9:s=e.sent,a=f(s),e.next=15;break;case 13:e.prev=13,e.t0=e.catch(3);case 15:return a||(a=f()),this.cacheIndexMap(t,n,a),e.abrupt("return",a);case 18:case"end":return e.stop()}}),e,this,[[3,13]])}))),function(e,t){return i.apply(this,arguments)})},{key:"clearCache",value:function(){this.indexMaps={}}}])&&o(t.prototype,n),a&&o(t,a),e}();function p(e,t,n,r,a,i,s){try{var o=e[i](s),c=o.value}catch(e){return void n(e)}o.done?t(c):Promise.resolve(c).then(r,a)}function h(e){return function(){var t=this,n=arguments;return new Promise((function(r,a){var i=e.apply(t,n);function s(e){p(i,r,a,s,o,"next",e)}function o(e){p(i,r,a,s,o,"throw",e)}s(void 0)}))}}function v(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}!function(e){e.DESC="desc",e.ASC="asc"}(c||(c={}));var d=n(5),m=n(0),x=n(2),b=(n(6),n(7)),y=n(8),g=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.ipfs=t}var t,n,r,a,i,s,o,c,u,f,l;return t=e,(n=[{key:"databaseExists",value:(l=h(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.fileExists(this.getDatabasePath(t)));case 1:case"end":return e.stop()}}),e,this)}))),function(e){return l.apply(this,arguments)})},{key:"tableExists",value:(f=h(regeneratorRuntime.mark((function e(t,n){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.fileExists(this.getTableDirectoryName(t,n)));case 1:case"end":return e.stop()}}),e,this)}))),function(e,t){return f.apply(this,arguments)})},{key:"rowExists",value:(u=h(regeneratorRuntime.mark((function e(t,n,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.fileExists("".concat(this.getTableDirectoryName(t,n),"/").concat(r)));case 1:case"end":return e.stop()}}),e,this)}))),function(e,t,n){return u.apply(this,arguments)})},{key:"getDatabasePath",value:function(t){return"/".concat(e.MFS_DB,"/").concat(t)}},{key:"getTableDirectoryName",value:function(e,t){return"".concat(this.getDatabasePath(e),"/").concat(t)}},{key:"fileExists",value:(c=h(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,this.ipfs.files.stat(t);case 3:return e.abrupt("return",!0);case 6:return e.prev=6,e.t0=e.catch(0),e.abrupt("return",!1);case 9:case"end":return e.stop()}}),e,this,[[0,6]])}))),function(e){return c.apply(this,arguments)})},{key:"getFileContent",value:(o=h(regeneratorRuntime.mark((function e(t){var n,r;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,d(this.ipfs.files.read(t));case 2:return n=e.sent,r=n.toString(),e.abrupt("return",JSON.parse(r));case 5:case"end":return e.stop()}}),e,this)}))),function(e){return o.apply(this,arguments)})},{key:"write",value:(s=h(regeneratorRuntime.mark((function e(t){var n;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.ipfs.add({content:m(t)});case 2:return n=e.sent,e.abrupt("return",n.cid);case 4:case"end":return e.stop()}}),e,this)}))),function(e){return s.apply(this,arguments)})},{key:"read",value:(i=h(regeneratorRuntime.mark((function e(t){var n;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,x(this.ipfs.get(t));case 2:return n=e.sent,e.t0=JSON,e.t1=b,e.t2=y,e.next=8,x(n[0].content);case 8:return e.t3=e.sent,e.t4=(0,e.t2)(e.t3),e.t5=(0,e.t1)(e.t4),e.abrupt("return",e.t0.parse.call(e.t0,e.t5));case 12:case"end":return e.stop()}}),e,this)}))),function(e){return i.apply(this,arguments)})},{key:"removeFile",value:(a=h(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.fileExists(t);case 2:if(!e.sent){e.next=5;break}return e.next=5,this.ipfs.files.rm(t);case 5:case"end":return e.stop()}}),e,this)}))),function(e){return a.apply(this,arguments)})}])&&v(t.prototype,n),r&&v(t,r),e}();function k(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return w(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return w(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,a=function(){};return{s:a,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,s=!0,o=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return s=e.done,e},e:function(e){o=!0,i=e},f:function(){try{s||null==n.return||n.return()}finally{if(o)throw i}}}}function w(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function S(e,t,n,r,a,i,s){try{var o=e[i](s),c=o.value}catch(e){return void n(e)}o.done?t(c):Promise.resolve(c).then(r,a)}function D(e){return function(){var t=this,n=arguments;return new Promise((function(r,a){var i=e.apply(t,n);function s(e){S(i,r,a,s,o,"next",e)}function o(e){S(i,r,a,s,o,"throw",e)}s(void 0)}))}}function R(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}g.MFS_DB="mfdb";var E=n(0),I=function(){function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.ioService=t,this.ipfs=n}var t,n,r,a,i;return t=e,(n=[{key:"saveDefinition",value:(i=D(regeneratorRuntime.mark((function t(n){var r;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return r="".concat(this.ioService.getDatabasePath(n.name),"/definition/").concat(e.DEFINITION_FILENAME),console.debug("Saving definition for database ".concat(n.name," (").concat(r,")")),t.next=4,this.ipfs.files.write(r,E(n),{create:!0,parents:!0,flush:!0});case 4:case"end":return t.stop()}}),t,this)}))),function(e){return i.apply(this,arguments)})},{key:"loadDefinition",value:(a=D(regeneratorRuntime.mark((function t(n){var r;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return r="".concat(this.ioService.getDatabasePath(n),"/definition/").concat(e.DEFINITION_FILENAME),t.next=3,this.ioService.getFileContent(r);case 3:this.activeDefinition=t.sent;case 4:case"end":return t.stop()}}),t,this)}))),function(e){return a.apply(this,arguments)})},{key:"validateTableDefinition",value:function(e){var t,n=0,r=k(e.columns);try{for(r.s();!(t=r.n()).done;)t.value.primary&&n++}catch(e){r.e(e)}finally{r.f()}if(0==n)throw Error("Invalid schema. Table ".concat(e.name," has no primary key."));if(n>1)throw Error("Invalid schema. Table ".concat(e.name," has multiple primary keys."))}},{key:"getTableDefinition",value:function(e){return this.activeDefinition.tables.filter((function(t){return t.name==e}))[0]}},{key:"getPrimaryKeyDefinition",value:function(e){return this.getTableDefinition(e).columns.filter((function(e){return 1==e.primary}))[0]}},{key:"clearCache",value:function(){delete this.activeDefinition}}])&&R(t.prototype,n),r&&R(t,r),e}();function T(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return M(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return M(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,a=function(){};return{s:a,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,s=!0,o=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return s=e.done,e},e:function(e){o=!0,i=e},f:function(){try{s||null==n.return||n.return()}finally{if(o)throw i}}}}function M(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function P(e,t,n,r,a,i,s){try{var o=e[i](s),c=o.value}catch(e){return void n(e)}o.done?t(c):Promise.resolve(c).then(r,a)}function C(e){return function(){var t=this,n=arguments;return new Promise((function(r,a){var i=e.apply(t,n);function s(e){P(i,r,a,s,o,"next",e)}function o(e){P(i,r,a,s,o,"throw",e)}s(void 0)}))}}function N(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}I.DEFINITION_FILENAME="definition.json";n(1).SortedMap,n(0),n(2);var j=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.ipfs=t,this.ioService=new g(this.ipfs),this.definitionService=new I(this.ioService,this.ipfs),this.indexService=new l(this.definitionService,this.ioService,this.ipfs,this)}var t,n,r,a,i,s,o,u,f,p,h,v,d,m,x,b,y;return t=e,(n=[{key:"createDatabase",value:(y=C(regeneratorRuntime.mark((function e(t){var n,r,a;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(null!=t.name){e.next=2;break}throw Error("Must give database a name");case 2:return e.next=4,this.ioService.databaseExists(t.name);case 4:if(!e.sent){e.next=6;break}throw Error("Database already exists");case 6:return console.debug("Creating database ".concat(t.name," at ").concat(this.ioService.getDatabasePath(t.name))),e.next=9,this.ipfs.files.mkdir(this.ioService.getDatabasePath(t.name),{parents:!0});case 9:n=T(t.tables);try{for(n.s();!(r=n.n()).done;)a=r.value,this.definitionService.validateTableDefinition(a)}catch(e){n.e(e)}finally{n.f()}return e.next=13,this.definitionService.saveDefinition(t);case 13:case"end":return e.stop()}}),e,this)}))),function(e){return y.apply(this,arguments)})},{key:"dropDatabase",value:(b=C(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,this.ipfs.files.rm(this.ioService.getDatabasePath(t),{recursive:!0});case 3:e.next=7;break;case 5:e.prev=5,e.t0=e.catch(0);case 7:case"end":return e.stop()}}),e,this,[[0,5]])}))),function(e){return b.apply(this,arguments)})},{key:"databaseExists",value:(x=C(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.ioService.databaseExists(t));case 1:case"end":return e.stop()}}),e,this)}))),function(e){return x.apply(this,arguments)})},{key:"useDatabase",value:(m=C(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return console.debug("Using database ".concat(t)),this.selectedDatabase=t,delete this.activeTransaction,e.next=5,this.definitionService.loadDefinition(t);case 5:return e.next=7,this.indexService.clearCache();case 7:case"end":return e.stop()}}),e,this)}))),function(e){return m.apply(this,arguments)})},{key:"startTransaction",value:function(){console.debug("Starting new transaction"),this.activeTransaction={changes:[],tables:[]}}},{key:"commit",value:(d=C(regeneratorRuntime.mark((function e(){var t,n,r,a,i,s;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:console.debug("Commiting ".concat(this.activeTransaction.changes.length," changes to: ").concat(this.activeTransaction.tables)),t=T(this.activeTransaction.changes),e.prev=2,t.s();case 4:if((n=t.n()).done){e.next=10;break}return r=n.value,e.next=8,r();case 8:e.next=4;break;case 10:e.next=15;break;case 12:e.prev=12,e.t0=e.catch(2),t.e(e.t0);case 15:return e.prev=15,t.f(),e.finish(15);case 18:a=T(this.activeTransaction.tables),e.prev=19,a.s();case 21:if((i=a.n()).done){e.next=27;break}return s=i.value,e.next=25,this.indexService.flushIndexes(s);case 25:e.next=21;break;case 27:e.next=32;break;case 29:e.prev=29,e.t1=e.catch(19),a.e(e.t1);case 32:return e.prev=32,a.f(),e.finish(32);case 35:delete this.activeTransaction;case 36:case"end":return e.stop()}}),e,this,[[2,12,15,18],[19,29,32,35]])}))),function(){return d.apply(this,arguments)})},{key:"insert",value:function(e,t){var n=this;if(!this.selectedDatabase)throw Error("No database selected");if(!this.activeTransaction)throw Error("No transaction started");this.queueChange(e,C(regeneratorRuntime.mark((function r(){return regeneratorRuntime.wrap((function(r){for(;;)switch(r.prev=r.next){case 0:return r.next=2,n.insertValue(e,t);case 2:case"end":return r.stop()}}),r)}))))}},{key:"insertValue",value:(v=C(regeneratorRuntime.mark((function e(t,n){var r,a,i,s,o,c;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.definitionService.getPrimaryKeyDefinition(t);case 2:if(r=e.sent,void 0!==n[r.name]){e.next=5;break}throw Error("Insert failed: Record does not contain primary key field ".concat(r.name));case 5:return e.next=7,this.get(t,n[r.name]);case 7:if(!e.sent){e.next=10;break}throw Error("Insert failed: Primary key ".concat(n[r.name]," already exists in ").concat(t," table"));case 10:return e.next=12,this.ioService.write(n);case 12:return a=e.sent,e.next=15,this.definitionService.getTableDefinition(t);case 15:i=e.sent,s=T(i.columns),e.prev=17,s.s();case 19:if((o=s.n()).done){e.next=25;break}return c=o.value,e.next=23,this.indexService.updateIndex({table:t,index:c.name,mapKey:c.primary?n[r.name]:n[c.name],mapValue:c.primary?a.toString():n[r.name]});case 23:e.next=19;break;case 25:e.next=30;break;case 27:e.prev=27,e.t0=e.catch(17),s.e(e.t0);case 30:return e.prev=30,s.f(),e.finish(30);case 33:case"end":return e.stop()}}),e,this,[[17,27,30,33]])}))),function(e,t){return v.apply(this,arguments)})},{key:"update",value:function(e,t){var n=this;if(!this.selectedDatabase)throw Error("No database selected");if(!this.activeTransaction)throw Error("No transaction started");this.queueChange(e,C(regeneratorRuntime.mark((function r(){return regeneratorRuntime.wrap((function(r){for(;;)switch(r.prev=r.next){case 0:return r.next=2,n.updateValue(e,t);case 2:case"end":return r.stop()}}),r)}))))}},{key:"updateValue",value:(h=C(regeneratorRuntime.mark((function e(t,n){var r,a,i,s,o,c,u;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.definitionService.getPrimaryKeyDefinition(t);case 2:if(r=e.sent,void 0!==n[r.name]){e.next=5;break}throw Error("Update failed: Record does not contain primary key field ".concat(r.name));case 5:return e.next=7,this.get(t,n[r.name]);case 7:if(void 0!==(a=e.sent)){e.next=10;break}throw Error("Update failed: Primary key ".concat(n[r.name]," does not exist in ").concat(t," table"));case 10:return e.next=12,this.ioService.write(n);case 12:return i=e.sent,e.next=15,this.definitionService.getTableDefinition(t);case 15:s=e.sent,o=T(s.columns),e.prev=17,o.s();case 19:if((c=o.n()).done){e.next=25;break}return u=c.value,e.next=23,this.indexService.updateIndex({table:t,index:u.name,mapKey:u.primary?n[r.name]:n[u.name],mapExistingKey:u.primary?n[r.name]:a[u.name],mapValue:u.primary?i.toString():n[r.name]});case 23:e.next=19;break;case 25:e.next=30;break;case 27:e.prev=27,e.t0=e.catch(17),o.e(e.t0);case 30:return e.prev=30,o.f(),e.finish(30);case 33:case"end":return e.stop()}}),e,this,[[17,27,30,33]])}))),function(e,t){return h.apply(this,arguments)})},{key:"put",value:function(e,t){var n=this;if(!this.selectedDatabase)throw Error("No database selected");if(!this.activeTransaction)throw Error("No transaction started");this.queueChange(e,C(regeneratorRuntime.mark((function r(){var a;return regeneratorRuntime.wrap((function(r){for(;;)switch(r.prev=r.next){case 0:return r.next=2,n.definitionService.getPrimaryKeyDefinition(e);case 2:if(a=r.sent,void 0!==t[a.name]){r.next=5;break}throw Error("Update failed: Record does not contain primary key field ".concat(a.name));case 5:return r.next=7,n.get(e,t[a.name]);case 7:if(!r.sent){r.next=13;break}return r.next=11,n.updateValue(e,t);case 11:r.next=15;break;case 13:return r.next=15,n.insertValue(e,t);case 15:case"end":return r.stop()}}),r)}))))}},{key:"getCID",value:(p=C(regeneratorRuntime.mark((function e(t,n){var r,a,i;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(this.selectedDatabase){e.next=2;break}throw Error("No database selected");case 2:return e.next=4,this.definitionService.getPrimaryKeyDefinition(t);case 4:return r=e.sent,e.next=7,this.indexService.getIndexMap(t,r.name);case 7:return a=e.sent,i=a.get(n.toString()),e.abrupt("return",i);case 10:case"end":return e.stop()}}),e,this)}))),function(e,t){return p.apply(this,arguments)})},{key:"get",value:(f=C(regeneratorRuntime.mark((function e(t,n){var r,a;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(this.selectedDatabase){e.next=2;break}throw Error("No database selected");case 2:return e.next=4,this.getCID(t,n);case 4:if(!(r=e.sent)){e.next=10;break}return e.next=8,this.ioService.read(r.toString());case 8:return a=e.sent,e.abrupt("return",a);case 10:case"end":return e.stop()}}),e,this)}))),function(e,t){return f.apply(this,arguments)})},{key:"searchIndex",value:(u=C(regeneratorRuntime.mark((function e(t){var n,r,a,i,s,o,u,f,l,p,h,v,d,m;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.definitionService.getTableDefinition(t.table);case 2:return n=e.sent,r=n.columns.filter((function(e){return e.name==t.index}))[0],e.next=6,this.indexService.getIndexMap(t.table,t.index);case 6:if(a=e.sent,n&&r&&a){e.next=9;break}return e.abrupt("return",[]);case 9:if(i=[],s=[],t.value){if(r.unique)(o=a.get(t.value))&&s.push(o);else if(u=a.get(t.value)){f=T(u);try{for(f.s();!(l=f.n()).done;)p=l.value,s.push(p)}catch(e){f.e(e)}finally{f.f()}}}else s=Object.keys(a.toSeq().toJS());s.sort(),t.sortDirection==c.ASC&&s.reverse(),h=0,v=T(s),e.prev=16,v.s();case 18:if((d=v.n()).done){e.next=35;break}if(m=d.value,!(i.length>=t.limit)){e.next=22;break}return e.abrupt("break",35);case 22:if(!(h<t.offset)){e.next=27;break}return h++,e.abrupt("continue",33);case 27:h++;case 28:return e.t0=i,e.next=31,this.get(t.table,m);case 31:e.t1=e.sent,e.t0.push.call(e.t0,e.t1);case 33:e.next=18;break;case 35:e.next=40;break;case 37:e.prev=37,e.t2=e.catch(16),v.e(e.t2);case 40:return e.prev=40,v.f(),e.finish(40);case 43:return e.abrupt("return",i);case 44:case"end":return e.stop()}}),e,this,[[16,37,40,43]])}))),function(e){return u.apply(this,arguments)})},{key:"count",value:(o=C(regeneratorRuntime.mark((function e(t){var n,r;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(this.selectedDatabase){e.next=2;break}throw Error("No database selected");case 2:return e.next=4,this.definitionService.getPrimaryKeyDefinition(t);case 4:return n=e.sent,e.next=7,this.indexService.getIndexMap(t,n.name);case 7:return r=e.sent,e.abrupt("return",r.size);case 9:case"end":return e.stop()}}),e,this)}))),function(e){return o.apply(this,arguments)})},{key:"delete",value:function(e,t){var n=this;if(!this.selectedDatabase)throw Error("No database selected");if(!this.activeTransaction)throw Error("No transaction started");this.queueChange(e,C(regeneratorRuntime.mark((function r(){var a,i,s,o,c;return regeneratorRuntime.wrap((function(r){for(;;)switch(r.prev=r.next){case 0:return r.next=2,n.definitionService.getPrimaryKeyDefinition(e);case 2:return r.sent,r.next=5,n.get(e,t);case 5:return a=r.sent,r.next=8,n.definitionService.getTableDefinition(e);case 8:i=r.sent,s=T(i.columns),r.prev=10,s.s();case 12:if((o=s.n()).done){r.next=18;break}return c=o.value,r.next=16,n.indexService.updateIndex({table:e,index:c.name,mapKey:void 0,mapExistingKey:a[c.name],mapValue:t});case 16:r.next=12;break;case 18:r.next=23;break;case 20:r.prev=20,r.t0=r.catch(10),s.e(r.t0);case 23:return r.prev=23,s.f(),r.finish(23);case 26:case"end":return r.stop()}}),r,null,[[10,20,23,26]])}))))}},{key:"flushToMFS",value:(s=C(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:case"end":return e.stop()}}),e)}))),function(){return s.apply(this,arguments)})},{key:"getDatabaseCID",value:(i=C(regeneratorRuntime.mark((function e(t){var n;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(this.ioService.databaseExists(t)){e.next=2;break}throw Error("Database does not exist");case 2:return e.next=4,this.ipfs.files.stat(this.ioService.getDatabasePath(t));case 4:return n=e.sent,e.abrupt("return",n.cid);case 6:case"end":return e.stop()}}),e,this)}))),function(e){return i.apply(this,arguments)})},{key:"updateFromCid",value:(a=C(regeneratorRuntime.mark((function e(t,n){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return console.log("Updating ".concat(t," from ").concat(n)),e.next=3,this.ioService.databaseExists(t);case 3:if(!e.sent){e.next=6;break}return e.next=6,this.ipfs.files.rm(this.ioService.getDatabasePath(t),{recursive:!0});case 6:return e.next=8,this.ipfs.files.cp("/ipfs/".concat(n),this.ioService.getDatabasePath(t));case 8:return e.next=10,this.useDatabase(t);case 10:case"end":return e.stop()}}),e,this)}))),function(e,t){return a.apply(this,arguments)})},{key:"queueChange",value:function(e,t){this.activeTransaction.changes.push(t),0==this.activeTransaction.tables.filter((function(t){return t==e})).length&&this.activeTransaction.tables.push(e)}}])&&N(t.prototype,n),r&&N(t,r),e}()}])})); |
@@ -12,16 +12,95 @@ import { IndexSearch } from "./service/index-service"; | ||
constructor(ipfs: any); | ||
/** | ||
* Create a new database from the passed in DatabaseDefinition. Will throw exceptions if there | ||
* are problems creating the database. | ||
* @param definition | ||
*/ | ||
createDatabase(definition: DatabaseDefinition): Promise<void>; | ||
/** | ||
* Drop a database from your local MFS. Does not delete underlying data. | ||
* @param name | ||
*/ | ||
dropDatabase(name: string): Promise<void>; | ||
databaseExists(database: string): Promise<boolean>; | ||
/** | ||
* Use the database with this name. All queries, inserts, updates, and deletes will use the tables in | ||
* this database. | ||
* @param name | ||
*/ | ||
useDatabase(name: string): Promise<void>; | ||
/** | ||
* Starts a new transaction. A transaction must be started before calling functions that change data. | ||
*/ | ||
startTransaction(): void; | ||
/** | ||
* Writes all changes to IPFS that have been called since we called startTransaction() | ||
*/ | ||
commit(): Promise<void>; | ||
/** | ||
* Queues a change to insert a record into a table. | ||
* @param table | ||
* @param value | ||
*/ | ||
insert(table: string, value: any): void; | ||
/** | ||
* Does the actual work of inserting a record. | ||
* @param table | ||
* @param value | ||
*/ | ||
private insertValue; | ||
/** | ||
* Update a record in a table. Matches on primary key. | ||
* @param table | ||
* @param value | ||
*/ | ||
update(table: string, value: any): void; | ||
/** | ||
* Does the actual work of inserting a record. | ||
* @param table | ||
* @param value | ||
*/ | ||
private updateValue; | ||
put(table: string, value: any): void; | ||
/** | ||
* Returns the CID for a record in a table. Key must match a value in the primary key of the table. | ||
* @param table | ||
* @param key | ||
*/ | ||
getCID(table: string, key: any): Promise<CID>; | ||
/** | ||
* Returns a record with the passed primary key in the named table. | ||
* @param table | ||
* @param key | ||
*/ | ||
get(table: string, key: any): Promise<any>; | ||
/** | ||
* Searches an index in a table for rows. Takes an IndexSearch object. | ||
* @param indexSearch | ||
*/ | ||
searchIndex(indexSearch: IndexSearch): Promise<any[]>; | ||
/** | ||
* Counts the records in a table. | ||
* @param table | ||
*/ | ||
count(table: string): Promise<any>; | ||
/** | ||
* Delete a record from a table. Also removes record from any indexes. | ||
* @param table | ||
* @param key | ||
*/ | ||
delete(table: string, key: any): void; | ||
/** | ||
* Flush data to MFS. | ||
*/ | ||
flushToMFS(): Promise<void>; | ||
getDatabaseCid(name: string): Promise<any>; | ||
/** | ||
* Returns the CID of the MFS directory where the database is stored. | ||
* @param name | ||
*/ | ||
getDatabaseCID(name: string): Promise<any>; | ||
/** | ||
* Mount an MFS directory by hash. | ||
* @param name | ||
* @param cid | ||
*/ | ||
updateFromCid(name: string, cid: string): Promise<void>; | ||
@@ -28,0 +107,0 @@ private queueChange; |
{ | ||
"name": "mfdb", | ||
"version": "0.0.17-alpha", | ||
"version": "0.0.18-alpha", | ||
"description": "MFdb is a portable P2P database backed by the IPFS Mutable File System.", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index-node.js", |
@@ -201,3 +201,3 @@ # MFdb | ||
### async databaseExists(name: string) | ||
### async databaseExists(database: string) : Promise<boolean> | ||
* Checks whether a database exists or not. | ||
@@ -217,2 +217,5 @@ | ||
### put(table:strig, value:any) | ||
* Calls insert if the record doesn't already exists. Calls update if it does exist. Slower than calling insert or update directly. | ||
### async get(table: string, key: any) | ||
@@ -262,3 +265,3 @@ * Query a table by primary key. Returns a single record. | ||
### async getDatabaseCid(name: string) | ||
### async getDatabaseCID(name: string) | ||
* Get the IPFS CID for the mutable file system folder where the database is stored. | ||
@@ -265,0 +268,0 @@ |
219
src/mfdb.ts
@@ -13,2 +13,3 @@ import { IndexSearch, IndexService, SortDirection } from "./service/index-service" | ||
import { DefinitionService } from "./service/definition-service" | ||
import { runInThisContext } from "vm" | ||
@@ -32,2 +33,7 @@ class MFdb { | ||
/** | ||
* Create a new database from the passed in DatabaseDefinition. Will throw exceptions if there | ||
* are problems creating the database. | ||
* @param definition | ||
*/ | ||
async createDatabase(definition: DatabaseDefinition) { | ||
@@ -60,2 +66,6 @@ | ||
/** | ||
* Drop a database from your local MFS. Does not delete underlying data. | ||
* @param name | ||
*/ | ||
async dropDatabase(name: string) { | ||
@@ -68,5 +78,14 @@ | ||
}) | ||
} catch (ex) { } | ||
} catch (ex) {} | ||
} | ||
async databaseExists(database: string) : Promise<boolean> { | ||
return this.ioService.databaseExists(database) | ||
} | ||
/** | ||
* Use the database with this name. All queries, inserts, updates, and deletes will use the tables in | ||
* this database. | ||
* @param name | ||
*/ | ||
async useDatabase(name: string) { | ||
@@ -85,2 +104,5 @@ | ||
/** | ||
* Starts a new transaction. A transaction must be started before calling functions that change data. | ||
*/ | ||
startTransaction() { | ||
@@ -94,2 +116,5 @@ console.debug('Starting new transaction') | ||
/** | ||
* Writes all changes to IPFS that have been called since we called startTransaction() | ||
*/ | ||
async commit() { | ||
@@ -113,2 +138,7 @@ | ||
/** | ||
* Queues a change to insert a record into a table. | ||
* @param table | ||
* @param value | ||
*/ | ||
insert(table:string, value: any) { | ||
@@ -120,38 +150,51 @@ | ||
this.queueChange(table, async () => { | ||
await this.insertValue(table, value) | ||
}) | ||
//Get primary key field | ||
let primaryKey:ColumnDefinition = await this.definitionService.getPrimaryKeyDefinition(table) | ||
} | ||
//Make sure we get passed a primary key | ||
if (value[primaryKey.name] === undefined) throw Error(`Insert failed: Record does not contain primary key field ${primaryKey.name}`) | ||
//Validate that the record doesn't exist otherwise throw an exception | ||
let existing = await this.get(table, value[primaryKey.name]) | ||
if (existing) { | ||
throw Error(`Insert failed: Primary key ${value[primaryKey.name]} already exists in ${table} table`) | ||
} | ||
/** | ||
* Does the actual work of inserting a record. | ||
* @param table | ||
* @param value | ||
*/ | ||
private async insertValue(table:string, value:any) { | ||
//Get primary key field | ||
let primaryKey:ColumnDefinition = await this.definitionService.getPrimaryKeyDefinition(table) | ||
//Save value | ||
let cid = await this.ioService.write(value) | ||
//Make sure we get passed a primary key | ||
if (value[primaryKey.name] === undefined) throw Error(`Insert failed: Record does not contain primary key field ${primaryKey.name}`) | ||
//Get definition | ||
let tableDefinition:TableDefinition = await this.definitionService.getTableDefinition(table) | ||
//Update indexes | ||
for (let column of tableDefinition.columns) { | ||
await this.indexService.updateIndex({ | ||
table: table, | ||
index: column.name, | ||
mapKey: column.primary ? value[primaryKey.name] : value[column.name], | ||
mapValue: column.primary ? cid.toString() : value[primaryKey.name] | ||
}) | ||
} | ||
//Validate that the record doesn't exist otherwise throw an exception | ||
let existing = await this.get(table, value[primaryKey.name]) | ||
if (existing) { | ||
throw Error(`Insert failed: Primary key ${value[primaryKey.name]} already exists in ${table} table`) | ||
} | ||
}) | ||
//Save value | ||
let cid = await this.ioService.write(value) | ||
//Get definition | ||
let tableDefinition:TableDefinition = await this.definitionService.getTableDefinition(table) | ||
//Update indexes | ||
for (let column of tableDefinition.columns) { | ||
await this.indexService.updateIndex({ | ||
table: table, | ||
index: column.name, | ||
mapKey: column.primary ? value[primaryKey.name] : value[column.name], | ||
mapValue: column.primary ? cid.toString() : value[primaryKey.name] | ||
}) | ||
} | ||
} | ||
/** | ||
* Update a record in a table. Matches on primary key. | ||
* @param table | ||
* @param value | ||
*/ | ||
update(table:string, value:any) { | ||
@@ -163,3 +206,58 @@ | ||
this.queueChange(table, async () => { | ||
await this.updateValue(table, value) | ||
}) | ||
} | ||
/** | ||
* Does the actual work of inserting a record. | ||
* @param table | ||
* @param value | ||
*/ | ||
private async updateValue(table:string, value:any) { | ||
//Get primary key field | ||
let primaryKey:ColumnDefinition = await this.definitionService.getPrimaryKeyDefinition(table) | ||
//Make sure we get passed a primary key | ||
if (value[primaryKey.name] === undefined) throw Error(`Update failed: Record does not contain primary key field ${primaryKey.name}`) | ||
//Get existing value | ||
let existing = await this.get(table, value[primaryKey.name]) | ||
//Validate that the record doesn't exist otherwise throw an exception | ||
if (existing === undefined) { | ||
throw Error(`Update failed: Primary key ${value[primaryKey.name]} does not exist in ${table} table`) | ||
} | ||
//Save value | ||
let cid = await this.ioService.write(value) | ||
//Get definition | ||
let tableDefinition:TableDefinition = await this.definitionService.getTableDefinition(table) | ||
//Update indexes | ||
for (let column of tableDefinition.columns) { | ||
await this.indexService.updateIndex({ | ||
table: table, | ||
index: column.name, | ||
mapKey: column.primary ? value[primaryKey.name] : value[column.name], | ||
mapExistingKey: column.primary ? value[primaryKey.name] : existing[column.name], | ||
mapValue: column.primary ? cid.toString() : value[primaryKey.name] | ||
}) | ||
} | ||
} | ||
put(table:string, value:any) { | ||
if (!this.selectedDatabase) throw Error("No database selected") | ||
if (!this.activeTransaction) throw Error("No transaction started") | ||
this.queueChange(table, async () => { | ||
//Get primary key field | ||
@@ -174,31 +272,20 @@ let primaryKey:ColumnDefinition = await this.definitionService.getPrimaryKeyDefinition(table) | ||
//Validate that the record doesn't exist otherwise throw an exception | ||
if (existing === undefined) { | ||
throw Error(`Update failed: Primary key ${value[primaryKey.name]} does not exist in ${table} table`) | ||
if (existing) { | ||
await this.updateValue(table, value) | ||
} else { | ||
await this.insertValue(table, value) | ||
} | ||
//Save value | ||
let cid = await this.ioService.write(value) | ||
//Get schema | ||
let tableDefinition:TableDefinition = await this.definitionService.getTableDefinition(table) | ||
//Update indexes except primary key | ||
for (let column of tableDefinition.columns.filter( column => !column.primary)) { | ||
}) | ||
await this.indexService.updateIndex({ | ||
table: table, | ||
index: column.name, | ||
mapKey: value[column.name], | ||
mapExistingKey: existing[column.name], | ||
mapValue: value[primaryKey.name] | ||
}) | ||
} | ||
}) | ||
} | ||
/** | ||
* Returns the CID for a record in a table. Key must match a value in the primary key of the table. | ||
* @param table | ||
* @param key | ||
*/ | ||
async getCID(table: string, key: any): Promise<CID> { | ||
@@ -217,2 +304,7 @@ | ||
/** | ||
* Returns a record with the passed primary key in the named table. | ||
* @param table | ||
* @param key | ||
*/ | ||
async get(table: string, key: any): Promise<any> { | ||
@@ -231,2 +323,6 @@ | ||
/** | ||
* Searches an index in a table for rows. Takes an IndexSearch object. | ||
* @param indexSearch | ||
*/ | ||
async searchIndex(indexSearch:IndexSearch) { | ||
@@ -237,2 +333,4 @@ | ||
let indexMap = await this.indexService.getIndexMap(indexSearch.table, indexSearch.index) | ||
//Todo: put some validation here | ||
@@ -265,3 +363,2 @@ if (!schema || !definition || !indexMap) return [] | ||
//Return all | ||
primaryKeys = Object.keys(indexMap.toSeq().toJS()) | ||
@@ -296,3 +393,6 @@ } | ||
/** | ||
* Counts the records in a table. | ||
* @param table | ||
*/ | ||
async count(table: string) { | ||
@@ -309,2 +409,7 @@ | ||
/** | ||
* Delete a record from a table. Also removes record from any indexes. | ||
* @param table | ||
* @param key | ||
*/ | ||
delete(table: string, key: any) { | ||
@@ -346,2 +451,5 @@ | ||
/** | ||
* Flush data to MFS. | ||
*/ | ||
async flushToMFS() { | ||
@@ -351,3 +459,7 @@ /** TODO */ | ||
async getDatabaseCid(name: string) { | ||
/** | ||
* Returns the CID of the MFS directory where the database is stored. | ||
* @param name | ||
*/ | ||
async getDatabaseCID(name: string) { | ||
@@ -364,2 +476,7 @@ if (!this.ioService.databaseExists(name)) { | ||
/** | ||
* Mount an MFS directory by hash. | ||
* @param name | ||
* @param cid | ||
*/ | ||
async updateFromCid(name: string, cid: string) { | ||
@@ -366,0 +483,0 @@ |
@@ -70,3 +70,3 @@ import assert from 'assert' | ||
//Get CID | ||
let cid = await db.getDatabaseCid('test') | ||
let cid = await db.getDatabaseCID('test') | ||
assert.strictEqual(cid.toString(), "QmektKwdwQA52fFRX9Di3gdY79LU7crKthwprko3eeXbgL") | ||
@@ -172,3 +172,3 @@ | ||
let cid = await db.getDatabaseCid('test') | ||
let cid = await db.getDatabaseCID('test') | ||
assert.strictEqual(cid.toString(), firstCid) | ||
@@ -239,3 +239,3 @@ | ||
secondCid = "QmPTu4esVgy9ykCNoajY1jc3KALFKWLm6Bt7RWQfpHrUko" | ||
let cid = await db.getDatabaseCid('test') | ||
let cid = await db.getDatabaseCID('test') | ||
assert.strictEqual(cid.toString(), secondCid) | ||
@@ -353,3 +353,3 @@ | ||
//Get CID | ||
let cid = await db.getDatabaseCid('test') | ||
let cid = await db.getDatabaseCID('test') | ||
assert.strictEqual(cid.toString(), "QmYKpu7bVay1PqhwAakrEigk441XJkUtkPs4HU8XXawpAD") | ||
@@ -445,4 +445,4 @@ | ||
//Get CID | ||
let cid = await db.getDatabaseCid('test') | ||
assert.strictEqual(cid.toString(), "QmZXZPAzCe6JcbrhGTbRhVk9UouwLLHbVrxNW3ctnMqxY1") | ||
let cid = await db.getDatabaseCID('test') | ||
assert.strictEqual(cid.toString(), "QmPiD48s5qPrUrJ3U556M7zpsSmd39MJRE73TmcF7Z1rkB") | ||
@@ -492,4 +492,4 @@ }) | ||
//Get CID | ||
thirdCid = "QmdBvJR1bCvMeTuu4vaWBLn9eTFjmdWuVhc6zdMQ3a3633" | ||
let cid = await db.getDatabaseCid('test') | ||
thirdCid = "QmWamWgQTxzc7iLgS9b6KyUKyXr8FZgvEQnEUPDV8A2DUY" | ||
let cid = await db.getDatabaseCID('test') | ||
assert.strictEqual(cid.toString(), thirdCid) | ||
@@ -499,2 +499,56 @@ | ||
it('should put a new record', async () => { | ||
//Act | ||
db.startTransaction() | ||
db.put("player", { | ||
id: '10000', | ||
name: "Bob Vance", | ||
currentTeam: "MIA", | ||
battingHand: "L", | ||
throwingHand: "L" | ||
}) | ||
await db.commit() | ||
//Assert | ||
let fetched = await db.get("player", "10000") | ||
assert.strictEqual(fetched.id, "10000") | ||
assert.strictEqual(fetched.name, "Bob Vance") | ||
assert.strictEqual(fetched.currentTeam, "MIA") | ||
assert.strictEqual(fetched.battingHand, "L") | ||
assert.strictEqual(fetched.throwingHand, "L") | ||
}) | ||
it('should put an existing record', async () => { | ||
//Act | ||
db.startTransaction() | ||
db.put("player", { | ||
id: '10000', | ||
name: "Bob Vance", | ||
currentTeam: "TEX", | ||
battingHand: "R", | ||
throwingHand: "R" | ||
}) | ||
await db.commit() | ||
//Assert | ||
let fetched = await db.get("player", "10000") | ||
assert.strictEqual(fetched.id, "10000") | ||
assert.strictEqual(fetched.name, "Bob Vance") | ||
assert.strictEqual(fetched.currentTeam, "TEX") | ||
assert.strictEqual(fetched.battingHand, "R") | ||
assert.strictEqual(fetched.throwingHand, "R") | ||
}) | ||
it('should load a database from cid', async () => { | ||
@@ -501,0 +555,0 @@ |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
658245
3436
283