@egi/smart-db 2.5.8 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,42 +1,31 @@
1
1
  import BetterSqlite3 from "better-sqlite3";
2
2
  import { AbstractModel } from "../models/abstract-model";
3
3
  import { SmartDb } from "../smart-db";
4
- import { GenericModelData, SmartDbConnector, SmartDbRunResult, SmartDbTableInfo } from "../smart-db-interfaces";
4
+ import { GenericModelData, SmartDbRunResult, SmartDbTableInfo } from "../smart-db-interfaces";
5
5
  import { SmartDbSqlBuildData } from "../smart-db-sql-build-data";
6
6
  declare type VariableArgFunction = (...params: any[]) => any;
7
7
  export declare class SmartDbBetterSqlite3 extends SmartDb {
8
8
  protected db: BetterSqlite3.Database;
9
9
  constructor(connectorOrDb: string | BetterSqlite3.Database, options?: BetterSqlite3.Options);
10
+ aggregate(name: string, options: BetterSqlite3.AggregateOptions): boolean;
11
+ backup(destinationFile: string, options?: BetterSqlite3.BackupOptions): Promise<BetterSqlite3.BackupMetadata>;
12
+ close(): Promise<boolean>;
10
13
  commitSync(): void;
11
- rollbackSync(): void;
12
- commit(): Promise<void>;
13
- rollback(): Promise<void>;
14
+ defaultSafeIntegers(toggleState?: boolean): boolean;
15
+ execSync(script: string): boolean;
16
+ existsSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): boolean;
17
+ func(name: string, options: BetterSqlite3.RegistrationOptions, cb: VariableArgFunction): boolean;
14
18
  getDatabaseType(): string;
15
- getDbQuote(): string;
16
- getDbConnector(): string | SmartDbConnector;
17
- hasConcurrentTransactions(): boolean;
18
- supportAsyncCalls(): boolean;
19
- supportSyncCalls(): boolean;
19
+ getTableInfo(tableName: string): Promise<SmartDbTableInfo>;
20
20
  hasTransaction(): boolean;
21
- exists<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): Promise<boolean>;
22
- existsSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): boolean;
23
- exec(script: string): Promise<any>;
24
- execSync(script: string): BetterSqlite3.Database | false;
25
- transaction<F extends VariableArgFunction>(fn: F): BetterSqlite3.Transaction | false;
21
+ loadExtension(path: string): boolean;
26
22
  pragma(source: string, options?: BetterSqlite3.PragmaOptions): unknown;
27
- func(name: string, options: BetterSqlite3.RegistrationOptions, cb: VariableArgFunction): BetterSqlite3.Database | false;
28
- aggregate(name: string, options: BetterSqlite3.AggregateOptions): BetterSqlite3.Database | false;
29
- loadExtension(path: string): BetterSqlite3.Database | false;
30
- closeSync(): boolean;
31
- defaultSafeIntegers(toggleState?: boolean): BetterSqlite3.Database | false;
32
- backup(destinationFile: string, options?: BetterSqlite3.BackupOptions): Promise<BetterSqlite3.BackupMetadata> | false;
33
- getTableInfo(tableName: string): Promise<SmartDbTableInfo>;
23
+ rollbackSync(): void;
24
+ transaction<F extends VariableArgFunction>(fn: F): boolean;
34
25
  protected statementRun(buildData: SmartDbSqlBuildData, retry?: number): Promise<SmartDbRunResult>;
35
26
  protected statementRunSync(buildData: SmartDbSqlBuildData): SmartDbRunResult;
36
- protected statementGet(buildData: SmartDbSqlBuildData): Promise<any>;
37
27
  protected statementGetSync(buildData: SmartDbSqlBuildData): any;
38
- protected statementGetAll(buildData: SmartDbSqlBuildData): Promise<any[]>;
39
28
  protected statementGetAllSync(buildData: SmartDbSqlBuildData): any[];
40
- close(): Promise<void>;
29
+ get supportSyncCalls(): boolean;
41
30
  }
42
31
  export {};
@@ -1 +1 @@
1
- import BetterSqlite3 from"better-sqlite3";import _ from"lodash";import{SqliteMasterModel}from"../models/sqlite-master-model";import{SmartDb}from"../smart-db";export class SmartDbBetterSqlite3 extends SmartDb{constructor(t,e){_.isString(t)?(super(t),this.db=new BetterSqlite3(t,e)):(super(null),this.db=t,this.db.inTransaction),this.isReady=!0}commitSync(){this.db.inTransaction&&this.db.exec("commit")}rollbackSync(){this.db.inTransaction&&this.db.exec("rollback")}commit(){return new Promise(((t,e)=>{try{this.commitSync(),t()}catch(t){e(t)}}))}rollback(){return new Promise(((t,e)=>{try{this.rollbackSync(),t()}catch(t){e(t)}}))}getDatabaseType(){return"sqlite3"}getDbQuote(){return'"'}getDbConnector(){return this.dbConnector}hasConcurrentTransactions(){return!1}supportAsyncCalls(){return!0}supportSyncCalls(){return!0}hasTransaction(){return this.db.inTransaction}exists(t,e,s){return new Promise(((r,n)=>{try{r(this.existsSync(t,e,s))}catch(t){n(t)}}))}existsSync(t,e,s){let r=!1;const n=_.isString(t)?t:t.getTableName(),a=this.getFirstSync(SqliteMasterModel,{name:n,type:e,tblName:s});if(!1===a)throw this.getLastError();return r=!!a,r}exec(t){return new Promise(((e,s)=>{const r=this.execSync(t);!1===r?s("unable to execute script"):e(r)}))}execSync(t){return this.saveExecute((()=>this.db.exec(t)))}transaction(t){return this.saveExecute((()=>this.db.transaction(t)))}pragma(t,e){return this.saveExecute((()=>this.db.pragma(t,e)))}func(t,e,s){return this.saveExecute((()=>{let r;return r=_.isFunction(e)?this.db.function(t,e):this.db.function(t,e,s),r}))}aggregate(t,e){return this.saveExecute((()=>this.db.aggregate(t,e)))}loadExtension(t){return this.saveExecute((()=>this.db.loadExtension(t)))}closeSync(){return this.saveExecute((()=>(this.smartDbLog.setDb(null),!!this.db.close())))}defaultSafeIntegers(t){return this.saveExecute((()=>this.db.defaultSafeIntegers(t)))}backup(t,e){return this.saveExecute((()=>this.db.backup(t,e)))}getTableInfo(t){return new Promise((e=>{const s=this.pragma(`table_info(${t})`);let r=[];s&&(r=s.map((t=>({cid:t.cid,name:t.name,type:t.type,notNull:0!==t.notnull,defaultValue:t.dflt_value,isPk:0!==t.pk}))),e({name:t,fields:r}))}))}statementRun(t,e=0){return new Promise(((s,r)=>{try{s(this.statementRunSync(t))}catch(n){"SQLITE_BUSY"==n.code&&e<10?setTimeout((()=>{this.statementRun(t,e+1).then((t=>{s(t)})).catch((t=>{r(t)}))}),100):r(n)}}))}statementRunSync(t){const e=this.db.prepare(t.sql),s=e&&e.run(t.values);return s&&{changes:s.changes,affected:s.changes,lastId:s.lastInsertRowid}}statementGet(t){return new Promise(((e,s)=>{try{e(this.db.prepare(t.sql).get(t.values))}catch(t){s(t)}}))}statementGetSync(t){const e=this.db.prepare(t.sql);return e&&e.get(t.values)}statementGetAll(t){return new Promise(((e,s)=>{try{e(this.db.prepare(t.sql).all(t.values))}catch(t){s(t)}}))}statementGetAllSync(t){const e=this.db.prepare(t.sql);return e&&e.all(t.values)}close(){return new Promise(((t,e)=>{try{this.smartDbLog.setDb(null),this.db.close(),t()}catch(t){e(t)}}))}}
1
+ import BetterSqlite3 from"better-sqlite3";import _ from"lodash";import{SqliteMasterModel}from"../models/sqlite-master-model";import{SmartDb}from"../smart-db";export class SmartDbBetterSqlite3 extends SmartDb{constructor(t,e){_.isString(t)?(super(t),this.db=new BetterSqlite3(t,e)):(super(null),this.db=t,this.db.inTransaction),this.isReady=!0}aggregate(t,e){return!!this.saveExecute((()=>this.db.aggregate(t,e)))}backup(t,e){return new Promise(((s,r)=>{const n=this.saveExecute((()=>this.db.backup(t,e)));0==n?r(this.getLastError()):s(n)}))}close(){return new Promise(((t,e)=>{try{this.smartDbLog.setDb(null),t(!!this.db.close())}catch(t){this.lastError=t,e(t)}}))}commitSync(){this.db.inTransaction&&this.db.exec("commit")}defaultSafeIntegers(t){return!!this.saveExecute((()=>this.db.defaultSafeIntegers(t)))}execSync(t){return!!this.saveExecute((()=>this.db.exec(t)))}existsSync(t,e,s){let r=!1;const n=_.isString(t)?t:t.getTableName(),a=this.getFirstSync(SqliteMasterModel,{name:n,type:e,tblName:s});if(!1===a)throw this.getLastError();return r=!!a,r}func(t,e,s){return this.saveExecute((()=>{let r;return r=_.isFunction(e)?this.db.function(t,e):this.db.function(t,e,s),r}))}getDatabaseType(){return"sqlite3"}getTableInfo(t){return new Promise((e=>{const s=this.pragma(`table_info(${t})`);let r=[];s&&(r=s.map((t=>({cid:t.cid,name:t.name,type:t.type,notNull:0!==t.notnull,defaultValue:t.dflt_value,isPk:0!==t.pk}))),e({name:t,fields:r}))}))}hasTransaction(){return this.db.inTransaction}loadExtension(t){return!!this.saveExecute((()=>this.db.loadExtension(t)))}pragma(t,e){return this.saveExecute((()=>this.db.pragma(t,e)))}rollbackSync(){this.db.inTransaction&&this.db.exec("rollback")}transaction(t){return!!this.saveExecute((()=>this.db.transaction(t)))}statementRun(t,e=0){return new Promise(((s,r)=>{try{s(this.statementRunSync(t))}catch(n){"SQLITE_BUSY"==n.code&&e<10?setTimeout((()=>{this.statementRun(t,e+1).then((t=>{s(t)})).catch((t=>{r(t)}))}),100):(this.lastError=n,r(n))}}))}statementRunSync(t){const e=this.db.prepare(t.sql),s=e&&e.run(t.values);return s&&{changes:s.changes,affected:s.changes,lastId:s.lastInsertRowid}}statementGetSync(t){const e=this.db.prepare(t.sql);return e&&e.get(t.values)}statementGetAllSync(t){const e=this.db.prepare(t.sql);return e&&e.all(t.values)}get supportSyncCalls(){return!0}}
@@ -6,28 +6,15 @@ import { SmartDbSqlBuildData } from "../smart-db-sql-build-data";
6
6
  export declare class SmartDbMysql extends SmartDb {
7
7
  protected db: Mysql.Connection;
8
8
  constructor(connectorOrDb: string | ConnectionConfig | Connection);
9
+ close(): Promise<boolean>;
10
+ commit(): Promise<void>;
11
+ exec(script: string): Promise<void>;
12
+ exists<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): Promise<boolean>;
9
13
  getDatabaseType(): string;
10
- getDbConnector(): string | Mysql.ConnectionConfig;
11
14
  getDbQuote(): string;
12
- hasConcurrentTransactions(): boolean;
13
- supportSyncCalls(): boolean;
14
- supportAsyncCalls(): boolean;
15
- hasTransaction(): boolean;
16
- closeSync(): boolean;
17
- commit(): Promise<void>;
15
+ getTableInfo(tableName: string): Promise<SmartDbTableInfo>;
18
16
  rollback(): Promise<void>;
19
- commitSync(): void;
20
- rollbackSync(): void;
21
- exists<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): Promise<boolean>;
22
- existsSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): boolean;
23
- exec(script: string): Promise<void>;
24
- execSync(script: string): boolean;
25
- getTableInfo(table: string): Promise<SmartDbTableInfo>;
26
- protected statementGet(buildData: SmartDbSqlBuildData): Promise<any>;
27
- protected statementGetSync(buildData: SmartDbSqlBuildData): any;
28
- protected statementGetAll(buildData: SmartDbSqlBuildData): Promise<any[]>;
29
- protected statementGetAllSync(buildData: SmartDbSqlBuildData): any[];
30
17
  protected statementRun(buildData: SmartDbSqlBuildData): Promise<SmartDbRunResult>;
31
- protected statementRunSync(buildData: SmartDbSqlBuildData): SmartDbRunResult;
32
- close(): Promise<void>;
18
+ protected statementGet<T extends object>(buildData: SmartDbSqlBuildData): Promise<T>;
19
+ protected statementGetAll<T>(buildData: SmartDbSqlBuildData): Promise<T[]>;
33
20
  }
@@ -1 +1 @@
1
- import _ from"lodash";import Mysql from"mysql";import{SmartDb}from"../smart-db";export class SmartDbMysql extends SmartDb{constructor(e){e.config&&e.connect?(super(e.config),this.db=e):(super(e),this.db=Mysql.createConnection(e))}getDatabaseType(){return"mysql"}getDbConnector(){return this.dbConnector}getDbQuote(){return"`"}hasConcurrentTransactions(){return!0}supportSyncCalls(){return!1}supportAsyncCalls(){return!0}hasTransaction(){throw new Error("Method not implemented.")}closeSync(){throw new Error("Method not implemented.")}commit(){return new Promise(((e,t)=>{this.db.commit((r=>{r?t(r):e()}))}))}rollback(){return new Promise(((e,t)=>{this.db.rollback((r=>{r?t(r):e()}))}))}commitSync(){throw new Error("Method not implemented.")}rollbackSync(){throw new Error("Method not implemented.")}exists(e,t,r){return new Promise(((t,r)=>{const n=_.isString(e)?e:e.getTableName();this.db.query(`show tables like '${n}'`,((e,n,o)=>{e?r(e):t(n&&n.length>0)}))}))}existsSync(e,t,r){throw new Error("Method not implemented.")}exec(e){return new Promise(((t,r)=>{try{this.db.query(e,((e,n,o)=>{e?r(e):t()}))}catch(e){r(e)}}))}execSync(e){throw new Error("Method not implemented.")}getTableInfo(e){return new Promise(((e,t)=>{}))}statementGet(e){return new Promise(((t,r)=>{try{this.db.query(e.sql,e.values,((e,n,o)=>{e?r(e):t(n&&n[0])}))}catch(e){r(e)}}))}statementGetSync(e){throw new Error("Method not implemented.")}statementGetAll(e){return new Promise(((t,r)=>{this.db.query(e.sql,e.values,((e,n,o)=>{e?r(e):(console.log(o),t(n&&n))}))}))}statementGetAllSync(e){throw new Error("Method not implemented.")}statementRun(e){return new Promise(((t,r)=>{this.db.query(e.sql,e.values,((e,n,o)=>{if(e)r(e);else{const e={changes:n.changedRows,affected:n.affectedRows,lastId:n.insertId};t(e)}}))}))}statementRunSync(e){throw new Error("Method not implemented.")}close(){return new Promise(((e,t)=>{this.db.end((r=>{r?t(r):e()}))}))}}
1
+ import _ from"lodash";import Mysql from"mysql";import{SmartDb}from"../smart-db";export class SmartDbMysql extends SmartDb{constructor(t){t.config&&t.connect?(super(t.config),this.db=t):(super(t),this.db=Mysql.createConnection(t))}close(){return new Promise((t=>{this.db.end((r=>{r?(this.lastError=r,t(!1)):t(!0)}))}))}commit(){return new Promise(((t,r)=>{this.db.commit((e=>{e?(this.lastError=e,r(e)):t()}))}))}exec(t){return new Promise(((r,e)=>{try{this.db.query(t,((t,s,o)=>{t?(this.lastError=t,e(t)):r()}))}catch(t){this.lastError=t,e(t)}}))}exists(t,r,e){return new Promise(((r,e)=>{const s=_.isString(t)?t:t.getTableName();this.db.query(`show tables like '${s}'`,((t,s,o)=>{t?(this.lastError=t,e(t)):r(s&&s.length>0)}))}))}getDatabaseType(){return"mysql"}getDbQuote(){return"`"}getTableInfo(t){throw new Error("Method not implemented (getTableInfo)")}rollback(){return new Promise(((t,r)=>{this.db.rollback((e=>{e?(this.lastError=e,r(e)):t()}))}))}statementRun(t){return new Promise(((r,e)=>{this.db.query(t.sql,t.values,((t,s,o)=>{if(t)this.lastError=t,e(t);else{const t={changes:s.changedRows,affected:s.affectedRows,lastId:s.insertId};r(t)}}))}))}statementGet(t){return new Promise(((r,e)=>{try{this.db.query(t.sql,t.values,((t,s,o)=>{t?(this.lastError=t,e(t)):r(s&&s[0])}))}catch(t){this.lastError=t,e(t)}}))}statementGetAll(t){return new Promise(((r,e)=>{this.db.query(t.sql,t.values,((t,s,o)=>{t?(this.lastError=t,e(t)):r(s&&s)}))}))}}
@@ -6,28 +6,15 @@ import { SmartDbSqlBuildData } from "../smart-db-sql-build-data";
6
6
  export declare class SmartDbMysql2 extends SmartDb {
7
7
  protected db: Mysql.Connection;
8
8
  constructor(connectorOrDb: string | ConnectionConfig | Connection);
9
+ close(): Promise<boolean>;
9
10
  commit(): Promise<void>;
10
- rollback(): Promise<void>;
11
- commitSync(): void;
12
- rollbackSync(): void;
11
+ exec(script: string): Promise<void>;
12
+ exists<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): Promise<boolean>;
13
13
  getDatabaseType(): string;
14
- getDbConnector(): string | Mysql.ConnectionConfig;
15
14
  getDbQuote(): string;
16
- hasConcurrentTransactions(): boolean;
17
- closeSync(): boolean;
18
- hasTransaction(): boolean;
19
- exists<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): Promise<boolean>;
20
- existsSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): boolean;
21
- exec(script: string): Promise<void>;
22
- execSync(script: string): boolean;
23
15
  getTableInfo(table: string): Promise<SmartDbTableInfo>;
