UNPKG

@nano-sql/adapter-leveldb

Version:

Easily Run LevelDB in NodeJS with nanoSQL 2!

398 lines 15.5 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); var utilities_1 = require("@nano-sql/core/lib/utilities"); var memoryIndex_1 = require("@nano-sql/core/lib/adapters/memoryIndex"); var wasm = require("./wasm-index"); var levelup = require("levelup"); var encode = require("encoding-down"); var lexint = require("lexicographic-integer-encoding"); var fs = require("fs"); var path = require("path"); var leveldown = require("leveldown"); var encoding = lexint("hex", { strict: true }); exports.rimraf = function (dir_path) { if (fs.existsSync(dir_path)) { fs.readdirSync(dir_path).forEach(function (entry) { var entry_path = path.join(dir_path, entry); if (fs.lstatSync(entry_path).isDirectory()) { exports.rimraf(entry_path); } else { fs.unlinkSync(entry_path); } }); fs.rmdirSync(dir_path); } }; var LevelDB = /** @class */ (function (_super) { __extends(LevelDB, _super); function LevelDB(dbPath, indexCache) { var _this = _super.call(this, false, false) || this; _this.dbPath = dbPath; _this.indexCache = indexCache; _this.plugin = { name: "LevelDB Adapter", version: 2.05 }; _this._indexNum = {}; _this._levelDBs = {}; _this._ai = {}; _this._tableConfigs = {}; if (typeof _this.dbPath === "string" || typeof _this.dbPath === "undefined") { _this._lvlDown = (function (dbId, tableName, tableData) { var basePath = path.join(_this.dbPath || ".", "db_" + dbId); if (!fs.existsSync(basePath)) { fs.mkdirSync(basePath); } return { lvld: leveldown(path.join(basePath, tableName)), args: { cacheSize: 64 * 1024 * 1024, writeBufferSize: 64 * 1024 * 1024 } }; }); } else { _this._lvlDown = _this.dbPath; } return _this; } LevelDB.prototype.connect = function (id, complete, error) { var _this = this; this._id = id; var tableName = "_ai_store_"; var lvlDownAI = this._lvlDown(this._id, tableName, __assign({}, utilities_1.blankTableDefinition, { pkType: "string" })); var keyEncoding = "binary"; levelup(encode(lvlDownAI.lvld, { valueEncoding: "json", keyEncoding: keyEncoding }), lvlDownAI.args, function (err, db) { if (err) { error(err); return; } if (_this.indexCache) { var checkWasm_1 = function () { if (wasm.loaded) { _this._levelDBs[tableName] = db; complete(); } else { setTimeout(checkWasm_1, 10); } }; checkWasm_1(); } else { _this._levelDBs[tableName] = db; complete(); } }); }; LevelDB.prototype.createTable = function (tableName, tableData, complete, error) { var _this = this; if (this._levelDBs[tableName]) { error(new Error("Table " + tableName + " already exists and is open!")); return; } this._tableConfigs[tableName] = tableData; var keyEncoding = { "int": encoding }[tableData.pkType] || "binary"; var lvlDown = this._lvlDown(this._id, tableName, tableData); levelup(encode(lvlDown.lvld, { valueEncoding: "json", keyEncoding: keyEncoding }), lvlDown.args, function (err, db) { if (err) { error(err); return; } _this._levelDBs[tableName] = db; _this._indexNum[tableName] = tableData.isPkNum ? wasm.new_index() : wasm.new_index_str(); _this._levelDBs["_ai_store_"].get(Buffer.from(tableName, "utf-8"), function (err, value) { _this._ai[tableName] = value ? value.ai || 0 : 0; if (_this.indexCache && tableData) { _this._levelDBs[tableName] .createKeyStream() .on("data", function (data) { if (tableData.isPkNum) { wasm.add_to_index(_this._indexNum[tableName], isNaN(data) ? 0 : parseFloat(data)); } else { wasm.add_to_index_str(_this._indexNum[tableName], String(data || "")); } }) .on("end", function () { complete(); }) .on("error", error); } else { complete(); } }); }); }; LevelDB.prototype.dropTable = function (table, complete, error) { var _this = this; this._levelDBs["_ai_store_"].del(Buffer.from(table, "utf-8")).then(function () { _this._levelDBs[table].close(function (err) { try { exports.rimraf(path.join((_this.dbPath || "."), "db_" + _this._id, table)); } catch (e) { error(e); return; } if (_this.indexCache && _this._tableConfigs[table]) { if (_this._tableConfigs[table].isPkNum) { wasm.empty_index(_this._indexNum[table]); } else { wasm.empty_index_str(_this._indexNum[table]); } } delete _this._levelDBs[table]; complete(); }, error); }).catch(error); }; LevelDB.prototype.disconnect = function (complete, error) { var _this = this; utilities_1.allAsync(Object.keys(this._levelDBs), function (table, i, next, error) { if (_this.indexCache && _this._tableConfigs[table]) { _this._tableConfigs[table].isPkNum ? wasm.empty_index(_this._indexNum[table]) : wasm.empty_index_str(_this._indexNum[table]); } _this._levelDBs[table].close(function (err) { if (err) { error(err); return; } delete _this._tableConfigs[table]; next(null); }); }).then(complete).catch(error); }; LevelDB.prototype.write = function (table, pk, row, complete, error) { var _this = this; pk = pk || utilities_1.generateID(this._tableConfigs[table].pkType, this._ai[table] + 1); if (typeof pk === "undefined") { error(new Error("Can't add a row without a primary key!")); return; } if (this._tableConfigs[table].ai) { this._ai[table] = Math.max(pk, this._ai[table]); } utilities_1.deepSet(this._tableConfigs[table].pkCol, row, pk); if (this.indexCache) { if (this._tableConfigs[table].isPkNum) { wasm.add_to_index(this._indexNum[table], isNaN(pk) ? 0 : parseFloat(pk)); } else { wasm.add_to_index_str(this._indexNum[table], String(pk || "")); } } this._levelDBs[table].put(this._encodePk(table, pk), row, function (err) { if (err) { error(err); } else { if (_this._tableConfigs[table].ai) { _this._levelDBs["_ai_store_"].put(Buffer.from(table, "utf-8"), { ai: _this._ai[table] }).then(function () { complete(pk); }).catch(error); } else { complete(pk); } } }); }; LevelDB.prototype.read = function (table, pk, complete, error) { this._levelDBs[table].get(this._encodePk(table, pk), function (err, row) { if (err) { complete(undefined); } else { complete(row); } }); }; LevelDB.prototype.readMulti = function (table, type, offsetOrLow, limitOrHigh, reverse, onRow, complete, error) { var _this = this; if (this.indexCache && type === "offset") { var ptrFn = this._tableConfigs[table].isPkNum ? wasm.read_index_offset : wasm.read_index_offset_str; var nextFn_1 = this._tableConfigs[table].isPkNum ? wasm.read_index_offset_next : wasm.read_index_offset_str_next; var it_1 = ptrFn(this._indexNum[table], reverse ? 1 : 0, reverse ? offsetOrLow + 2 : offsetOrLow + 1); if (it_1 === 0) { complete(); return; } var nextKey_1 = 0; var count_1 = 0; var nextRow_1 = function () { nextKey_1 = nextFn_1(_this._indexNum[table], it_1, reverse ? 1 : 0, limitOrHigh, count_1); if (count_1 < limitOrHigh) { _this.read(table, nextKey_1, function (row) { if (row) { onRow(row, count_1); } if (count_1 % 500 === 0) { setTimeout(nextRow_1, 0); } else { nextRow_1(); } }, error); } else { complete(); } count_1++; }; nextRow_1(); return; } var i = 0; this._levelDBs[table] .createValueStream(type === "range" ? { gte: type === "range" ? this._encodePk(table, offsetOrLow) : undefined, lte: type === "range" ? this._encodePk(table, limitOrHigh) : undefined, reverse: reverse } : type === "offset" ? { reverse: reverse, limit: type === "offset" ? (offsetOrLow + limitOrHigh + (reverse ? 1 : 0)) : undefined } : { reverse: reverse, }) .on("data", function (data) { if (type === "offset" && (reverse ? i < offsetOrLow + 1 : i < offsetOrLow)) { i++; return; } onRow(data, i); i++; }) .on("end", function () { complete(); }) .on("error", error); }; LevelDB.prototype._writeNumberBuffer = function (table, num) { switch (this._tableConfigs[table].pkType) { case "int": return num; // case "float": // case "number": default: return Buffer.from(String(num), "utf-8"); } }; LevelDB.prototype._readNumberBuffer = function (table, buff) { switch (this._tableConfigs[table].pkType) { case "int": return buff; // case "float": // case "number": default: var buffer = new Buffer(buff); return parseFloat(buffer.toString("utf-8")); } }; LevelDB.prototype._encodePk = function (table, pk) { return this._tableConfigs[table].isPkNum ? this._writeNumberBuffer(table, pk) : Buffer.from(pk, "utf-8"); }; LevelDB.prototype._decodePK = function (table, pk) { return this._tableConfigs[table].isPkNum ? this._readNumberBuffer(table, pk) : new Buffer(pk).toString("utf-8"); }; LevelDB.prototype.delete = function (table, pk, complete, error) { var _this = this; this._levelDBs[table].del(this._encodePk(table, pk), function (err) { if (err) { throw Error(err); } else { if (_this.indexCache && _this._tableConfigs[table]) { if (_this._tableConfigs[table].isPkNum) { wasm.del_key(_this._indexNum[table], isNaN(pk) ? 0 : parseFloat(pk)); } else { wasm.del_key_str(_this._indexNum[table], String(pk || "")); } } complete(); } }); }; LevelDB.prototype.getTableIndex = function (table, complete, error) { var _this = this; if (this.indexCache && this._tableConfigs[table]) { var ptrFn = this._tableConfigs[table].isPkNum ? wasm.read_index : wasm.read_index_str; var nextFn = this._tableConfigs[table].isPkNum ? wasm.read_index_next : wasm.read_index_str_next; var it_2 = ptrFn(this._indexNum[table], 0); if (!it_2) { complete([]); return; } it_2 = it_2.split(",").map(function (s) { return parseInt(s); }); var nextKey = 0; var count = 0; var keys = []; while (count < it_2[1]) { nextKey = nextFn(this._indexNum[table], it_2[0], 0, count); count++; keys.push(nextKey); } complete(keys); return; } var index = []; this._levelDBs[table] .createKeyStream() .on("data", function (pk) { index.push(_this._decodePK(table, pk)); }) .on("end", function () { complete(index); }) .on("error", error); }; LevelDB.prototype.getTableIndexLength = function (table, complete, error) { if (this.indexCache && this._tableConfigs[table]) { complete(this._tableConfigs[table].isPkNum ? wasm.get_total(this._indexNum[table]) : wasm.get_total_str(this._indexNum[table])); return; } var count = 0; this._levelDBs[table] .createKeyStream() .on("data", function (pk) { count++; }) .on("end", function () { complete(count); }) .on("error", error); }; return LevelDB; }(memoryIndex_1.nanoSQLMemoryIndex)); exports.LevelDB = LevelDB; //# sourceMappingURL=index.js.map