@nozbe/watermelondb
Version:
Build powerful React Native and React web apps that scale from hundreds to tens of thousands of records and remain fast
215 lines (211 loc) • 7.21 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
exports.getPath = getPath;
var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
var _wrapNativeSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapNativeSuper"));
var _Database = _interopRequireDefault(require("./Database"));
function fixArgs(args) {
return args.map(function (value) {
if ('boolean' === typeof value) {
return value ? 1 : 0;
}
return value;
});
}
var MigrationNeededError = /*#__PURE__*/function (_Error) {
function MigrationNeededError(databaseVersion) {
var _this = _Error.call(this, 'MigrationNeededError') || this;
_this.databaseVersion = databaseVersion;
_this.type = 'MigrationNeededError';
_this.message = 'MigrationNeededError';
return _this;
}
(0, _inheritsLoose2.default)(MigrationNeededError, _Error);
return MigrationNeededError;
}(/*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
var SchemaNeededError = /*#__PURE__*/function (_Error2) {
function SchemaNeededError() {
var _this2 = _Error2.call(this, 'SchemaNeededError') || this;
_this2.type = 'SchemaNeededError';
_this2.message = 'SchemaNeededError';
return _this2;
}
(0, _inheritsLoose2.default)(SchemaNeededError, _Error2);
return SchemaNeededError;
}(/*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
function getPath(dbName) {
if (':memory:' === dbName || 'file::memory:' === dbName) {
return dbName;
}
var path = dbName.startsWith('/') || dbName.startsWith('file:') ? dbName : "".concat(process.cwd(), "/").concat(dbName);
if (-1 === path.indexOf('.db')) {
if (0 <= path.indexOf('?')) {
var index = path.indexOf('?');
path = "".concat(path.substring(0, index), ".db").concat(path.substring(index));
} else {
path = "".concat(path, ".db");
}
}
return path;
}
var DatabaseDriver = /*#__PURE__*/function () {
function DatabaseDriver() {
this.cachedRecords = {};
}
var _proto = DatabaseDriver.prototype;
_proto.initialize = function (dbName, schemaVersion) {
this.init(dbName);
this.isCompatible(schemaVersion);
};
_proto.setUpWithSchema = function (dbName, schema, schemaVersion) {
this.init(dbName);
this.unsafeResetDatabase({
version: schemaVersion,
sql: schema
});
this.isCompatible(schemaVersion);
};
_proto.setUpWithMigrations = function (dbName, migrations) {
this.init(dbName);
this.migrate(migrations);
this.isCompatible(migrations.to);
};
_proto.init = function (dbName) {
this.database = new _Database.default(getPath(dbName));
var isSharedMemory = 0 < dbName.indexOf('mode=memory') && 0 < dbName.indexOf('cache=shared');
if (isSharedMemory) {
if (!DatabaseDriver.sharedMemoryConnections[dbName]) {
DatabaseDriver.sharedMemoryConnections[dbName] = this.database;
}
this.database = DatabaseDriver.sharedMemoryConnections[dbName];
}
};
_proto.find = function (table, id) {
if (this.isCached(table, id)) {
return id;
}
var query = "SELECT * FROM '".concat(table, "' WHERE id == ? LIMIT 1");
var results = this.database.queryRaw(query, [id]);
if (0 === results.length) {
return null;
}
this.markAsCached(table, id);
return results[0];
};
_proto.cachedQuery = function (table, query, args) {
var _this3 = this;
var results = this.database.queryRaw(query, fixArgs(args));
return results.map(function (row) {
var id = "".concat(row.id);
if (_this3.isCached(table, id)) {
return id;
}
_this3.markAsCached(table, id);
return row;
});
};
_proto.queryIds = function (query, args) {
return this.database.queryRaw(query, fixArgs(args)).map(function (row) {
return "".concat(row.id);
});
};
_proto.unsafeQueryRaw = function (query, args) {
return this.database.queryRaw(query, fixArgs(args));
};
_proto.count = function (query, args) {
return this.database.count(query, fixArgs(args));
};
_proto.batch = function (operations) {
var _this4 = this;
var newIds = [];
var removedIds = [];
this.database.inTransaction(function () {
operations.forEach(function (operation) {
var [cacheBehavior, table, sql, argBatches] = operation;
argBatches.forEach(function (args) {
_this4.database.execute(sql, fixArgs(args));
if (1 === cacheBehavior) {
newIds.push([table, args[0]]);
} else if (-1 === cacheBehavior) {
removedIds.push([table, args[0]]);
}
});
});
});
newIds.forEach(function ([table, id]) {
_this4.markAsCached(table, id);
});
removedIds.forEach(function ([table, id]) {
_this4.removeFromCache(table, id);
});
}
// MARK: - LocalStorage
;
_proto.getLocal = function (key) {
var results = this.database.queryRaw('SELECT `value` FROM `local_storage` WHERE `key` = ?', [key]);
if (0 < results.length) {
return results[0].value;
}
return null;
}
// MARK: - Record caching
;
_proto.hasCachedTable = function (table) {
// $FlowFixMe
return Object.prototype.hasOwnProperty.call(this.cachedRecords, table);
};
_proto.isCached = function (table, id) {
if (this.hasCachedTable(table)) {
return this.cachedRecords[table].has(id);
}
return false;
};
_proto.markAsCached = function (table, id) {
if (!this.hasCachedTable(table)) {
this.cachedRecords[table] = new Set();
}
this.cachedRecords[table].add(id);
};
_proto.removeFromCache = function (table, id) {
if (this.hasCachedTable(table) && this.cachedRecords[table].has(id)) {
this.cachedRecords[table].delete(id);
}
}
// MARK: - Other private details
;
_proto.isCompatible = function (schemaVersion) {
var databaseVersion = this.database.userVersion;
if (schemaVersion !== databaseVersion) {
if (0 < databaseVersion && databaseVersion < schemaVersion) {
throw new MigrationNeededError(databaseVersion);
} else {
throw new SchemaNeededError();
}
}
};
_proto.unsafeResetDatabase = function (schema) {
var _this5 = this;
this.database.unsafeDestroyEverything();
this.cachedRecords = {};
this.database.inTransaction(function () {
_this5.database.executeStatements(schema.sql);
_this5.database.userVersion = schema.version;
});
};
_proto.migrate = function (migrations) {
var _this6 = this;
var databaseVersion = this.database.userVersion;
if ("".concat(migrations.from) !== "".concat(databaseVersion)) {
throw new Error("Incompatbile migration set applied. DB: ".concat(databaseVersion, ", migration: ").concat(migrations.from));
}
this.database.inTransaction(function () {
_this6.database.executeStatements(migrations.sql);
_this6.database.userVersion = migrations.to;
});
};
return DatabaseDriver;
}();
DatabaseDriver.sharedMemoryConnections = {};
var _default = exports.default = DatabaseDriver;