24
- supportSyncCalls(): boolean;
25
- supportAsyncCalls(): boolean;
26
- protected statementGet(buildData: SmartDbSqlBuildData): Promise<any>;
27
- protected statementGetSync(buildData: SmartDbSqlBuildData): any;
28
- protected statementGetAll(buildData: SmartDbSqlBuildData): Promise<any[]>;
29
- protected statementGetAllSync(buildData: SmartDbSqlBuildData): any[];
16
+ rollback(): Promise<void>;
30
17
  protected statementRun(buildData: SmartDbSqlBuildData): Promise<SmartDbRunResult>;
31
- protected statementRunSync(buildData: SmartDbSqlBuildData): SmartDbRunResult;
32
- close(): Promise<void>;
18
+ protected statementGet<T extends object>(buildData: SmartDbSqlBuildData): Promise<T>;
19
+ protected statementGetAll<T>(buildData: SmartDbSqlBuildData): Promise<T[]>;
33
20
  }
@@ -1 +1 @@
1
- import _ from"lodash";import Mysql from"mysql";import{SmartDb}from"../smart-db";export class SmartDbMysql2 extends SmartDb{constructor(e){e.config&&e.connect?(super(e.config),this.db=e):(super(e),this.db=Mysql.createConnection(e))}commit(){return new Promise(((e,t)=>{this.db.commit((r=>{r?t(r):e()}))}))}rollback(){return new Promise(((e,t)=>{this.db.rollback((r=>{r?t(r):e()}))}))}commitSync(){throw new Error("Method not implemented.")}rollbackSync(){throw new Error("Method not implemented.")}getDatabaseType(){return"mysql"}getDbConnector(){return this.dbConnector}getDbQuote(){return"`"}hasConcurrentTransactions(){return!0}closeSync(){throw new Error("Method not implemented.")}hasTransaction(){throw new Error("Method not implemented.")}exists(e,t,r){return new Promise(((t,r)=>{const n=_.isString(e)?e:e.getTableName();this.db.query(`show tables like '${n}'`,((e,n,o)=>{e?r(e):t(n&&n.length>0)}))}))}existsSync(e,t,r){throw new Error("Method not implemented.")}exec(e){return new Promise(((t,r)=>{try{this.db.query(e,((e,n,o)=>{e?r(e):t()}))}catch(e){r(e)}}))}execSync(e){throw new Error("Method not implemented.")}getTableInfo(e){return new Promise(((e,t)=>{}))}supportSyncCalls(){return!1}supportAsyncCalls(){return!0}statementGet(e){return new Promise(((t,r)=>{try{this.db.query(e.sql,e.values,((e,n,o)=>{e?r(e):t(n&&n[0])}))}catch(e){r(e)}}))}statementGetSync(e){throw new Error("Method not implemented.")}statementGetAll(e){return new Promise(((t,r)=>{this.db.query(e.sql,e.values,((e,n,o)=>{e?r(e):(console.log(o),t(n&&n))}))}))}statementGetAllSync(e){throw new Error("Method not implemented.")}statementRun(e){return new Promise(((t,r)=>{this.db.query(e.sql,e.values,((e,n,o)=>{if(e)r(e);else{const e={changes:n.changedRows,affected:n.affectedRows,lastId:n.insertId};t(e)}}))}))}statementRunSync(e){throw new Error("Method not implemented.")}close(){return new Promise(((e,t)=>{this.db.end((r=>{r?t(r):e()}))}))}}
1
+ import _ from"lodash";import Mysql from"mysql";import{SmartDb}from"../smart-db";export class SmartDbMysql2 extends SmartDb{constructor(t){t.config&&t.connect?(super(t.config),this.db=t):(super(t),this.db=Mysql.createConnection(t))}close(){return new Promise(((t,e)=>{this.db.end((e=>{e?(this.lastError=e,t(!1)):t(!0)}))}))}commit(){return new Promise(((t,e)=>{this.db.commit((r=>{r?(this.lastError=r,e(r)):t()}))}))}exec(t){return new Promise(((e,r)=>{try{this.db.query(t,((t,s,o)=>{t?(this.lastError=t,r(t)):e()}))}catch(t){r(t)}}))}exists(t,e,r){return new Promise(((e,r)=>{const s=_.isString(t)?t:t.getTableName();this.db.query(`show tables like '${s}'`,((t,s,o)=>{t?(this.lastError=t,r(t)):e(s&&s.length>0)}))}))}getDatabaseType(){return"mysql"}getDbQuote(){return"`"}getTableInfo(t){throw new Error("Method not implemented (getTableInfo)")}rollback(){return new Promise(((t,e)=>{this.db.rollback((r=>{r?(this.lastError=r,e(r)):t()}))}))}statementRun(t){return new Promise(((e,r)=>{this.db.query(t.sql,t.values,((t,s,o)=>{if(t)this.lastError=t,r(t);else{const t={changes:s.changedRows,affected:s.affectedRows,lastId:s.insertId};e(t)}}))}))}statementGet(t){return new Promise(((e,r)=>{try{this.db.query(t.sql,t.values,((t,s,o)=>{t?(this.lastError=t,r(t)):e(s&&s[0])}))}catch(t){this.lastError=t,r(t)}}))}statementGetAll(t){return new Promise(((e,r)=>{this.db.query(t.sql,t.values,((t,s,o)=>{t?(this.lastError=t,r(t)):(console.log(o),e(s&&s))}))}))}}
@@ -1,7 +1,7 @@
1
1
  import { Connection } from "oracledb";
2
2
  import { AbstractModel } from "../models/abstract-model";
3
3
  import { SmartDb } from "../smart-db";
4
- import { GenericModelData, SmartDbConnector, SmartDbRunResult, SmartDbTableInfo } from "../smart-db-interfaces";
4
+ import { GenericModelData, SmartDbRunResult, SmartDbTableInfo } from "../smart-db-interfaces";
5
5
  import { SmartDbSqlBuildData } from "../smart-db-sql-build-data";
6
6
  export interface SmartDbOracleOptions {
7
7
  user: string;
@@ -16,30 +16,17 @@ export declare class SmartDbOracle extends SmartDb {
16
16
  private options;
17
17
  static libInit: boolean;
18
18
  constructor(connectorOrDb: string | Connection, options?: SmartDbOracleOptions);
19
+ close(): Promise<boolean>;
20
+ commit(): Promise<void>;
21
+ exec(script: string): Promise<void>;
22
+ exists<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): Promise<boolean>;
19
23
  getDatabaseType(): string;
20
- getDbConnector(): string | SmartDbConnector;
21
- getDbQuote(): string;
24
+ getTableInfo(tableName: string): Promise<SmartDbTableInfo>;
22
25
  hasConcurrentTransactions(): boolean;
23
- supportSyncCalls(): boolean;
24
- supportAsyncCalls(): boolean;
25
- hasTransaction(): boolean;
26
- exists<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): Promise<boolean>;
27
- existsSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): boolean;
28
- exec(script: string): Promise<void>;
29
- execSync(script: string): Connection | false;
30
26
  reconnect(connectorOrDb?: string | Connection, options?: SmartDbOracleOptions): void;
31
- closeSync(): boolean;
32
- commit(): Promise<void>;
33
- commitSync(): void;
34
27
  rollback(): Promise<void>;
35
- rollbackSync(): void;
36
- getTableInfo(tableName: string): Promise<SmartDbTableInfo>;
37
28
  protected statementRun(buildData: SmartDbSqlBuildData): Promise<SmartDbRunResult>;
38
- protected statementRunSync(buildData: SmartDbSqlBuildData): SmartDbRunResult;
39
29
  protected statementGet<T extends object>(buildData: SmartDbSqlBuildData): Promise<T>;
40
- protected statementGetSync(buildData: SmartDbSqlBuildData): void;
41
30
  protected statementGetAll<T>(buildData: SmartDbSqlBuildData): Promise<T[]>;
42
- protected statementGetAllSync(buildData: SmartDbSqlBuildData): any[];
43
31
  private replacePlaceholders;
44
- close(): Promise<void>;
45
32
  }
@@ -1 +1 @@
1
- import fs from"fs";import process from"node:process";import oracleDb from"oracledb";import{take}from"rxjs";import{OracleCatModel}from"../models/oracle-cat-model";import{OracleUserTabColumnsViewModel}from"../models/oracle-user-tab-columns-view-model";import{SmartDb}from"../smart-db";export class SmartDbOracle extends SmartDb{constructor(e,t){if(!SmartDbOracle.libInit){let e;"darwin"===process.platform&&(e=process.env.ORACLE_HOME),e&&fs.existsSync(e)&&oracleDb.initOracleClient({libDir:e}),SmartDbOracle.libInit=!0}"string"==typeof e?super(e,t?.noDbLogging):super(null),this.reconnect(e,t)}getDatabaseType(){return"oracle"}getDbConnector(){return this.dbConnector}getDbQuote(){return'"'}hasConcurrentTransactions(){return!0}supportSyncCalls(){return!1}supportAsyncCalls(){return!0}hasTransaction(){throw new Error("Method not implemented.")}exists(e,t,r){return new Promise(((r,o)=>{try{const n="string"==typeof e?e:e.getTableName();this.getFirst(OracleCatModel,{name:n.toUpperCase(),type:t?t.toUpperCase():void 0}).then((e=>{null===e?o(this.getLastError()):r(!!e)})).catch((e=>{o(e)}))}catch(e){o(e)}}))}existsSync(e,t,r){const o="string"==typeof e?e:e.getTableName();return!!this.getFirstSync(OracleCatModel,{name:o.toUpperCase(),type:t?t.toUpperCase():void 0})}exec(e){return new Promise(((t,r)=>{try{this.db.execute(e,(e=>{e?r(e):t()}))}catch(e){r(e)}}))}execSync(e){throw new Error("Method not implemented.")}reconnect(e,t){e?this.connectorOrDb=e:e=this.connectorOrDb,t?this.options=t:t=this.options,"string"==typeof e?oracleDb.getConnection(Object.assign({connectString:e},t??this.options)).then((e=>{this.db=e,t&&t.onReady&&this.onReady().pipe(take(1)).subscribe((r=>{r&&t.onReady(e)})),this.exec("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'").then((e=>{this.exec("ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY:MM:DD HH24:MI:SS.FF'").then((e=>{this.isReady=!0})).catch((e=>{throw e}))})).catch((e=>{throw e}))})).catch((e=>{t&&t.onReady&&t.onReady(null,e),t.silent||console.log("unable prepare session database connection",e),this.isReady=null})):this.db=e}closeSync(){throw new Error("Method not implemented.")}commit(){return this.db.commit()}commitSync(){throw new Error("Method not implemented.")}rollback(){return this.db.rollback()}rollbackSync(){throw new Error("Method not implemented.")}getTableInfo(e){return new Promise((async(t,r)=>{await this.getAll(OracleUserTabColumnsViewModel,{tableName:e.toUpperCase()}).then((o=>{if(!1!==o){let r=[];r=o.map((e=>({cid:e.columnId,name:e.columnName,type:e.dataType,notNull:"Y"!=e.nullable,defaultValue:e.defaultValue,isPk:"P"==e.constraintType}))),t({name:e,fields:r})}else r(this.getLastError())})).catch((e=>{r(e)}))}))}statementRun(e){return new Promise(((t,r)=>{try{this.db.execute(this.replacePlaceholders(e.sql),e.values,((e,o)=>{e?r(e):this.commit().then((()=>{t({changes:o.rowsAffected,affected:o.rowsAffected,lastId:null})})).catch((e=>{r(e)}))}))}catch(e){r(e)}}))}statementRunSync(e){throw new Error("Method not implemented.")}statementGet(e){return new Promise(((t,r)=>{try{this.db.execute(this.replacePlaceholders(this.replacePlaceholders(e.sql)),e.values,{maxRows:1,outFormat:oracleDb.OUT_FORMAT_OBJECT},((e,o)=>{if(e)r(e);else{const e=o.rows[0];let r=null;if(e){r={};Object.keys(e).forEach((t=>{r[t.toLowerCase()]=e[t]}))}t(r)}}))}catch(e){r(e)}}))}statementGetSync(e){throw new Error("Method not implemented.")}statementGetAll(e){return new Promise(((t,r)=>{try{this.db.execute(this.replacePlaceholders(e.sql),e.values,{maxRows:0,outFormat:oracleDb.OUT_FORMAT_OBJECT}).then((e=>{t(e.rows)})).catch((e=>{r(e)}))}catch(e){r(e)}}))}statementGetAllSync(e){throw new Error("Method not implemented.")}replacePlaceholders(e){let t=1,r=!1;for(let o=0;o<e.length;o++)"'"==e[o]?r=!r:r||"?"!=e[o]||(e=e.substring(0,o)+":"+t+++e.substring(o+1));return e}close(){return new Promise(((e,t)=>{try{this.smartDbLog.setDb(null),this.db.close((r=>{r?t(r):(this._onReady.next(!1),e())}))}catch(e){t(e)}}))}}SmartDbOracle.libInit=!1;
1
+ import fs from"fs";import process from"node:process";import oracleDb from"oracledb";import{take}from"rxjs";import{OracleCatModel}from"../models/oracle-cat-model";import{OracleUserTabColumnsViewModel}from"../models/oracle-user-tab-columns-view-model";import{SmartDb}from"../smart-db";export class SmartDbOracle extends SmartDb{constructor(e,t){if(!SmartDbOracle.libInit){let e;"darwin"===process.platform&&(e=process.env.ORACLE_HOME),e&&fs.existsSync(e)&&oracleDb.initOracleClient({libDir:e}),SmartDbOracle.libInit=!0}"string"==typeof e?super(e,t?.noDbLogging):super(null),this.reconnect(e,t)}close(){return new Promise(((e,t)=>{try{this.smartDbLog.setDb(null),this.db.close((t=>{t?(this.lastError=t,e(!1)):(this._onReady.next(!1),e(!0))}))}catch(e){this.lastError=e,t(e)}}))}commit(){return this.db.commit()}exec(e){return new Promise(((t,r)=>{try{this.db.execute(e,(e=>{e?(this.lastError=e,r(e)):t()}))}catch(e){this.lastError=e,r(e)}}))}exists(e,t,r){return new Promise(((r,s)=>{try{const o="string"==typeof e?e:e.getTableName();this.getFirst(OracleCatModel,{name:o.toUpperCase(),type:t?t.toUpperCase():void 0}).then((e=>{r(!!e)})).catch((e=>{s(e)}))}catch(e){this.lastError=e,s(e)}}))}getDatabaseType(){return"oracle"}getTableInfo(e){return new Promise((async(t,r)=>{await this.getAll(OracleUserTabColumnsViewModel,{tableName:e.toUpperCase()}).then((s=>{if(!1!==s){let r=[];r=s.map((e=>({cid:e.columnId,name:e.columnName,type:e.dataType,notNull:"Y"!=e.nullable,defaultValue:e.defaultValue,isPk:"P"==e.constraintType}))),t({name:e,fields:r})}else r(this.getLastError())})).catch((e=>{this.lastError=e,r(e)}))}))}hasConcurrentTransactions(){return!0}reconnect(e,t){e?this.connectorOrDb=e:e=this.connectorOrDb,t?this.options=t:t=this.options,"string"==typeof e?oracleDb.getConnection(Object.assign({connectString:e},t??this.options)).then((e=>{this.db=e,t&&t.onReady&&this.onReady().pipe(take(1)).subscribe((r=>{r&&t.onReady(e)})),this.exec("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'").then((e=>{this.exec("ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY:MM:DD HH24:MI:SS.FF'").then((e=>{this.isReady=!0})).catch((e=>{throw e}))})).catch((e=>{throw e}))})).catch((e=>{t&&t.onReady&&t.onReady(null,e),t.silent||console.log("unable prepare session database connection",e),this.isReady=null})):this.db=e}rollback(){return this.db.rollback()}statementRun(e){return new Promise(((t,r)=>{try{this.db.execute(this.replacePlaceholders(e.sql),e.values,((e,s)=>{e?(this.lastError=e,r(e)):this.commit().then((()=>{t({changes:s.rowsAffected,affected:s.rowsAffected,lastId:null})})).catch((e=>{r(e)}))}))}catch(e){this.lastError=e,r(e)}}))}statementGet(e){return new Promise(((t,r)=>{try{this.db.execute(this.replacePlaceholders(this.replacePlaceholders(e.sql)),e.values,{maxRows:1,outFormat:oracleDb.OUT_FORMAT_OBJECT},((e,s)=>{if(e)this.lastError=e,r(e);else{const e=s.rows[0];let r=null;if(e){r={};Object.keys(e).forEach((t=>{r[t.toLowerCase()]=e[t]}))}t(r)}}))}catch(e){this.lastError=e,r(e)}}))}statementGetAll(e){return new Promise(((t,r)=>{try{this.db.execute(this.replacePlaceholders(e.sql),e.values,{maxRows:0,outFormat:oracleDb.OUT_FORMAT_OBJECT}).then((e=>{t(e.rows)})).catch((e=>{this.lastError=e,r(e)}))}catch(e){this.lastError=e,r(e)}}))}replacePlaceholders(e){let t=1,r=!1;for(let s=0;s<e.length;s++)"'"==e[s]?r=!r:r||"?"!=e[s]||(e=e.substring(0,s)+":"+t+++e.substring(s+1));return e}}SmartDbOracle.libInit=!1;
@@ -1,7 +1,7 @@
1
1
  import Sqlite3 from "sqlite3";
2
2
  import { AbstractModel } from "../models/abstract-model";
3
3
  import { SmartDb } from "../smart-db";
4
- import { GenericModelData, SmartDbConnector, SmartDbRunResult, SmartDbTableInfo } from "../smart-db-interfaces";
4
+ import { GenericModelData, SmartDbRunResult, SmartDbTableInfo } from "../smart-db-interfaces";
5
5
  import { SmartDbSqlBuildData } from "../smart-db-sql-build-data";
