This commit is contained in:
Peter Maquiran
2023-07-10 12:38:29 +01:00
parent f6f61a11ca
commit b3bbbffadd
103 changed files with 5600 additions and 10 deletions
+6
View File
@@ -0,0 +1,6 @@
import { actionParam, dbType } from './intreface.js';
export declare class DBSwitch {
private static header;
static requestHandler(TableName: string, DatabaseName: string, dbType: dbType, action: actionParam, arg: any, queryId: any): Promise<unknown>;
static callBackRequestHandler(TableName: string, DatabaseName: string, dbType: dbType, action: actionParam, arg: any, callback: Function, queryId: string): Promise<void>;
}
+40
View File
@@ -0,0 +1,40 @@
import { indexedDB } from './indexedDb/indexedb.js';
import { taskHolder } from './taskHolder.js';
import { WorkerManager } from './workerManager.js';
export class DBSwitch {
static header({ TableName, DatabaseName, queryId, action, arg, dbType, callback }) {
return {
params: { TableName, DatabaseName, queryId, action, arg, dbType },
queryId: queryId,
method: 'execute',
callback: (message) => {
callback(message.value);
}
};
}
static async requestHandler(TableName, DatabaseName, dbType, action, arg, queryId) {
return new Promise(async (resolve, reject) => {
const header = this.header({ TableName, DatabaseName, queryId, action, arg, dbType, callback: (data) => {
resolve(data);
taskHolder.finish(queryId);
} });
if (typeof (Worker) !== "undefined" && WorkerManager.webWorkerModuleSupport) {
WorkerManager.register(header);
}
else {
taskHolder.register(header);
indexedDB.requestHandler(TableName, DatabaseName, queryId)[action](arg);
}
});
}
static async callBackRequestHandler(TableName, DatabaseName, dbType, action, arg, callback, queryId) {
const header = this.header({ TableName, DatabaseName, queryId, action, arg, dbType, callback });
if (typeof (Worker) !== "undefined" && WorkerManager.webWorkerModuleSupport) {
WorkerManager.register(header);
}
else {
taskHolder.register(header);
indexedDB.requestHandler(TableName, DatabaseName, queryId)[action](arg);
}
}
}
@@ -0,0 +1,9 @@
import { DatabaseSchema } from "../../models/register-modal.interface.js";
import { Database } from "./database.js";
export declare class DatabaseManager {
static databases: {
[databaseName: string]: Database;
};
static prepare(config: DatabaseSchema): Promise<void>;
static getDb(databaseName: any): Database;
}
@@ -0,0 +1,12 @@
import { Database } from "./database.js";
// inspire by https://github.com/hc-oss/use-indexeddb
export class DatabaseManager {
static async prepare(config) {
this.databases[config.databaseName] = new Database({ config });
await this.databases[config.databaseName].migrate();
}
static getDb(databaseName) {
return this.databases[databaseName];
}
}
DatabaseManager.databases = {};
+6
View File
@@ -0,0 +1,6 @@
import { DatabaseSchema } from "../../models/register-modal.interface.js";
export declare class IndexedDBConnector {
static connect(config: DatabaseSchema): Promise<IDBDatabase>;
static migrate(config: DatabaseSchema): Promise<boolean>;
private static runMigrations;
}
@@ -0,0 +1,61 @@
// inspire by https://github.com/hc-oss/use-indexeddb
export class IndexedDBConnector {
static connect(config) {
return new Promise((resolve, reject) => {
const idbInstance = indexedDB || self.indexedDB || self.mozIndexedDB || self.webkitIndexedDB || self.msIndexedDB;
if (idbInstance) {
const request = idbInstance.open(config.databaseName, config.version);
request.onsuccess = () => {
resolve(request.result);
};
request.onerror = (e) => {
reject(e.target.error.name);
};
request.onupgradeneeded = async (e) => {
await this.migrate(config);
return await this.connect(config);
};
// request.onblocked = async (e: any) => {
// reject(e.target.error.name);
// }
}
else {
reject("IDBDatabase not supported inside webworker");
}
});
}
static migrate(config) {
return new Promise((resolve, reject) => {
const idbInstance = indexedDB || self.indexedDB || self.mozIndexedDB || self.webkitIndexedDB || self.msIndexedDB;
if (idbInstance) {
const request = idbInstance.open(config.databaseName, config.version);
request.onsuccess = () => {
// request.result.close()
resolve(false);
};
request.onerror = (e) => {
reject(e.target.error.name);
};
request.onupgradeneeded = async (e) => {
const db = e.target.result;
await this.runMigrations(db, config);
db.close();
resolve(true);
};
}
else {
reject("Failed to connect");
}
});
}
static async runMigrations(db, config) {
await config.stores.forEach(async (storeSchema) => {
if (!db.objectStoreNames.contains(storeSchema.name)) {
const ObjectStore = db.createObjectStore(storeSchema.name, storeSchema.id);
storeSchema.fields.forEach(c => {
ObjectStore.createIndex(c.name, c.keyPath, c.options);
});
}
});
}
}
+28
View File
@@ -0,0 +1,28 @@
import { DatabaseSchema } from '../../models/register-modal.interface';
import { ObjectStore } from './objectStore.js';
export declare class Database {
name: string;
version: string;
objectStore: {
[storeName: string]: ObjectStore;
};
dbInstance: IDBDatabase;
executingTransaction: {
[key: string]: boolean;
};
storeUsingDbInstance: {
[key: string]: boolean;
};
config: DatabaseSchema;
constructor({ config }: {
config: DatabaseSchema;
});
getDatabaseConnection(): Promise<IDBDatabase>;
getOrCreateTransaction({ TableName, queryId }: {
TableName: any;
queryId: any;
}, mode: any, callback: any): Promise<void>;
getObjectStore(TableName: any): ObjectStore;
transactionFinish: (TableName: any) => void;
migrate(): Promise<boolean>;
}
@@ -0,0 +1,42 @@
import { ObjectStore } from './objectStore.js';
import { IndexedDBConnector } from './connect.js';
export class Database {
constructor({ config }) {
this.name = '';
this.version = '';
this.objectStore = {};
this.executingTransaction = {};
this.storeUsingDbInstance = {};
this.transactionFinish = (TableName) => {
delete this.storeUsingDbInstance[TableName];
delete this.storeUsingDbInstance[TableName];
if (Object.keys(this.storeUsingDbInstance).length == 0) {
this.dbInstance.close();
delete this.dbInstance;
}
};
this.config = config;
this.name = this.config.databaseName;
for (let store of config.stores) {
this.objectStore[store.name] = new ObjectStore({ store });
this.objectStore[store.name].transactionFinish = this.transactionFinish;
}
}
async getDatabaseConnection() {
if (!this.dbInstance) {
this.dbInstance = await IndexedDBConnector.connect(this.config);
}
return this.dbInstance;
}
async getOrCreateTransaction({ TableName, queryId }, mode, callback) {
const Database = await this.getDatabaseConnection();
this.storeUsingDbInstance[TableName] = true;
this.objectStore[TableName].getOrCreateTransaction({ Database, queryId }, "readonly", callback);
}
getObjectStore(TableName) {
return this.objectStore[TableName];
}
async migrate() {
return await IndexedDBConnector.migrate(this.config);
}
}
+38
View File
@@ -0,0 +1,38 @@
import { DatabaseSchema, TableSchema } from "../../models/register-modal.interface.js";
import { Method } from "../../models/model.interface.js";
import { Database } from "./database.js";
declare class indexedDBInterface {
getActions: (TableName: string, Database: Database, queryId: string) => {
getByID: (id: string | number) => Promise<any>;
getOneByIndex: (keyPath: string, value: string | number) => Promise<any>;
getAll: () => Promise<any[]>;
add: ({ value, key, add, index }: {
value: any;
key: any;
add: any;
index: any;
}) => Promise<unknown>;
update: ({ value, key }: {
value: any;
key?: any;
}) => Promise<any>;
deleteByID: (id: any) => Promise<any>;
deleteAll: () => Promise<any>;
};
requestHandler: (TableName: string, DatabaseName: string, queryId: any, PostMessage?: typeof postMessage) => {
select: (methods: Method[]) => Promise<unknown>;
update: (methods: Method[]) => Promise<void>;
delete: (methods: Method[]) => Promise<void>;
insert: (methods: Method[]) => Promise<void>;
migrate: ({ DatabaseSchema, TableSchema }: {
DatabaseSchema: DatabaseSchema;
TableSchema: TableSchema;
}) => Promise<void>;
trigger: ({ type, subscribe }: {
type: any;
subscribe: any;
}) => Promise<void>;
};
}
export declare const indexedDB: indexedDBInterface;
export {};
@@ -0,0 +1,352 @@
import { SqlObject } from "../../sql/sqlObject/sqlObject.js";
import { PostMessage as PostMessageWorker } from "./postMessage.js";
import { DatabaseManager } from "./DatabaseManager.js";
// inspire by https://github.com/hc-oss/use-indexeddb
class indexedDBInterface {
constructor() {
this.getActions = (TableName, Database, queryId) => {
const DatabaseName = Database.name;
return {
getByID: (id) => {
return new Promise((resolve, reject) => {
Database.getOrCreateTransaction({ TableName, queryId }, 'readonly', (transaction) => {
let objectStore = transaction.objectStore(TableName);
let request = objectStore.get({ id });
request.onsuccess = async (e) => {
resolve(e.target.result);
};
});
});
},
getOneByIndex: (keyPath, value) => {
return new Promise((resolve, reject) => {
Database.getOrCreateTransaction({ TableName, queryId }, 'readonly', (transaction) => {
let objectStore = transaction.objectStore(TableName);
let request = objectStore.index({ keyPath, value });
request.onsuccess = async (e) => {
resolve(e.target.result);
};
});
});
},
// getManyByIndex:(keyPath: string, value: string | number) => {
// return new Promise<any[]>((resolve, reject) => {
// this.getConnection(DatabaseName)
// .then(db => {
// this.validateBeforeTransaction(db, TableName, reject);
// let tx = this.createTransaction(db, "readonly", TableName, resolve, reject);
// let objectStore = tx.objectStore(TableName);
// let index = objectStore.index(keyPath);
// let request = index.getAll(value);
// request.onsuccess = (e: any) => {
// resolve(e.target.result);
// };
// })
// .catch(reject);
// });
// },
getAll: () => {
return new Promise((resolve, reject) => {
Database.getOrCreateTransaction({ TableName, queryId }, 'readonly', (transaction) => {
let objectStore = transaction.objectStore(TableName);
let request = objectStore.getAll();
request.onsuccess = async (e) => {
resolve(e.target.result);
};
});
});
},
add: ({ value, key, add, index }) => {
return new Promise((resolve, reject) => {
Database.getOrCreateTransaction({ TableName, queryId }, 'readwrite', (transaction) => {
let objectStore = transaction.objectStore(TableName);
let request = objectStore.add({ value });
request.onsuccess = async (e) => {
const id = e.target.result;
add(id, index);
resolve(true);
};
request.onerror = (e) => {
let data = {
error: e.target['error']
};
resolve(true);
};
});
});
},
update: ({ value, key = undefined }) => {
return new Promise((resolve, reject) => {
Database.getOrCreateTransaction({ TableName, queryId }, 'readwrite', (transaction) => {
let objectStore = transaction.objectStore(TableName);
let request = objectStore.put({ value, key });
request.onsuccess = async (e) => {
resolve(e.target.result);
};
request.onerror = (e) => {
let data = {
error: e.target['error']
};
resolve(data);
};
});
});
},
deleteByID: (id) => {
return new Promise((resolve, reject) => {
Database.getOrCreateTransaction({ TableName, queryId }, 'readwrite', (transaction) => {
let objectStore = transaction.objectStore(TableName);
let request = objectStore.delete({ id });
request.onsuccess = async (e) => {
resolve(e.target.result);
};
request.onerror = (e) => {
let data = {
error: e.target['error']
};
resolve(data);
};
});
});
},
deleteAll: () => {
return new Promise((resolve, reject) => {
Database.getOrCreateTransaction({ TableName, queryId }, 'readwrite', (transaction) => {
let objectStore = transaction.objectStore(TableName);
let request = objectStore.clear();
request.onsuccess = async (e) => {
resolve(e.target.result);
};
});
});
}
};
};
this.requestHandler = (TableName, DatabaseName, queryId, PostMessage = PostMessageWorker) => {
const db = DatabaseManager.getDb(DatabaseName);
return {
select: async (methods) => {
const TableSchema = db.objectStore[TableName].config;
if (methods[0].methodName == 'all') {
PostMessage({
run: 'callback',
queryId: queryId,
value: await this.getActions(TableName, db, queryId).getAll()
});
}
else if (methods[0].methodName == 'get') {
const args = methods[0].arguments;
if (Object.keys(args).length == 1) {
const key = Object.keys(args)[0];
const value = args[key];
if (TableSchema.id.keyPath == key) {
PostMessage({
run: 'callback',
queryId: queryId,
value: await this.getActions(TableName, db, queryId).getByID(value)
});
}
else {
PostMessage({
run: 'callback',
queryId: queryId,
value: await this.getActions(TableName, db, queryId).getOneByIndex(key, value)
});
}
}
else if (methods[0].arguments[TableSchema.id.keyPath]) {
PostMessage({
run: 'callback',
queryId: queryId,
value: await this.getActions(TableSchema.name, db, queryId).getByID(args[TableSchema.id.keyPath])
});
}
}
else if (methods[methods.length - 1].methodName == 'execute') {
const sqlObject = new SqlObject(TableSchema, methods);
//await this.getActions(TableSchema.name, config, queryId).openCursor(async(event: any) => {
//var cursor = event.target.result;
//if(cursor) {
const rows = await this.getActions(TableName, db, queryId).getAll();
for (const row of rows) {
//const row = cursor.value
await sqlObject.runFirstMethod(row);
//cursor.continue();
}
//} else {
sqlObject.doneRunFirstMethod();
sqlObject.run();
PostMessage({
run: 'callback',
queryId: queryId,
value: sqlObject.firstMethod.rows
});
//}
//})
}
else if (methods[methods.length - 1].methodName == 'first') {
return new Promise(async (resolve, reject) => {
PostMessage({
run: 'callback',
queryId: queryId,
value: (await this.getActions(TableName, db, queryId).getAll())[0]
});
});
}
},
update: async (methods) => {
const TableSchema = db.objectStore[TableName].config;
if (methods[0].methodName == 'save') {
const args = methods[0].arguments;
const idFieldName = TableSchema.id.keyPath;
const idValue = args[idFieldName];
if (idValue) {
this.getActions(TableSchema.name, db, queryId).update({ value: args });
}
else {
this.getActions(TableSchema.name, db, queryId).update({ value: args, key: idValue });
}
db.getOrCreateTransaction({ TableName: TableName, queryId }, 'readwrite', (transaction) => {
PostMessage({
run: 'callback',
queryId: queryId,
value: true
});
transaction.done();
});
}
else if (methods[0].methodName != 'update' && methods[methods.length - 1].methodName == 'update') {
const argsToUpdate = methods[methods.length - 1].arguments;
const customMethods = Object.create(methods);
customMethods[methods.length - 1].methodName = 'execute';
await this.requestHandler(TableSchema.name, DatabaseName, queryId, ({ value }) => {
const rows = value;
for (let row of rows) {
const updateRow = Object.assign(row, argsToUpdate);
this.getActions(TableSchema.name, db, queryId).update({ value: updateRow });
}
db.getOrCreateTransaction({ TableName: TableName, queryId }, 'readwrite', (transaction) => {
PostMessage({
run: 'callback',
queryId: queryId,
value: true
});
transaction.done();
});
}).select(customMethods);
}
else if (methods[0].methodName == 'update') {
const argsToUpdate = methods[0].arguments;
const idFieldName = TableSchema.id.keyPath;
//await this.getActions(TableSchema.name, config).update(argsToUpdate)
const idValue = argsToUpdate[idFieldName];
if (idValue) {
this.getActions(TableSchema.name, db, queryId).update({ value: argsToUpdate });
}
else {
this.getActions(TableSchema.name, db, queryId).update({ value: argsToUpdate, key: idValue });
}
db.getOrCreateTransaction({ TableName: TableSchema.name, queryId }, 'readwrite', (transaction) => {
PostMessage({
run: 'callback',
queryId: queryId,
value: true
});
transaction.done();
});
}
},
delete: async (methods) => {
const TableSchema = db.objectStore[TableName].config;
if (methods[methods.length - 1].methodName == 'delete' &&
methods[methods.length - 1].arguments == null) {
const customMethods = Object.create(methods);
customMethods[methods.length - 1].methodName = 'execute';
await this.requestHandler(TableName, DatabaseName, queryId, ({ value }) => {
const rows = value;
for (let row of rows) {
const id = row[TableSchema.id.keyPath];
this.getActions(TableSchema.name, db, queryId).deleteByID(id);
}
db.getOrCreateTransaction({ TableName: TableName, queryId }, 'readwrite', (transaction) => {
PostMessage({
run: 'callback',
queryId: queryId,
value: rows.length
});
transaction.done();
});
}).select(customMethods);
}
else if (methods[methods.length - 1].methodName == 'delete' &&
typeof methods[methods.length - 1].arguments == 'object') {
const IdInObject = methods[methods.length - 1].arguments;
const idValue = IdInObject[TableSchema.id.keyPath];
PostMessage({
run: 'callback',
queryId: queryId,
value: await this.getActions(TableName, db, queryId).deleteByID(idValue)
});
}
else if (methods[methods.length - 1].methodName == 'delete' &&
methods[methods.length - 1].arguments == '*') {
PostMessage({
run: 'callback',
queryId: queryId,
value: await this.getActions(TableName, db, queryId).deleteAll()
});
}
},
insert: async (methods) => {
const rows = methods[0].arguments;
const add = (id, index) => {
PostMessage({
run: 'callback',
queryId: queryId,
value: { id, index }
});
};
for (let i = 0; i < rows.length; i++) {
const insert = rows[i];
this.getActions(TableName, db, queryId).add({ value: insert, key: null, index: i, add });
}
db.getOrCreateTransaction({ TableName: TableName, queryId }, 'readwrite', (transaction) => {
PostMessage({
run: 'done',
queryId: queryId,
value: true
});
transaction.done();
});
},
migrate: async ({ DatabaseSchema, TableSchema }) => {
await DatabaseManager.prepare(DatabaseSchema);
PostMessage({
run: 'callback',
queryId: queryId,
value: true
});
},
trigger: async ({ type, subscribe }) => {
const objectStore = db.getObjectStore(TableName);
if (type == 'transactionOnCommit') {
if (subscribe) {
PostMessage(objectStore.transactionOnCommitSubscribe(TableName, DatabaseName, queryId));
}
else {
PostMessage(objectStore.transactionOnCommitUnSubscribe(TableName, DatabaseName, queryId));
}
}
else if (type == 'trigger') {
PostMessage({
run: 'callback',
queryId: queryId,
value: true
});
}
}
};
};
}
}
export const indexedDB = new indexedDBInterface();
+61
View File
@@ -0,0 +1,61 @@
import { TableSchema } from "../../models/register-modal.interface.js";
import { transaction } from './transaction.js';
export declare class ObjectStore {
transactions: {
callback: Function;
queryId: string;
mode: string;
}[];
parallelTransactions: {
callback: Function;
queryId: string;
mode: string;
DatabaseName: string;
}[];
transactionsToCommit: {
callback: Function;
queryId: string;
mode: string;
}[];
dbInstance: IDBDatabase;
txInstance: {
IDBTransaction: IDBTransaction;
IDBTransactionMode: IDBTransactionMode;
active: boolean;
};
executingTransaction: boolean;
txInstanceMode: object;
storeCache: {
[store: string]: object[];
};
transactionOnCommit: {
[queryId: string]: Object;
};
name: string;
transactionFinish: (TableName: any) => void;
config: TableSchema;
constructor({ store }: {
store: TableSchema;
});
transactionTrigger(): Promise<void>;
executeTransaction(): void;
parallelExecuteTransaction(): void;
getOrCreateTransaction({ queryId, Database }: {
queryId: any;
Database: any;
}, mode: IDBTransactionMode, callback: (transaction: transaction) => void): void;
private createTransaction;
private validateBeforeTransaction;
transactionOnCommitSubscribe(TableName: string, DatabaseName: string, SubscriptionName: any): {
run: string;
subscription: boolean;
queryId: any;
value: boolean;
};
transactionOnCommitUnSubscribe(TableName: any, DatabaseName: string, SubscriptionName: any): {
run: string;
subscription: boolean;
queryId: any;
value: boolean;
};
}
@@ -0,0 +1,175 @@
import { transaction } from './transaction.js';
import { PostMessage } from "./postMessage.js";
// inspire by https://github.com/hc-oss/use-indexeddb
export class ObjectStore {
constructor({ store }) {
this.transactions = [];
this.parallelTransactions = [];
this.transactionsToCommit = [];
this.executingTransaction = false;
this.txInstanceMode = {};
this.storeCache = {};
this.transactionOnCommit = {};
this.name = '';
this.transactionFinish = (TableName) => { };
this.name = store.name;
this.config = store;
}
async transactionTrigger() {
var _a, _b;
if (this.txInstanceMode['readwrite']) {
try {
(_b = (_a = this.txInstance.IDBTransaction) === null || _a === void 0 ? void 0 : _a.commit) === null || _b === void 0 ? void 0 : _b.call(_a);
this.transactionsToCommit = [];
(async () => {
for (let [queryId, value] of Object.entries(this.transactionOnCommit)) {
PostMessage({
run: 'callback',
queryId: queryId,
value: true
});
}
})();
}
catch (error) {
// no commit need
}
}
}
executeTransaction() {
const { mode, callback } = this.transactions[0];
this.txInstanceMode[mode] = true;
const done = async () => {
const transaction = this.transactions.shift();
this.transactionsToCommit.push(transaction);
if (this.transactions.length == 0) {
this.executingTransaction = false;
this.transactionTrigger();
delete this.txInstance;
this.txInstanceMode[mode] = false;
this.transactionFinish(this.name);
}
else {
this.executeTransaction();
}
};
const doneButFailed = async () => {
var _a, _b;
this.transactions.shift();
this.txInstance.active = false;
if (this.transactionsToCommit.length >= 1) {
try {
(_b = (_a = this.txInstance.IDBTransaction) === null || _a === void 0 ? void 0 : _a.commit) === null || _b === void 0 ? void 0 : _b.call(_a);
this.transactionsToCommit = [];
}
catch (error) { }
}
if (this.transactions.length >= 1) {
const tx = this.createTransaction(this.dbInstance, "readwrite", (onerror) => { }, (oncomplete) => { }, (onabort) => { });
this.txInstance = {
IDBTransaction: tx,
active: true,
IDBTransactionMode: "readwrite"
};
this.executeTransaction();
}
else {
this.transactionTrigger();
}
};
this.validateBeforeTransaction(this.dbInstance, (data) => {
});
const transactionInstance = new transaction({
store: this.name,
done,
doneButFailed,
db: this.dbInstance,
tx: this.txInstance.IDBTransaction
});
callback(transactionInstance);
}
parallelExecuteTransaction() {
const { mode, callback } = this.parallelTransactions.shift();
this.txInstanceMode[mode] = true;
const tx = this.createTransaction(this.dbInstance, "readonly", (onerror) => { }, (oncomplete) => { }, (onabort) => { });
const done = async () => {
if (this.parallelTransactions.length == 0) {
this.txInstanceMode[mode] = false;
}
};
const doneButFailed = async () => {
if (this.parallelTransactions.length == 0) {
this.txInstanceMode[mode] = false;
}
};
const transactionInstance = new transaction({
store: this.name,
done,
doneButFailed,
db: this.dbInstance,
tx: this.txInstance.IDBTransaction
});
callback(transactionInstance);
}
getOrCreateTransaction({ queryId, Database }, mode, callback) {
//if(mode == 'readonly' && !this.txInstance) {
// this.parallelTransactions.push({DatabaseName, queryId, mode, callback})
// this.parallelExecuteTransaction(DatabaseName, TableName)
//} else {
this.transactions.push({ queryId, mode, callback });
//}
if (this.executingTransaction == false) {
this.executingTransaction = true;
const tx = this.createTransaction(Database, "readwrite", (onerror) => { }, (oncomplete) => { }, (onabort) => { });
this.dbInstance = Database;
if (!this.txInstance) {
this.txInstance = {
IDBTransaction: tx,
active: true,
IDBTransactionMode: "readwrite"
};
}
this.txInstance.IDBTransaction = tx;
this.txInstance.active = true;
// this.dbInstanceUsing = true
this.executeTransaction();
}
else {
if (mode == 'readonly') {
}
}
}
createTransaction(db, dbMode, onerror, oncomplete, onabort) {
let tx = db.transaction(this.name, dbMode);
tx.onerror = onerror;
tx.oncomplete = oncomplete;
tx.onabort = onabort;
return tx;
}
validateBeforeTransaction(db, reject) {
if (!db) {
reject("Queried before opening connection");
}
// if (!this.validateStore(db, storeName)) {
// reject(`Store ${storeName} not found`);
// }
}
transactionOnCommitSubscribe(TableName, DatabaseName, SubscriptionName) {
this.transactionOnCommit[SubscriptionName] = {};
return {
run: 'callback',
subscription: true,
queryId: SubscriptionName,
value: true
};
}
transactionOnCommitUnSubscribe(TableName, DatabaseName, SubscriptionName) {
delete this.transactionOnCommit[SubscriptionName];
return {
run: 'callback',
subscription: false,
queryId: SubscriptionName,
value: true
};
}
}
+1
View File
@@ -0,0 +1 @@
export declare let PostMessage: typeof postMessage;
@@ -0,0 +1,17 @@
var _a;
import { taskHolder } from '../taskHolder.js';
export let PostMessage;
try {
if (!window || (window === null || window === void 0 ? void 0 : window.document) === undefined) {
// web worker
PostMessage = (_a = (this || {})) === null || _a === void 0 ? void 0 : _a.postMessage;
}
else {
// main thread
PostMessage = taskHolder.onmessage;
}
}
catch (error) {
// web worker
PostMessage = postMessage;
}
+52
View File
@@ -0,0 +1,52 @@
declare class transactionRequest {
type: string;
value: any;
key: any;
result: any;
store: string;
onsuccessFunc: Function;
onerrorFunc: Function;
set onsuccess(func: any);
set onerror(func: any);
}
export declare class transaction {
store: any;
done: Function;
doneButFailed: Function;
tx: IDBTransaction;
trigger: {
beforeInsert: boolean;
afterInsert: boolean;
};
constructor({ store, done, db, tx, doneButFailed }: {
store: any;
done: any;
db: any;
tx: any;
doneButFailed: any;
});
request: any[];
FinishRequest: any[];
objectStore: (currentStore: any) => {
add: ({ value }: {
value: any;
}) => transactionRequest;
getAll: () => transactionRequest;
put: ({ value, key }: {
value: any;
key?: any;
}) => transactionRequest;
clear: () => transactionRequest;
delete: ({ id }: {
id: any;
}) => transactionRequest;
get: ({ id }: {
id: any;
}) => transactionRequest;
index: ({ keyPath, value }: {
keyPath: any;
value: any;
}) => transactionRequest;
};
}
export {};
@@ -0,0 +1,142 @@
class transactionRequest {
set onsuccess(func) {
this.onsuccessFunc = func;
}
set onerror(func) {
this.onerrorFunc = func;
}
}
export class transaction {
constructor({ store, done, db, tx, doneButFailed }) {
this.trigger = {
beforeInsert: false,
afterInsert: false,
};
this.request = [];
this.FinishRequest = [];
this.objectStore = (currentStore) => {
return {
add: ({ value }) => {
const request = new transactionRequest();
request.type = 'add';
request.value = value;
this.request.push(request);
let objectStore = this.tx.objectStore(currentStore);
let addGetList = objectStore.add(value);
addGetList.onsuccess = async (e) => {
request === null || request === void 0 ? void 0 : request.onsuccessFunc(e);
this.done();
};
addGetList.onerror = async (e) => {
request === null || request === void 0 ? void 0 : request.onerrorFunc(e);
this.doneButFailed();
};
return request;
},
getAll: () => {
const request = new transactionRequest();
this.request.push(request);
request.type = 'getAll';
let objectStore = this.tx.objectStore(currentStore);
let getList = objectStore.getAll();
getList.onsuccess = (e) => {
this.done();
request === null || request === void 0 ? void 0 : request.onsuccessFunc(e);
};
getList.onerror = (e) => {
this.doneButFailed();
request === null || request === void 0 ? void 0 : request.onerrorFunc(e);
};
return request;
},
put: ({ value, key = undefined }) => {
const request = new transactionRequest();
this.request.push(request);
request.type = 'put';
this.request.push(request);
let objectStore = this.tx.objectStore(currentStore);
let updateRequest = objectStore.put(value, key);
updateRequest.onsuccess = async (e) => {
request === null || request === void 0 ? void 0 : request.onsuccessFunc(e);
this.done();
};
updateRequest.onerror = async (e) => {
request === null || request === void 0 ? void 0 : request.onerrorFunc(e);
this.doneButFailed();
};
return request;
},
clear: () => {
const request = new transactionRequest();
this.request.push(request);
request.type = 'clear';
let objectStore = this.tx.objectStore(currentStore);
objectStore.clear();
this.tx.oncomplete = async (e) => {
request === null || request === void 0 ? void 0 : request.onsuccessFunc(e);
this.done();
};
this.tx.onerror = async (e) => {
request === null || request === void 0 ? void 0 : request.onerrorFunc(e);
this.doneButFailed();
};
return request;
},
delete: ({ id }) => {
const request = new transactionRequest();
this.request.push(request);
request.type = 'delete';
let objectStore = this.tx.objectStore(currentStore);
let deleteRequest = objectStore.delete(id);
deleteRequest.onsuccess = async (e) => {
request === null || request === void 0 ? void 0 : request.onsuccessFunc(e);
this.done();
};
deleteRequest.onerror = async (e) => {
request === null || request === void 0 ? void 0 : request.onerrorFunc(e);
this.doneButFailed();
};
return request;
},
get: ({ id }) => {
const request = new transactionRequest();
this.request.push(request);
request.type = 'get';
let objectStore = this.tx.objectStore(currentStore);
let getRequest = objectStore.get(id);
getRequest.onsuccess = (e) => {
this.done();
request === null || request === void 0 ? void 0 : request.onsuccessFunc(e);
};
getRequest.onerror = (e) => {
this.doneButFailed();
request === null || request === void 0 ? void 0 : request.onerrorFunc(e);
};
return request;
},
index: ({ keyPath, value }) => {
const request = new transactionRequest();
this.request.push(request);
request.type = 'get';
let objectStore = this.tx.objectStore(currentStore);
let targe = objectStore.index(keyPath);
let getRequest = targe.get(value);
getRequest.onsuccess = (e) => {
this.done();
request === null || request === void 0 ? void 0 : request.onsuccessFunc(e);
};
getRequest.onerror = (e) => {
this.doneButFailed();
request === null || request === void 0 ? void 0 : request.onerrorFunc(e);
};
return request;
}
};
};
// currentStore = store
this.doneButFailed = doneButFailed;
this.done = done;
// this.db = db
this.tx = tx;
}
}
@@ -0,0 +1,18 @@
interface Trigger {
callback: Function;
SubscriptionName: string;
}
export declare class triggerSignal {
static beforeInsertExist(Model: any): Trigger;
static beforeInsert(instance: any): Promise<void>;
static AfterInsertExist(Model: any): Trigger;
static AfterInsert(instance: any): Promise<void>;
static AfterDeleteExist(Model: any): Trigger;
static AfterDelete(instance: string, { modelName, databaseName }: any): Promise<void>;
static BeforeDeleteExist(Model: any): Trigger;
static BeforeDelete(instance: string, { modelName, databaseName }: {
modelName: any;
databaseName: any;
}): Promise<void>;
}
export {};
@@ -0,0 +1,51 @@
let triggerBeforeInsert = {};
let triggerAfterInsert = {};
let triggerBeforeDelete = {};
let triggerAfterDelete = {};
function setUpSignal() { }
export class triggerSignal {
static beforeInsertExist(Model) {
var _a;
const ModelName = Model.getModelName();
const databaseName = Model.getDBSchema().databaseName;
return (_a = triggerBeforeInsert === null || triggerBeforeInsert === void 0 ? void 0 : triggerBeforeInsert[databaseName]) === null || _a === void 0 ? void 0 : _a[ModelName];
}
static async beforeInsert(instance) {
const ModelName = instance.getModelName();
const databaseName = instance.getDBSchema().databaseName;
postMessage({
queryId: triggerBeforeInsert[databaseName][ModelName].SubscriptionName,
value: instance
});
}
static AfterInsertExist(Model) {
var _a;
const ModelName = Model.getModelName();
const databaseName = Model.getDBSchema().databaseName;
return (_a = triggerAfterInsert === null || triggerAfterInsert === void 0 ? void 0 : triggerAfterInsert[databaseName]) === null || _a === void 0 ? void 0 : _a[ModelName];
}
static async AfterInsert(instance) {
const ModelName = instance.getModelName();
const databaseName = instance.getDBSchema().databaseName;
postMessage({
queryId: triggerBeforeInsert[databaseName][ModelName].SubscriptionName,
value: instance
});
}
static AfterDeleteExist(Model) {
var _a;
const ModelName = Model.getModelName();
const databaseName = Model.getDBSchema().databaseName;
return (_a = triggerAfterDelete === null || triggerAfterDelete === void 0 ? void 0 : triggerAfterDelete[databaseName]) === null || _a === void 0 ? void 0 : _a[ModelName];
}
static async AfterDelete(instance, { modelName, databaseName }) {
}
static BeforeDeleteExist(Model) {
var _a;
const ModelName = Model.getModelName();
const databaseName = Model.getDBSchema().databaseName;
return (_a = triggerBeforeDelete === null || triggerBeforeDelete === void 0 ? void 0 : triggerBeforeDelete[databaseName]) === null || _a === void 0 ? void 0 : _a[ModelName];
}
static async BeforeDelete(instance, { modelName, databaseName }) {
}
}
+2
View File
@@ -0,0 +1,2 @@
export declare type actionParam = 'insert' | 'update' | 'delete' | 'select' | 'migrate' | 'trigger';
export declare type dbType = 'indexedDB' | 'localStorage';
+1
View File
@@ -0,0 +1 @@
export {};
View File
+17
View File
@@ -0,0 +1,17 @@
export interface TaskHolderInterface {
type?: 'response' | 'Register';
queryId: string;
params: any;
method: 'execute' | 'migrate';
callback: Function;
done?: Function;
}
declare class _taskHolder {
private tasks;
register(data: TaskHolderInterface): void;
finish(queryId: string): void;
updateFunction(queryId: any, run: any, func: Function): void;
onmessage(data: any): Promise<void>;
}
export declare const taskHolder: _taskHolder;
export {};
+24
View File
@@ -0,0 +1,24 @@
class _taskHolder {
constructor() {
this.tasks = {};
}
register(data) {
this.tasks[data.queryId] = data;
}
finish(queryId) {
try {
delete this.tasks[queryId];
}
catch (error) { }
}
updateFunction(queryId, run, func) {
this.tasks[queryId][run] = (message) => {
func(message.value);
};
}
async onmessage(data) {
const value = this.tasks[data.queryId];
value[data.run](data);
}
}
export const taskHolder = new _taskHolder();
+1
View File
@@ -0,0 +1 @@
export {};
+10
View File
@@ -0,0 +1,10 @@
import { indexedDB } from './indexedDb/indexedb.js';
onmessage = async (oEvent) => {
const { TableName, DatabaseName, queryId, action, arg } = oEvent.data;
indexedDB.requestHandler(TableName, DatabaseName, queryId)[action](arg).then((result) => {
// console.log('result', result)
// postMessage(result)
}, (error) => {
console.log('error', error);
});
};
+18
View File
@@ -0,0 +1,18 @@
export interface WsRegister {
type?: 'response' | 'Register';
queryId: string;
params: any;
method: 'execute' | 'migrate';
callback: Function;
done?: Function;
}
declare class _WorkerManager {
private myWorker;
webWorkerModuleSupport: boolean;
constructor();
supportsWorkerType(): boolean;
register(data: WsRegister): string;
private onmessage;
}
export declare const WorkerManager: _WorkerManager;
export {};
@@ -0,0 +1,40 @@
import { taskHolder } from './taskHolder.js';
class _WorkerManager {
constructor() {
this.webWorkerModuleSupport = false;
this.webWorkerModuleSupport = this.supportsWorkerType();
if (this.webWorkerModuleSupport) {
this.myWorker = new Worker(new URL('./worker.js', import.meta.url), { type: "module" });
this.myWorker.onmessage = (oEvent) => {
const data = oEvent.data;
this.onmessage(data);
};
this.myWorker.onerror = (error) => {
console.log('myWorker', error);
};
}
}
// https://stackoverflow.com/a/62963963/14115342
supportsWorkerType() {
var _a;
let supports = false;
const tester = {
get type() { return supports = true; } // it's been called, it's supported
};
try {
const worker = new Worker('blob://', tester);
}
finally {
return supports && ((_a = (window || {})) === null || _a === void 0 ? void 0 : _a.document);
}
}
register(data) {
this.myWorker.postMessage(data.params);
taskHolder.register(data);
return data.queryId;
}
async onmessage(data) {
taskHolder.onmessage(data);
}
}
export const WorkerManager = new _WorkerManager();
+49
View File
@@ -0,0 +1,49 @@
import { Model } from './models/model.js';
import { LocalStorage } from './models/model.js';
import { ModelReader } from './models/model.reader.js';
import { registerModel, migrate } from './models/register-model.js';
export declare const models: {
Value(arg: any): {};
preset(): any;
core: {
localStorage: {
rewrite: {
rewriteGet: {
connect(callback: (params: import("./models/signal.interface.js").params) => void, models: (typeof LocalStorage)[]): void;
};
rewriteSave: {
connect(callback: (params: import("./models/signal.interface.js").params) => void, models: (typeof LocalStorage)[]): void;
};
rewriteDelete: {
connect(callback: (params: import("./models/signal.interface.js").params) => void, models: (typeof LocalStorage)[]): void;
};
hasRewriteGet(ModalName: string): boolean;
hasRewriteSave(ModalName: string): boolean;
hasRewriteDelete(ModalName: string): boolean;
};
};
};
CharField(data?: import("./models/field/interface.js").CharFieldParams): string;
BooleanField(data?: import("./models/field/interface.js").BooleanFieldParams): boolean;
TextField(data?: import("./models/field/interface.js").TextFieldParams): string;
IntegerField(data?: import("./models/field/interface.js").IntegerFieldParams): number;
DateField(data?: import("./models/field/interface.js").DateFieldParams): Date;
DateTimeField(data?: import("./models/field/interface.js").DateTimeFieldParams): string;
BigIntegerField(data?: import("./models/field/interface.js").BigIntegerFieldParams): number;
AutoField(data?: import("./models/field/interface.js").AutoFieldParams): any;
OneToOneField(data: import("./models/field/interface.js").OneToOneFieldParams): string | number;
ForeignKey(data: import("./models/field/interface.js").ForeignKeyParams): string | number;
ManyToManyField(data?: import("./models/field/interface.js").ManyToManyFieldParams): string | number;
indexedDB: {
fields: {
JsonField: (data?: import("./models/field/interface.js").IndexedDBJsonFieldParams) => Object;
ArrayField: (data?: import("./models/field/interface.js").IndexedDBArrayFieldParams) => any[];
};
};
Model: typeof Model;
LocalStorage: typeof LocalStorage;
read: typeof ModelReader.read;
migrate: typeof migrate;
register: typeof registerModel.register;
};
export default models;
+19
View File
@@ -0,0 +1,19 @@
import { Model } from './models/model.js';
import { LocalStorage } from './models/model.js';
import * as Fields from './models/field/fields.js';
import { ModelReader } from './models/model.reader.js';
import { registerModel, migrate } from './models/register-model.js';
import { rewrite } from './models/signal.js';
export const models = Object.assign(Object.assign({ Model,
LocalStorage, read: ModelReader.read, migrate: migrate, register: registerModel.register }, Fields), { Value(arg) {
if (arg == 'null') {
return {};
}
},
preset() { }, core: {
// signals
localStorage: {
rewrite
}
} });
export default models;
+140
View File
@@ -0,0 +1,140 @@
import { FieldType } from '../../sql/query/interface.js';
import { field } from './field.js';
import { FieldKeys } from './fields.interface.js';
import { AutoFieldParams, BooleanFieldParams, DateFieldParams, DateTimeFieldParams, ForeignKeyParams, IndexedDBArrayFieldParams, IndexedDBJsonFieldParams, IntegerFieldParams, ManyToManyFieldParams, OneToOneFieldParams } from './interface.js';
import { BigIntegerFieldParams } from './interface.js';
import { CharFieldParams } from './interface.js';
import { TextFieldParams } from './interface.js';
export declare class AutoField extends field {
fieldName: FieldKeys;
unique: boolean;
autoIncrement: boolean;
primaryKey?: boolean;
type: FieldType;
blank: boolean;
default?: any;
constructor(data?: AutoFieldParams);
valid(value: any): boolean;
}
export declare class BigIntegerField extends field {
fieldName: FieldKeys;
unique?: boolean;
primaryKey?: boolean;
blank?: boolean;
default?: any;
type: FieldType;
constructor(data?: BigIntegerFieldParams);
valid(value: any): boolean;
}
export declare class BooleanField extends field {
fieldName: FieldKeys;
unique?: boolean;
blank?: boolean;
default?: any;
constructor(data?: BooleanFieldParams);
valid(value: any): boolean;
}
export declare class CharField extends field {
fieldName: FieldKeys;
maxLength?: number | undefined;
minLength?: number | undefined;
choices?: any[] | undefined;
primaryKey?: boolean;
blank?: boolean;
default?: any;
unique?: boolean;
type: FieldType;
constructor(data?: CharFieldParams);
valid(value: any): boolean;
}
export declare class DateField extends field {
fieldName: FieldKeys;
type: FieldType;
blank?: boolean;
default?: any;
constructor(data?: DateFieldParams);
valid(value: any): boolean;
}
export declare class DateTimeField extends field {
fieldName: FieldKeys;
type: FieldType;
blank?: boolean;
default?: any;
constructor(data?: DateTimeFieldParams);
valid(value: any): boolean;
}
export declare class indexedDBArrayField extends field {
fieldName: FieldKeys;
type: FieldType;
blank?: boolean;
default?: any;
maxLength?: number;
minLength?: number;
size?: number;
private _field?;
get field(): any;
set field(value: any);
constructor(data?: IndexedDBArrayFieldParams);
valid(value: any): boolean;
}
export declare class indexedDBJsonField extends field {
fieldName: FieldKeys;
type: FieldType;
blank?: boolean;
default?: any;
null?: boolean;
constructor(data?: IndexedDBJsonFieldParams);
valid(value: any): boolean;
}
export declare class TextField extends field {
fieldName: FieldKeys;
maxLength?: number | undefined;
minLength?: number | undefined;
primaryKey?: boolean;
blank?: boolean;
default?: any;
type: FieldType.TEXT;
constructor(data?: TextFieldParams);
valid(value: any): boolean;
}
export declare class IntegerField extends field {
fieldName: FieldKeys;
unique?: boolean;
primaryKey?: boolean;
type: FieldType;
blank?: boolean;
default?: any;
constructor(data?: IntegerFieldParams);
valid(value: any): boolean;
}
export declare class ForeignKey extends field {
fieldName: FieldKeys;
model: any;
foreignKey: boolean;
blank?: boolean;
default?: any;
constructor(data?: ForeignKeyParams);
valid(value: any): boolean;
}
export declare class OneToOneField extends field {
fieldName: FieldKeys;
foreignKey: boolean;
model: any;
blank?: boolean;
default?: any;
onDelete?: any;
constructor(data?: OneToOneFieldParams);
contractor(contractor: any): void;
valid(value: any): boolean;
}
export declare class ManyToManyField extends field {
fieldName: FieldKeys;
model: any;
foreignKey: boolean;
blank?: boolean;
default?: any;
onDelete?: any;
unique?: boolean;
constructor(data?: ManyToManyFieldParams);
valid(value: any): boolean;
}
+253
View File
@@ -0,0 +1,253 @@
import { FieldType } from '../../sql/query/interface.js';
import { field } from './field.js';
export class AutoField extends field {
constructor(data) {
super();
this.fieldName = 'AutoField';
this.unique = true;
this.autoIncrement = true;
this.type = FieldType.BIGINT;
this.blank = true;
Object.assign(this, data);
}
valid(value) {
if (!(typeof value == 'bigint' || typeof value == 'number')) {
return false;
}
else if (!((this === null || this === void 0 ? void 0 : this.blank) == undefined && this.isNull(value) == false)) {
return false;
}
return false;
}
}
export class BigIntegerField extends field {
constructor(data) {
super();
this.fieldName = 'BigIntegerField';
this.type = FieldType.BIGINT;
Object.assign(this, data);
}
valid(value) {
if (!(typeof value == 'bigint' || typeof value == 'number')) {
if ((this === null || this === void 0 ? void 0 : this.blank) != true) {
return false;
}
else if (!(value === null || value === undefined)) {
return false;
}
}
else if (!this.rules(this, value)) {
return false;
}
return true;
}
}
export class BooleanField extends field {
constructor(data) {
super();
this.fieldName = 'BooleanField';
Object.assign(this, data);
}
valid(value) {
if (typeof value != 'boolean') {
return false;
}
return true;
}
}
export class CharField extends field {
constructor(data) {
super();
this.fieldName = 'CharField';
this.type = FieldType.DATE;
Object.assign(this, data);
}
valid(value) {
if (!(typeof value == 'string')) {
if ((this === null || this === void 0 ? void 0 : this.blank) != true) {
return false;
}
else if (!(value === null || value === undefined)) {
return false;
}
}
else if (!this.rules(this, value)) {
return false;
}
return true;
}
}
export class DateField extends field {
constructor(data) {
super();
this.fieldName = 'DateField';
this.type = FieldType.DATE;
Object.assign(this, data);
}
valid(value) {
if (!(typeof value == 'string')) {
if ((this === null || this === void 0 ? void 0 : this.blank) != true) {
return false;
}
}
else if (!((this === null || this === void 0 ? void 0 : this.blank) == undefined && this.isNull(value) == false)) {
return true;
}
return false;
}
}
export class DateTimeField extends field {
constructor(data) {
super();
this.fieldName = 'DateTimeField';
this.type = FieldType.DATE;
Object.assign(this, data);
}
valid(value) {
if (!(typeof value == 'string')) {
if ((this === null || this === void 0 ? void 0 : this.blank) != true) {
return false;
}
}
else if (!((this === null || this === void 0 ? void 0 : this.blank) == undefined && this.isNull(value) == false)) {
return false;
}
return true;
}
}
export class indexedDBArrayField extends field {
constructor(data) {
super();
this.fieldName = 'indexedDBArrayField';
this.type = FieldType.ARRAY;
Object.assign(this, data);
}
get field() {
return this._field;
}
set field(value) {
this._field = value;
}
valid(value) {
if (!(Array.isArray(value))) {
if ((this === null || this === void 0 ? void 0 : this.blank) != true) {
return false;
}
}
else if (this.isNull(value) == true) {
if ((this === null || this === void 0 ? void 0 : this.blank) != true) {
return false;
}
}
else if (this.size) {
if (value.length != this.size) {
return false;
}
}
if (this.field) {
for (const e of value) {
if (!this.field.valid(e)) {
return false;
}
}
}
return true;
}
}
export class indexedDBJsonField extends field {
constructor(data) {
super();
this.fieldName = 'indexedDBJsonField';
this.type = FieldType.JSON;
Object.assign(this, data);
}
valid(value) {
if (!(typeof value == 'object' && Array.isArray(value) == false)) {
if ((this === null || this === void 0 ? void 0 : this.blank) != true) {
return false;
}
}
else if (this.isNull(value) == true) {
}
return true;
}
}
export class TextField extends field {
constructor(data) {
super();
this.fieldName = 'TextField';
Object.assign(this, data);
}
valid(value) {
if (!(typeof value == 'string')) {
if ((this === null || this === void 0 ? void 0 : this.blank) != true) {
return false;
}
else if (!(value === null || value === undefined)) {
return false;
}
}
else if (!this.rules(this, value)) {
return false;
}
return true;
}
}
export class IntegerField extends field {
constructor(data) {
super();
this.fieldName = 'IntegerField';
this.type = FieldType.INT;
Object.assign(this, data);
}
valid(value) {
if (!(typeof value == 'number')) {
if ((this === null || this === void 0 ? void 0 : this.blank) != true) {
return false;
}
else if (!(value === null || value === undefined)) {
return false;
}
}
else if (!this.rules(this, value)) {
return false;
}
return true;
}
}
export class ForeignKey extends field {
constructor(data) {
super();
this.fieldName = 'ForeignKey';
this.foreignKey = true;
Object.assign(this, data);
}
valid(value) {
return !this.isNull(value);
}
}
export class OneToOneField extends field {
constructor(data) {
super();
this.fieldName = 'OneToOneField';
this.foreignKey = true;
Object.assign(this, data);
}
contractor(contractor) {
throw new Error('Method not implemented.');
}
valid(value) {
return !this.isNull(value);
}
}
export class ManyToManyField extends field {
constructor(data) {
super();
this.fieldName = 'ManyToManyField';
this.foreignKey = true;
Object.assign(this, data);
}
valid(value) {
return !this.isNull(value);
}
}
+17
View File
@@ -0,0 +1,17 @@
import { FieldKeys } from "./fields.interface";
export declare class field {
fieldName: FieldKeys;
primaryKey?: any;
maxLength?: number | undefined;
minLength?: number | undefined;
choices?: any[] | undefined;
type: number;
blank?: boolean;
default?: any;
unique?: boolean;
foreignKey?: boolean;
model?: field;
get field(): boolean;
isNull(value: any): boolean;
rules(field: field, value: any): boolean;
}
+32
View File
@@ -0,0 +1,32 @@
export class field {
get field() {
return true;
}
isNull(value) {
if (value == undefined) {
return true;
}
else if (value == null) {
return true;
}
else if (value == '' && !Array.isArray(value)) {
return true;
}
return false;
}
rules(field, value) {
if (field === null || field === void 0 ? void 0 : field.maxLength) {
if (value.toString().length > field.maxLength) {
return false;
}
}
if (field === null || field === void 0 ? void 0 : field.minLength) {
if (value.toString().length < field.minLength) {
return false;
}
}
if (field === null || field === void 0 ? void 0 : field.foreignKey) {
}
return true;
}
}
+18
View File
@@ -0,0 +1,18 @@
import { AutoFieldParams, BigIntegerFieldParams, BooleanFieldParams, CharFieldParams, DateFieldParams, DateTimeFieldParams, ForeignKeyParams, IndexedDBArrayFieldParams, IndexedDBJsonFieldParams, IntegerFieldParams, ManyToManyFieldParams, OneToOneFieldParams, TextFieldParams } from './interface.js';
export declare function CharField(data?: CharFieldParams): string;
export declare function BooleanField(data?: BooleanFieldParams): boolean;
export declare function TextField(data?: TextFieldParams): string;
export declare function IntegerField(data?: IntegerFieldParams): number;
export declare function DateField(data?: DateFieldParams): Date;
export declare function DateTimeField(data?: DateTimeFieldParams): string;
export declare function BigIntegerField(data?: BigIntegerFieldParams): number;
export declare function AutoField(data?: AutoFieldParams): any;
export declare const indexedDB: {
fields: {
JsonField: (data?: IndexedDBJsonFieldParams) => Object;
ArrayField: (data?: IndexedDBArrayFieldParams) => any[];
};
};
export declare function OneToOneField(data: OneToOneFieldParams): string | number;
export declare function ForeignKey(data: ForeignKeyParams): string | number;
export declare function ManyToManyField(data?: ManyToManyFieldParams): string | number;
+10
View File
@@ -0,0 +1,10 @@
export declare const FieldKeysArray: readonly ["CharField", "JsonField", "AutoField", "BigIntegerField", "DateField", "IntegerField", "TextField", "BooleanField", "OneToOneField", "ForeignKey", "ManyToManyField", "indexedDBJsonField", "indexedDBArrayField", "DateTimeField", "DateField", "Unknown"];
export declare const AttributesArray: readonly ["maxLength", "minLength", "choices", "primaryKey", "unique", "autoIncrement", "type", "choices", "model", "blank", "default", "onDelete", "foreignKey"];
export declare type FieldKeys = typeof FieldKeysArray[number];
export declare type FieldsMap<K extends string | number | symbol, T> = {
[P in K]?: T;
};
export declare type FieldAttributesKeys = typeof AttributesArray[number];
export declare type AttributesMap<K extends string | number | symbol, T> = {
[P in K]?: T;
};
@@ -0,0 +1,34 @@
export const FieldKeysArray = [
'CharField',
'JsonField',
'AutoField',
'BigIntegerField',
'DateField',
'IntegerField',
'TextField',
'BooleanField',
'OneToOneField',
'ForeignKey',
'ManyToManyField',
'indexedDBJsonField',
'indexedDBArrayField',
'DateTimeField',
'DateField',
'Unknown'
]; // TS3.4 syntax
export const AttributesArray = [
'maxLength',
'minLength',
'choices',
'primaryKey',
'unique',
'autoIncrement',
'type',
'choices',
'model',
'blank',
'default',
'onDelete',
'foreignKey'
]; // TS3.4 syntax
// https://stackoverflow.com/a/64694571/14115342
+40
View File
@@ -0,0 +1,40 @@
import * as Fields from './allFields.js';
export function CharField(data) {
return new Fields.CharField(data);
}
export function BooleanField(data) {
return new Fields.BooleanField(data);
}
export function TextField(data) {
return new Fields.TextField(data);
}
export function IntegerField(data) {
return new Fields.IntegerField(data);
}
export function DateField(data) {
return new Fields.DateField(data);
}
export function DateTimeField(data) {
return new Fields.DateTimeField(data);
}
export function BigIntegerField(data) {
return new Fields.BigIntegerField(data);
}
export function AutoField(data) {
return new Fields.AutoField(data);
}
export const indexedDB = {
fields: {
JsonField: (data) => new Fields.indexedDBJsonField(data),
ArrayField: (data) => new Fields.indexedDBArrayField(data)
}
};
export function OneToOneField(data) {
return new Fields.OneToOneField(data);
}
export function ForeignKey(data) {
return new Fields.ForeignKey(data);
}
export function ManyToManyField(data) {
return new Fields.ManyToManyField(data);
}
+97
View File
@@ -0,0 +1,97 @@
import { field } from './field.js';
export interface CharFieldParams {
maxLength?: number;
minLength?: number;
primaryKey?: boolean;
choices?: any[] | undefined;
unique?: boolean;
blank?: boolean;
default?: any;
}
export interface TextFieldParams {
maxLength?: number;
minLength?: number;
primaryKey?: boolean;
unique?: boolean;
default?: any;
blank?: boolean;
}
export interface IntegerFieldParams {
primaryKey?: boolean;
unique?: boolean;
default?: any;
blank?: boolean;
}
export interface BigIntegerFieldParams {
primaryKey?: boolean;
unique?: boolean;
default?: any;
blank?: boolean;
}
export interface AutoFieldParams {
primaryKey?: boolean;
}
export interface IndexedDBJsonFieldParams {
unique?: boolean;
blank?: boolean;
null?: boolean;
default?: any;
}
export interface IndexedDBArrayFieldParams {
unique?: boolean;
blank?: boolean;
type?: any;
default?: any;
maxLength?: number;
minLength?: number;
field?: field | any;
size?: number;
}
export interface DateTimeFieldParams {
unique?: boolean;
blank?: boolean;
default?: any;
}
export interface DateFieldParams {
unique?: boolean;
blank?: boolean;
default?: any;
}
export interface BooleanFieldParams {
unique?: boolean;
blank?: boolean;
default?: any;
}
export interface ForeignKeyParams {
model: any;
unique?: boolean;
blank?: boolean;
default?: any;
onDelete?: any;
primaryKey?: boolean;
}
export interface OneToOneFieldParams {
model: any;
unique?: boolean;
blank?: boolean;
default?: any;
onDelete?: any;
}
export interface ManyToManyFieldParams {
model: any;
unique?: boolean;
blank?: boolean;
default?: any;
onDelete?: any;
}
export interface PossibleFieldAttributes {
model?: any;
unique?: boolean;
blank?: boolean;
default?: any;
onDelete?: any;
primaryKey?: boolean;
maxLength?: number;
minLength?: number;
choices?: any[] | undefined;
}
+1
View File
@@ -0,0 +1 @@
export {};
+13
View File
@@ -0,0 +1,13 @@
export declare class _ModelMigrations {
callback: {
[dbName: string]: Function[];
};
migrated: {
[dbName: string]: boolean;
};
prepare(databaseName: any): void;
migrationsState(databaseName: string, value: boolean): void;
isReady(modelClassRepresentation: any): void;
waitMigration(databaseName: string): Promise<unknown>;
}
export declare const ModelMigrations: _ModelMigrations;
+37
View File
@@ -0,0 +1,37 @@
export class _ModelMigrations {
constructor() {
this.callback = {};
this.migrated = {};
}
prepare(databaseName) {
if (!this.callback[databaseName]) {
this.callback[databaseName] = [];
}
}
migrationsState(databaseName, value) {
this.migrated[databaseName] = value;
this.prepare(databaseName);
if (this.migrated[databaseName]) {
this.callback[databaseName].forEach((callback, index, object) => {
callback();
});
}
}
isReady(modelClassRepresentation) {
// const classInstance: typeof models.Model = new modelClassRepresentation()
}
async waitMigration(databaseName) {
return new Promise((resolve, reject) => {
if (!this.migrated[databaseName]) {
this.prepare(databaseName);
this.callback[databaseName].push(() => {
resolve('ready');
});
}
else {
resolve('ready');
}
});
}
}
export const ModelMigrations = new _ModelMigrations();
View File
View File
+16
View File
@@ -0,0 +1,16 @@
import { Methods, Method } from './model.interface.js';
import { DatabaseSchema, TableSchema } from './register-modal.interface.js';
export declare class ModelAPIRequest {
constructor();
static obj: (DatabaseSchema: DatabaseSchema, TableSchema?: TableSchema) => {
create: (args: Method[], queryId: string, callback: any) => Promise<void>;
get: (arg: Method[], queryId: string) => Promise<unknown>;
save: (arg: Method[], queryId: string) => Promise<unknown>;
execute: (arg: Methods | Method[], queryId: string) => Promise<any>;
update: (arg: any, queryId: string) => Promise<unknown>;
delete: (arg: any, queryId: string) => Promise<unknown>;
all: (arg: any, queryId: string) => Promise<any>;
migrate: (queryId?: string) => Promise<unknown>;
trigger: (args: any, Subscription: string, callback: Function) => Promise<void>;
};
}
+46
View File
@@ -0,0 +1,46 @@
var _a;
import { DBSwitch } from '../connection/dbSwtich.js';
import { ModelMigrations } from './mode-migrations.js';
import { uniqueGenerator } from '../utils.js';
export class ModelAPIRequest {
constructor() { }
}
_a = ModelAPIRequest;
ModelAPIRequest.obj = (DatabaseSchema, TableSchema) => {
return {
create: async (args, queryId, callback) => {
await ModelMigrations.waitMigration(DatabaseSchema.databaseName);
return await DBSwitch.callBackRequestHandler(TableSchema.name, DatabaseSchema.databaseName, DatabaseSchema.type, 'insert', args, callback, queryId);
},
get: async (arg, queryId) => {
await ModelMigrations.waitMigration(DatabaseSchema.databaseName);
return await DBSwitch.requestHandler(TableSchema.name, DatabaseSchema.databaseName, DatabaseSchema.type, 'select', arg, queryId);
},
save: async (arg, queryId) => {
await ModelMigrations.waitMigration(DatabaseSchema.databaseName);
return await DBSwitch.requestHandler(TableSchema.name, DatabaseSchema.databaseName, DatabaseSchema.type, 'update', arg, queryId);
},
execute: async (arg, queryId) => {
await ModelMigrations.waitMigration(DatabaseSchema.databaseName);
return await DBSwitch.requestHandler(TableSchema.name, DatabaseSchema.databaseName, DatabaseSchema.type, 'select', arg, queryId);
},
update: async (arg, queryId) => {
await ModelMigrations.waitMigration(DatabaseSchema.databaseName);
return await DBSwitch.requestHandler(TableSchema.name, DatabaseSchema.databaseName, DatabaseSchema.type, 'update', arg, queryId);
},
delete: async (arg, queryId) => {
await ModelMigrations.waitMigration(DatabaseSchema.databaseName);
return await DBSwitch.requestHandler(TableSchema.name, DatabaseSchema.databaseName, DatabaseSchema.type, 'delete', arg, queryId);
},
all: async (arg, queryId) => {
await ModelMigrations.waitMigration(DatabaseSchema.databaseName);
return await DBSwitch.requestHandler(TableSchema.name, DatabaseSchema.databaseName, DatabaseSchema.type, 'select', arg, queryId);
},
migrate: async (queryId = uniqueGenerator()) => {
return await DBSwitch.requestHandler(null, DatabaseSchema.databaseName, DatabaseSchema.type, 'migrate', { DatabaseSchema, TableSchema }, queryId);
}, trigger: async (args, Subscription, callback) => {
await ModelMigrations.waitMigration(DatabaseSchema.databaseName);
DBSwitch.callBackRequestHandler(TableSchema.name, DatabaseSchema.databaseName, DatabaseSchema.type, 'trigger', args, callback, Subscription);
}
};
};
+87
View File
@@ -0,0 +1,87 @@
import { getParams } from './model.interface.js';
import { DatabaseSchema, DatabaseSchemaLocalStorage, TableSchema, TableSchemaLocalStorage } from './register-modal.interface.js';
export declare class Model {
constructor();
get(arg: any): Promise<any>;
getModelName(): string;
getDBSchema(): DatabaseSchema;
getTableSchema(): TableSchema;
filter(...arg: any[]): {
filter: (...args: any[]) => void;
execute: () => Promise<any[]>;
update: (args: any) => Promise<unknown>;
delete: () => Promise<unknown>;
all: () => Promise<any[]>;
};
getPrimaryKeyValue(): any;
private setDataToInstance;
private static setDataToInstance;
save(): Promise<void>;
delete(): Promise<void>;
static deleteAll(): Promise<void>;
all(): Promise<any[]>;
getFields(arg: any): {};
formValidation(data: any): boolean;
Value(args: any): string;
static Value(args: any): string;
static formValidation(data: any): boolean;
static getModelsFields(arg: any): Promise<void>;
static all(): Promise<any[]>;
static get(arg: getParams): Promise<any>;
static getOrCreate(arg: getParams): Promise<any>;
private static getId;
static getModelName(): string;
static filter(...arg: any[]): {
filter: (...args: any[]) => void;
execute: () => Promise<any[]>;
update: (args: any) => Promise<unknown>;
delete: () => Promise<unknown>;
all: () => Promise<any[]>;
};
static getDBSchema(): DatabaseSchema;
static getTableSchema(): TableSchema;
private static getEmptyFields;
private static getFields;
static create(arg: any): Promise<any>;
static getMode(TableSchema: any): any;
private static newInstance;
static createOrFind(getArg: any, defaultCreate: any): Promise<any[]>;
static updateOrCreate(...args: any[]): Promise<any>;
static update(arg: any): Promise<unknown>;
static transactionOnCommit(callback: () => void): {
queryId: string;
subscribe: boolean;
unsubscribe: () => Promise<unknown>;
};
static ReactiveList(callback: (Model: Model) => void): {
readonly value: any;
readonly subscribe: any;
unsubscribe: () => Promise<any>;
setUpdateUi(func: any): void;
};
static object: ({ queryId, DBconfig, TableSchema, some }: {
queryId: any;
DBconfig: any;
TableSchema: any;
some?: any;
}) => {
filter: (...args: any[]) => void;
execute: () => Promise<any[]>;
update: (args: any) => Promise<unknown>;
delete: () => Promise<unknown>;
all: () => Promise<any[]>;
};
}
export declare class LocalStorage {
constructor();
static save(data?: Object): void;
static get(): any;
static getModelName(): any;
static getDBSchema(): DatabaseSchemaLocalStorage;
static getTableSchema(): TableSchemaLocalStorage;
private static getFields;
private static formValidation;
static clear(): void;
static clearComponent(): void;
static clearStorage(): void;
}
+10
View File
@@ -0,0 +1,10 @@
export declare const MethodNameArray: readonly ["save", "filter", "get", "create", "execute", "update", "delete", "all", "first"];
export declare type MethodName = typeof MethodNameArray[number];
export interface Method {
methodName: MethodName;
arguments: any;
}
export declare type Methods = {
[key: string]: Method[];
};
export declare type getParams = Object;
+11
View File
@@ -0,0 +1,11 @@
export const MethodNameArray = [
'save',
'filter',
'get',
'create',
'execute',
'update',
'delete',
'all',
'first',
]; // TS3.4 syntax
+518
View File
@@ -0,0 +1,518 @@
var _a;
import { hashCode, uniqueGenerator } from '../utils.js';
import { ModelAPIRequest } from './model-manager.js';
import { objModels } from './register-model.js';
import { FieldType } from '../sql/query/interface.js';
import * as Fields from './field/allFields.js';
import { taskHolder } from '../connection/taskHolder.js';
import { transactionOnCommit } from '../triggers/transaction.js';
import { ReactiveList } from '../reactive/DynamicList.js';
import { signalExecutor, rewrite } from './signal.js';
let methods = {} = {};
// inspire by https://github.com/brianschardt/browser-orm
export class Model {
constructor() { }
get(arg) {
return Model.get(arg);
}
getModelName() {
return this.constructor.name;
}
getDBSchema() {
return {};
}
getTableSchema() {
return {};
}
filter(...arg) {
return Model.filter(arg);
}
getPrimaryKeyValue() {
const TableSchema = this.getTableSchema();
const idFieldName = TableSchema.id.keyPath;
return this[idFieldName];
}
setDataToInstance(obj, Fields = {}) {
const tableSchema = this.getTableSchema();
const fiendsName = tableSchema.fields.map((field) => field.name);
Fields = {};
for (let name of fiendsName) {
Fields[name] = obj[name];
}
if (obj[tableSchema.id.keyPath]) {
Fields[tableSchema.id.keyPath] = obj[tableSchema.id.keyPath];
}
return Fields;
}
static setDataToInstance(obj, Fields = {}) {
const tableSchema = this.getTableSchema();
const fiendsName = tableSchema.fields.map((field) => field.name);
Fields = {};
for (let name of fiendsName) {
Fields[name] = obj[name];
}
if (obj[tableSchema.id.keyPath]) {
Fields[tableSchema.id.keyPath] = obj[tableSchema.id.keyPath];
}
return Fields;
}
async save() {
const DBconfig = this.getDBSchema();
const tableSchema = this.getTableSchema();
const Fields = this.setDataToInstance(this);
const methods = [{ methodName: 'save', arguments: Fields }];
const queryId = uniqueGenerator();
await ModelAPIRequest.obj(DBconfig, tableSchema).save(methods, queryId);
taskHolder.finish(queryId);
}
async delete() {
const DBconfig = this.getDBSchema();
const TableSchema = this.getTableSchema();
const idFieldName = TableSchema.id.keyPath;
const createArg = {};
createArg[idFieldName] = this[idFieldName];
const _methods = [{ methodName: 'delete', arguments: createArg }];
const queryId = uniqueGenerator();
await ModelAPIRequest.obj(DBconfig, TableSchema).delete(_methods, queryId);
taskHolder.finish(queryId);
}
static async deleteAll() {
const DBconfig = this.getDBSchema();
const TableSchema = this.getTableSchema();
const idFieldName = TableSchema.id.keyPath;
const createArg = {};
createArg[idFieldName] = this[idFieldName];
const _methods = [{ methodName: 'delete', arguments: '*' }];
const queryId = uniqueGenerator();
await ModelAPIRequest.obj(DBconfig, TableSchema).delete(_methods, queryId);
taskHolder.finish(queryId);
}
async all() {
const DBconfig = this.getDBSchema();
const TableSchema = this.getTableSchema();
const queryId = uniqueGenerator();
const result = await Model.object({ queryId, DBconfig, TableSchema }).all();
taskHolder.finish(queryId);
return result;
}
getFields(arg) {
return Model.getFields(arg);
}
formValidation(data) {
return Model.formValidation(data);
}
Value(args) {
return Model.Value(args);
}
static Value(args) {
return '';
}
static formValidation(data) {
const TableSchema = this.getTableSchema();
for (let field of TableSchema.fields) {
const Field = new Fields[field.className](field.fieldAttributes);
const FieldValue = data[field.name];
if (!Field.valid(FieldValue)) {
throw ('invalid insert into ' + TableSchema.name + ', invalid value for field ' + field.name + ' = ' + JSON.stringify(FieldValue));
}
}
return true;
}
static async getModelsFields(arg) {
var _b;
const newArgs = {};
const TableSchema = this.getTableSchema();
if ((_b = TableSchema.id) === null || _b === void 0 ? void 0 : _b.autoIncrement) {
TableSchema.fields.push({
keyPath: TableSchema.id.keyPath,
name: TableSchema.id.keyPath,
options: {
type: FieldType.INT,
unique: true
}
});
}
for (const fieldName in TableSchema.fields) {
newArgs[fieldName] = arg[fieldName];
}
}
static async all() {
const DBconfig = this.getDBSchema();
const TableSchema = this.getTableSchema();
const queryId = uniqueGenerator();
const result = await Model.object({ queryId, DBconfig, TableSchema }).all();
taskHolder.finish(queryId);
return result;
}
static async get(arg) {
if (Object.values(arg).length >= 2) {
throw ("get only works with one field");
}
const _methods = [{ methodName: 'get', arguments: arg }];
const DBconfig = this.getDBSchema();
const TableSchema = this.getTableSchema();
const queryId = uniqueGenerator();
const foundObj = await ModelAPIRequest.obj(DBconfig, TableSchema).get(_methods, queryId);
taskHolder.finish(queryId);
if (!foundObj) {
return false;
}
let newInstance = this.newInstance({ TableSchema, DBconfig, dataToMerge: foundObj });
return newInstance;
}
static async getOrCreate(arg) {
const object = await this.get(arg);
if (!object) {
return await this.create(arg);
}
else {
return object;
}
}
static getId() {
return hashCode(this.toString());
}
static getModelName() {
return this.toString().split('(' || /s+/)[0].split(' ' || /s+/)[1];
}
static filter(...arg) {
const queryId = uniqueGenerator();
const DBconfig = this.getDBSchema();
const TableSchema = this.getTableSchema();
return this.object({ queryId, DBconfig, TableSchema, some: ['filter', arg] });
}
static getDBSchema() {
return {};
}
static getTableSchema() {
return {};
}
static async getEmptyFields() {
const TableSchema = this.getTableSchema();
const emptyFields = {};
const fieldsName = TableSchema.fields.map((field) => field.name);
for (let fieldName of fieldsName) {
emptyFields[fieldName] = null;
}
return emptyFields;
}
static getFields(arg) {
const TableSchema = this.getTableSchema();
const filteredArgs = {};
const fieldsName = TableSchema.fields.map((field) => field.name);
for (let fieldName of fieldsName) {
if (arg.hasOwnProperty(fieldName)) {
filteredArgs[fieldName] = arg[fieldName];
}
}
return filteredArgs;
}
static async create(arg) {
return new Promise(async (resolve, reject) => {
if (arg.constructor.name != 'Array') {
arg = [arg];
}
const emptyFields = await this.getEmptyFields();
const TableSchema = this.getTableSchema();
const ModelName = TableSchema.name;
for (let i in arg) {
arg[i] = this.setDataToInstance(this.getFields(arg[i]), emptyFields);
if (!this.formValidation(arg[i])) {
throw ('invalid ' + JSON.stringify(arg[i]));
}
}
for (let i in arg) {
if (TableSchema.attributes.foreignKey) {
for (let field of TableSchema.attributes.foreignKey) {
try {
arg[i][field] = arg[i][field].getPrimaryKeyValue();
}
catch (error) { }
}
}
}
const _methods = [{ methodName: 'create', arguments: arg }];
const DBconfig = this.getDBSchema();
const queryId = uniqueGenerator();
const result = [];
await ModelAPIRequest.obj(DBconfig, TableSchema).create(_methods, queryId, ({ id, index }) => {
const insert = arg[index];
insert[TableSchema.id.keyPath] = id;
const instance = this.newInstance({ TableSchema, DBconfig, dataToMerge: insert });
result.push(instance);
});
taskHolder.updateFunction(queryId, "done", () => {
if (arg.length == 1) {
resolve(result[0]);
}
else {
resolve(result);
}
taskHolder.finish(queryId);
});
});
}
static getMode(TableSchema) {
return objModels[TableSchema.databaseName + TableSchema.name];
}
static newInstance({ TableSchema, DBconfig, dataToMerge }) {
const model = this.getMode(TableSchema);
let newInstance = new model();
delete newInstance[TableSchema.id.keyPath];
if (TableSchema.fieldTypes.ManyToManyField) {
for (let field of TableSchema.fieldTypes.ManyToManyField) {
newInstance[field] = null;
}
}
if (TableSchema.fieldTypes.OneToOneField) {
for (let field of TableSchema.fieldTypes.OneToOneField) {
newInstance[field] = null;
}
}
Object.assign(newInstance, dataToMerge);
if (newInstance[TableSchema.id.keyPath]) {
Object.defineProperty(newInstance, TableSchema.id.keyPath, {
configurable: false,
writable: false
});
}
delete newInstance.obj;
return newInstance;
}
static async createOrFind(getArg, defaultCreate) {
const result = await this.filter(getArg).execute();
const TableSchema = this.getTableSchema();
const DBconfig = this.getDBSchema();
let instance;
let created;
if (result.length == 1) {
created = false;
instance = await this.newInstance({ TableSchema, DBconfig, dataToMerge: result[0] });
}
else {
created = true;
instance = await this.create(Object.assign(getArg, defaultCreate));
}
return [instance, created];
}
static async updateOrCreate(...args) {
if (args.length == 1) {
if (Array.isArray(args)) {
const TableSchema = this.getTableSchema();
let created = [];
let updated = [];
const list = args;
const uniqueFields = TableSchema.attributes["unique"].concat(TableSchema.id.keyPath);
for (const object of list) {
const uniqueFieldName = uniqueFields.find((fieldName) => {
if (object[fieldName]) {
return true;
}
return false;
});
const params = {};
params[uniqueFieldName] = object[uniqueFieldName];
try {
const instanceModel = await this.get(params);
updated.push(instanceModel);
}
catch (error) {
const instanceModel = await this.create(params);
created.push(instanceModel);
}
}
return { created, updated };
}
else {
const TableSchema = this.getTableSchema();
let instance;
let created = false;
const uniqueFields = TableSchema.attributes["unique"].concat(TableSchema.id.keyPath);
const uniqueFieldName = uniqueFields.find((fieldName) => {
if (args[fieldName]) {
return true;
}
return false;
});
const params = {};
params[uniqueFieldName] = args[uniqueFieldName];
try {
const object = await this.get(params);
instance = object;
await object.save(args);
}
catch (error) {
instance = await this.create(params);
return instance;
}
return { instance, created };
}
}
else {
let argToFind = args[0];
let argsToUpdate = args[1];
let [instance, created] = await this.createOrFind(argToFind, argsToUpdate);
if (!created) {
const params = Object.assign(argToFind, argsToUpdate);
instance = Object.assign(instance, params);
await instance.save();
}
return instance;
}
}
static async update(arg) {
arg = this.getFields(arg);
const DBconfig = this.getDBSchema();
const TableSchema = this.getTableSchema();
const _methods = [{ methodName: 'update', arguments: arg }];
const queryId = uniqueGenerator();
const result = await ModelAPIRequest.obj(DBconfig, TableSchema).update(_methods, queryId);
taskHolder.finish(queryId);
return result;
}
static transactionOnCommit(callback) {
return transactionOnCommit.subscribe(this, callback);
}
static ReactiveList(callback) {
return ReactiveList.subscribe(this, callback);
}
}
_a = Model;
Model.object = ({ queryId, DBconfig, TableSchema, some = null }) => {
const ModelName = TableSchema.name;
if (!methods[queryId]) {
methods[queryId] = [];
}
if (some) {
const methodName = some[0];
const methodArgs = some[1];
_a.object({ queryId, DBconfig, TableSchema })[methodName](...methodArgs);
}
return {
filter: (...args) => {
methods[queryId].push({ methodName: 'filter', arguments: args });
_a.object({ DBconfig, TableSchema, queryId });
},
execute: async () => {
return new Promise(async (resolve, reject) => {
methods[queryId].push({ methodName: 'execute', arguments: null });
const _methods = methods[queryId];
methods[queryId] = [];
const result = await ModelAPIRequest.obj(DBconfig, TableSchema).execute(_methods, queryId);
resolve(result);
for (let i of result) {
result[i] = _a.newInstance({ TableSchema, DBconfig, dataToMerge: result[i] });
}
});
},
update: async (args) => {
methods[queryId].push({ methodName: 'update', arguments: args });
const _methods = methods[queryId];
methods[queryId] = [];
return await ModelAPIRequest.obj(DBconfig, TableSchema).update(_methods, queryId);
},
delete: async () => {
methods[queryId].push({ methodName: 'delete', arguments: null });
const _methods = methods[queryId];
methods[queryId] = [];
return await ModelAPIRequest.obj(DBconfig, TableSchema).delete(_methods, queryId);
},
all: async () => {
return new Promise(async (resolve, reject) => {
methods[queryId].push({ methodName: 'all', arguments: null });
const _methods = methods[queryId];
methods[queryId] = [];
const result = await ModelAPIRequest.obj(DBconfig, TableSchema).all(_methods, queryId);
resolve(result);
for (let i of result) {
result[i] = _a.newInstance({ TableSchema, DBconfig, dataToMerge: result[i] });
}
});
}
};
};
export class LocalStorage {
constructor() { }
static save(data = {}) {
const key = this.getTableSchema().id;
const _data = typeof data == 'object' ? data : {};
const dataToSave = this.getFields(Object.assign(this, Object.assign({}, _data)));
const hasSignal = rewrite.hasRewriteSave(key.keyPath);
if (hasSignal) {
signalExecutor.rewriteSave(key.keyPath, this, dataToSave);
}
else {
localStorage.setItem(key.keyPath, JSON.stringify(dataToSave));
}
}
static get() {
const key = this.getTableSchema().id;
const hasSignal = rewrite.hasRewriteGet(key.keyPath);
if (hasSignal) {
signalExecutor.rewriteGet(key.keyPath, this);
}
else {
const restedData = JSON.parse(localStorage.getItem(key.keyPath));
Object.assign(this, Object.assign({}, restedData));
return restedData;
}
}
static getModelName() {
return this['$keyName'] || this.toString().split('(' || /s+/)[0].split(' ' || /s+/)[1];
}
static getDBSchema() {
return;
}
static getTableSchema() {
return;
}
static getFields(arg) {
const TableSchema = this.getTableSchema();
const DBSchema = this.getDBSchema();
const ignoreFieldsStartWidth = (DBSchema === null || DBSchema === void 0 ? void 0 : DBSchema.ignoreFieldsStartWidth) || [];
const filteredArgs = {};
const fieldsName = TableSchema.fields.map((field) => field.name);
const fieldNameFilter = fieldsName.filter((fieldName) => {
for (let Attribute of ignoreFieldsStartWidth) {
if (fieldName.startsWith(Attribute)) {
return false;
}
}
return true;
});
for (let fieldName of fieldNameFilter) {
if (arg.hasOwnProperty(fieldName)) {
filteredArgs[fieldName] = arg[fieldName];
}
}
return filteredArgs;
}
static formValidation(data) {
const TableSchema = this.getTableSchema();
for (let field of TableSchema.fields) {
const Field = new Fields[field.className](field.fieldAttributes);
const FieldValue = data[field.name];
if (!Field.valid(FieldValue)) {
throw ('invalid insert into ' + TableSchema.name + ', invalid value for field ' + field.name + ' = ' + JSON.stringify(FieldValue));
}
}
return true;
}
static clear() {
this.clearComponent();
this.clearStorage();
}
static clearComponent() {
const key = this.getTableSchema().id;
}
static clearStorage() {
const key = this.getTableSchema().id;
const hasSignal = rewrite.hasRewriteDelete(key.keyPath);
if (hasSignal) {
signalExecutor.rewriteDelete(key.keyPath, this);
}
else {
localStorage.removeItem(key.keyPath);
}
}
}
+21
View File
@@ -0,0 +1,21 @@
import { FieldsMap, AttributesMap } from './field/fields.interface.js';
export declare class ModelReader {
static read(modelClassRepresentation: any): {
modelName: string;
fields: {
[key: string]: any;
};
fieldTypes: FieldsMap<"CharField" | "JsonField" | "AutoField" | "BigIntegerField" | "DateField" | "IntegerField" | "TextField" | "BooleanField" | "OneToOneField" | "ForeignKey" | "ManyToManyField" | "indexedDBJsonField" | "indexedDBArrayField" | "DateTimeField" | "Unknown", string[]>;
attributes: AttributesMap<"maxLength" | "minLength" | "choices" | "primaryKey" | "unique" | "autoIncrement" | "type" | "model" | "blank" | "default" | "onDelete" | "foreignKey", string[]>;
};
}
export declare class LocalStorageModelReader {
static read(modelClassRepresentation: any, ignoreFieldsStartWidth: string[]): {
modelName: any;
fields: {
[key: string]: any;
};
attributes: AttributesMap<"maxLength" | "minLength" | "choices" | "primaryKey" | "unique" | "autoIncrement" | "type" | "model" | "blank" | "default" | "onDelete" | "foreignKey", string[]>;
fieldTypes: FieldsMap<"CharField" | "JsonField" | "AutoField" | "BigIntegerField" | "DateField" | "IntegerField" | "TextField" | "BooleanField" | "OneToOneField" | "ForeignKey" | "ManyToManyField" | "indexedDBJsonField" | "indexedDBArrayField" | "DateTimeField" | "Unknown", string[]>;
};
}
+84
View File
@@ -0,0 +1,84 @@
import { FieldKeysArray } from './field/fields.interface.js';
export class ModelReader {
static read(modelClassRepresentation) {
const classInstance = new modelClassRepresentation();
const modelName = classInstance.getModelName();
const fieldTypes = {};
const fields = {};
const attributes = {};
for (const [fieldName, Field] of Object.entries(classInstance)) {
const type = Field === null || Field === void 0 ? void 0 : Field.fieldName;
if (FieldKeysArray.includes(type)) {
fields[fieldName] = Field;
if (!fieldTypes[type]) {
fieldTypes[type] = [];
}
fieldTypes[type].push(fieldName);
for (const [FieldProperty, value] of Object.entries(Field)) {
if (typeof value != "function") {
if (!attributes[FieldProperty]) {
attributes[FieldProperty] = [];
}
attributes[FieldProperty].push(fieldName);
}
}
}
else {
fields[fieldName] = Field;
if (!fieldTypes["Unknown"]) {
fieldTypes["Unknown"] = [];
}
fieldTypes["Unknown"].push(fieldName);
}
}
return {
modelName,
fields,
fieldTypes,
attributes,
};
}
}
export class LocalStorageModelReader {
static read(modelClassRepresentation, ignoreFieldsStartWidth) {
const classInstance = modelClassRepresentation;
const fieldTypes = {};
const attributes = {};
const modelName = classInstance.getModelName();
const fields = {};
for (const [fieldName, Field] of Object.entries(classInstance)) {
const ignore = ignoreFieldsStartWidth.find(e => fieldName.startsWith(e));
if (!ignore) {
const type = Field === null || Field === void 0 ? void 0 : Field.fieldName;
if (FieldKeysArray.includes(type)) {
fields[fieldName] = Field;
if (!fieldTypes[type]) {
fieldTypes[type] = [];
}
fieldTypes[type].push(fieldName);
for (const [FieldProperty, value] of Object.entries(Field)) {
if (typeof value != "function") {
if (!attributes[FieldProperty]) {
attributes[FieldProperty] = [];
}
attributes[FieldProperty].push(fieldName);
}
}
}
else {
fields[fieldName] = Field;
if (!fieldTypes["Unknown"]) {
fieldTypes["Unknown"] = [];
}
fieldTypes["Unknown"].push(fieldName);
}
}
}
return {
modelName,
fields,
attributes,
fieldTypes
};
}
}
+52
View File
@@ -0,0 +1,52 @@
import { FieldType } from '../sql/query/interface.js';
import { FieldsMap, FieldKeys, AttributesMap, FieldAttributesKeys } from './field/fields.interface.js';
import { PossibleFieldAttributes } from './field/interface.js';
export interface FieldSchema {
name: string;
keyPath: string;
className?: FieldKeys;
fieldAttributes?: PossibleFieldAttributes;
options?: {
unique?: boolean;
type: FieldType;
};
}
export interface TableSchema {
databaseName: string;
name: string;
id: {
keyPath: string;
autoIncrement?: boolean;
type: FieldType;
};
fields: FieldSchema[];
attributes: AttributesMap<FieldAttributesKeys, string[]>;
fieldTypes: FieldsMap<FieldKeys, string[]>;
middle?: boolean;
}
export interface DatabaseSchema {
databaseName: string;
type: 'indexedDB' | 'localStorage';
version: number;
webWorker?: boolean;
stores?: TableSchema[];
}
export interface TableSchemaLocalStorage {
name: string;
id: {
keyPath: string;
autoIncrement?: boolean;
type: FieldType;
};
fields: FieldSchema[];
attributes: AttributesMap<FieldAttributesKeys, string[]>;
fieldTypes: FieldsMap<FieldKeys, string[]>;
}
export interface DatabaseSchemaLocalStorage {
databaseName: string;
type: 'localStorage';
version: number;
webWorker?: boolean;
stores?: TableSchemaLocalStorage[];
ignoreFieldsStartWidth?: string[];
}
@@ -0,0 +1 @@
export {};
+45
View File
@@ -0,0 +1,45 @@
import { Model, LocalStorage } from './model.js';
import { DatabaseSchema, DatabaseSchemaLocalStorage, TableSchema, TableSchemaLocalStorage } from './register-modal.interface.js';
import { OneToOneField, ForeignKey, ManyToManyField } from './field/allFields.js';
interface register {
databaseName: string;
version: number;
type: 'indexedDB' | 'localStorage';
models: typeof Model[] | typeof LocalStorage[];
/**
* @description restore values from localStorage for LocalStorage Models
*/
restore?: boolean;
ignoreFieldsStartWidth?: string[];
}
export declare const objModels: {};
export declare const modelsConfig: {
[key: string]: {
DatabaseSchema: DatabaseSchema;
TableSchema: TableSchema;
OneToOneField?: {
[key: string]: {};
};
};
};
export declare function migrate(register: register): void;
export declare class registerModel {
static ModalName(): void;
static register(entries: register): Promise<void>;
static manyToManyRelationShip(foreignKeyField: ManyToManyField, FieldName: string, modelName: string, databaseSchema: DatabaseSchema): Model;
}
export declare class registerLocalStorage {
static register(entries: register): Promise<void>;
static edit(ModelName: any, databaseSchema: any, modelClassRepresentations: any, entries: any): void;
static ModelName(modelClassRepresentations: typeof LocalStorage, DbName: any): string;
}
export declare class ModelEditor {
static setTableSchemaLocalStorage(ModelToEdit: typeof LocalStorage, TableSchema: TableSchemaLocalStorage): void;
static getDBSchemaLocalStorage(ModelToEdit: typeof LocalStorage, DatabaseSchema: DatabaseSchemaLocalStorage): void;
static setTableSchema(ModelToEdit: typeof Model, DbName: any): void;
static getDBSchema(ModelToEdit: typeof Model, DbName: any): void;
static addMethodOneToOneField(foreignKeyField: OneToOneField, FieldName: string, modelName: string, databaseSchema: DatabaseSchema): void;
static addMethodForeignKey(foreignKeyField: ForeignKey, FieldName: string, modelName: string, databaseSchema: DatabaseSchema): void;
static addMethodManyToManyField(foreignKeyField: ManyToManyField, FieldName: string, modelName: string, databaseSchema: DatabaseSchema): Promise<void>;
}
export {};
+448
View File
@@ -0,0 +1,448 @@
import { Model } from './model.js';
import { LocalStorageModelReader, ModelReader } from './model.reader.js';
import { OneToOneField, ForeignKey, ManyToManyField } from './field/allFields.js';
import { hashCode, uncapitalize, uniqueGenerator } from '../utils.js';
import { FieldType } from '../sql/query/interface.js';
import { ModelMigrations } from './mode-migrations.js';
import { ModelAPIRequest } from './model-manager.js';
import { transactionOnCommit } from '../triggers/transaction.js';
import { DatabaseManagerSchema } from './schema/databae-manager-schema.js';
const models = {};
export const objModels = {};
export const modelsConfig = {};
const modelsLocalStorage = {};
const modelsConfigLocalStorage = {};
export function migrate(register) {
if (register.type == 'indexedDB') {
registerModel.register(register);
}
else if (register.type == 'localStorage') {
registerLocalStorage.register(register);
}
}
export class registerModel {
static ModalName() { }
static async register(entries) {
var _a, _b, _c, _d;
const databaseSchema = {
databaseName: entries.databaseName || uniqueGenerator(),
version: entries.version,
type: entries.type,
stores: []
};
let index = 0;
for (const modelClassRepresentations of entries.models) {
const ModelName = modelClassRepresentations.getModelName();
models[ModelName] = modelClassRepresentations;
const { fields, modelName, attributes, fieldTypes } = ModelReader.read(modelClassRepresentations);
const idFieldName = (_a = attributes === null || attributes === void 0 ? void 0 : attributes.primaryKey) === null || _a === void 0 ? void 0 : _a.shift();
databaseSchema.stores.push({
databaseName: databaseSchema.databaseName,
name: modelName,
id: {
keyPath: idFieldName || 'id',
autoIncrement: fields[idFieldName] ? ((_b = fields[idFieldName]) === null || _b === void 0 ? void 0 : _b.primaryKey) == true : true,
type: FieldType.INT
},
attributes: attributes,
fields: [],
fieldTypes
});
for (const [fieldName, Field] of Object.entries(fields)) {
// dont register fields that is primary key and auto increment
if (!((Field === null || Field === void 0 ? void 0 : Field.primaryKey) && (Field === null || Field === void 0 ? void 0 : Field.autoIncrement)) && !((_c = fieldTypes['ManyToManyField']) === null || _c === void 0 ? void 0 : _c.includes(fieldName)) && !((_d = fieldTypes['Unknown']) === null || _d === void 0 ? void 0 : _d.includes(fieldName))) {
const removeReferenceField = Object.assign({}, Field);
if (removeReferenceField === null || removeReferenceField === void 0 ? void 0 : removeReferenceField.model) {
removeReferenceField.model = removeReferenceField.model.getModelName();
}
databaseSchema.stores[index].fields.push({
name: fieldName,
keyPath: fieldName,
options: {
unique: (Field === null || Field === void 0 ? void 0 : Field.unique) || false,
type: Field.type
},
className: Field === null || Field === void 0 ? void 0 : Field.fieldName,
fieldAttributes: Object.assign({}, removeReferenceField)
});
}
if (Field instanceof OneToOneField) {
await ModelEditor.addMethodOneToOneField(Field, fieldName, modelName, databaseSchema);
}
else if (Field instanceof ForeignKey) {
await ModelEditor.addMethodForeignKey(Field, fieldName, modelName, databaseSchema);
}
else if (Field instanceof ManyToManyField) {
await ModelEditor.addMethodManyToManyField(Field, fieldName, modelName, databaseSchema);
}
}
models[ModelName] = modelClassRepresentations;
const tableSchema = databaseSchema.stores.find((e) => e.name == ModelName);
modelsConfig[ModelName] = {
DatabaseSchema: databaseSchema,
TableSchema: tableSchema
};
index++;
}
DatabaseManagerSchema.prepare(databaseSchema);
for (const stores of databaseSchema.stores) {
const model = models[stores.name];
const DbName = databaseSchema.databaseName;
ModelEditor.setTableSchema(model, DbName);
ModelEditor.getDBSchema(model, DbName);
// ModelEditor.setModel(model, DbName)
DatabaseManagerSchema.getDb(DbName).getTable(stores.name).setModel(model);
transactionOnCommit.prepare(model);
objModels[DbName + stores.name] = model;
}
if (databaseSchema.type == 'indexedDB') {
await ModelAPIRequest.obj(databaseSchema).migrate();
ModelMigrations.migrationsState(databaseSchema.databaseName, true);
}
}
static manyToManyRelationShip(foreignKeyField, FieldName, modelName, databaseSchema) {
const foreignKeyFieldModel = foreignKeyField.model;
const currentModel = models[modelName];
const foreignKeyFieldModelName = foreignKeyFieldModel.getModelName();
const currentModelName = models[modelName].getModelName();
const tableName = currentModelName + foreignKeyFieldModelName;
const num = databaseSchema.stores.push({
databaseName: databaseSchema.databaseName,
name: tableName,
id: { keyPath: 'id', autoIncrement: true, type: FieldType.INT },
fields: [
{
name: 'iD' + foreignKeyFieldModelName,
keyPath: 'iD' + foreignKeyFieldModelName,
options: {
unique: false,
type: FieldType.INT
},
className: 'IntegerField'
},
{
name: 'iD' + currentModelName,
keyPath: 'iD' + currentModelName,
options: {
unique: false,
type: FieldType.INT
},
className: 'IntegerField'
}
],
attributes: {},
fieldTypes: {
IntegerField: ['iD' + foreignKeyFieldModelName, 'iD' + currentModelName]
}
});
const id = num - 1;
models[tableName] = generateGenericModel({
DBSchema: databaseSchema,
ModelName: tableName,
TableSchema: databaseSchema.stores[id]
});
return generateGenericModel({
DBSchema: databaseSchema,
ModelName: tableName,
TableSchema: databaseSchema.stores[id]
});
}
}
async function cachedValue(Model) {
const emptyFields = Model.getEmptyFields();
Model.getEmptyFields = function () {
return emptyFields;
};
const getModelName = Model.getModelName();
Model.getModelName = function () {
return getModelName;
};
}
export class registerLocalStorage {
static async register(entries) {
const databaseSchema = {
databaseName: entries.databaseName,
version: entries.version,
type: 'localStorage',
stores: []
};
let index = 0;
for (const modelClassRepresentations of entries.models) {
const ModelName = this.ModelName(modelClassRepresentations, entries.databaseName);
modelsLocalStorage[ModelName] = modelClassRepresentations;
const { fields, modelName, attributes, fieldTypes } = LocalStorageModelReader.read(modelClassRepresentations, entries.ignoreFieldsStartWidth || []);
databaseSchema.stores.push({
name: ModelName,
id: {
keyPath: ModelName,
type: FieldType.VARCHAR,
autoIncrement: false
},
attributes: attributes,
fields: [],
fieldTypes
});
for (const [fieldName, Field] of Object.entries(fields)) {
databaseSchema.stores[index].fields.push({
name: fieldName,
keyPath: fieldName,
options: {
unique: false,
type: null
},
className: Field === null || Field === void 0 ? void 0 : Field.fieldName,
fieldAttributes: Object.assign({}, Field)
});
}
index++;
}
for (const stores of databaseSchema.stores) {
const model = modelsLocalStorage[stores.name];
ModelEditor.setTableSchemaLocalStorage(model, stores);
ModelEditor.getDBSchemaLocalStorage(model, databaseSchema);
}
}
static edit(ModelName, databaseSchema, modelClassRepresentations, entries) {
const tableSchema = databaseSchema.stores.find((e) => e.name == ModelName);
modelClassRepresentations.getDBSchema = () => {
return databaseSchema;
};
modelClassRepresentations.getTableSchema = () => {
return tableSchema;
};
modelClassRepresentations.getModelName = () => {
return ModelName;
};
modelsConfigLocalStorage[ModelName] = {
DatabaseSchema: databaseSchema,
TableSchema: tableSchema
};
modelsLocalStorage[ModelName] = modelClassRepresentations;
if (entries === null || entries === void 0 ? void 0 : entries.restore) {
modelClassRepresentations.get(null);
}
}
static ModelName(modelClassRepresentations, DbName) {
const ModelName = DbName + '/' + modelClassRepresentations.getModelName();
if (modelsLocalStorage[ModelName]) {
return hashCode(DbName + '/' + modelClassRepresentations.toString()).toString();
}
return ModelName;
}
}
export class ModelEditor {
static setTableSchemaLocalStorage(ModelToEdit, TableSchema) {
ModelToEdit.getTableSchema = () => {
return TableSchema;
};
}
static getDBSchemaLocalStorage(ModelToEdit, DatabaseSchema) {
ModelToEdit.getDBSchema = () => {
return DatabaseSchema;
};
}
static setTableSchema(ModelToEdit, DbName) {
const ModelName = ModelToEdit.getModelName();
const DBSchema = DatabaseManagerSchema.getDb(DbName);
const TableSchemaClass = DBSchema.getTable(ModelName);
ModelToEdit.prototype.getTableSchema = () => {
return TableSchemaClass.config;
};
ModelToEdit.getTableSchema = () => {
return TableSchemaClass.config;
};
}
static getDBSchema(ModelToEdit, DbName) {
const ModelName = ModelToEdit.getModelName();
const DBSchema = DatabaseManagerSchema.getDb(DbName);
ModelToEdit.prototype.getDBSchema = () => {
return DBSchema.config;
};
ModelToEdit.getDBSchema = () => {
return DBSchema.config;
};
}
// static setModel(ModelToEdit: typeof Model, DbName) {
// const ModelName = ModelToEdit.getModelName()
// const DBSchema = DatabaseManagerSchema.getDb(DbName)
// const TableSchemaClass = DBSchema.getTable(ModelName)
// console.log('set model '+ ModelName)
// ModelToEdit.prototype.getModel = () => {
// const model = TableSchemaClass.getModel()
// if(!model) {
// console.log('model!!!!!!!!!!!!!', model, ModelName)
// }
// return new model()
// }
// ModelToEdit.getModel = () => {
// const model = TableSchemaClass.getModel()
// if(!model) {
// console.log('model!!!!!!!!!!!!!', model, ModelName)
// }
// return new model()
// }
// }
static addMethodOneToOneField(foreignKeyField, FieldName, modelName, databaseSchema) {
const foreignKeyFieldModel = foreignKeyField.model;
const currentModel = models[modelName];
// place
foreignKeyFieldModel['prototype'][modelName] = async function (body) {
const foreignModel = currentModel;
const TableSchema = foreignModel.getTableSchema();
const obj = {};
obj[FieldName] = this.getPrimaryKeyValue();
return await foreignModel.get(obj);
};
// restaurant
currentModel['prototype'][foreignKeyFieldModel['name']] = async function () {
const foreignModel = foreignKeyFieldModel;
let params = {};
const TableSchema = foreignModel.getTableSchema();
params[TableSchema.id.keyPath] = this[FieldName];
return await foreignModel.get(params);
};
}
static addMethodForeignKey(foreignKeyField, FieldName, modelName, databaseSchema) {
const foreignKeyFieldModel = foreignKeyField.model;
const currentModel = models[modelName];
const FunctionName = uncapitalize(modelName);
foreignKeyFieldModel['prototype'][FunctionName + '_setAll'] = async function () {
const obj = {};
obj[FieldName] = this.getPrimaryKeyValue();
const currentModel = models[modelName];
return await currentModel.filter(obj).execute();
};
foreignKeyFieldModel['prototype'][FunctionName + '_setAdd'] = async function (arg) {
const reporter = this;
arg[FieldName] = reporter;
return currentModel['create'](arg);
};
currentModel['prototype'][foreignKeyFieldModel.getModelName()] = async function () {
const TableSchema = foreignKeyFieldModel.getTableSchema();
const obj = {};
obj[TableSchema.id.keyPath] = this[FieldName];
return foreignKeyFieldModel.filter(obj).execute();
};
}
static async addMethodManyToManyField(foreignKeyField, FieldName, modelName, databaseSchema) {
const foreignKeyFieldModel = foreignKeyField.model;
FieldName = FieldName;
const currentModel = models[modelName];
const _middleTable = await registerModel.manyToManyRelationShip(foreignKeyField, FieldName, modelName, databaseSchema);
currentModel['prototype'][FieldName + '_add'] = async function (modelInstances) {
const middleTable = DatabaseManagerSchema.getDb(databaseSchema.databaseName).getTable(_middleTable.getModelName()).getModel();
if (modelInstances.constructor.name != 'Array') {
modelInstances = [modelInstances];
}
for (const modelInstance of modelInstances) {
if (modelInstance instanceof foreignKeyFieldModel) {
let params = {};
params[`iD${currentModel.getModelName()}`] = this.getPrimaryKeyValue();
params[`iD${modelInstance.getModelName()}`] = modelInstance.getPrimaryKeyValue();
await middleTable['create'](params);
}
else {
throw ('Need to be instance of ' + foreignKeyFieldModel.getModelName());
}
}
};
currentModel['prototype'][FieldName] = function () {
const middleTable = DatabaseManagerSchema.getDb(databaseSchema.databaseName).getTable(_middleTable.getModelName()).getModel();
let _model = this;
return {
async all() {
let params = {};
params[`iD${_model.getModelName()}`] = _model.getPrimaryKeyValue();
const middleTableResult = await middleTable['filter'](params).execute();
foreignKeyField.model;
return middleTableResult;
}
};
};
currentModel['prototype'][FieldName + '_all'] = async function () {
const middleTable = DatabaseManagerSchema.getDb(databaseSchema.databaseName).getTable(_middleTable.getModelName()).getModel();
let _model = this;
let params = {};
let result = [];
params[`iD${_model.getModelName()}`] = _model.getPrimaryKeyValue();
const middleTableResult = await middleTable['filter'](params).execute();
let ids;
if (middleTableResult) {
const TableSchema = foreignKeyField.model.getTableSchema();
ids = middleTableResult.map((e) => {
return e[`iD${foreignKeyField.model.name}`];
});
let params = {};
for (const id of ids) {
try {
params[TableSchema.id.keyPath] = id;
const row = await foreignKeyField.model.get(params);
result.push(row);
}
catch (error) {
}
}
}
return result;
};
foreignKeyField.model['prototype'][uncapitalize(modelName) + '_set_all'] = async function () {
let _model = this;
const middleTable = DatabaseManagerSchema.getDb(databaseSchema.databaseName).getTable(_middleTable.getModelName()).getModel();
let params = {};
let result = [];
params[`iD${_model.getModelName()}`] = _model.getPrimaryKeyValue();
const middleTableResult = await middleTable['filter'](params).execute();
let ids;
if (middleTableResult) {
const TableSchema = currentModel.getTableSchema();
ids = middleTableResult.map((e) => {
return e[`iD${modelName}`];
});
let params = {};
for (const id of ids) {
try {
params[TableSchema.id.keyPath] = id;
const row = await currentModel.get(params);
result.push(row);
}
catch (error) {
}
}
}
return result;
};
}
}
function generateGenericModel({ DBSchema, ModelName, TableSchema }) {
class GenericModel extends Model {
}
for (const [Field, value] of Object.entries(Model)) {
GenericModel[Field] = value;
}
// GenericModel.prototype = Model.prototype
GenericModel.prototype['getDBSchema'] = () => {
return DBSchema;
};
GenericModel.prototype['getModelName'] = () => {
return ModelName;
};
GenericModel.prototype['getTableSchema'] = () => {
return TableSchema;
};
// GenericModel.prototype.getModel = (): any => {
// return new GenericModel()
// }
// GenericModel.getModel = (): any => {
// return new GenericModel()
// }
GenericModel['getDBSchema'] = () => {
return DBSchema;
};
GenericModel['getModelName'] = () => {
return ModelName;
};
GenericModel['getTableSchema'] = () => {
return TableSchema;
};
return GenericModel;
}
@@ -0,0 +1,7 @@
import { DatabaseSchema as DatabaseSchemaInterface } from "../register-modal.interface.js";
import { DatabaseSchemaClass } from "./database-schema.js";
export declare class DatabaseManagerSchema {
private static databases;
static prepare(config: DatabaseSchemaInterface): Promise<void>;
static getDb(databaseName: any): DatabaseSchemaClass;
}
@@ -0,0 +1,13 @@
import { DatabaseSchemaClass } from "./database-schema.js";
export class DatabaseManagerSchema {
static async prepare(config) {
if (this.databases[config.databaseName]) {
throw ('Database name already exist. Force create');
}
this.databases[config.databaseName] = new DatabaseSchemaClass({ config });
}
static getDb(databaseName) {
return this.databases[databaseName];
}
}
DatabaseManagerSchema.databases = {};
+14
View File
@@ -0,0 +1,14 @@
import { DatabaseSchema as DatabaseSchemaInterface } from '../register-modal.interface.js';
import { TableSchemaClass } from './table-schema.js';
export declare class DatabaseSchemaClass {
name: string;
version: string;
tables: {
[storeName: string]: TableSchemaClass;
};
config: DatabaseSchemaInterface;
constructor({ config }: {
config: DatabaseSchemaInterface;
});
getTable(name: any): TableSchemaClass;
}
@@ -0,0 +1,16 @@
import { TableSchemaClass } from './table-schema.js';
export class DatabaseSchemaClass {
constructor({ config }) {
this.name = '';
this.version = '';
this.tables = {};
this.config = config;
this.name = this.config.databaseName;
for (let store of config.stores) {
this.tables[store.name] = new TableSchemaClass({ store });
}
}
getTable(name) {
return this.tables[name];
}
}
+13
View File
@@ -0,0 +1,13 @@
import { Model } from '../model.js';
import { TableSchema as FieldSchemaInterface } from '../register-modal.interface.js';
export declare class TableSchemaClass {
config: FieldSchemaInterface;
name: string;
version: string;
model: typeof Model;
constructor({ store }: {
store: FieldSchemaInterface;
});
setModel(modal: any): void;
getModel(): typeof Model;
}
@@ -0,0 +1,14 @@
export class TableSchemaClass {
constructor({ store }) {
this.name = '';
this.version = '';
this.name = store.name;
this.config = store;
}
setModel(modal) {
this.model = modal;
}
getModel() {
return this.model;
}
}
+21
View File
@@ -0,0 +1,21 @@
import { LocalStorage } from "./model.js";
import { params } from './signal.interface.js';
export declare const rewrite: {
rewriteGet: {
connect(callback: (params: params) => void, models: (typeof LocalStorage)[]): void;
};
rewriteSave: {
connect(callback: (params: params) => void, models: (typeof LocalStorage)[]): void;
};
rewriteDelete: {
connect(callback: (params: params) => void, models: (typeof LocalStorage)[]): void;
};
hasRewriteGet(ModalName: string): boolean;
hasRewriteSave(ModalName: string): boolean;
hasRewriteDelete(ModalName: string): boolean;
};
export declare const signalExecutor: {
rewriteGet(ModalName: string, instance: any): any;
rewriteSave(ModalName: string, instance: any, dataToSave: any): any;
rewriteDelete(ModalName: string, instance: any): any;
};
+7
View File
@@ -0,0 +1,7 @@
import { LocalStorage } from "./model";
export interface params {
key: string;
localStorage: typeof localStorage;
instance: typeof LocalStorage[];
dataToSave: any;
}
@@ -0,0 +1 @@
export {};
+51
View File
@@ -0,0 +1,51 @@
const signalServiceData = {
rewriteGet: {},
rewriteSave: {},
rewriteDelete: {},
};
export const rewrite = {
rewriteGet: {
connect(callback, models) {
for (let model of models) {
const modelName = model.getTableSchema().id.keyPath;
signalServiceData.rewriteGet[modelName] = callback;
}
}
},
rewriteSave: {
connect(callback, models) {
for (let model of models) {
const modelName = model.getTableSchema().id.keyPath;
signalServiceData.rewriteSave[modelName] = callback;
}
}
},
rewriteDelete: {
connect(callback, models) {
for (let model of models) {
const modelName = model.getTableSchema().id.keyPath;
signalServiceData.rewriteDelete[modelName] = callback;
}
}
},
hasRewriteGet(ModalName) {
return signalServiceData.rewriteGet[ModalName] != null;
},
hasRewriteSave(ModalName) {
return signalServiceData.rewriteSave[ModalName] != null;
},
hasRewriteDelete(ModalName) {
return signalServiceData.rewriteDelete[ModalName] != null;
}
};
export const signalExecutor = {
rewriteGet(ModalName, instance) {
return signalServiceData.rewriteGet[ModalName]({ key: ModalName, localStorage: localStorage, instance });
},
rewriteSave(ModalName, instance, dataToSave) {
return signalServiceData.rewriteSave[ModalName]({ key: ModalName, localStorage: localStorage, instance, dataToSave });
},
rewriteDelete(ModalName, instance) {
return signalServiceData.rewriteDelete[ModalName]({ key: ModalName, localStorage: localStorage, instance });
}
};
+2
View File
@@ -0,0 +1,2 @@
import { Model } from "./model.js";
export declare const split: (name: any, model: Model) => Model;
+9
View File
@@ -0,0 +1,9 @@
export const split = (name, model) => {
model['prototype']['getModelName'] = function () {
return name;
};
model['getModelName'] = function () {
return name;
};
return model;
};
+9
View File
@@ -0,0 +1,9 @@
import { Model } from "../models/model.js";
export declare class ReactiveList {
static subscribe(model: typeof Model, callback: any): {
readonly value: any;
readonly subscribe: any;
unsubscribe: () => Promise<any>;
setUpdateUi(func: any): void;
};
}
+36
View File
@@ -0,0 +1,36 @@
import { Model } from "../models/model.js";
import { transactionOnCommit } from "../triggers/transaction.js";
let values = {};
export class ReactiveList {
static subscribe(model, callback) {
let transactionOnCommitSubscription;
let value;
let updateUi;
transactionOnCommitSubscription = transactionOnCommit.subscribe(model, async () => {
value = await callback(Model);
if (updateUi) {
updateUi();
}
});
callback(Model).then(result => {
value = result;
if (updateUi) {
updateUi();
}
});
return {
get value() {
return value;
},
get subscribe() {
return transactionOnCommitSubscription.subscribe;
},
unsubscribe: async () => {
return await transactionOnCommitSubscription.unsubscribe();
},
setUpdateUi(func) {
updateUi = func;
}
};
}
}
@@ -0,0 +1,10 @@
import { TableSchema } from '../../models/register-modal.interface.js';
import { argsAttributes } from './args-attributes.js';
export declare class ObjectConditionOperator {
private TableSchema;
private args;
row: any;
constructor(TableSchema: TableSchema, args: argsAttributes);
run(row: any): boolean | any;
private execute;
}
@@ -0,0 +1,33 @@
export class ObjectConditionOperator {
constructor(TableSchema, args) {
this.TableSchema = TableSchema;
this.args = args;
}
run(row) {
this.row = row;
for (const arg of this.args.value) {
const result = this.execute(arg);
if (result) {
return true;
}
}
}
execute(objOperator) {
for (let objOperatorFieldName in objOperator) {
const field = objOperator[objOperatorFieldName];
const fieldName = field.fieldName;
const fieldPath = field.fieldPath;
const operation = field.operation;
const operationArg = field.operationArg;
const fieldClassName = field.fieldClassName;
const operator = field.operator;
const customData = field.customData({ row: this.row, fieldPath });
const arg = operationArg;
let operationResult = operator({ fieldName, arg, row: this.row, TableSchema: this.TableSchema, element: fieldName, fieldPath, customData });
if (!operationResult) {
return false;
}
}
return true;
}
}
+31
View File
@@ -0,0 +1,31 @@
import { AttributesMap, FieldKeys, FieldsMap } from "../../models/field/fields.interface.js";
import { OperatorKeys } from "./object-operator.js";
import { TableSchema, FieldSchema } from '../../models/register-modal.interface.js';
export interface Field {
fieldName: string;
fieldPath: string;
operation: OperatorKeys;
operationArg?: string;
operator: Function;
fieldClassName: FieldKeys;
customData?: Function;
}
export interface value {
fieldName: string;
fieldPath: string;
operation: any;
operationArg: any;
operator: Function;
fieldClassName: any;
customData?: Function;
}
export declare class argsAttributes {
private TableSchema;
value: Array<FieldsMap<string, Field>>;
schemeFields: AttributesMap<string, FieldSchema>;
constructor(args: any, TableSchema: TableSchema);
private analyzeArgs;
private detectClassName;
private detectOperator;
private argsPrettyTransform;
}
@@ -0,0 +1,114 @@
import { OperatorsKeysArray, operator, ObjOperatorOverwrite, ArrOperatorOverwrite } from "./object-operator.js";
import { info } from "./operators.js";
export class argsAttributes {
constructor(args, TableSchema) {
this.TableSchema = TableSchema;
this.value = [];
this.schemeFields = {} = {};
for (const field of this.TableSchema.fields) {
this.schemeFields[field.name] = field;
}
this.schemeFields[this.TableSchema.id.keyPath] = {
keyPath: this.TableSchema.id.keyPath,
name: this.TableSchema.id.keyPath,
className: 'IntegerField',
};
if (args.constructor.name != 'Array') {
args = [args];
}
const conditions = this.argsPrettyTransform(args);
this.value = this.analyzeArgs(conditions);
}
analyzeArgs(conditions) {
return conditions.map((condition) => {
const newObject = {};
const keys = Object.keys(condition);
for (let field of keys) {
let fieldName;
let fieldPath;
let arg;
const element = field.split('__');
if (element.length == 1) {
element.push('eq');
}
let operation = element[element.length - 1];
if (OperatorsKeysArray.includes(operation)) {
operation = element.pop();
}
else {
operation = 'eq';
}
fieldName = element[0];
fieldPath = element.join('.');
if (OperatorsKeysArray.includes(operation)) {
arg = condition[field];
}
else {
throw ('operator');
}
const fieldClassName = this.detectClassName(fieldName);
newObject[field] = {
fieldName: fieldName,
fieldPath: fieldPath,
operation: operation,
operationArg: arg,
operator: this.detectOperator(fieldClassName, operation, fieldName),
fieldClassName: fieldClassName,
};
if (fieldClassName == 'indexedDBArrayField' || fieldClassName == 'indexedDBJsonField') {
newObject[field]['customData'] = info.run;
}
else {
newObject[field]['customData'] = () => { };
}
}
return newObject;
});
}
detectClassName(fieldName) {
return this.schemeFields[fieldName].className;
}
detectOperator(fieldClassName, operation, fieldName) {
try {
if (fieldClassName == 'indexedDBJsonField') {
return ObjOperatorOverwrite[operation];
}
else if (fieldClassName == 'indexedDBArrayField') {
return ArrOperatorOverwrite[operation];
}
else {
return operator[operation];
}
}
catch (err) {
throw ('Field ' + fieldName + ' does not exit on the table' + err);
}
}
argsPrettyTransform(args) {
const conditions = [];
const loop = (o) => {
// https://stackoverflow.com/a/38597076/14115342
const condition = {};
for (const k of Object.keys(o)) {
if (o[k].constructor.name === 'Array') {
loop(o[k]);
}
else {
if (o.constructor.name === 'Array') {
for (const j of Object.keys(o[k])) {
condition[j] = o[k][j];
}
}
else {
condition[k] = o[k];
}
}
}
if (JSON.stringify(condition) !== '{}') {
conditions.push(condition);
}
};
loop(args);
return conditions;
}
}
+478
View File
@@ -0,0 +1,478 @@
export declare const OperatorsKeysArray: readonly ["gt", "gte", "lt", "lte", "not", "eq", "contains", "len", "hasKey", "ForeignKey", "containedBy", "overlap", "isNull", "contained_by", "has_key", "has_keys", "has_any_keys", "len", "overlap", "iexact"];
export declare type OperatorKeys = typeof OperatorsKeysArray[number];
export declare const operator: {
gt: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
gte: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
lt: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
lte: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
not: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
eq: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
contains: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => any;
len({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
hasKey({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
containedBy({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
overlap({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): any;
isNull({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
iexact({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
};
export declare const ObjOperatorOverwrite: {
gt: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
gte: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
lt: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
lte: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
not: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
eq: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
contains: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => any;
len({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
hasKey({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
containedBy({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
overlap({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): any;
isNull({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
iexact({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
} & {
isNull({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
eq: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
contains: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
contained_by: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
has_key({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
has_keys({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
has_any_keys({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
};
export declare const ArrOperatorOverwrite: {
gt: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
gte: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
lt: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
lte: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
not: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
eq: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
contains: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => any;
len({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
hasKey({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
containedBy({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
overlap({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): any;
isNull({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
iexact({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
} & {
isNull({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}): boolean;
eq: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
contains: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
contained_by: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
len: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
overlap: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
TableSchema: any;
element: any;
fieldPath: any;
customData: any;
}) => boolean;
};
@@ -0,0 +1,107 @@
import * as operatorsObject from './operators.js';
export const OperatorsKeysArray = [
'gt',
'gte',
'lt',
'lte',
'not',
'eq',
'contains',
'len',
'hasKey',
'ForeignKey',
'containedBy',
'overlap',
'isNull',
'contained_by',
'has_key',
'has_keys',
'has_any_keys',
'len',
'overlap',
'iexact'
]; // TS3.4 syntax
export const operator = {
gt: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) => {
return operatorsObject.gt.validate({ fieldName, arg, row, fieldPath, customData });
},
gte: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) => {
return operatorsObject.gte.validate({ fieldName, arg, row, fieldPath, customData });
},
lt: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) => {
return operatorsObject.lt.validate({ fieldName, arg, row, fieldPath, customData });
},
lte: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) => {
return operatorsObject.lte.validate({ fieldName, arg, row, fieldPath });
},
not: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) => {
return operatorsObject.not.validate({ fieldName, arg, row, fieldPath });
},
eq: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) => {
return operatorsObject.eq.validate({ fieldName, arg, row, fieldPath, customData });
},
contains: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) => {
return operatorsObject.contains.validate({ fieldName, arg, row, fieldPath, customData });
},
len({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) {
return operatorsObject.len.validate({ fieldName, arg, row, fieldPath, customData });
},
hasKey({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) {
return operatorsObject.hasKey.validate({ fieldName, arg, row, fieldPath, customData });
},
containedBy({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) {
return operatorsObject.containedBy.validate({ fieldName, arg, row, fieldPath, customData });
},
overlap({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) {
return operatorsObject.overlap.validate({ fieldName, arg, row, fieldPath, customData });
},
isNull({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) {
return operatorsObject.isNull.validate({ fieldName, arg, row, fieldPath, customData });
},
iexact({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) {
return operatorsObject.iexact.validate({ fieldName, arg, row, fieldPath, customData });
}
};
export const ObjOperatorOverwrite = Object.assign(Object.assign({}, operator), {
isNull({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) {
return operatorsObject.objectIsnull.validate({ fieldName, arg, row, fieldPath, customData });
},
eq: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) => {
return operatorsObject.objectEq.validate({ fieldName, arg, row, fieldPath, customData });
},
contains: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) => {
return operatorsObject.objectContains.validate({ fieldName, arg, row, fieldPath, customData });
},
contained_by: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) => {
return operatorsObject.objectContains_by.validate({ fieldName, arg, row, fieldPath, customData });
},
has_key({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) {
return operatorsObject.objectHasKey.validate({ fieldName, arg, row, fieldPath, customData });
},
has_keys({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) {
return operatorsObject.objectHasKeys.validate({ fieldName, arg, row, fieldPath, customData });
},
has_any_keys({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) {
return operatorsObject.objectHasnyKeys.validate({ fieldName, arg, row, fieldPath, customData });
}
});
export const ArrOperatorOverwrite = Object.assign(Object.assign({}, operator), {
isNull({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) {
return operatorsObject.objectIsnull.validate({ fieldName, arg, row, fieldPath, customData });
},
eq: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) => {
return operatorsObject.ArrayFieldEq.validate({ fieldName, arg, row, fieldPath, customData });
},
contains: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) => {
return operatorsObject.ArrayFieldContains.validate({ fieldName, arg, row, fieldPath, customData });
},
contained_by: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) => {
return operatorsObject.ArrayFieldContains_by.validate({ fieldName, arg, row, fieldPath, customData });
},
len: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) => {
return operatorsObject.ArrayFieldContains_len.validate({ fieldName, arg, row, fieldPath, customData });
},
overlap: ({ fieldName, arg, row, TableSchema, element, fieldPath, customData }) => {
return operatorsObject.ArrayFieldContains_overlap.validate({ fieldName, arg, row, fieldPath, customData });
}
});
+258
View File
@@ -0,0 +1,258 @@
export declare class gt {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class iexact {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class gte {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class lt {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class lte {
static validate({ fieldName, arg, row, fieldPath }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
}): boolean;
}
export declare class not {
static validate({ fieldName, arg, row, fieldPath }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
}): boolean;
}
export declare class eq {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class contains {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): any;
}
export declare class info {
static run({ row, fieldPath }: {
row: any;
fieldPath: any;
}): {
value: any;
present: any;
};
}
export declare class containsOBj {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class containedBy {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class overlap {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): any;
}
export declare class len {
static validate({ fieldName, arg, rowFieldValue, row, fieldPath, customData }: {
fieldName: any;
arg: any;
rowFieldValue?: any[];
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class hasKey {
static validate({ fieldName, arg, rowFieldValue, row, fieldPath, customData }: {
fieldName: any;
arg: any;
rowFieldValue?: any[];
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class hasAnyKeys {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): any;
}
/**
* @returns true when all of the given keys are in the data
*/
export declare class hasKeys {
static validate(fieldObj: any, keys: any, row: any): boolean;
}
export declare class isNull {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class objectIsnull {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class objectEq {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class objectContains {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class objectContains_by {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class objectHasKey {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class objectHasKeys {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class objectHasnyKeys {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class ArrayFieldEq {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class ArrayFieldContains {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class ArrayFieldContains_by {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class ArrayFieldContains_overlap {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
export declare class ArrayFieldContains_len {
static validate({ fieldName, arg, row, fieldPath, customData }: {
fieldName: any;
arg: any;
row: any;
fieldPath: any;
customData: any;
}): boolean;
}
+573
View File
@@ -0,0 +1,573 @@
import { getDeep } from '../../utils.js';
export class gt {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
return _rowFieldValue > arg;
}
}
export class iexact {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
return _rowFieldValue === arg;
}
}
export class gte {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
return _rowFieldValue >= arg;
}
}
export class lt {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
return _rowFieldValue < arg;
}
}
export class lte {
static validate({ fieldName, arg, row, fieldPath }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
return _rowFieldValue <= arg;
}
}
export class not {
static validate({ fieldName, arg, row, fieldPath }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
return _rowFieldValue != arg;
}
}
export class eq {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
return _rowFieldValue == arg;
}
}
export class contains {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
return _rowFieldValue.some(r => arg.includes(r));
}
}
export class info {
static run({ row, fieldPath }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return {
present: false,
value: undefined
};
}
}
catch (error) {
return {
present: false,
value: undefined
};
}
return {
present: true,
value: undefined
};
}
}
export class containsOBj {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
const keys = Object.keys(arg);
for (let key of keys) {
if (!_rowFieldValue[key]) {
return false;
}
}
return true;
}
}
export class containedBy {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
for (let value of _rowFieldValue) {
if (!arg.includes(value)) {
return false;
}
}
return true;
}
}
export class overlap {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
return _rowFieldValue.some(r => arg.includes(r));
}
}
export class len {
static validate({ fieldName, arg, rowFieldValue = [], row, fieldPath, customData }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
return _rowFieldValue.length == arg;
}
}
export class hasKey {
static validate({ fieldName, arg, rowFieldValue = [], row, fieldPath, customData }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
const keys = Object.keys(arg);
for (let key of keys) {
if (!_rowFieldValue[key]) {
return false;
}
}
}
}
export class hasAnyKeys {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
return _rowFieldValue.some(key => !arg.includes(key));
}
}
/**
* @returns true when all of the given keys are in the data
*/
export class hasKeys {
static validate(fieldObj, keys, row) {
for (let fieldName of keys) {
if (!fieldObj[fieldName]) {
return false;
}
}
return true;
}
}
// Slice transforms
export class isNull {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
return (_rowFieldValue == null) == arg;
}
}
// object
export class objectIsnull {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let rowFieldValue;
try {
rowFieldValue = getDeep(row, fieldPath);
if (rowFieldValue === undefined) {
if (arg == true) {
return true;
}
}
}
catch (error) {
if (arg == true) {
return true;
}
return false;
}
if (JSON.stringify(rowFieldValue) == '{}' && arg == false) {
return true;
}
else if (rowFieldValue == null && arg == true) {
return true;
}
else if (rowFieldValue == undefined) {
return true;
}
return false;
}
}
export class objectEq {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
if (JSON.stringify(_rowFieldValue = getDeep(row, fieldPath)) == '{}' && '{}' == JSON.stringify(arg)) {
return true;
}
else if (arg == null && JSON.stringify(_rowFieldValue) == '{}') {
return true;
}
else if (fieldPath) {
if (arg == _rowFieldValue) {
return true;
}
}
return false;
}
}
export class objectContains {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let rowValue;
try {
rowValue = getDeep(row, fieldPath);
if (rowValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
for (const keys of Object.keys(arg)) {
if (!rowValue[keys]) {
return false;
}
else {
if (rowValue[keys] != arg[keys]) {
return false;
}
}
}
return true;
}
}
export class objectContains_by {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let rowValue;
const keyCount = Object.keys(arg).length;
let keyFoundNEqual = 0;
try {
rowValue = getDeep(row, fieldPath);
if (rowValue === undefined) {
return false;
}
else {
for (const keys of Object.keys(arg)) {
if (rowValue[keys]) {
if (rowValue[keys] == arg[keys]) {
keyFoundNEqual++;
}
}
}
}
}
catch (error) {
return false;
}
if (keyFoundNEqual == 0) {
return true;
}
else if (keyFoundNEqual == keyCount) {
return true;
}
return false;
}
}
export class objectHasKey {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let rowValue;
try {
rowValue = getDeep(row, fieldPath);
if (rowValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
if (rowValue[arg]) {
return true;
}
return false;
}
}
export class objectHasKeys {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let rowValue;
try {
rowValue = getDeep(row, fieldPath);
if (rowValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
const keys = Object.keys(rowValue);
for (const a of arg) {
if (!keys.includes(a)) {
return false;
}
}
return true;
}
}
export class objectHasnyKeys {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let rowValue;
try {
rowValue = getDeep(row, fieldPath);
if (rowValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
const keys = Object.keys(rowValue);
for (const a of arg) {
if (keys.includes(a)) {
return true;
}
}
return false;
}
}
// array shit
export class ArrayFieldEq {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let _rowFieldValue;
try {
_rowFieldValue = getDeep(row, fieldPath);
if (_rowFieldValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
if (JSON.stringify(_rowFieldValue) == '[]' && '[]' == JSON.stringify(arg)) {
return true;
}
else if (arg == null && JSON.stringify(_rowFieldValue) == '[]') {
return true;
}
else if (fieldPath) {
if (arg == _rowFieldValue) {
return true;
}
}
return false;
}
}
export class ArrayFieldContains {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let rowValue;
try {
rowValue = getDeep(row, fieldPath);
if (rowValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
try {
for (const keys of arg) {
if (!rowValue.includes(keys)) {
return false;
}
}
}
catch (error) {
return false;
}
return true;
}
}
export class ArrayFieldContains_by {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let rowValue;
try {
rowValue = getDeep(row, fieldPath);
if (rowValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
try {
for (const keys of arg) {
if (rowValue.includes(keys)) {
return true;
}
}
}
catch (error) {
return false;
}
return false;
}
}
export class ArrayFieldContains_overlap {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let rowValue;
try {
rowValue = getDeep(row, fieldPath);
if (rowValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
try {
for (const keys of arg) {
if (rowValue.includes(keys)) {
return true;
}
}
}
catch (error) {
return false;
}
return false;
}
}
export class ArrayFieldContains_len {
static validate({ fieldName, arg, row, fieldPath, customData }) {
let rowValue;
try {
rowValue = getDeep(row, fieldPath);
if (rowValue === undefined) {
return false;
}
}
catch (error) {
return false;
}
if (rowValue.length == arg) {
return true;
}
return false;
}
}
View File
+11
View File
@@ -0,0 +1,11 @@
import { ObjectConditionOperator } from '../Operators/Object-condition-operator.js';
import { argsAttributes } from '../Operators/args-attributes.js';
export declare class filter {
private arg;
private TableSchema;
rows: any[];
operator: ObjectConditionOperator;
constructor(arg: argsAttributes, TableSchema: any);
cursor(row: object, resolve?: any, limit?: any): Promise<void>;
run(rows: any[]): Promise<any[]>;
}
+28
View File
@@ -0,0 +1,28 @@
import { ObjectConditionOperator } from '../Operators/Object-condition-operator.js';
export class filter {
constructor(arg, TableSchema) {
this.arg = arg;
this.TableSchema = TableSchema;
this.rows = [];
this.operator = new ObjectConditionOperator(this.TableSchema, this.arg);
}
async cursor(row, resolve, limit) {
const operationsResult = await this.operator.run(row);
if (operationsResult == true) {
this.rows.push(row);
if (this.rows.length == limit) {
resolve(this.rows);
}
}
}
async run(rows) {
const newRows = [];
for (let row of rows) {
const operationsResult = await this.operator.run(row);
if (operationsResult == true) {
newRows.push(row);
}
}
return newRows;
}
}
+14
View File
@@ -0,0 +1,14 @@
export declare const methodsType: readonly ["filter"];
export declare type methodsTypeKeys = typeof methodsType[number];
export declare type methodsMap<K extends string | number | symbol, T> = {
[P in K]?: T;
};
export declare class methodFunction {
private arg;
private TableSchema;
rows: any[];
constructor(arg: any, TableSchema: any);
cursor(row: object, resolve?: any, limit?: any): Promise<void>;
run(rows: any[]): Promise<any[]>;
}
export declare const methods: methodsMap<methodsTypeKeys, methodFunction>;
+7
View File
@@ -0,0 +1,7 @@
import { filter } from './filter.js';
export const methodsType = [
'filter',
]; // TS3.4 syntax
export const methods = {
filter: filter
};
+12
View File
@@ -0,0 +1,12 @@
export declare enum FieldType {
AUTO = 0,
INT = 1,
BIGINT = 2,
TEXT = 3,
VARCHAR = 4,
DATE = 5,
BOOL = 6,
CHAR = 7,
JSON = 8,
ARRAY = 9
}
+14
View File
@@ -0,0 +1,14 @@
export var FieldType;
(function (FieldType) {
FieldType[FieldType["AUTO"] = 0] = "AUTO";
FieldType[FieldType["INT"] = 1] = "INT";
FieldType[FieldType["BIGINT"] = 2] = "BIGINT";
FieldType[FieldType["TEXT"] = 3] = "TEXT";
FieldType[FieldType["VARCHAR"] = 4] = "VARCHAR";
FieldType[FieldType["DATE"] = 5] = "DATE";
FieldType[FieldType["BOOL"] = 6] = "BOOL";
FieldType[FieldType["CHAR"] = 7] = "CHAR";
FieldType[FieldType["JSON"] = 8] = "JSON";
FieldType[FieldType["ARRAY"] = 9] = "ARRAY";
})(FieldType || (FieldType = {}));
//
+3
View File
@@ -0,0 +1,3 @@
declare class sql {
filter(): void;
}
+3
View File
@@ -0,0 +1,3 @@
class sql {
filter() { }
}
+17
View File
@@ -0,0 +1,17 @@
import { Method } from '../../models/model.interface.js';
import { TableSchema } from '../../models/register-modal.interface.js';
import { methodFunction } from '../methods/methods.js';
import { argsAttributes } from '../Operators/args-attributes.js';
export declare class SqlObject {
private TableSchema;
private Methods;
limit: number;
rows: any[];
firstMethod: methodFunction;
params: any[];
argsAttributes: argsAttributes;
constructor(TableSchema: TableSchema, Methods: Method[]);
runFirstMethod(row: any, resolve?: any, limit?: any): Promise<void>;
doneRunFirstMethod(): Promise<void>;
run(): Promise<void>;
}
+31
View File
@@ -0,0 +1,31 @@
import { methods } from '../methods/methods.js';
import { argsAttributes } from '../Operators/args-attributes.js';
export class SqlObject {
constructor(TableSchema, Methods) {
this.TableSchema = TableSchema;
this.Methods = Methods;
this.limit = 0;
this.rows = [];
this.params = [];
const arg = this.Methods[0].arguments;
const methodName = this.Methods[0].methodName;
this.argsAttributes = new argsAttributes(arg, TableSchema);
this.firstMethod = new methods[methodName](this.argsAttributes, this.TableSchema);
}
async runFirstMethod(row, resolve, limit) {
this.firstMethod.cursor(row, resolve, limit);
}
async doneRunFirstMethod() {
this.rows = this.firstMethod.rows;
}
async run() {
for (let i = 1; i < this.Methods.length; i++) {
const method = this.Methods[i];
const methodName = method.methodName;
if (methods[methodName]) {
const methodToExecute = new methods[methodName](this.argsAttributes, this.TableSchema);
this.rows = await methodToExecute.run(this.rows);
}
}
}
}
+19
View File
@@ -0,0 +1,19 @@
import { Model } from "../models/model.js";
export declare class transactionOnCommit {
static stores: {
[dbName: string]: {
[store: string]: {
[requestId: string]: Function;
};
};
};
static subscription: {
[SubscriptionName: string]: boolean;
};
static prepare(model: typeof Model): void;
static subscribe(model: typeof Model, callback: any): {
queryId: string;
subscribe: boolean;
unsubscribe: () => Promise<unknown>;
};
}
+59
View File
@@ -0,0 +1,59 @@
import { taskHolder } from "../connection/taskHolder.js";
import { ModelAPIRequest } from "../models/model-manager.js";
import { uniqueGenerator } from "../utils.js";
export class transactionOnCommit {
static prepare(model) {
const TableSchema = model.getTableSchema();
const DatabaseSchema = model.getDBSchema();
const databaseName = DatabaseSchema.databaseName;
const table = TableSchema.name;
this.stores[databaseName] = {};
this.stores[databaseName][table] = {};
}
static subscribe(model, callback) {
const TableSchema = model.getTableSchema();
const DatabaseSchema = model.getDBSchema();
const databaseName = DatabaseSchema.databaseName;
const table = TableSchema.name;
const SubscriptionName = databaseName + table;
const queryId = uniqueGenerator();
let subscribe = false;
this.stores[databaseName][table][queryId] = callback;
if (!this.subscription[SubscriptionName]) {
//
const args = {
type: 'transactionOnCommit',
subscribe: true
};
ModelAPIRequest.obj(DatabaseSchema, TableSchema).trigger(args, SubscriptionName, async () => {
subscribe = true;
taskHolder.updateFunction(SubscriptionName, 'callback', () => {
for (const [requestId, callback] of Object.entries(this.stores[databaseName][table])) {
callback();
}
});
});
}
return {
queryId,
subscribe,
unsubscribe: () => {
return new Promise((resolve, reject) => {
delete this.stores[databaseName][table][queryId];
if (Object.keys(this.stores[databaseName][table]).length == 0) {
ModelAPIRequest.obj(DatabaseSchema, TableSchema).trigger({ type: 'transactionOnCommit', subscribe: false }, SubscriptionName, async (data) => {
delete this.subscription[SubscriptionName];
taskHolder.finish(SubscriptionName);
resolve(data);
});
}
else {
resolve(true);
}
});
}
};
}
}
transactionOnCommit.stores = {};
transactionOnCommit.subscription = {};
+36
View File
@@ -0,0 +1,36 @@
import { Model } from "../models/model.js";
interface Trigger {
callback: Function;
}
export declare class triggers {
static beforeInsert(Model: Model, callback: Function): {
SubscriptionName: string;
disconnect(): void;
};
static AfterInsert(Model: any, callback: Function): {
dispatchUID: string;
disconnect(): void;
};
static beforeDelete(Model: any, callback: Function): {
dispatchUID: string;
disconnect(): void;
};
static AfterDelete(Model: any, callback: Function): {
dispatchUID: string;
disconnect(): void;
};
}
export declare class triggerSignal {
static beforeInsertExist(Model: any): Trigger[];
static beforeInsert(instance: Model): Promise<void>;
static AfterInsertExist(Model: any): Trigger[];
static AfterInsert(instance: Model): Promise<void>;
static AfterDeleteExist(Model: any): Trigger[];
static AfterDelete(instance: Model | string, { modelName, databaseName }: any): Promise<void>;
static BeforeDeleteExist(Model: any): Trigger[];
static BeforeDelete(instance: Model | string, { modelName, databaseName }: {
modelName: any;
databaseName: any;
}): Promise<void>;
}
export {};
+152
View File
@@ -0,0 +1,152 @@
import { ModelAPIRequest } from "../models/model-manager.js";
import { hashCode, uniqueGenerator } from "../utils.js";
let triggerBeforeInsert = {};
let triggerAfterInsert = {};
let triggerBeforeDelete = {};
let triggerAfterDelete = {};
function createModelAttributeBefore(Model, triggerType) {
const ModelName = Model.getModelName();
const databaseName = Model.getDBSchema().databaseName;
if (!triggerBeforeInsert[databaseName]) {
triggerBeforeInsert[databaseName] = {};
}
if (!triggerBeforeInsert[databaseName][ModelName]) {
triggerBeforeInsert[databaseName][ModelName] = [];
}
return { ModelName, databaseName };
}
function createModelAttributeAfter(Model, triggerType) {
const ModelName = Model.getModelName();
const databaseName = Model.getDBSchema().databaseName;
if (!triggerAfterInsert[databaseName]) {
triggerAfterInsert[databaseName] = {};
}
if (!triggerAfterInsert[databaseName][ModelName]) {
triggerAfterInsert[databaseName][ModelName] = [];
}
return { ModelName, databaseName };
}
function deleteModelAttributeBeforeDelete(Model, triggerType) {
const ModelName = Model.getModelName();
const databaseName = Model.getDBSchema().databaseName;
if (!triggerBeforeDelete[databaseName]) {
triggerBeforeDelete[databaseName] = {};
}
if (!triggerBeforeDelete[databaseName][ModelName]) {
triggerBeforeDelete[databaseName][ModelName] = [];
}
return { ModelName, databaseName };
}
function deleteModelAttributeAfterDelete(Model, triggerType) {
const ModelName = Model.getModelName();
const databaseName = Model.getDBSchema().databaseName;
if (!triggerAfterDelete[databaseName]) {
triggerAfterDelete[databaseName] = {};
}
if (!triggerAfterDelete[databaseName][ModelName]) {
triggerAfterDelete[databaseName][ModelName] = [];
}
return { ModelName, databaseName };
}
export class triggers {
static beforeInsert(Model, callback) {
const SubscriptionName = Model.getDBSchema().databaseName + Model.getTableSchema().name + 'beforeInsert';
const Subscription = hashCode(SubscriptionName).toString();
const { ModelName, databaseName } = createModelAttributeBefore(Model);
triggerBeforeInsert[databaseName][ModelName].push({ callback });
const functionId = uniqueGenerator();
const args = {};
const eventHandler = () => {
};
ModelAPIRequest.obj(Model.getDBSchema(), Model.getTableSchema()).trigger(args, Subscription, eventHandler);
return {
SubscriptionName: SubscriptionName,
disconnect() {
delete triggerBeforeInsert[databaseName][ModelName];
}
};
}
static AfterInsert(Model, callback) {
const id = uniqueGenerator();
const { ModelName, databaseName } = createModelAttributeAfter(Model);
triggerAfterInsert[databaseName][ModelName].push({ callback });
return {
dispatchUID: id,
disconnect() {
delete triggerBeforeInsert[databaseName][ModelName];
}
};
}
static beforeDelete(Model, callback) {
const id = uniqueGenerator();
const { ModelName, databaseName } = deleteModelAttributeBeforeDelete(Model);
triggerBeforeDelete[databaseName][ModelName].push({ callback });
return {
dispatchUID: id,
disconnect() {
delete triggerBeforeDelete[databaseName][ModelName];
}
};
}
static AfterDelete(Model, callback) {
const id = uniqueGenerator();
const { ModelName, databaseName } = deleteModelAttributeAfterDelete(Model);
triggerAfterDelete[databaseName][ModelName].push({ callback });
return {
dispatchUID: id,
disconnect() {
delete triggerAfterDelete[databaseName][ModelName];
}
};
}
}
export class triggerSignal {
static beforeInsertExist(Model) {
var _a;
const ModelName = Model.getModelName();
const databaseName = Model.getDBSchema().databaseName;
return (_a = triggerBeforeInsert === null || triggerBeforeInsert === void 0 ? void 0 : triggerBeforeInsert[databaseName]) === null || _a === void 0 ? void 0 : _a[ModelName];
}
static async beforeInsert(instance) {
const ModelName = instance.getModelName();
const databaseName = instance.getDBSchema().databaseName;
for (const trigger of triggerBeforeInsert[databaseName][ModelName]) {
trigger.callback(instance);
}
}
static AfterInsertExist(Model) {
var _a;
const ModelName = Model.getModelName();
const databaseName = Model.getDBSchema().databaseName;
return (_a = triggerAfterInsert === null || triggerAfterInsert === void 0 ? void 0 : triggerAfterInsert[databaseName]) === null || _a === void 0 ? void 0 : _a[ModelName];
}
static async AfterInsert(instance) {
const ModelName = instance.getModelName();
const databaseName = instance.getDBSchema().databaseName;
for (const trigger of triggerAfterInsert[databaseName][ModelName]) {
trigger.callback(instance);
}
}
static AfterDeleteExist(Model) {
var _a;
const ModelName = Model.getModelName();
const databaseName = Model.getDBSchema().databaseName;
return (_a = triggerAfterDelete === null || triggerAfterDelete === void 0 ? void 0 : triggerAfterDelete[databaseName]) === null || _a === void 0 ? void 0 : _a[ModelName];
}
static async AfterDelete(instance, { modelName, databaseName }) {
for (const trigger of triggerAfterDelete[databaseName][modelName]) {
trigger.callback(instance);
}
}
static BeforeDeleteExist(Model) {
var _a;
const ModelName = Model.getModelName();
const databaseName = Model.getDBSchema().databaseName;
return (_a = triggerBeforeDelete === null || triggerBeforeDelete === void 0 ? void 0 : triggerBeforeDelete[databaseName]) === null || _a === void 0 ? void 0 : _a[ModelName];
}
static async BeforeDelete(instance, { modelName, databaseName }) {
for (const trigger of triggerBeforeDelete[databaseName][modelName]) {
trigger.callback(instance);
}
}
}
File diff suppressed because one or more lines are too long
+7
View File
@@ -0,0 +1,7 @@
export declare function uniqueGenerator(): string;
export declare function hashCode(str: string): number;
export declare function getDeep(obj: any, path: any): any;
/** First Character uppercase */
export declare function capitalize(str: any): any;
/** First Character lowercase */
export declare function uncapitalize(str: any): any;
+34
View File
@@ -0,0 +1,34 @@
// generate unique string
export function uniqueGenerator() {
return (Math.random() + 'uuid' + new Date().getTime()).slice(2);
}
export function hashCode(str) {
var hash = 0;
for (var i = 0; i < str.length; i++) {
var char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash;
}
return hash;
}
export function getDeep(obj, path) {
try {
for (var i = 0, path = path.split('.'), len = path.length; i < len; i++) {
obj = obj[path[i]];
}
;
return obj;
}
catch (error) {
return undefined;
}
}
;
/** First Character uppercase */
export function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
/** First Character lowercase */
export function uncapitalize(str) {
return str.charAt(0).toLowerCase() + str.slice(1);
}