6
6
  export interface SmartDbSqlite3Options {
7
7
  mode?: number;
@@ -10,28 +10,14 @@ export interface SmartDbSqlite3Options {
10
10
  export declare class SmartDbSqlite3 extends SmartDb {
11
11
  protected db: Sqlite3.Database;
12
12
  constructor(connectorOrDb: string | Sqlite3.Database, options?: SmartDbSqlite3Options);
13
- getDatabaseType(): string;
14
- getDbConnector(): string | SmartDbConnector;
15
- getDbQuote(): string;
16
- hasConcurrentTransactions(): boolean;
17
- supportSyncCalls(): boolean;
18
- supportAsyncCalls(): boolean;
19
- hasTransaction(): boolean;
13
+ close(): Promise<boolean>;
20
14
  commit(): Promise<void>;
21
- rollback(): Promise<void>;
22
- commitSync(): void;
23
- rollbackSync(): void;
24
- exists<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): Promise<boolean>;
25
- existsSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): boolean;
26
15
  exec(script: string): Promise<void>;
27
- execSync(script: string): Sqlite3.Database | false;
28
- closeSync(): boolean;
16
+ exists<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): Promise<boolean>;
17
+ getDatabaseType(): string;
29
18
  getTableInfo(table: string): Promise<SmartDbTableInfo>;
19
+ rollback(): Promise<void>;
30
20
  protected statementRun(buildData: SmartDbSqlBuildData): Promise<SmartDbRunResult>;
31
- protected statementRunSync(buildData: SmartDbSqlBuildData): SmartDbRunResult;
32
- protected statementGet(buildData: SmartDbSqlBuildData): Promise<any>;
33
- protected statementGetSync(buildData: SmartDbSqlBuildData): void;
34
- protected statementGetAll(buildData: SmartDbSqlBuildData): Promise<any[]>;
35
- protected statementGetAllSync(buildData: SmartDbSqlBuildData): any[];
36
- close(): Promise<void>;
21
+ protected statementGet<T extends object>(buildData: SmartDbSqlBuildData): Promise<T>;
22
+ protected statementGetAll<T>(buildData: SmartDbSqlBuildData): Promise<T[]>;
37
23
  }
@@ -1 +1 @@
1
- import _ from"lodash";import Sqlite3 from"sqlite3";import{SqliteMasterModel}from"../models/sqlite-master-model";import{SmartDb}from"../smart-db";export class SmartDbSqlite3 extends SmartDb{constructor(t,e){_.isString(t)?(super(t),this.db=new Sqlite3.Database(t,e&&e.mode,e&&e.callback)):(super(null),this.db=t)}getDatabaseType(){return"sqlite3"}getDbConnector(){return this.dbConnector}getDbQuote(){return'"'}hasConcurrentTransactions(){return!1}supportSyncCalls(){return!0}supportAsyncCalls(){return!1}hasTransaction(){throw new Error("Method not implemented.")}commit(){return this.exec("commit")}rollback(){return this.exec("rollback")}commitSync(){throw new Error("Method not implemented.")}rollbackSync(){throw new Error("Method not implemented.")}exists(t,e,r){return new Promise(((n,o)=>{try{const s=_.isString(t)?t:t.getTableName();this.getFirst(SqliteMasterModel,{name:s,type:e,tblName:r}).then((t=>{null===t?o(this.getLastError()):n(!!t)})).catch((t=>{o(t)}))}catch(t){o(t)}}))}existsSync(t,e,r){throw new Error("Method not implemented.")}exec(t){return new Promise(((e,r)=>{try{this.db.exec(t,(function(t){t?r(t):e()}))}catch(t){r(t)}}))}execSync(t){throw new Error("Method not implemented.")}closeSync(){throw new Error("Method not implemented.")}getTableInfo(t){throw new Error("Method not implemented.")}statementRun(t){return new Promise(((e,r)=>{try{this.db.run(t.sql,t.values,(function(t){t?r(t):e({changes:this.changes,affected:this.changes,lastId:this.lastID})}))}catch(t){r(t)}}))}statementRunSync(t){throw new Error("Method not implemented.")}statementGet(t){return new Promise(((e,r)=>{try{this.db.prepare(t.sql,(function(n){n?r(n):this.get(t.values,(function(t,n){t?r(t):e(n)}))}))}catch(t){r(t)}}))}statementGetSync(t){throw new Error("Method not implemented.")}statementGetAll(t){return new Promise(((e,r)=>{try{this.db.prepare(t.sql,(function(n){n?r(n):this.all(t.values,(function(t,n){t?r(t):e(n)}))}))}catch(t){r(t)}}))}statementGetAllSync(t){throw new Error("Method not implemented.")}close(){return new Promise(((t,e)=>{try{this.smartDbLog.setDb(null),this.db.close((function(r){r?e(r):t()}))}catch(t){e(t)}}))}}
1
+ import _ from"lodash";import Sqlite3 from"sqlite3";import{SqliteMasterModel}from"../models/sqlite-master-model";import{SmartDb}from"../smart-db";export class SmartDbSqlite3 extends SmartDb{constructor(t,r){_.isString(t)?(super(t),this.db=new Sqlite3.Database(t,r&&r.mode,r&&r.callback)):(super(null),this.db=t)}close(){return new Promise(((t,r)=>{try{this.smartDbLog.setDb(null),this.db.close((r=>{r?(this.lastError=r,t(!1)):t(!0)}))}catch(t){this.lastError=t,r(t)}}))}commit(){return this.exec("commit")}exec(t){return new Promise(((r,e)=>{try{this.db.exec(t,(t=>{t?(this.lastError=t,e(t)):r()}))}catch(t){this.lastError=t,e(t)}}))}exists(t,r,e){return new Promise(((s,a)=>{try{const i=_.isString(t)?t:t.getTableName();this.getFirst(SqliteMasterModel,{name:i,type:r,tblName:e}).then((t=>{s(!!t)})).catch((t=>{a(t)}))}catch(t){this.lastError=t,a(t)}}))}getDatabaseType(){return"sqlite3"}getTableInfo(t){throw new Error("Method not implemented (getTableInfo)")}rollback(){return this.exec("rollback")}statementRun(t){return new Promise(((r,e)=>{try{const s=this;this.db.run(t.sql,t.values,(function(t){t?(s.lastError=t,e(t)):r({changes:this.changes,affected:this.changes,lastId:this.lastID})}))}catch(t){this.lastError=t,e(t)}}))}statementGet(t){return new Promise(((r,e)=>{try{const s=this;this.db.prepare(t.sql,(function(a){a?e(a):this.get(t.values,(function(t,a){t?(s.lastError=t,e(t)):r(a)}))}))}catch(t){this.lastError=t,e(t)}}))}statementGetAll(t){return new Promise(((r,e)=>{try{const s=this;this.db.prepare(t.sql,(function(a){a?(s.lastError=a,e(a)):this.all(t.values,(function(t,a){t?(s.lastError=t,e(t)):r(a)}))}))}catch(t){this.lastError=t,e(t)}}))}}
@@ -1 +1 @@
1
- import fs from"fs";import _ from"lodash";import process from"process";import{SmartDbBetterSqlite3}from"../drivers/smart-db-better-sqlite3";import{SmartDbOracle}from"../drivers/smart-db-oracle";import{OracleCatModel}from"../models/oracle-cat-model";import{SmartDbCoreTableModel}from"../models/smart-db-core-table-model";import{SqliteMasterModel}from"../models/sqlite-master-model";import{IN,NE,NOT_LIKE}from"../smart-db-globals";function getType(e){let t;return t=e?e.match(/varchar/i)||e.match(/text/i)?"string":e.match(/integer\(1\)/i)?"boolean":e.match(/date/i)?"Date":e.match(/integer/i)||e.match(/number/i)?"number":e.match(/long/i)||e.match(/raw/i)?"any":"SqlValueType":"SqlValueType",t}function getRelations(e){return new Promise((async(t,r)=>{e instanceof SmartDbOracle?e.getAll(OracleCatModel,{type:IN(["TABLE","VIEW"]),name:NOT_LIKE("BIN$%")}).then((a=>{a?t(a.map((e=>e.name.toLowerCase()))):r(e.getLastError())})).catch((e=>{r(e)})):e instanceof SmartDbBetterSqlite3?e.getAll(SqliteMasterModel,{type:IN(["table","view"]),name:NE("sqlite_sequence")}).then((a=>{a?t(a.map((e=>e.name))):r(e.getLastError())})).catch((e=>{r(e)})):r("unimplemented database type")}))}async function extractDbApi(e){console.log(`extract interface from '${e.db.getDbConnector()}' to '${e.modelDirectory}'`);const t=["break","case","catch","class","const","continue","debugger","default","delete","do","else","enum","export","extends","false","finally","for","function","If","import","in","instanceOf","interface","new","null","return","super","switch","this","throw","true","try","typeOf","var","void","while","with"];fs.existsSync(e.modelDirectory)||fs.mkdirSync(e.modelDirectory,{recursive:!0}),getRelations(e.db).then((async r=>{let a=[];if((e.skipCoreTables||e.justCoreTables)&&await e.db.exists(SmartDbCoreTableModel)){const t=await e.db.getAll(SmartDbCoreTableModel);if(!1===t)throw e.db.getLastError();t.forEach((e=>{a.push(e.name)}))}const n=[];for(const s of r){let r=!0;if(e.justCoreTables?r=a.includes(s):e.skipCoreTables&&(r=!a.includes(s)),r){const r=s[0].toUpperCase()+_.camelCase(s.substring(1))+"Model",a=[];console.log("working on",s),await e.db.getTableInfo(s).then((o=>{const i=o.fields;let l=!1,c="",m="",p="",d="",b="";const u=s.toLowerCase().replace(/[^[a-z0-9]/g,"-")+"-model";if(n.push({className:r,fileName:u}),c+="/* eslint-disable @typescript-eslint/member-ordering */\n",c+="// noinspection JSUnusedGlobalSymbols\n",i){e.abstractModelModule==e.smartDbInterfaces?e.separateApi?(p+=`import {GenericModelData} from "${e.abstractModelModule}";\n`,b+=`import {AbstractModel, ModelAttributeMap} from "${e.abstractModelModule}";\n`,b+=`import {${r}Data} from "./${u}-api";\n`):b+=`import {AbstractModel, GenericModelData, ModelAttributeMap} from "${e.abstractModelModule}";\n`:e.separateApi?(p+=`import {GenericModelData} from "${e.smartDbInterfaces}";\n`,b+=`import {ModelAttributeMap} from "${e.smartDbInterfaces}";\n`,b+=`import {AbstractModel} from "${e.abstractModelModule}";\n`,b+=`import {${r}Data} from "./${u}-api";\n`):(b+=`import {GenericModelData, ModelAttributeMap} from "${e.smartDbInterfaces}";\n`,b+=`import {AbstractModel} from "${e.abstractModelModule}";\n`),m+=`export interface ${r}Data extends GenericModelData {\n`;let n,o="",f="",h=!1;const g=[];i.forEach((e=>{const t=e.name.match(/([a-z0-9]{1,4})_/i);e.isPk&&(o=e.name,t&&(f=t[1])),t?g.includes(t[1])||g.push(t[1]):h=!0})),f||h||1!=g.length||(f=g[0]),f&&(n=new RegExp(`^${f}_(.*)$`));const y={};i.forEach((t=>{const r=getType(t.type);let o;l||"SqlValueType"!=r||(p+=`import {SqlValueType} from "${e.smartDbInterfaces}";\n`,b+=`import {SqlValueType} from "${e.smartDbInterfaces}";\n`,l=!0);const i=n&&t.name.match(n);o=i?_.camelCase(i[1]):_.camelCase(t.name);let c=!0;if(o!=t.name&&(a.push({name:o,attribute:o,type:r,typeScriptStyle:c,alias:t.name}),c=!1),o!=t.name.toLowerCase()&&(a.push({name:t.name.toLowerCase(),attribute:o,type:r,physical:void 0!==t.cid&&t.name==t.name.toLowerCase(),typeScriptStyle:c}),c=!1),o!=t.name.toUpperCase()&&a.push({name:t.name.toUpperCase(),attribute:o,type:r,physical:void 0!==t.cid&&t.name==t.name.toUpperCase(),typeScriptStyle:c}),t.cid){const e=a.find((e=>e.physical&&e.name.toLowerCase()==t.name.toLowerCase()));e||a.push({name:t.name,attribute:o,type:r,physical:!0,typeScriptStyle:c})}y[o]=r,"user"==s&&"name"==o&&(m+=" // @ts-ignore"),m+=` ${o}?: ${r};\n`})),m+="}\n",d+=`export class ${r} extends AbstractModel<${r}, ${r}Data> {\n`,_.forEach(y,((e,t)=>{d+=` private _${t}?: ${e};\n`})),"user"==s&&(d+=" private _hash?: string;\n",d+=" private _privileges?: string[];\n"),d+="\n",d+=" static readonly attributeMap: ModelAttributeMap = {\n",a.forEach(((e,t)=>{t>0&&(d+=",\n"),d+=` ${e.name}: {\n`,e.physical&&(d+=" physical: true,\n"),e.alias&&(d+=` alias: "${e.alias}",\n`),e.virtual&&(d+=" virtual: true,\n"),e.typeScriptStyle&&(d+=" typeScriptStyle: true,\n"),d+=` type: "${e.type}",\n`,d+=` attribute: "_${e.attribute}"\n`,d+=" }"})),d+="\n",d+=" };\n",d+="\n",d+=" static getClassName(): string {\n",d+=` return "${r}";\n`,d+=" }\n",d+="\n",d+=" static getTableName(): string {\n",d+=` return "${s}";\n`,d+=" }\n",d+="\n",d+=" static getPrimaryKey(): string {\n",d+=` return "${o}";\n`,d+=" }\n",d+="\n",d+=` static from(other: ${r} | ${r}Data): ${r} {\n`,d+=` let value: ${r} = null;\n`,d+=" if (other) {\n",d+=` value = new ${r}();\n`,d+=` if (other instanceof ${r}) {\n`,d+=" Object.assign(value, other);\n",d+=" } else {\n",d+=" value.assign(other);\n",d+=" }\n",d+=" }\n",d+=" return value;\n",d+=" }\n",d+="\n",d+=` constructor(data?: ${r} | ${r}Data) {\n`,d+=" super();\n",d+=" if (data) {\n",d+=" this.assign(data);\n",d+=" }\n",d+=" }\n",d+="\n",d+=` public clone(): ${r} {\n`,d+=` return ${r}.from(this);\n`,d+=" }\n",d+="\n",d+=" public getClassName(): string {\n",d+=` return "${r}";\n`,d+=" }\n",d+="\n",d+=" public getTableName(): string {\n",d+=` return "${s}";\n`,d+=" }\n",d+="\n",d+=" public getPrimaryKey(): string {\n",d+=` return "${o}";\n`,d+=" }\n",d+="\n",d+=" public getAttributeMap(): ModelAttributeMap {\n",d+=` return ${r}.attributeMap;\n`,d+=" }\n",a.forEach((e=>{let r;d+="\n",r=e.name.length<3||e.name.match(/_/)?"FunctionNamingConventionJS":"",""!==r&&(d+=` // noinspection ${r}\n`),d+=` get ${e.name}(): ${e.type} {\n`,d+=` return this._${e.attribute};\n`,d+=" }\n\n",""!==r&&(d+=` // noinspection ${r}\n`);let a=e.attribute;t.includes(a)&&(a="value"),d+=` set ${e.name}(${a}: ${e.type}) {\n`,d+=` this._${e.attribute} = ${a};\n`,d+=" }\n"})),"user"==s&&(d+="\n",d+=" get hash(): string {\n",d+=" return this._hash;\n",d+=" }\n\n",d+=" set hash(hash: string) {\n",d+=" this._hash = hash;\n",d+=" }\n",d+="\n",d+=" get privileges(): string[] {\n",d+=" return this._privileges;\n",d+=" }\n\n",d+=" set privileges(p: string[]) {\n",d+=" this._privileges = p;\n",d+=" }\n"),d+="}\n",e.separateApi?(m=c+"\n"+p+"\n"+m,fs.writeFileSync(`${e.modelDirectory}/${u+"-api.ts"}`,m),d=c+"\n"+b+"\n"+d):d=c+"\n"+b+"\n"+m+"\n"+d,fs.writeFileSync(`${e.modelDirectory}/${u+".ts"}`,d)}else console.log("error: table has no fields")})).catch((e=>{console.error(e),process.abort()}))}}let s=`import {AbstractModel} from "${e.abstractModelModule}";\n`;_.forEach(n,(e=>{s+=`import {${e.className}} from "./${e.fileName}";\n`})),s+="\n",s+="interface SmartDbDictionaryEntry {\n",s+=" cls: "+n.map((e=>"typeof "+e.className)).join(" |\n "),s+=";\n",s+="}\n\n",s+="export class SmartDbDictionary {\n",s+=" static models: { [relation: string]: SmartDbDictionaryEntry; } = {\n",_.forEach(n,(e=>{s+=` ${e.className}: {\n`,s+=` cls: ${e.className}\n`,s+=" },\n"})),s=s.substring(0,s.length-2)+"\n",s+=" };\n",s+="}\n",fs.writeFileSync(`${e.modelDirectory}/smart-db-dictionary.ts`,s)})).catch((e=>{console.error("extraction error",e)}))}(async()=>{let e=!1;const t=Array.from(process.argv);let r,a,n,s=!1;for(t.shift(),t.shift();t[0]&&"--"==t[0].substring(0,2);)"--separate-api"==t[0]?(e=!0,t.shift()):"--connector"==t[0]?(r=t[1],t.shift(),t.shift()):"--username"==t[0]?(a=t[1],t.shift(),t.shift()):"--password"==t[0]?(r=t[1],t.shift(),t.shift()):"--create"==t[0]?(s=!0,t.shift()):(console.error(`unknown option '${t[2]}'`),process.exit(-1));if(r||(r=process.env.ORACLE_SID),a||(a=process.env.ORA_USER),n||(n=process.env.ORA_PASS),r&&t.length<=1){let o;a&&n?o=new SmartDbOracle(r,{user:a,password:n,noDbLogging:!0}):s||fs.existsSync(r)?o=new SmartDbBetterSqlite3(r,{}):(console.error(`ERROR: missing sqlite3 database file ${r}`),process.exit(-1)),1==t.length?o.onReady().subscribe((async r=>{if(r){o.getLogger().setDbLogging(!1);const r={skipCoreTables:!0,modelDirectory:t[0],smartDbInterfaces:"@egi/smart-db",abstractModelModule:"@egi/smart-db",separateApi:e,db:o};await extractDbApi(r)}})):fs.existsSync("src/helpers/extract-db-api.ts")?o.onReady().subscribe((t=>{if(t){const t={justCoreTables:!0,modelDirectory:"src/models/generated",smartDbInterfaces:"../smart-db-interfaces",abstractModelModule:"./abstract-model",separateApi:e,db:o};t.db.initDb({module:"smart-db-core",sqlFilesDirectory:"assets/sqlite3"}).then((async()=>{await extractDbApi(t)}))}else console.error("unable to connect to database")})):console.log("command must be run at the root directory of the smart-db project")}else console.log("USAGE: extract-db-api --connector {db-connector|path-to-db} [{options}] {target-models-directory}\n"),console.log("Options are: [--username {username}]"),console.log(" [--password {password}]"),console.log(" [--create"),console.log(" [--separate-api]")})();
1
+ import fs from"fs";import _ from"lodash";import process from"process";import{SmartDbBetterSqlite3}from"../drivers/smart-db-better-sqlite3";import{SmartDbOracle}from"../drivers/smart-db-oracle";import{OracleCatModel}from"../models/oracle-cat-model";import{SmartDbCoreTableModel}from"../models/smart-db-core-table-model";import{SqliteMasterModel}from"../models/sqlite-master-model";import{IN,NE,NOT_LIKE}from"../smart-db-globals";function getType(e){let t;return t=e?e.match(/varchar/i)||e.match(/text/i)?"string":e.match(/integer\(1\)/i)?"boolean":e.match(/date/i)?"Date":e.match(/integer/i)||e.match(/number/i)?"number":e.match(/long/i)||e.match(/raw/i)?"any":"SqlValueType":"SqlValueType",t}function getRelations(e){return new Promise((async(t,r)=>{e instanceof SmartDbOracle?e.getAll(OracleCatModel,{type:IN(["TABLE","VIEW"]),name:NOT_LIKE("BIN$%")}).then((a=>{a?t(a.map((e=>e.name.toLowerCase()))):r(e.getLastError())})).catch((e=>{r(e)})):e instanceof SmartDbBetterSqlite3?e.getAll(SqliteMasterModel,{type:IN(["table","view"]),name:NE("sqlite_sequence")}).then((a=>{a?t(a.map((e=>e.name))):r(e.getLastError())})).catch((e=>{r(e)})):r("unimplemented database type")}))}async function extractDbApi(e){console.log(`extract interface from '${e.db.getDbConnector()}' to '${e.modelDirectory}'`);const t=["break","case","catch","class","const","continue","debugger","default","delete","do","else","enum","export","extends","false","finally","for","function","If","import","in","instanceOf","interface","new","null","return","super","switch","this","throw","true","try","typeOf","var","void","while","with"];fs.existsSync(e.modelDirectory)||fs.mkdirSync(e.modelDirectory,{recursive:!0}),getRelations(e.db).then((async r=>{let a=[];if((e.skipCoreTables||e.justCoreTables)&&await e.db.exists(SmartDbCoreTableModel)){const t=await e.db.getAll(SmartDbCoreTableModel);if(!1===t)throw e.db.getLastError();t.forEach((e=>{a.push(e.name)}))}const n=[];for(const s of r){let r=!0;if(e.justCoreTables?r=a.includes(s):e.skipCoreTables&&(r=!a.includes(s)),r){const r=s[0].toUpperCase()+_.camelCase(s.substring(1))+"Model",a=[];console.log("working on",s),await e.db.getTableInfo(s).then((o=>{const i=o.fields;let l=!1,c="",m="",p="",d="",b="";const u=s.toLowerCase().replace(/[^[a-z0-9]/g,"-")+"-model";if(n.push({className:r,fileName:u}),c+="/* eslint-disable @typescript-eslint/member-ordering */\n",c+="// noinspection JSUnusedGlobalSymbols\n",i){e.abstractModelModule==e.smartDbInterfaces?e.separateApi?(p+=`import {GenericModelData} from "${e.abstractModelModule}";\n`,b+=`import {AbstractModel, ModelAttributeMap} from "${e.abstractModelModule}";\n`,b+=`import {${r}Data} from "./${u}-api";\n`):b+=`import {AbstractModel, GenericModelData, ModelAttributeMap} from "${e.abstractModelModule}";\n`:e.separateApi?(p+=`import {GenericModelData} from "${e.smartDbInterfaces}";\n`,b+=`import {ModelAttributeMap} from "${e.smartDbInterfaces}";\n`,b+=`import {AbstractModel} from "${e.abstractModelModule}";\n`,b+=`import {${r}Data} from "./${u}-api";\n`):(b+=`import {GenericModelData, ModelAttributeMap} from "${e.smartDbInterfaces}";\n`,b+=`import {AbstractModel} from "${e.abstractModelModule}";\n`),m+=`export interface ${r}Data extends GenericModelData {\n`;let n,o="",f="",h=!1;const g=[];i.forEach((e=>{const t=e.name.match(/([a-z0-9]{1,4})_/i);e.isPk&&(o=e.name,t&&(f=t[1])),t?g.includes(t[1])||g.push(t[1]):h=!0})),f||h||1!=g.length||(f=g[0]),f&&(n=new RegExp(`^${f}_(.*)$`));const y={};i.forEach((t=>{const r=getType(t.type);let o;l||"SqlValueType"!=r||(p+=`import {SqlValueType} from "${e.smartDbInterfaces}";\n`,b+=`import {SqlValueType} from "${e.smartDbInterfaces}";\n`,l=!0);const i=n&&t.name.match(n);o=i?_.camelCase(i[1]):_.camelCase(t.name);let c=!0;if(o!=t.name&&(a.push({name:o,attribute:o,type:r,typeScriptStyle:c,alias:t.name}),c=!1),o!=t.name.toLowerCase()&&(a.push({name:t.name.toLowerCase(),attribute:o,type:r,physical:void 0!==t.cid&&t.name==t.name.toLowerCase(),typeScriptStyle:c}),c=!1),o!=t.name.toUpperCase()&&a.push({name:t.name.toUpperCase(),attribute:o,type:r,physical:void 0!==t.cid&&t.name==t.name.toUpperCase(),typeScriptStyle:c}),t.cid){const e=a.find((e=>e.physical&&e.name.toLowerCase()==t.name.toLowerCase()));e||a.push({name:t.name,attribute:o,type:r,physical:!0,typeScriptStyle:c})}y[o]=r,"user"==s&&"name"==o&&(m+=" // @ts-ignore"),m+=` ${o}?: ${r};\n`})),m+="}\n",d+=`export class ${r} extends AbstractModel<${r}, ${r}Data> {\n`,_.forEach(y,((e,t)=>{d+=` private _${t}?: ${e};\n`})),"user"==s&&(d+=" private _hash?: string;\n",d+=" private _privileges?: string[];\n"),d+="\n",d+=" static readonly attributeMap: ModelAttributeMap = {\n",a.forEach(((e,t)=>{t>0&&(d+=",\n"),d+=` ${e.name}: {\n`,e.physical&&(d+=" physical: true,\n"),e.alias&&(d+=` alias: "${e.alias}",\n`),e.virtual&&(d+=" virtual: true,\n"),e.typeScriptStyle&&(d+=" typeScriptStyle: true,\n"),d+=` type: "${e.type}",\n`,d+=` attribute: "_${e.attribute}"\n`,d+=" }"})),d+="\n",d+=" };\n",d+="\n",d+=" static getClassName(): string {\n",d+=` return "${r}";\n`,d+=" }\n",d+="\n",d+=" static getTableName(): string {\n",d+=` return "${s}";\n`,d+=" }\n",d+="\n",d+=" static getPrimaryKey(): string {\n",d+=` return "${o}";\n`,d+=" }\n",d+="\n",d+=` static from(other: ${r} | ${r}Data): ${r} {\n`,d+=` let value: ${r} = null;\n`,d+=" if (other) {\n",d+=` value = new ${r}();\n`,d+=` if (other instanceof ${r}) {\n`,d+=" Object.assign(value, other);\n",d+=" } else {\n",d+=" value.assign(other);\n",d+=" }\n",d+=" }\n",d+=" return value;\n",d+=" }\n",d+="\n",d+=` constructor(data?: ${r} | ${r}Data) {\n`,d+=" super();\n",d+=" if (data) {\n",d+=" this.assign(data);\n",d+=" }\n",d+=" }\n",d+="\n",d+=` public clone(): ${r} {\n`,d+=` return ${r}.from(this);\n`,d+=" }\n",d+="\n",d+=" public getClassName(): string {\n",d+=` return "${r}";\n`,d+=" }\n",d+="\n",d+=" public getTableName(): string {\n",d+=` return "${s}";\n`,d+=" }\n",d+="\n",d+=" public getPrimaryKey(): string {\n",d+=` return "${o}";\n`,d+=" }\n",d+="\n",d+=" public getAttributeMap(): ModelAttributeMap {\n",d+=` return ${r}.attributeMap;\n`,d+=" }\n",a.forEach((e=>{let r;d+="\n",r=e.name.length<3||e.name.match(/_/)?"FunctionNamingConventionJS":"",""!==r&&(d+=` // noinspection ${r}\n`),d+=` get ${e.name}(): ${e.type} {\n`,d+=` return this._${e.attribute};\n`,d+=" }\n\n",""!==r&&(d+=` // noinspection ${r}\n`);let a=e.attribute;t.includes(a)&&(a="value"),d+=` set ${e.name}(${a}: ${e.type}) {\n`,d+=` this._${e.attribute} = ${a};\n`,d+=" }\n"})),"user"==s&&(d+="\n",d+=" get hash(): string {\n",d+=" return this._hash;\n",d+=" }\n\n",d+=" set hash(hash: string) {\n",d+=" this._hash = hash;\n",d+=" }\n",d+="\n",d+=" get privileges(): string[] {\n",d+=" return this._privileges;\n",d+=" }\n\n",d+=" set privileges(p: string[]) {\n",d+=" this._privileges = p;\n",d+=" }\n"),d+="}\n",e.separateApi?(m=c+"\n"+p+"\n"+m,fs.writeFileSync(`${e.modelDirectory}/${u+"-api.ts"}`,m),d=c+"\n"+b+"\n"+d):d=c+"\n"+b+"\n"+m+"\n"+d,fs.writeFileSync(`${e.modelDirectory}/${u+".ts"}`,d)}else console.log("error: table has no fields")})).catch((e=>{console.error(e),process.abort()}))}}let s=`import {AbstractModel} from "${e.abstractModelModule}";\n`;_.forEach(n,(e=>{s+=`import {${e.className}} from "./${e.fileName}";\n`})),s+="\n",s+="interface SmartDbDictionaryEntry {\n",s+=" cls: "+n.map((e=>"typeof "+e.className)).join(" |\n "),s+=";\n",s+="}\n\n",s+="export class SmartDbDictionary {\n",s+=" static models: { [relation: string]: SmartDbDictionaryEntry; } = {\n",_.forEach(n,(e=>{s+=` ${e.className}: {\n`,s+=` cls: ${e.className}\n`,s+=" },\n"})),s=s.substring(0,s.length-2)+"\n",s+=" };\n",s+="}\n",fs.writeFileSync(`${e.modelDirectory}/smart-db-dictionary.ts`,s)})).catch((e=>{console.error("extraction error",e)}))}(async()=>{let e=!1;const t=Array.from(process.argv);let r,a,n,s=!1;for(t.shift(),t.shift();t[0]&&"--"==t[0].substring(0,2);)"--separate-api"==t[0]?(e=!0,t.shift()):"--database"==t[0]?(r=t[1],t.shift(),t.shift()):"--username"==t[0]?(a=t[1],t.shift(),t.shift()):"--password"==t[0]?(n=t[1],t.shift(),t.shift()):"--create"==t[0]?(s=!0,t.shift()):(console.error(`unknown option '${t[2]}'`),process.exit(-1));if(r||(r=process.env.ORACLE_SID),fs.existsSync(r)||(a||(a=process.env.ORA_USER),n||(n=process.env.ORA_PASS)),r&&t.length<=1){let o;a&&n?o=new SmartDbOracle(r,{user:a,password:n,noDbLogging:!0}):s||fs.existsSync(r)?o=new SmartDbBetterSqlite3(r,{}):(console.error(`ERROR: missing sqlite3 database file ${r}`),process.exit(-1)),1==t.length?o.onReady().subscribe((async r=>{if(r){o.getLogger().setDbLogging(!1);const r={skipCoreTables:!0,modelDirectory:t[0],smartDbInterfaces:"@egi/smart-db",abstractModelModule:"@egi/smart-db",separateApi:e,db:o};await extractDbApi(r)}})):fs.existsSync("src/helpers/extract-db-api.ts")?o.onReady().subscribe((t=>{if(t){const t={justCoreTables:!0,modelDirectory:"src/models/generated",smartDbInterfaces:"../smart-db-interfaces",abstractModelModule:"./abstract-model",separateApi:e,db:o};t.db.initDb({module:"smart-db-core",sqlFilesDirectory:"assets/sqlite3"}).then((async()=>{await extractDbApi(t)}))}else console.error("unable to connect to database")})):console.log("command must be run at the root directory of the smart-db project")}else console.log("USAGE: extract-db-api --database {db-connector|path-to-db} [{options}] {target-models-directory}\n"),console.log("Options are: [--username {username}]"),console.log(" [--password {password}]"),console.log(" [--create"),console.log(" [--separate-api]")})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@egi/smart-db",
3
- "version": "2.5.8",
3
+ "version": "2.6.1",
4
4
  "description": "Unified Smart DB Access",
5
5
  "author": "Marcel Egloff",
6
6
  "type": "module",
@@ -16,19 +16,21 @@
16
16
  "DB"
17
17
  ],
18
18
  "scripts": {
19
- "test": "echo \"Error: no test specified\" && exit 1",
20
- "copy-assets": "bin/copy-assets",
21
19
  "clean": "rm -rf dist/*",
22
- "build": "npm-run-all clean tsc copy-assets",
23
- "build-pro": "npm-run-all clean tsc-pro terser copy-assets",
24
- "build-watch": "npm-run-all clean copy-assets tsc-watch",
25
- "build-test-models": "tsc --build tsconfig.test-model.json",
26
- "tsc": "tsc --build tsconfig.json",
27
- "tsc-pro": "tsc --build tsconfig.pro.json",
28
- "tsc:pro:watch": "tsc --build tsconfig.pro.json --watch",
29
- "tsc-watch": "tsc --build tsconfig.json --watch",
20
+ "copy:assets": "bin/copy-assets",
21
+ "dev:build": "npm-run-all clean dev:tsc copy:assets",
22
+ "dev:tsc": "tsc --build tsconfig.json",
23
+ "dev:tsc:watch": "tsc --build tsconfig.json --watch",
24
+ "dev:watch": "npm-run-all clean copy:assets dev:tsc:watch",
25
+ "extract:db:api": "bin/extract-db-api && tsc --build tsconfig.test-model.json",
26
+ "publish": "npm-run-all pro:build npm:publish",
27
+ "npm:publish": "cd dist; npm publish",
28
+ "pro:build": "npm-run-all clean pro:tsc terser copy:assets",
29
+ "pro:tsc": "tsc --build tsconfig.pro.json",
30
+ "pro:tsc:watch": "tsc --build tsconfig.pro.json --watch",
31
+ "pro:watch": "npm-run-all clean copy:assets pro:tsc:watch",
30
32
  "terser": "node dist/helpers/terser-tree 'dist/**/*.js' && rm -f dist/helpers/terser-tree.*",
31
- "extract-db-api": "bin/extract-db-api && tsc --build tsconfig.test-model.json"
33
+ "test:models": "tsc --build tsconfig.test-model.json"
32
34
  },
33
35
  "exports": {
34
36
  ".": "./smart-db-api.js",
package/smart-db-api.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./smart-db";
2
+ export * from "./smart-error";
2
3
  export * from "./models/abstract-model";
3
4
  export * from "./models/smart-db-core-table-model";
4
5
  export * from "./models/smart-db-dictionary";
package/smart-db-api.js CHANGED
@@ -1 +1 @@
1
- export*from"./smart-db";export*from"./models/abstract-model";export*from"./models/smart-db-core-table-model";export*from"./models/smart-db-dictionary";export*from"./models/smart-db-log-model";export*from"./models/smart-db-version-model";export*from"./models/smart-db-version-view-model";export*from"./models/sqlite-master-model";export*from"./models/sqlite-sequence-model";export*from"./smart-db-log";export*from"./smart-db-globals";export*from"./smart-db-interfaces";
1
+ export*from"./smart-db";export*from"./smart-error";export*from"./models/abstract-model";export*from"./models/smart-db-core-table-model";export*from"./models/smart-db-dictionary";export*from"./models/smart-db-log-model";export*from"./models/smart-db-version-model";export*from"./models/smart-db-version-view-model";export*from"./models/sqlite-master-model";export*from"./models/sqlite-sequence-model";export*from"./smart-db-log";export*from"./smart-db-globals";export*from"./smart-db-interfaces";
@@ -1,8 +1,5 @@
1
- import { Observable } from "rxjs";
2
1
  import { AbstractModel } from "./models/abstract-model";
3
2
  import { SmartDbDictionary } from "./models/smart-db-dictionary";
4
- import { SmartDbVersionViewModel } from "./models/smart-db-version-view-model";
5
- import { SmartDbSqlBuildData } from "./smart-db-sql-build-data";
6
3
  export interface SmartDbOptions {
7
4
  module: string;
8
5
  sqlFilesDirectory: string;
@@ -138,44 +135,6 @@ export interface SmartDbSqlBuildDataResults {
138
135
  sql: string;
139
136
  values: SqlValueType[];
140
137
  }
141
- export interface SmartDbApi {
142
- initDb(appOptions: SmartDbOptions): Promise<SmartDbVersionViewModel[]>;
143
- exists<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): Promise<boolean>;
144
- existsSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): boolean;
145
- get<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), options: SmartDbSqlOptions<T, D>): Promise<(T | D)[] | T | D | SqlValueType | IndexedGenericModelData<T, D> | string | string[]>;
146
- getSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), options: SmartDbSqlOptions<T, D>): (T | D)[] | T | D | IndexedGenericModelData<T, D> | SqlValueType | string[] | false;
147
- getFirst<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere, fields?: string | string[] | null, orderBy?: SqlOrderBy): Promise<T | false>;
148
- getFirstSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere, fields?: string | string[] | null, orderBy?: SqlOrderBy): T | false;
149
- getAll<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere, fields?: string | string[] | null, orderBy?: SqlOrderBy, limit?: SqlLimit): Promise<T[] | false>;
150
- getAllSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere, fields?: string | string[] | null, orderBy?: SqlOrderBy, limit?: SqlLimit): T[] | false;
151
- delete<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere): Promise<number>;
152
- deleteSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere): number | false;
153
- update<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: SqlUpdateValues | T, where?: SqlWhere): Promise<number>;
154
- updateSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: SqlUpdateValues | T, where?: SqlWhere): number | false;
155
- insert<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: SqlUpdateValues | T): Promise<number>;
156
- insertSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: SqlUpdateValues | T): number | false;
157
- exec(script: string): Promise<void>;
158
- execSync(script: string): SmartDbDatabase | false;
159
- getLastError(): any;
160
- getLastBuildData(): SmartDbSqlBuildData;
161
- getDbQuote(): string;
162
- getTableInfo(table: string): Promise<SmartDbTableInfo>;
163
- toDate(d: Date | number | string): Date | null;
164
- getDbConnector(): string | SmartDbConnector;
165
- toDbTimestamp(d: Date | number): string;
166
- toDbDate(d: Date | number): string;
167
- hasConcurrentTransactions(): boolean;
168
- supportSyncCalls(): boolean;
169
- supportAsyncCalls(): boolean;
170
- closeSync(): boolean;
171
- onReady(): Observable<boolean>;
172
- hasTransaction(): boolean;
173
- commitSync(): void;
174
- rollbackSync(): void;
175
- commit(): Promise<void>;
176
- rollback(): Promise<void>;
177
- close(): Promise<void>;
178
- }
179
138
  export interface SmartDbDatabase {
180
139
  }
181
140
  export interface SmartDbConnector {
package/smart-db-log.d.ts CHANGED
@@ -1,25 +1,5 @@
1
- import { SmartDbApi } from "./smart-db-interfaces";
2
- export declare const SmartDbLogLocation: {
3
- Frontend: string;
4
- Backend: string;
5
- Database: string;
6
- UpgradeManager: string;
7
- Other: string;
8
- };
9
- export declare type SmartDbLogLocationType = typeof SmartDbLogLocation;
10
- export declare type SmartDbLogLocationKey = keyof SmartDbLogLocationType;
11
- export declare type SmartDbLogLocationValue = SmartDbLogLocationType[keyof SmartDbLogLocationType];
12
- export declare const SeverityCode: {
13
- readonly Fatal: "F";
14
- readonly Error: "E";
15
- readonly Warning: "W";
16
- readonly Info: "I";
17
- readonly Debug: "D";
18
- readonly Local: "L";
19
- };
20
- export declare type SeverityCodeType = typeof SeverityCode;
21
- export declare type SeverityCodeKey = keyof SeverityCodeType;
22
- export declare type SeverityCodeValue = SeverityCodeType[keyof SeverityCodeType];
1
+ import { SmartDb } from "./smart-db";
2
+ import { SmartErrorSeverityValue, SmartErrorLocationValue } from "./smart-error";
23
3
  export declare const SeverityLevel: {
24
4
  readonly None: 0;
25
5
  readonly Fatal: 1;
@@ -40,21 +20,21 @@ export declare class SmartDbLog {
40
20
  private dbLogging;
41
21
  private isLogging;
42
22
  private logFifo;
43
- constructor(db?: SmartDbApi);
23
+ constructor(db?: SmartDb);
44
24
  getConsoleLogLevel(): SeverityLevelValue;
45
- setConsoleLogLevel(consoleLogLevel: SeverityLevelValue): void;
46
25
  getDbLogLevel(): SeverityLevelValue;
26
+ getDbLogging(): boolean;
27
+ logDebug(type: SmartErrorLocationValue, location: string, message: string | Error, data?: any): void;
28
+ logError(type: SmartErrorLocationValue, location: string, message: string | Error, data?: any): void;
29
+ logFatal(type: SmartErrorLocationValue, location: string, message: string | Error, data?: any): void;
30
+ logInfo(type: SmartErrorLocationValue, location: string, message: string | Error, data?: any): void;
31
+ logWarning(type: SmartErrorLocationValue, location: string, message: string | Error, data?: any): void;
32
+ setConsoleLogLevel(consoleLogLevel: SeverityLevelValue): void;
33
+ setDb(db: SmartDb): void;
47
34
  setDbLogLevel(dbLogLevel: SeverityLevelValue): void;
48
- setDb(db: SmartDbApi): void;
49
- setUserId(userId: string | number): void;
50
35
  setDbLogging(dbLogging: boolean): void;
51
- getDbLogging(): boolean;
52
- logFatal(type: SmartDbLogLocationValue, location: string, message: string | Error, data?: any): void;
53
- logError(type: SmartDbLogLocationValue, location: string, message: string | Error, data?: any): void;
54
- logWarning(type: SmartDbLogLocationValue, location: string, message: string | Error, data?: any): void;
55
- logInfo(type: SmartDbLogLocationValue, location: string, message: string | Error, data?: any): void;
56
- logDebug(type: SmartDbLogLocationValue, location: string, message: string | Error, data?: any): void;
57
- writeLog(type: SmartDbLogLocationValue, location: string, severity: SeverityCodeValue, message: string | Error, data: unknown, timestamp?: Date | string | number): void;
36
+ setUserId(userId: string | number): void;
37
+ writeLog(type: SmartErrorLocationValue, location: string, severity: SmartErrorSeverityValue, message: string | Error, data: unknown, timestamp?: Date | string | number): void;
58
38
  private nextStackEntry;
59
39
  }
60
40
  export declare const smartDbLog: SmartDbLog;
package/smart-db-log.js CHANGED
@@ -1 +1 @@
1
- import _ from"lodash";import{SmartDbLogModel}from"./models/smart-db-log-model";import{SmartDbDateRegexp,SmartDbTimestampRegexp,toSmartDbTimestamp}from"./smart-db-globals";export const SmartDbLogLocation={Frontend:"frontend",Backend:"backend",Database:"database",UpgradeManager:"upgrade-manager",Other:"other"};export const SeverityCode={Fatal:"F",Error:"E",Warning:"W",Info:"I",Debug:"D",Local:"L"};export const SeverityLevel={None:0,Fatal:1,Error:2,Warning:3,Info:4,Debug:5,All:9};export class SmartDbLog{constructor(e){this.userId=null,this.dbLogging=!0,this.isLogging=!1,this.logFifo=[],this.db=e,this.dbLogging=!!e,this.dbLogLevel=SeverityLevel.Info,this.consoleLogLevel=SeverityLevel.Info}getConsoleLogLevel(){return this.consoleLogLevel}setConsoleLogLevel(e){this.consoleLogLevel=e}getDbLogLevel(){return this.dbLogLevel}setDbLogLevel(e){this.dbLogLevel=e}setDb(e){this.db=e,this.db?this.db.exists(SmartDbLogModel).then((e=>{this.dbLogging=e})).catch((e=>{throw e})):this.dbLogging=!1}setUserId(e){this.userId=e}setDbLogging(e){this.dbLogging=e}getDbLogging(){return this.dbLogging}logFatal(e,t,o,i){this.writeLog(e,t,SeverityCode.Fatal,o,i)}logError(e,t,o,i){this.writeLog(e,t,SeverityCode.Error,o,i)}logWarning(e,t,o,i){this.writeLog(e,t,SeverityCode.Warning,o,i)}logInfo(e,t,o,i){this.writeLog(e,t,SeverityCode.Info,o,i)}logDebug(e,t,o,i){this.writeLog(e,t,SeverityCode.Debug,o,i)}writeLog(e,t,o,i,s,r){try{if(this.isLogging)this.logFifo.push({type:e,location:t,severity:o,message:i,data:s,timestamp:r??new Date});else{this.isLogging=!0;let a,n,g=SeverityLevel.None;switch(o){case SeverityCode.Fatal:a=console.error,g=SeverityLevel.Fatal;break;case SeverityCode.Error:a=console.error,g=SeverityLevel.Error;break;case SeverityCode.Warning:a=console.warn,g=SeverityLevel.Warning;break;case SeverityCode.Info:a=console.info,g=SeverityLevel.Info;break;case SeverityCode.Debug:a=console.debug,g=SeverityLevel.Debug}if(_.isString(r)){const e=r.match(SmartDbTimestampRegexp),t=e&&r.match(SmartDbDateRegexp);n=e?e[1]:t?t[1]+".000":toSmartDbTimestamp(new Date)}else n=_.isDate(r)?toSmartDbTimestamp(r):_.isNumber(r)?toSmartDbTimestamp(new Date(r)):toSmartDbTimestamp(new Date);if(_.isObjectLike(i))if(i instanceof Error)s||(s=i),i=i.message;else try{i=JSON.stringify(i)}catch(e){i=i.toString()}else"boolean"==typeof i&&(i=i?"<true>":"<false>");if(s){if(s instanceof Error)s=s.stack;else if(_.isObject(s))try{s=JSON.stringify(s)}catch(e){s=s.toString(),this.db&&this.dbLogLevel>=g&&console.error("unable to stringify log data",s)}else s.toString?s=s.toString():(s=null,this.db&&this.dbLogLevel>=g&&console.error("unable to store log data",s));s&&(i+=` (${s})`)}if(this.consoleLogLevel>=g){const r=e.substring(0,1).toUpperCase();if(e==SmartDbLogLocation.Database&&this.db&&a(`${o}-${r}-${n}: last statement:`,this.db.getLastBuildData()),a(`${o}-${r}-${n}: ${i}`),this.dbLogging)try{e==SmartDbLogLocation.Database&&(s||(s=JSON.stringify(this.db.getLastBuildData()))),this.db.supportAsyncCalls()?this.db.insert(SmartDbLogModel,{severity:o,type:e,location:t,info:i||"<empty>",data:s,user:this.userId,timestamp:new Date(n)}).then((()=>{this.db.commit().then((()=>{this.isLogging=!1,this.nextStackEntry()})).catch((e=>{console.error(`F-B-${n}: unable to commit log transaction`,e,e.code,e.name,e.message),this.isLogging=!1,this.nextStackEntry()}))})).catch((e=>{console.error(`F-B-${n}: unable to write the log statement below to database`,e,e.code,e.name,e.message),this.isLogging=!1,this.nextStackEntry()})):(this.db.insertSync(SmartDbLogModel,{severity:o,type:e,location:t,info:i||"<empty>",data:s,user:this.userId,timestamp:new Date(n)}),this.isLogging=!1,this.nextStackEntry())}catch(e){console.error(`F-B-${n}: unable to write the log statement below to database`,e,e.code,e.name,e.message);try{a(`F-B-${n}: last statement:`,this.db.getLastBuildData())}catch{a(`F-B-${n}: last statement not available`)}this.isLogging=!1,this.nextStackEntry()}else this.isLogging=!1,this.nextStackEntry()}else this.isLogging=!1,this.nextStackEntry()}}catch(e){this.isLogging=!1,console.error("fatal logging error",e)}}nextStackEntry(){if(this.logFifo.length>0){const e=this.logFifo.shift();this.writeLog(e.type,e.location,e.severity,e.message,e.data,e.timestamp)}}}export const smartDbLog=new SmartDbLog;
1
+ import _ from"lodash";import{SmartDbLogModel}from"./models/smart-db-log-model";import{SmartErrorSeverity,SmartErrorLocation}from"./smart-error";import{SmartDbDateRegexp,SmartDbTimestampRegexp,toSmartDbTimestamp}from"./smart-db-globals";export const SeverityLevel={None:0,Fatal:1,Error:2,Warning:3,Info:4,Debug:5,All:9};export class SmartDbLog{constructor(t){this.userId=null,this.dbLogging=!0,this.isLogging=!1,this.logFifo=[],this.db=t,this.dbLogging=!1,this.dbLogLevel=SeverityLevel.Info,this.consoleLogLevel=SeverityLevel.Info}getConsoleLogLevel(){return this.consoleLogLevel}getDbLogLevel(){return this.dbLogLevel}getDbLogging(){return this.dbLogging}logDebug(t,e,r,o){this.writeLog(t,e,SmartErrorSeverity.Debug,r,o)}logError(t,e,r,o){this.writeLog(t,e,SmartErrorSeverity.Error,r,o)}logFatal(t,e,r,o){this.writeLog(t,e,SmartErrorSeverity.Fatal,r,o)}logInfo(t,e,r,o){this.writeLog(t,e,SmartErrorSeverity.Info,r,o)}logWarning(t,e,r,o){this.writeLog(t,e,SmartErrorSeverity.Warning,r,o)}setConsoleLogLevel(t){this.consoleLogLevel=t}setDb(t){this.db=t,this.db?this.db.exists(SmartDbLogModel).then((t=>{this.dbLogging=t})).catch((t=>{throw t})):this.dbLogging=!1}setDbLogLevel(t){this.dbLogLevel=t}setDbLogging(t){this.dbLogging=t}setUserId(t){this.userId=t}writeLog(t,e,r,o,i,s){try{if(this.isLogging)this.logFifo.push({type:t,location:e,severity:r,message:o,data:i,timestamp:s??new Date});else{this.isLogging=!0;let a,g,n=SeverityLevel.None;switch(r){case SmartErrorSeverity.Fatal:a=console.error,n=SeverityLevel.Fatal;break;case SmartErrorSeverity.Error:a=console.error,n=SeverityLevel.Error;break;case SmartErrorSeverity.Warning:a=console.warn,n=SeverityLevel.Warning;break;case SmartErrorSeverity.Info:a=console.info,n=SeverityLevel.Info;break;case SmartErrorSeverity.Debug:a=console.debug,n=SeverityLevel.Debug}if(_.isString(s)){const t=s.match(SmartDbTimestampRegexp),e=t&&s.match(SmartDbDateRegexp);g=t?t[1]:e?e[1]+".000":toSmartDbTimestamp(new Date)}else g=_.isDate(s)?toSmartDbTimestamp(s):_.isNumber(s)?toSmartDbTimestamp(new Date(s)):toSmartDbTimestamp(new Date);if(_.isObjectLike(o))if(o instanceof Error)i||(i=o),o=o.message;else try{o=JSON.stringify(o)}catch(t){o=o.toString()}else"boolean"==typeof o&&(o=o?"<true>":"<false>");if(i){if(i instanceof Error)i=i.stack;else if(_.isObject(i))try{i=JSON.stringify(i)}catch(t){i=i.toString(),this.db&&this.dbLogLevel>=n&&console.error("unable to stringify log data",i)}else i.toString?i=i.toString():(i=null,this.db&&this.dbLogLevel>=n&&console.error("unable to store log data",i));i&&(o+=` (${i})`)}if(this.consoleLogLevel>=n){const s=t.substring(0,1).toUpperCase();if(t==SmartErrorLocation.Database&&this.db&&a(`${r}-${s}-${g}: last statement:`,this.db.getLastBuildData()),a(`${r}-${s}-${g}: ${o}`),this.dbLogging)try{t==SmartErrorLocation.Database&&(i||(i=JSON.stringify(this.db.getLastBuildData()))),this.db.supportSyncCalls?(this.db.insertSync(SmartDbLogModel,{severity:r,type:t,location:e,info:o||"<empty>",data:i,user:this.userId,timestamp:new Date(g)}),this.isLogging=!1,this.nextStackEntry()):this.db.insert(SmartDbLogModel,{severity:r,type:t,location:e,info:o||"<empty>",data:i,user:this.userId,timestamp:new Date(g)}).then((()=>{this.db.commit().then((()=>{this.isLogging=!1,this.nextStackEntry()})).catch((t=>{console.error(`F-B-${g}: unable to commit log transaction`,t,t.code,t.name,t.message),this.isLogging=!1,this.nextStackEntry()}))})).catch((t=>{console.error(`F-B-${g}: unable to write the log statement below to database`,t,t.code,t.name,t.message),this.isLogging=!1,this.nextStackEntry()}))}catch(t){console.error(`F-B-${g}: unable to write the log statement below to database`,t,t.code,t.name,t.message);try{a(`F-B-${g}: last statement:`,this.db.getLastBuildData())}catch{a(`F-B-${g}: last statement not available`)}this.isLogging=!1,this.nextStackEntry()}else this.isLogging=!1,this.nextStackEntry()}else this.isLogging=!1,this.nextStackEntry()}}catch(t){this.isLogging=!1,console.error("fatal logging error",t)}}nextStackEntry(){if(this.logFifo.length>0){const t=this.logFifo.shift();this.writeLog(t.type,t.location,t.severity,t.message,t.data,t.timestamp)}}}export const smartDbLog=new SmartDbLog;
@@ -7,7 +7,6 @@ export declare class SmartDbUpgradeManager {
7
7
  constructor(db: SmartDb);
8
8
  hasDatabaseModule(module: string): Promise<boolean>;
9
9
  prepareDatabase(options: SmartDbOptions): Promise<SmartDbVersionViewModel>;
10
- private executeSqlScript;
11
10
  private upgradeDatabase;
12
- private executeScriptSequentially;
11
+ private executeScriptsSequentially;
13
12
  }
@@ -1 +1 @@
1
- import*as fs from"fs";import _ from"lodash";import{SmartDbVersionModel}from"./models/smart-db-version-model";import{SmartDbVersionViewModel}from"./models/smart-db-version-view-model";import{SmartDbLogLocation}from"./smart-db-log";export class SmartDbUpgradeManager{constructor(e){this.db=e,this.log=e.getLogger()}hasDatabaseModule(e){return new Promise(((t,a)=>{this.db.exists(SmartDbVersionModel).then((o=>{o?this.db.getFirst(SmartDbVersionModel,{module:e}).then((e=>{t(!!e)})).catch((e=>{a(e)})):t(!1)})).catch((e=>{a(e)}))}))}prepareDatabase(e){return new Promise(((t,a)=>{try{const o=fs.existsSync(e.sqlFilesDirectory)&&fs.statSync(e.sqlFilesDirectory);if(o&&o.isDirectory()){const o=e.sqlFilesDirectory+`/${e.module}-init.sql`;fs.existsSync(o)?this.hasDatabaseModule(e.module).then((r=>{r?(this.log.logInfo(SmartDbLogLocation.UpgradeManager,"prepareDatabase",`database module '${e.module}' exists`),this.upgradeDatabase(e).then((a=>{this.log.logInfo(SmartDbLogLocation.UpgradeManager,"prepareDatabase",`connected to module '${e.module}' version ${a.versionString}`),t(a)})).catch((e=>{a(e)}))):(this.log.setDbLogging(!1),this.log.logInfo(SmartDbLogLocation.UpgradeManager,"prepareDatabase",`database module '${e.module}' doesn't exists - begin creation`),this.executeSqlScript(o).then((()=>{this.log.setDbLogging(this.db.dbLogging),this.log.logInfo(SmartDbLogLocation.UpgradeManager,"prepareDatabase","database module creation complete"),this.hasDatabaseModule(e.module).then((o=>{o?(this.log.logInfo(SmartDbLogLocation.UpgradeManager,"prepareDatabase",`successfully initialized database for new module ${e.module}`),this.upgradeDatabase(e).then((a=>{this.log.logInfo(SmartDbLogLocation.UpgradeManager,"prepareDatabase",`connected to module '${e.module}' version ${a.versionString}`),t(a)})).catch((e=>{a(e)}))):a("error running database initialization script")})).catch((e=>{a(e)}))})).catch((e=>{a(e)})))})).catch((e=>{a(e)})):a(`missing mandatory '${e.module}-init.sql' file in ${o}`)}else a(`option 'sqlFilesDirectory' (${e.sqlFilesDirectory}) must point to an existing directory (absolute or relative to ${fs.realpathSync(".")})`)}catch(e){a(e)}}))}executeSqlScript(e){return new Promise((async(t,a)=>{const o=fs.readFileSync(e,"utf8"),r=[];let s=0,i=0,n=!1,l=0,c=!1,d="";for(;i<o.length;)"'"==o[i]?n=!n:n||c||!o.substring(i,i+6).match(/^begin(\s|\n)/)?l>0&&!n&&!c&&o.substring(i,i+4).match(/^end;/)?(l-=1,i+=4):0!==l||n||"/"!=o[i]?n||"-"!=o[i]||"-"!=o[i+1]?c&&"\n"==o[i]?(c=!1,s=i+2):0!==l||n||c||";"!=o[i]||(r.push(d+o.substring(s,i).trim()),d="",s=i+2):(d+=o.substring(s,i),c=!0):(r.push(d+o.substring(s,i).trim()),d="",s=i+2):(l+=1,i+=6),i+=1;if(s<o.length){const e=o.substring(s,o.length).trim().replace(/;$/,"");console.log(e),""!==e&&r.push(e)}for(const e of r)try{await this.db.exec(e)}catch(t){if("drop "!=e.substring(0,5).toLowerCase())throw t}await this.db.exec("COMMIT WORK"),t()}))}upgradeDatabase(e){return new Promise(((t,a)=>{this.db.getFirst(SmartDbVersionViewModel,{module:e.module}).then((o=>{o?fs.readdir(e.sqlFilesDirectory,((r,s)=>{if(r)a(`unable to read database files from ${e.sqlFilesDirectory}`);else{let r=[];s.forEach((t=>{const a=new RegExp(`^${e.module}-update.([0-9]{3})\\..*\\.sql$`),s=t.match(a);if(s){parseInt(s[1],10)>o.sequence&&r.push(t)}})),r=_.sortBy(r),this.executeScriptSequentially(r,e).then((()=>{this.db.getFirst(SmartDbVersionViewModel,{module:e.module},"*","sequence DESC").then((e=>{e?t(SmartDbVersionViewModel.from(e)):a("unable to determine final smart db version")})).catch((e=>{a(e)}))})).catch((e=>{a(e)}))}})):a(`missing version entry for module ${e.module} - add the mandatory insert into smart_db_version statement to your database creation script!`)})).catch((e=>{a(e)}))}))}executeScriptSequentially(e,t){return new Promise((async(a,o)=>{e&&e.length>0?(this.log.logInfo(SmartDbLogLocation.UpgradeManager,"upgradeDatabase",`execute update script '${e[0]}' for module ${t.module}`),await this.executeSqlScript(`${t.sqlFilesDirectory}/${e[0]}`).then((()=>{this.log.logInfo(SmartDbLogLocation.UpgradeManager,"upgradeDatabase",`successfully executed update script '${e[0]}' for module ${t.module}`),1==e.length&&a(!0)})).catch((e=>{o(e)})),e.length>1&&this.executeScriptSequentially(e.splice(1),t).then((e=>{a(e)})).catch((e=>{o(e)}))):a(!0)}))}}
1
+ import*as fs from"fs";import _ from"lodash";import{SmartDbVersionModel}from"./models/smart-db-version-model";import{SmartDbVersionViewModel}from"./models/smart-db-version-view-model";import{SmartErrorLocation}from"./smart-error";export class SmartDbUpgradeManager{constructor(e){this.db=e,this.log=e.getLogger()}hasDatabaseModule(e){return new Promise(((t,r)=>{this.db.exists(SmartDbVersionModel).then((a=>{a?this.db.getFirst(SmartDbVersionModel,{module:e}).then((e=>{t(!!e)})).catch((e=>{r(e)})):t(!1)})).catch((e=>{r(e)}))}))}prepareDatabase(e){return new Promise(((t,r)=>{try{const a=fs.existsSync(e.sqlFilesDirectory)&&fs.statSync(e.sqlFilesDirectory);if(a&&a.isDirectory()){const a=e.sqlFilesDirectory+`/${e.module}-init.sql`;fs.existsSync(a)?this.hasDatabaseModule(e.module).then((o=>{o?(this.log.logInfo(SmartErrorLocation.UpgradeManager,"prepareDatabase",`database module '${e.module}' exists`),this.upgradeDatabase(e).then((r=>{this.log.logInfo(SmartErrorLocation.UpgradeManager,"prepareDatabase",`connected to module '${e.module}' version ${r.versionString}`),t(r)})).catch((e=>{r(e)}))):(this.log.setDbLogging(!1),this.log.logInfo(SmartErrorLocation.UpgradeManager,"prepareDatabase",`database module '${e.module}' doesn't exists - begin creation`),this.db.execScript(a,!0).then((()=>{this.log.setDbLogging(this.db.dbLogging),this.log.logInfo(SmartErrorLocation.UpgradeManager,"prepareDatabase","database module creation complete"),this.hasDatabaseModule(e.module).then((a=>{a?(this.log.logInfo(SmartErrorLocation.UpgradeManager,"prepareDatabase",`successfully initialized database for new module ${e.module}`),this.upgradeDatabase(e).then((r=>{this.log.logInfo(SmartErrorLocation.UpgradeManager,"prepareDatabase",`connected to module '${e.module}' version ${r.versionString}`),t(r)})).catch((e=>{r(e)}))):r("error running database initialization script")})).catch((e=>{r(e)}))})).catch((e=>{r(e)})))})).catch((e=>{r(e)})):r(`missing mandatory '${e.module}-init.sql' file in ${a}`)}else r(`option 'sqlFilesDirectory' (${e.sqlFilesDirectory}) must point to an existing directory (absolute or relative to ${fs.realpathSync(".")})`)}catch(e){r(e)}}))}upgradeDatabase(e){return new Promise(((t,r)=>{this.db.getFirst(SmartDbVersionViewModel,{module:e.module}).then((a=>{a?fs.readdir(e.sqlFilesDirectory,((o,s)=>{if(o)r(`unable to read database files from ${e.sqlFilesDirectory}`);else{let o=[];s.forEach((t=>{const r=new RegExp(`^${e.module}-update.([0-9]{3})\\..*\\.sql$`),s=t.match(r);if(s){parseInt(s[1],10)>a.sequence&&o.push(t)}})),o=_.sortBy(o),this.executeScriptsSequentially(o,e).then((()=>{this.db.getFirst(SmartDbVersionViewModel,{module:e.module},"*","sequence DESC").then((e=>{e?t(SmartDbVersionViewModel.from(e)):r("unable to determine final smart db version")})).catch((e=>{r(e)}))})).catch((e=>{r(e)}))}})):r(`missing version entry for module ${e.module} - add the mandatory insert into smart_db_version statement to your database creation script!`)})).catch((e=>{r(e)}))}))}executeScriptsSequentially(e,t){return new Promise((async(r,a)=>{e&&e.length>0?(this.log.logInfo(SmartErrorLocation.UpgradeManager,"upgradeDatabase",`execute update script '${e[0]}' for module ${t.module}`),await this.db.execScript(`${t.sqlFilesDirectory}/${e[0]}`).then((()=>{this.log.logInfo(SmartErrorLocation.UpgradeManager,"upgradeDatabase",`successfully executed update script '${e[0]}' for module ${t.module}`),1==e.length&&r(!0)})).catch((e=>{a(e)})),e.length>1&&this.executeScriptsSequentially(e.splice(1),t).then((e=>{r(e)})).catch((e=>{a(e)}))):r(!0)}))}}
package/smart-db.d.ts CHANGED
@@ -1,67 +1,68 @@
1
1
  import { BehaviorSubject, Subject } from "rxjs";
2
2
  import { AbstractModel } from "./models/abstract-model";
3
3
  import { SmartDbVersionViewModel } from "./models/smart-db-version-view-model";
4
- import { GenericModelData, IndexedGenericModelData, SmartDbApi, SmartDbConnector, SmartDbDatabase, SmartDbOptions, SmartDbRunResult, SmartDbSqlOptions, SmartDbTableInfo, SqlFieldDescriptor, SqlLimit, SqlOrderBy, SqlUpdateValues, SqlValueType, SqlWhere } from "./smart-db-interfaces";
4
+ import { GenericModelData, IndexedGenericModelData, SmartDbConnector, SmartDbDatabase, SmartDbOptions, SmartDbRunResult, SmartDbSqlOptions, SmartDbTableInfo, SqlFieldDescriptor, SqlLimit, SqlOrderBy, SqlUpdateValues, SqlValueType, SqlWhere } from "./smart-db-interfaces";
5
5
  import { SmartDbLog } from "./smart-db-log";
6
6
  import { SmartDbSqlBuildData } from "./smart-db-sql-build-data";
7
- export declare abstract class SmartDb implements SmartDbApi {
7
+ import { SmartError } from "./smart-error";
8
+ export declare abstract class SmartDb {
8
9
  abstract getDatabaseType(): string;
9
- abstract hasConcurrentTransactions(): boolean;
10
- abstract supportSyncCalls(): boolean;
11
- abstract supportAsyncCalls(): boolean;
12
- abstract exists<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): Promise<boolean>;
13
- abstract existsSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): boolean;
14
- abstract exec(script: string): Promise<void>;
15
- abstract execSync(script: string): SmartDbDatabase | false;
16
- abstract close(): Promise<void>;
17
- abstract closeSync(): boolean;
18
- abstract getDbQuote(): string;
19
10
  abstract getTableInfo(table: string): Promise<SmartDbTableInfo>;
20
- abstract getDbConnector(): string | SmartDbConnector;
21
- abstract hasTransaction(): boolean;
22
- abstract commit(): Promise<void>;
23
- abstract rollback(): Promise<void>;
24
- abstract commitSync(): void;
25
- abstract rollbackSync(): void;
26
- protected abstract statementRun(buildData: SmartDbSqlBuildData): Promise<SmartDbRunResult>;
27
- protected abstract statementRunSync(buildData: SmartDbSqlBuildData): SmartDbRunResult;
28
- protected abstract statementGet(buildData: SmartDbSqlBuildData): Promise<any>;
29
- protected abstract statementGetSync(buildData: SmartDbSqlBuildData): any;
30
- protected abstract statementGetAll(buildData: SmartDbSqlBuildData): Promise<any[]>;
31
- protected abstract statementGetAllSync(buildData: SmartDbSqlBuildData): any[];
32
11
  protected: any;
33
12
  readonly dbLogging: boolean;
34
13
  protected dbConnector: SmartDbConnector;
35
- protected lastError: Error;
36
14
  protected lastBuildData: SmartDbSqlBuildData;
37
15
  protected smartDbLog: SmartDbLog;
38
16
  protected _onReady: BehaviorSubject<boolean>;
39
17
  protected db: SmartDbDatabase;
18
+ private _lastError;
40
19
  private dictionaries;
41
20
  private _isReady;
42
21
  protected constructor(dbConnector: SmartDbConnector, noDbLogging?: boolean);
43
- initDb(appOptions: SmartDbOptions): Promise<SmartDbVersionViewModel[]>;
44
- onReady(): Subject<boolean>;
45
- getLogger(): SmartDbLog;
46
- getDb(): SmartDbDatabase;
47
- getLastBuildData(): SmartDbSqlBuildData;
22
+ buildSelectStatement<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), options: SmartDbSqlOptions<T, D>): SmartDbSqlBuildData;
23
+ close(): Promise<boolean>;
24
+ closeSync(): boolean;
25
+ commit(): Promise<void>;
26
+ commitSync(): void;
27
+ delete<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere): Promise<number>;
28
+ deleteSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere): number | false;
29
+ exec(script: string): Promise<void>;
30
+ execScript(script: string, ignoreDropError?: boolean): Promise<void>;
31
+ execScriptSync(script: string): void;
32
+ execSync(script: string): boolean;
33
+ exists<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): Promise<boolean>;
34
+ existsSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): boolean;
48
35
  get<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), options: SmartDbSqlOptions<T, D>): Promise<(T | D)[] | T | D | SqlValueType | IndexedGenericModelData<T, D> | string | string[] | false>;
49
- getSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), options: SmartDbSqlOptions<T, D>): (T | D)[] | T | D | SqlValueType | IndexedGenericModelData<T, D> | string | string[] | false;
50
- getFirst<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere, fields?: string | string[] | null, orderBy?: SqlOrderBy): Promise<T | false>;
51
- getFirstSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere, fields?: string | string[] | null, orderBy?: SqlOrderBy): T | false;
52
36
  getAll<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere, fields?: string | string[] | null, orderBy?: SqlOrderBy, limit?: SqlLimit): Promise<T[] | false>;
53
37
  getAllSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere, fields?: string | string[] | null, orderBy?: SqlOrderBy, limit?: SqlLimit): T[] | false;
54
- delete<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere): Promise<number>;
55
- deleteSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere): number | false;
56
- update<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: SqlUpdateValues | T, where?: SqlWhere): Promise<number>;
57
- updateSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: SqlUpdateValues | T, where?: SqlWhere): number | false;
38
+ getDb(): SmartDbDatabase;
39
+ getDbConnector(): string | SmartDbConnector;
40
+ getDbQuote(): string;
41
+ getFirst<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere, fields?: string | string[] | null, orderBy?: SqlOrderBy): Promise<T | false>;
42
+ getFirstSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere, fields?: string | string[] | null, orderBy?: SqlOrderBy): T | false;
43
+ getLastBuildData(): SmartDbSqlBuildData;
44
+ getLastError(): SmartError;
45
+ getLogger(): SmartDbLog;
46
+ getSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), options: SmartDbSqlOptions<T, D>): (T | D)[] | T | D | SqlValueType | IndexedGenericModelData<T, D> | string | string[] | false;
47
+ hasConcurrentTransactions(): boolean;
48
+ hasTransaction(): boolean;
49
+ initDb(appOptions: SmartDbOptions): Promise<SmartDbVersionViewModel[]>;
58
50
  insert<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: SqlUpdateValues | T): Promise<number>;
59
51
  insertSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: SqlUpdateValues | T): number | false;
60
- getLastError(): Error;
61
- buildSelectStatement<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), options: SmartDbSqlOptions<T, D>): SmartDbSqlBuildData;
52
+ onReady(): Subject<boolean>;
53
+ rollback(): Promise<void>;
54
+ rollbackSync(): void;
62
55
  toDate(d: Date | number | string): Date | null;
63
- toDbTimestamp(d: Date | number): string;
64
56
  toDbDate(d: Date | number): string;
57
+ toDbTimestamp(d: Date | number): string;
58
+ update<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: SqlUpdateValues | T, where?: SqlWhere): Promise<number>;
59
+ updateSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: SqlUpdateValues | T, where?: SqlWhere): number | false;
60
+ protected statementRun(buildData: SmartDbSqlBuildData): Promise<SmartDbRunResult>;
61
+ protected statementRunSync(buildData: SmartDbSqlBuildData): SmartDbRunResult;
62
+ protected statementGet<T extends object>(buildData: SmartDbSqlBuildData): Promise<T>;
63
+ protected statementGetSync(buildData: SmartDbSqlBuildData): any;
64
+ protected statementGetAll<T>(buildData: SmartDbSqlBuildData): Promise<T[]>;
65
+ protected statementGetAllSync(buildData: SmartDbSqlBuildData): any[];
65
66
  protected buildWhere<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where: SqlWhere, op?: string): SmartDbSqlBuildData;
66
67
  protected buildDeleteStatement<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere): SmartDbSqlBuildData;
67
68
  protected buildUpdateStatement<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: D | T, where?: SqlWhere): SmartDbSqlBuildData;
@@ -74,9 +75,13 @@ export declare abstract class SmartDb implements SmartDbApi {
74
75
  protected makeDbValue(value: SqlValueType): SqlValueType;
75
76
  protected makeArgumentDbValue(value: SqlValueType): SqlValueType;
76
77
  protected saveExecute<T>(fn: () => T): T | false;
78
+ private scriptParser;
77
79
  private prepareResultRow;
78
80
  private prepareResultRows;
79
81
  private getTableName;
80
82
  get isReady(): boolean;
81
83
  set isReady(ready: boolean);
84
+ get lastError(): SmartError;
85
+ set lastError(value: any);
86
+ get supportSyncCalls(): boolean;
82
87
  }
package/smart-db.js CHANGED
@@ -1 +1 @@
1
- import _ from"lodash";import{BehaviorSubject}from"rxjs";import{AbstractModel}from"./models/abstract-model";import{SmartDbDictionary}from"./models/smart-db-dictionary";import{SmartDbLogModel}from"./models/smart-db-log-model";import{IN,smartDbToDate,toSmartDbDate,toSmartDbTimestamp}from"./smart-db-globals";import{FieldNamingStyle,SqlFieldOperationType,SqlOperationType}from"./smart-db-interfaces";import{SmartDbLog,SmartDbLogLocation}from"./smart-db-log";import{SmartDbSqlBuildData}from"./smart-db-sql-build-data";import{SmartDbUpgradeManager}from"./smart-db-upgrade-manager";export class SmartDb{constructor(e,t){this.dictionaries=[],this.dbConnector=e,this.smartDbLog=new SmartDbLog(t?null:this),this.dbLogging=!t,this.db=null,this._isReady=null,this._onReady=new BehaviorSubject(!1)}initDb(e){return new Promise(((t,a)=>{this.dictionaries.push(SmartDbDictionary);const s=new SmartDbUpgradeManager(this);let r;r=import.meta&&import.meta.url?import.meta.url.replace(/file:\/\//,"").replace(/\/[^/]*$/,""):__dirname;const i={module:"smart-db-core",sqlFilesDirectory:r+"/assets/"+this.getDatabaseType()};s.prepareDatabase(i).then((r=>{this.exists(SmartDbLogModel).then((i=>{this.smartDbLog.setDbLogging(this.dbLogging&&i),s.prepareDatabase(e).then((e=>{t([r,e])}),(e=>{a(e)}))}))})).catch((e=>{a(e)}))}))}onReady(){return this._onReady}getLogger(){return this.smartDbLog}getDb(){return this.db}getLastBuildData(){return this.lastBuildData}get(e,t){return new Promise(((a,s)=>{if(this.supportAsyncCalls()){t||(t={});const r=this.buildSelectStatement(e,t);t.firstOnly||t.count?this.statementGet(r).then((s=>{a(this.prepareResultRow(e,s,t))})).catch((e=>{s(e)})):this.statementGetAll(r).then((s=>{a(this.prepareResultRows(e,s,t))})).catch((e=>{s(e)}))}else s("get: this database driver doesn't support async calls")}))}getSync(e,t){if(this.supportSyncCalls())return this.saveExecute((()=>{t||(t={});const a=this.buildSelectStatement(e,t);let s;if(t.firstOnly||t.count){const r=this.statementGetSync(a);s=this.prepareResultRow(e,r,t)}else{const r=this.statementGetAllSync(a);s=this.prepareResultRows(e,r,t)}return s}));throw"getSync: this database driver doesn't support sync calls"}getFirst(e,t,a,s){return this.get(e,{firstOnly:!0,where:t,fields:a,orderBy:s})}getFirstSync(e,t,a,s){return this.getSync(e,{firstOnly:!0,where:t,fields:a,orderBy:s})}getAll(e,t,a,s,r){return this.get(e,{where:t,fields:a,orderBy:s,limit:r})}getAllSync(e,t,a,s,r){return this.getSync(e,{where:t,fields:a,orderBy:s,limit:r})}delete(e,t){return new Promise(((a,s)=>{if(this.supportAsyncCalls()){const r=this.buildDeleteStatement(e,t);this.statementRun(r).then((e=>{e?a(e.changes):s(this.getLastError())})).catch((e=>{s(e)}))}else s("delete: this database driver doesn't support sync calls")}))}deleteSync(e,t){if(this.supportSyncCalls())return this.saveExecute((()=>{const a=this.buildDeleteStatement(e,t);return this.statementRunSync(a).changes}));throw"deleteSync: this database driver doesn't support sync calls"}update(e,t,a){return new Promise(((s,r)=>{if(this.supportAsyncCalls()){const i=this.buildUpdateStatement(e,t,a);this.statementRun(i).then((e=>{e?s(e.changes):r(this.getLastError())})).catch((e=>{r(e)}))}else r("update: this database driver doesn't support sync calls")}))}updateSync(e,t,a){if(this.supportSyncCalls())return this.saveExecute((()=>{const s=this.buildUpdateStatement(e,t,a);return this.statementRunSync(s).changes}));throw"updateSync: this database driver doesn't support sync calls"}insert(e,t){return new Promise(((a,s)=>{if(this.supportAsyncCalls()){const r=this.buildInsertStatement(e,t);this.statementRun(r).then((e=>{e?a(e.lastId):s(this.getLastError())})).catch((e=>{s(e)}))}else s("insert: this database driver doesn't support sync calls")}))}insertSync(e,t){if(this.supportSyncCalls())return this.saveExecute((()=>{const a=this.buildInsertStatement(e,t);return this.statementRunSync(a).lastId}));throw"insertSync: this database driver doesn't support sync calls"}getLastError(){return this.lastError}buildSelectStatement(e,t){t||(t={});const a=this.buildSelectSectionStatement(e,t);if(_.forEach(["union","minus","intersect"],(e=>{let s=_.get(t,e);s&&(_.isArray(s)||(s=[s]),_.forEach(s,(t=>{const s=this.buildSelectSectionStatement(t.model,t);a.sql+=" "+e.toUpperCase()+" ",a.append(s)})))})),t.orderBy){a.sql+=" ORDER BY ";const s=_.isString(t.orderBy)?t.orderBy.split(/ *, */):t.orderBy;a.sql+=s.map((t=>{let a="";const s=t.match(/^(\w*) (asc|desc)$/i);return s&&(t=s[1],a=s[2].toUpperCase()),t=this.translateFieldName(e,t),a&&(t+=" "+a),t})).join(", ")}return t.limit&&(t.limit.limit&&(a.sql+=" LIMIT "+t.limit.limit.toString()),t.limit.offset&&(a.sql+=" OFFSET "+t.limit.offset.toString())),this.lastBuildData=a,a}toDate(e){return smartDbToDate(e)}toDbTimestamp(e){return toSmartDbTimestamp(e)}toDbDate(e){return toSmartDbDate(e)}buildWhere(e,t,a){const s=new SmartDbSqlBuildData;return t&&_.keys(t).length>0&&(a||(a="AND",s.sql+=" WHERE "),s.sql+=_.map(t,((t,r)=>{const i=r.toUpperCase();if("AND"==i||"OR"==i){let a="";return(_.isArray(t)?t:[t]).forEach(((t,r)=>{const l=this.buildWhere(e,t,i);r>0&&(a+=" "+i+" "),a+=l.sql,s.values=_.concat(s.values,l.values)})),a="("+a+")",a}if("EXPRESSION"==i){let r=[];return _.forEach(t,(t=>{const a=this.prepareField(e,t.compare,s.values),i=this.prepareField(e,t.with,s.values);let l;l=_.isString(t.operation)&&SqlOperationType[t.operation]?SqlOperationType[t.operation]:t.operation||SqlOperationType.EQ,r.push(`${a} ${l} ${i}`)})),r.join(" "+a+" ")}{let a,i,l=!0;if(_.isArray(t)&&(t=IN(t)),_.isObject(t)){const e=t;switch(_.isString(e.operation)&&SqlOperationType[e.operation]&&(e.operation=SqlOperationType[e.operation]),e.operation){case SqlOperationType.IN:case SqlOperationType.NOT_IN:const t=new Array(e.value.length);t.fill("?"),a=e.operation+" ("+t.join(", ")+")",s.values=_.concat(s.values,e.value);break;case SqlOperationType.IS_NULL:case SqlOperationType.IS_NOT_NULL:a=e.operation;break;case SqlOperationType.LITERAL:r=e.key;const i=e.literalOperation||SqlOperationType.EQ;if(i==SqlOperationType.IN||i==SqlOperationType.NOT_IN){const t=new Array(e.value.length);t.fill("?"),a=i+" ("+t.join(", ")+")",s.values=_.concat(s.values,e.value)}else _.isUndefined(e.value)?a=i:(a=i+" ?",s.values.push(this.makeDbValue(e.value)));l=!1;break;default:a=e.operation+" ?",s.values.push(this.makeDbValue(e.value))}}else null===t?a=SqlOperationType.IS_NULL:void 0===t?(r="1",a="= 1",l=!1):(a=_.isString(t)&&t.match(/[%_]/)?SqlOperationType.LIKE+" ?":SqlOperationType.EQ+" ?",s.values.push(this.makeDbValue(t)));return i=l?this.translateFieldName(e,r)+" "+a:r+" "+a,i}})).join(" "+a+" ")),s}buildDeleteStatement(e,t){const a=this.getTableName(e),s=new SmartDbSqlBuildData("DELETE FROM");return s.sql+=" "+a,t&&s.append(this.buildWhere(e,t)),this.lastBuildData=s,s}buildUpdateStatement(e,t,a){const s=this.getTableName(e),r=new SmartDbSqlBuildData("UPDATE");r.sql+=" "+s+" SET ";const i=[],l=t instanceof AbstractModel?t.getPlainObject(FieldNamingStyle.Database):t;return _.forOwn(l,((t,a)=>{i.push(this.translateFieldName(e,a)+" = ?"),r.values.push(this.makeDbValue(t))})),r.sql+=i.join(", "),a&&r.append(this.buildWhere(e,a)),this.lastBuildData=r,r}buildInsertStatement(e,t){const a=this.getTableName(e),s=new SmartDbSqlBuildData("INSERT");s.sql+=" INTO "+a;const r=[];t instanceof AbstractModel&&(t=t.getPlainObject(FieldNamingStyle.Database)),_.forOwn(t,((t,a)=>{a=this.translateFieldName(e,a),r.push(a),s.values.push(this.makeDbValue(t))}));const i=new Array(r.length);return i.fill("?"),s.sql+=" ("+r.join(", ")+") VALUES ("+i.join(", ")+")",this.lastBuildData=s,s}prepareFieldValue(e,t){let a="<undefined>";switch(t.operation){case SqlFieldOperationType.FIELD:a=this.translateFieldName(e,t.value);break;case SqlFieldOperationType.VALUE:null===t.value?a="NULL":t.literal?a=t.value:_.isString(t.value)?!isNaN(parseFloat(t.value))&&isFinite(t.value)||(a="'"+t.value+"'"):_.isNumber(t.value)?a=t.value.toString():_.isBoolean(t.value)?a=t.value?"1":"0":_.isDate(t.value)?a="'"+t.value.toISOString().substr(0,23).replace("T"," ")+"'":console.error("unhandled field data type",typeof t.value,t.value);break;case SqlFieldOperationType.COUNT:a=_.isArray(t.value)?"COUNT("+t.value.join(",")+")":"COUNT("+(t.value||"")+")";break;case SqlFieldOperationType.COALESCE:const s=_.isArray(t.value)?t.value:[t.value];a="COALESCE("+this.buildFieldList(e,s).join(",")+")"}if(t.alias){const e=this.getDbQuote();a+=` as ${e}${t.alias}${e}`}return a}prepareField(e,t,a){let s;if(null===t)s="NULL";else if(_.isString(t)){const r=t.match(/^'(.*)'$/);r?a?(s="?",a.push(r[1])):s=t:s=this.translateFieldName(e,t)}else t.operation?s=this.prepareFieldValue(e,t):a?(s="?",a.push(t)):s=this.makeArgumentDbValue(t).toString();return s}buildFieldList(e,t){const a=[];return _.forEach(t,(t=>{a.push(this.prepareField(e,t))})),a}buildSelectSectionStatement(e,t){const a=this.getTableName(e);let s,r;if(_.isArray(t.fields))s=t.fields;else if(_.isString(t.fields)){const e=t.fields.trim();s=""===e||"*"==e?[]:e.split(/,/)}else s=t.fields&&t.fields.operation?[t.fields]:[];if(s.length>0){r=this.buildFieldList(e,s).join(", ")}else r="*";t.distinct&&(r="DISTINCT "+r),t.count&&(r=`COUNT(${r})`);const i=new SmartDbSqlBuildData(`SELECT ${r} FROM ${a}`);if(t.where&&i.append(this.buildWhere(e,t.where)),t.groupBy){i.sql+=" GROUP BY ";const a=_.isArray(t.groupBy)?t.groupBy:[t.groupBy];i.sql+=a.map((t=>this.translateFieldName(e,t))).join(", ")}return i}translateFieldName(e,t){if(_.isString(e)){const t=e;let a=!1;_.forEach(this.dictionaries,(s=>(s.models&&s.models[t]&&(e=s.models[t].cls,a=!0),!a)))}if(!_.isString(e)){const a=e.attributeMap[t];if(a)a.alias&&(t=a.alias);else{const a=e.getTableName();this.lastError=new Error(`unknown field '${t}' in table '${a}'`),this.smartDbLog.logError(SmartDbLogLocation.Database,"translateFieldName",this.lastError)}}return t}makeDbValue(e){return _.isBoolean(e)?e=e?1:0:_.isDate(e)&&(e=toSmartDbDate(e)),e}makeArgumentDbValue(e){return _.isBoolean(e)?e=e?1:0:_.isDate(e)?e=`'${toSmartDbDate(e)}'`:_.isString(e)&&(e=`'${e.replace(/'/,"''").replace(/\\/,"\\\\")}'`),e}saveExecute(e){let t;try{t=e()}catch(e){this.lastError=e instanceof Error?e:new Error(e||"Unknown error"),this.smartDbLog.logFatal(SmartDbLogLocation.Database,"saveExecute-catch",this.lastError),t=!1}return t}prepareResultRow(e,t,a){let s;if(a.indexedBy&&this.smartDbLog.logWarning(SmartDbLogLocation.Database,"AbstractModel.get","option 'indexedBy' not supported without 'all'"),t)if(a.count)s=parseInt(_.values(t)[0],10);else if(a.collapseRow)s=_.values(t).join(",");else{const r=e.from(t);s=a.style==FieldNamingStyle.TypeScript?r.getPlainObject():r}return s}prepareResultRows(e,t,a){let s;if(!t||!a.indexedBy&&!a.collapseRow&&_.isString(e))s=t;else{const r=e;s=a.indexedBy?{}:new Array(t.length),_.forEach(t,((e,t)=>{let i=r.from?r.from(e):null,l=null;if(a.indexedBy&&(l=i?i.getValue(a.indexedBy):e[a.indexedBy]),a.collapseRow){const a=_.values(e).join(",");l?s[l]=a:s[t]=a}else i&&a.style==FieldNamingStyle.TypeScript&&(i=i.getPlainObject()),l?s[l]=i||e:s[t]=i||e}))}return s}getTableName(e){let t;if(_.isString(e)){let a=e;_.forEach(this.dictionaries,(e=>(e.models&&e.models[a]&&(t=e.models[a].cls.getTableName()),!t))),t||(t=a)}else{if(!e||!e.getTableName)throw new Error(`unknown model: ${e}`);t=e.getTableName()}return t}get isReady(){return this._isReady}set isReady(e){this._isReady=e,this._onReady.next(e)}}
1
+ import fs from"fs";import _ from"lodash";import{BehaviorSubject}from"rxjs";import{AbstractModel}from"./models/abstract-model";import{SmartDbDictionary}from"./models/smart-db-dictionary";import{SmartDbLogModel}from"./models/smart-db-log-model";import{IN,smartDbToDate,toSmartDbDate,toSmartDbTimestamp}from"./smart-db-globals";import{FieldNamingStyle,SqlFieldOperationType,SqlOperationType}from"./smart-db-interfaces";import{SmartDbLog}from"./smart-db-log";import{SmartDbSqlBuildData}from"./smart-db-sql-build-data";import{SmartDbUpgradeManager}from"./smart-db-upgrade-manager";import{SmartError,SmartErrorLocation}from"./smart-error";export class SmartDb{constructor(t,e){this.dictionaries=[],this.dbConnector=t,this.smartDbLog=new SmartDbLog(e?null:this),this.dbLogging=!e,this.db=null,this._isReady=null,this._onReady=new BehaviorSubject(!1)}buildSelectStatement(t,e){e||(e={});const r=this.buildSelectSectionStatement(t,e);if(_.forEach(["union","minus","intersect"],(t=>{let s=_.get(e,t);s&&(_.isArray(s)||(s=[s]),_.forEach(s,(e=>{const s=this.buildSelectSectionStatement(e.model,e);r.sql+=" "+t.toUpperCase()+" ",r.append(s)})))})),e.orderBy){r.sql+=" ORDER BY ";const s=_.isString(e.orderBy)?e.orderBy.split(/ *, */):e.orderBy;r.sql+=s.map((e=>{let r="";const s=e.match(/^(\w*) (asc|desc)$/i);return s&&(e=s[1],r=s[2].toUpperCase()),e=this.translateFieldName(t,e),r&&(e+=" "+r),e})).join(", ")}return e.limit&&(e.limit.limit&&(r.sql+=" LIMIT "+e.limit.limit.toString()),e.limit.offset&&(r.sql+=" OFFSET "+e.limit.offset.toString())),this.lastBuildData=r,r}close(){return new Promise(((t,e)=>{try{t(this.closeSync())}catch(t){e(t)}}))}closeSync(){throw new Error("Method not implemented (close)")}commit(){return new Promise(((t,e)=>{try{this.commitSync(),t()}catch(t){e(t)}}))}commitSync(){throw new Error("Method not implemented (commit)")}delete(t,e){return new Promise(((r,s)=>{const a=this.buildDeleteStatement(t,e);this.statementRun(a).then((t=>{t?r(t.changes):s(this.getLastError())})).catch((t=>{this.lastError=t,s(t)}))}))}deleteSync(t,e){if(this.supportSyncCalls)return this.saveExecute((()=>{const r=this.buildDeleteStatement(t,e);return this.statementRunSync(r).changes}));throw"This database driver doesn't support sync calls (deleteSync)"}exec(t){return new Promise(((e,r)=>{try{this.execSync(t)?e():r(this.getLastError())}catch(t){r(t)}}))}execScript(t,e){return new Promise((async(r,s)=>{const a=this.scriptParser(t);let i=!1;for(const t of a)try{await this.exec(t)}catch(r){if(!e||"drop "!=t.trim().substring(0,5).toLowerCase()){i=!0,this.lastBuildData=new SmartDbSqlBuildData(t),this.lastError=r;break}}i?(await this.rollback(),s(this.lastError)):(await this.commit(),r())}))}execScriptSync(t){if(!this.supportSyncCalls)throw"This database driver doesn't support sync calls (execScriptSync)";{const e=this.scriptParser(t);for(const t of e)try{this.execSync(t)}catch(e){if("drop "!=t.substring(0,5).toLowerCase())throw this.lastBuildData=new SmartDbSqlBuildData(t),this.lastError=e,e}this.commitSync()}}execSync(t){throw new Error("Method not implemented (exec)")}exists(t,e,r){return new Promise(((s,a)=>{try{s(this.existsSync(t,e,r))}catch(t){a(t)}}))}existsSync(t,e,r){throw new Error("Method not implemented (exists)")}get(t,e){return new Promise(((r,s)=>{e||(e={});const a=this.buildSelectStatement(t,e);e.firstOnly||e.count?this.statementGet(a).then((s=>{r(this.prepareResultRow(t,s,e))})).catch((t=>{s(t)})):this.statementGetAll(a).then((s=>{r(this.prepareResultRows(t,s,e))})).catch((t=>{s(t)}))}))}getAll(t,e,r,s,a){return this.get(t,{where:e,fields:r,orderBy:s,limit:a})}getAllSync(t,e,r,s,a){return this.getSync(t,{where:e,fields:r,orderBy:s,limit:a})}getDb(){return this.db}getDbConnector(){return this.dbConnector}getDbQuote(){return'"'}getFirst(t,e,r,s){return this.get(t,{firstOnly:!0,where:e,fields:r,orderBy:s})}getFirstSync(t,e,r,s){return this.getSync(t,{firstOnly:!0,where:e,fields:r,orderBy:s})}getLastBuildData(){return this.lastBuildData}getLastError(){return this.lastError}getLogger(){return this.smartDbLog}getSync(t,e){if(this.supportSyncCalls)return this.saveExecute((()=>{e||(e={});const r=this.buildSelectStatement(t,e);let s;if(e.firstOnly||e.count){const a=this.statementGetSync(r);s=this.prepareResultRow(t,a,e)}else{const a=this.statementGetAllSync(r);s=this.prepareResultRows(t,a,e)}return s}));throw"This database driver doesn't support sync calls (getSync)"}hasConcurrentTransactions(){return!1}hasTransaction(){throw new Error("Method not implemented (hasTransaction)")}initDb(t){return new Promise(((e,r)=>{this.dictionaries.push(SmartDbDictionary);const s=new SmartDbUpgradeManager(this);let a;a=import.meta&&import.meta.url?import.meta.url.replace(/file:\/\//,"").replace(/\/[^/]*$/,""):__dirname;const i={module:"smart-db-core",sqlFilesDirectory:a+"/assets/"+this.getDatabaseType()};s.prepareDatabase(i).then((a=>{this.exists(SmartDbLogModel).then((i=>{this.smartDbLog.setDbLogging(this.dbLogging&&i),s.prepareDatabase(t).then((t=>{e([a,t])}),(t=>{r(t)}))}))})).catch((t=>{r(t)}))}))}insert(t,e){return new Promise(((r,s)=>{const a=this.buildInsertStatement(t,e);this.statementRun(a).then((t=>{t?r(t.lastId):s(this.getLastError())})).catch((t=>{s(t)}))}))}insertSync(t,e){if(this.supportSyncCalls)return this.saveExecute((()=>{const r=this.buildInsertStatement(t,e);return this.statementRunSync(r).lastId}));throw"This database driver doesn't support sync calls (insertSync)"}onReady(){return this._onReady}rollback(){return new Promise(((t,e)=>{try{this.rollbackSync(),t()}catch(t){e(t)}}))}rollbackSync(){throw new Error("Method not implemented (rollback)")}toDate(t){return smartDbToDate(t)}toDbDate(t){return toSmartDbDate(t)}toDbTimestamp(t){return toSmartDbTimestamp(t)}update(t,e,r){return new Promise(((s,a)=>{const i=this.buildUpdateStatement(t,e,r);this.statementRun(i).then((t=>{t?s(t.changes):a(this.getLastError())})).catch((t=>{a(t)}))}))}updateSync(t,e,r){if(this.supportSyncCalls)return this.saveExecute((()=>{const s=this.buildUpdateStatement(t,e,r);return this.statementRunSync(s).changes}));throw"This database driver doesn't support sync calls (updateSync)"}statementRun(t){return new Promise(((e,r)=>{try{e(this.statementRun(t))}catch(t){r(t)}}))}statementRunSync(t){throw new Error("Method not implemented (statementRun)")}statementGet(t){return new Promise(((e,r)=>{try{e(this.statementGetSync(t))}catch(t){r(t)}}))}statementGetSync(t){throw new Error("Method not implemented (statementGet)")}statementGetAll(t){return new Promise(((e,r)=>{try{e(this.statementGetAllSync(t))}catch(t){r(t)}}))}statementGetAllSync(t){throw new Error("Method not implemented (statementGetAll)")}buildWhere(t,e,r){const s=new SmartDbSqlBuildData;return e&&_.keys(e).length>0&&(r||(r="AND",s.sql+=" WHERE "),s.sql+=_.map(e,((e,a)=>{const i=a.toUpperCase();if("AND"==i||"OR"==i){let r="";return(_.isArray(e)?e:[e]).forEach(((e,a)=>{const n=this.buildWhere(t,e,i);a>0&&(r+=" "+i+" "),r+=n.sql,s.values=_.concat(s.values,n.values)})),r="("+r+")",r}if("EXPRESSION"==i){let a=[];return _.forEach(e,(e=>{const r=this.prepareField(t,e.compare,s.values),i=this.prepareField(t,e.with,s.values);let n;n=_.isString(e.operation)&&SqlOperationType[e.operation]?SqlOperationType[e.operation]:e.operation||SqlOperationType.EQ,a.push(`${r} ${n} ${i}`)})),a.join(" "+r+" ")}{let r,i,n=!0;if(_.isArray(e)&&(e=IN(e)),_.isObject(e)){const t=e;switch(_.isString(t.operation)&&SqlOperationType[t.operation]&&(t.operation=SqlOperationType[t.operation]),t.operation){case SqlOperationType.IN:case SqlOperationType.NOT_IN:const e=new Array(t.value.length);e.fill("?"),r=t.operation+" ("+e.join(", ")+")",s.values=_.concat(s.values,t.value);break;case SqlOperationType.IS_NULL:case SqlOperationType.IS_NOT_NULL:r=t.operation;break;case SqlOperationType.LITERAL:a=t.key;const i=t.literalOperation||SqlOperationType.EQ;if(i==SqlOperationType.IN||i==SqlOperationType.NOT_IN){const e=new Array(t.value.length);e.fill("?"),r=i+" ("+e.join(", ")+")",s.values=_.concat(s.values,t.value)}else _.isUndefined(t.value)?r=i:(r=i+" ?",s.values.push(this.makeDbValue(t.value)));n=!1;break;default:r=t.operation+" ?",s.values.push(this.makeDbValue(t.value))}}else null===e?r=SqlOperationType.IS_NULL:void 0===e?(a="1",r="= 1",n=!1):(r=_.isString(e)&&e.match(/[%_]/)?SqlOperationType.LIKE+" ?":SqlOperationType.EQ+" ?",s.values.push(this.makeDbValue(e)));return i=n?this.translateFieldName(t,a)+" "+r:a+" "+r,i}})).join(" "+r+" ")),s}buildDeleteStatement(t,e){const r=this.getTableName(t),s=new SmartDbSqlBuildData("DELETE FROM");return s.sql+=" "+r,e&&s.append(this.buildWhere(t,e)),this.lastBuildData=s,s}buildUpdateStatement(t,e,r){const s=this.getTableName(t),a=new SmartDbSqlBuildData("UPDATE");a.sql+=" "+s+" SET ";const i=[],n=e instanceof AbstractModel?e.getPlainObject(FieldNamingStyle.Database):e;return _.forOwn(n,((e,r)=>{i.push(this.translateFieldName(t,r)+" = ?"),a.values.push(this.makeDbValue(e))})),a.sql+=i.join(", "),r&&a.append(this.buildWhere(t,r)),this.lastBuildData=a,a}buildInsertStatement(t,e){const r=this.getTableName(t),s=new SmartDbSqlBuildData("INSERT");s.sql+=" INTO "+r;const a=[];e instanceof AbstractModel&&(e=e.getPlainObject(FieldNamingStyle.Database)),_.forOwn(e,((e,r)=>{r=this.translateFieldName(t,r),a.push(r),s.values.push(this.makeDbValue(e))}));const i=new Array(a.length);return i.fill("?"),s.sql+=" ("+a.join(", ")+") VALUES ("+i.join(", ")+")",this.lastBuildData=s,s}prepareFieldValue(t,e){let r="<undefined>";switch(e.operation){case SqlFieldOperationType.FIELD:r=this.translateFieldName(t,e.value);break;case SqlFieldOperationType.VALUE:null===e.value?r="NULL":e.literal?r=e.value:_.isString(e.value)?!isNaN(parseFloat(e.value))&&isFinite(e.value)||(r="'"+e.value+"'"):_.isNumber(e.value)?r=e.value.toString():_.isBoolean(e.value)?r=e.value?"1":"0":_.isDate(e.value)?r="'"+e.value.toISOString().substring(0,23).replace("T"," ")+"'":console.error("unhandled field data type",typeof e.value,e.value);break;case SqlFieldOperationType.COUNT:r=_.isArray(e.value)?"COUNT("+e.value.join(",")+")":"COUNT("+(e.value||"")+")";break;case SqlFieldOperationType.COALESCE:const s=_.isArray(e.value)?e.value:[e.value];r="COALESCE("+this.buildFieldList(t,s).join(",")+")"}if(e.alias){const t=this.getDbQuote();r+=` as ${t}${e.alias}${t}`}return r}prepareField(t,e,r){let s;if(null===e)s="NULL";else if(_.isString(e)){const a=e.match(/^'(.*)'$/);a?r?(s="?",r.push(a[1])):s=e:s=this.translateFieldName(t,e)}else e.operation?s=this.prepareFieldValue(t,e):r?(s="?",r.push(e)):s=this.makeArgumentDbValue(e).toString();return s}buildFieldList(t,e){const r=[];return _.forEach(e,(e=>{r.push(this.prepareField(t,e))})),r}buildSelectSectionStatement(t,e){const r=this.getTableName(t);let s,a;if(_.isArray(e.fields))s=e.fields;else if(_.isString(e.fields)){const t=e.fields.trim();s=""===t||"*"==t?[]:t.split(/,/)}else s=e.fields&&e.fields.operation?[e.fields]:[];if(s.length>0){a=this.buildFieldList(t,s).join(", ")}else a="*";e.distinct&&(a="DISTINCT "+a),e.count&&(a=`COUNT(${a})`);const i=new SmartDbSqlBuildData(`SELECT ${a} FROM ${r}`);if(e.where&&i.append(this.buildWhere(t,e.where)),e.groupBy){i.sql+=" GROUP BY ";const r=_.isArray(e.groupBy)?e.groupBy:[e.groupBy];i.sql+=r.map((e=>this.translateFieldName(t,e))).join(", ")}return i}translateFieldName(t,e){if(_.isString(t)){const e=t;let r=!1;_.forEach(this.dictionaries,(s=>(s.models&&s.models[e]&&(t=s.models[e].cls,r=!0),!r)))}if(!_.isString(t)){const r=t.attributeMap[e];if(r)r.alias&&(e=r.alias);else{const r=t.getTableName();this.lastError=new Error(`unknown field '${e}' in table '${r}'`),this.smartDbLog.logError(SmartErrorLocation.Database,"translateFieldName",this.lastError)}}return e}makeDbValue(t){return _.isBoolean(t)?t=t?1:0:_.isDate(t)&&(t=toSmartDbDate(t)),t}makeArgumentDbValue(t){return _.isBoolean(t)?t=t?1:0:_.isDate(t)?t=`'${toSmartDbDate(t)}'`:_.isString(t)&&(t=`'${t.replace(/'/,"''").replace(/\\/,"\\\\")}'`),t}saveExecute(t){let e;try{e=t()}catch(t){this.lastError=t instanceof Error?t:new Error(t||"Unknown error"),this.smartDbLog.logFatal(SmartErrorLocation.Database,"saveExecute-catch",this.lastError),e=!1}return e}scriptParser(t){const e=fs.readFileSync(t,"utf8"),r=[];let s=0,a=0,i=!1,n=0,l=!1,o="";for(;a<e.length;){if(l){if("\n"==e[a])for(l=!1,s=a+1;" "==e[s]||"\n"==e[s]||"\n"==e[s];)s+=1}else"'"==e[a]?i=!i:!i&&e.substring(a,a+6).match(/^begin(\s|\n)/)?(n+=1,a+=6):n>0&&!i&&e.substring(a,a+4).match(/^end;/)?(n-=1,a+=4):0!==n||i||"/"!=e[a]?i||"-"!=e[a]||"-"!=e[a+1]?0!==n||i||";"!=e[a]||(r.push((o+e.substring(s,a)).trim()),o="",s=a+2):(o+=e.substring(s,a),l=!0):(r.push((o+e.substring(s,a)).trim()),o="",s=a+2);a+=1}if(s<e.length){const t=e.substring(s,e.length).trim().replace(/;$/,"");console.log(t),""!==t&&r.push(t)}return r}prepareResultRow(t,e,r){let s;if(r.indexedBy&&this.smartDbLog.logWarning(SmartErrorLocation.Database,"AbstractModel.get","option 'indexedBy' not supported without 'all'"),e)if(r.count)s=parseInt(_.values(e)[0],10);else if(r.collapseRow)s=_.values(e).join(",");else{const a=t.from(e);s=r.style==FieldNamingStyle.TypeScript?a.getPlainObject():a}return s}prepareResultRows(t,e,r){let s;if(!e||!r.indexedBy&&!r.collapseRow&&_.isString(t))s=e;else{const a=t;s=r.indexedBy?{}:new Array(e.length),_.forEach(e,((t,e)=>{let i=a.from?a.from(t):null,n=null;if(r.indexedBy&&(n=i?i.getValue(r.indexedBy):t[r.indexedBy]),r.collapseRow){const r=_.values(t).join(",");n?s[n]=r:s[e]=r}else i&&r.style==FieldNamingStyle.TypeScript&&(i=i.getPlainObject()),n?s[n]=i||t:s[e]=i||t}))}return s}getTableName(t){let e;if(_.isString(t)){let r=t;_.forEach(this.dictionaries,(t=>(t.models&&t.models[r]&&(e=t.models[r].cls.getTableName()),!e))),e||(e=r)}else{if(!t||!t.getTableName)throw new Error(`unknown model: ${t}`);e=t.getTableName()}return e}get isReady(){return this._isReady}set isReady(t){this._isReady=t,this._onReady.next(t)}get lastError(){return this._lastError}set lastError(t){this._lastError=new SmartError(t),this._lastError.location=SmartErrorLocation.Database}get supportSyncCalls(){return!1}}
@@ -0,0 +1,41 @@
1
+ export declare const SmartErrorLocation: {
2
+ App: SmartErrorLocationValue;
3
+ Frontend: SmartErrorLocationValue;
4
+ Backend: SmartErrorLocationValue;
5
+ Database: SmartErrorLocationValue;
6
+ UpgradeManager: SmartErrorLocationValue;
7
+ };
8
+ export declare type SmartErrorLocationType = typeof SmartErrorLocation;
9
+ export declare type SmartErrorLocationKey = keyof SmartErrorLocationType;
10
+ export declare type SmartErrorLocationValue = "APP" | "FRONTEND" | "BACKEND" | "DATABASE" | "UPGRADE-MANAGER";
11
+ export declare const SmartErrorSeverity: {
12
+ readonly Fatal: SmartErrorSeverityValue;
13
+ readonly Error: SmartErrorSeverityValue;
14
+ readonly Warning: SmartErrorSeverityValue;
15
+ readonly Info: SmartErrorSeverityValue;
16
+ readonly Debug: SmartErrorSeverityValue;
17
+ readonly Local: SmartErrorSeverityValue;
18
+ };
19
+ export declare type SmartErrorSeverityType = typeof SmartErrorSeverity;
20
+ export declare type SmartErrorSeverityKey = keyof SmartErrorSeverityType;
21
+ export declare type SmartErrorSeverityValue = "F" | "E" | "W" | "I" | "D" | "L";
22
+ export interface SmartErrorData {
23
+ message: string;
24
+ name: string;
25
+ code?: number | string;
26
+ type?: SmartErrorSeverityValue;
27
+ location?: SmartErrorLocationValue;
28
+ timestamp?: Date | string | number;
29
+ info?: Record<string, any>;
30
+ }
31
+ export declare class SmartError extends Error implements SmartErrorData {
32
+ code: number | string;
33
+ type: SmartErrorSeverityValue;
34
+ location: SmartErrorLocationValue;
35
+ timestamp: Date | string | number;
36
+ info: Record<string, any>;
37
+ private smartErrorKeys;
38
+ constructor(message: any);
39
+ toObject(): SmartErrorData;
40
+ toString(): string;
41
+ }
package/smart-error.js ADDED
@@ -0,0 +1 @@
1
+ export const SmartErrorLocation={App:"APP",Frontend:"FRONTEND",Backend:"BACKEND",Database:"DATABASE",UpgradeManager:"UPGRADE-MANAGER"};export const SmartErrorSeverity={Fatal:"F",Error:"E",Warning:"W",Info:"I",Debug:"D",Local:"L"};export class SmartError extends Error{constructor(t){let e,r,s,o,i,n,a;if(void 0===t||"string"==typeof t)e=t;else if("object"==typeof t){if(e="string"==typeof t.message?t.message:"string"==typeof t.text?t.text:"string"==typeof t.error?t.error:"Error",i=t.name,r=t.code,s=t.type,o=t.location,n=t.timestamp,!t.constructor){const e=Object.keys(t).filter((t=>!this.smartErrorKeys.includes(t)));e.length>0&&(a={},e.forEach((e=>{a[e]=t[e]})))}}else e="function"==typeof t.toString?t.toString():t;super(e),this.name=i??"",this.code=r??-1,this.type&&(this.type=s??"E"),o&&(this.location=o),n&&(this.timestamp=n),a&&(this.info=a),this.smartErrorKeys=["message","name","code","type","location","timestamp","info"]}toObject(){const t={name:this.name,message:this.message};return this.smartErrorKeys.forEach((e=>{"name"!=e&&"message"!=e&&this[e]&&(t[e]=this[e])})),t}toString(){let t=super.toString(),e="";return this.type&&(e+=this.type),this.location&&(""!==e&&(e+="-"),e+=this.location),this.code&&(""!==e&&(e+=" #"),e+=this.code),t+" ("+e+")"}}