@egi/smart-db 2.3.0 → 2.3.2
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.
- package/.eslintrc.json +212 -0
- package/README.md +2 -0
- package/bin/copy-assets +6 -0
- package/package.json +4 -4
- package/src/drivers/smart-db-better-sqlite3.ts +284 -0
- package/src/drivers/smart-db-mysql.ts +159 -0
- package/src/drivers/smart-db-mysql2.ts +159 -0
- package/src/drivers/smart-db-sqlite3.ts +198 -0
- package/src/helpers/extract-db-api.ts +465 -0
- package/src/helpers/terser-tree.ts +39 -0
- package/src/models/abstract-model.ts +209 -0
- package/src/models/smart-db-core-table-model.ts +161 -0
- package/src/models/smart-db-dictionary.ts +28 -0
- package/src/models/smart-db-log-model.ts +316 -0
- package/src/models/smart-db-version-model.ts +316 -0
- package/src/models/smart-db-version-view-model.ts +347 -0
- package/src/models/sqlite-master-model.ts +140 -0
- package/src/models/sqlite-sequence-model.ts +91 -0
- package/{smart-db-api.d.ts → src/smart-db-api.ts} +3 -0
- package/src/smart-db-globals.ts +136 -0
- package/{smart-db-interfaces.d.ts → src/smart-db-interfaces.ts} +82 -34
- package/src/smart-db-log.ts +262 -0
- package/src/smart-db-sql-build-data.ts +28 -0
- package/src/smart-db-upgrade-manager.ts +171 -0
- package/src/smart-db.ts +854 -0
- package/test/data/sql-engine-tests.json +232 -0
- package/test/db/mysql/database-init.sql +11 -0
- package/test/db/sqlite3/database-init.sql +11 -0
- package/test/exer.js +28 -0
- package/test/model/smart-db-dictionary.ts +19 -0
- package/test/model/test-table-model.ts +214 -0
- package/test/test.js +273 -0
- package/test/test2.js +252 -0
- package/tsconfig.json +32 -0
- package/tsconfig.pro.json +32 -0
- package/tsconfig.test-model.json +23 -0
- package/drivers/smart-db-better-sqlite3.d.ts +0 -36
- package/drivers/smart-db-better-sqlite3.js +0 -1
- package/drivers/smart-db-mysql.d.ts +0 -26
- package/drivers/smart-db-mysql.js +0 -1
- package/drivers/smart-db-mysql2.d.ts +0 -26
- package/drivers/smart-db-mysql2.js +0 -1
- package/drivers/smart-db-sqlite3.d.ts +0 -30
- package/drivers/smart-db-sqlite3.js +0 -1
- package/helpers/extract-db-api.d.ts +0 -1
- package/helpers/extract-db-api.js +0 -1
- package/models/abstract-model.d.ts +0 -22
- package/models/abstract-model.js +0 -1
- package/models/smart-db-core-table-model.d.ts +0 -35
- package/models/smart-db-core-table-model.js +0 -1
- package/models/smart-db-dictionary.d.ts +0 -13
- package/models/smart-db-dictionary.js +0 -1
- package/models/smart-db-log-model.d.ts +0 -65
- package/models/smart-db-log-model.js +0 -1
- package/models/smart-db-version-model.d.ts +0 -65
- package/models/smart-db-version-model.js +0 -1
- package/models/smart-db-version-view-model.d.ts +0 -71
- package/models/smart-db-version-view-model.js +0 -1
- package/models/sqlite-master-model.d.ts +0 -36
- package/models/sqlite-master-model.js +0 -1
- package/models/sqlite-sequence-model.d.ts +0 -24
- package/models/sqlite-sequence-model.js +0 -1
- package/smart-db-api.js +0 -1
- package/smart-db-globals.d.ts +0 -22
- package/smart-db-globals.js +0 -1
- package/smart-db-interfaces.js +0 -1
- package/smart-db-log.d.ts +0 -58
- package/smart-db-log.js +0 -1
- package/smart-db-sql-build-data.d.ts +0 -9
- package/smart-db-sql-build-data.js +0 -1
- package/smart-db-upgrade-manager.d.ts +0 -13
- package/smart-db-upgrade-manager.js +0 -1
- package/smart-db.d.ts +0 -67
- package/smart-db.js +0 -1
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { SmartDbVersionViewModel } from "./models/smart-db-version-view-model";
|
|
2
|
-
import { SmartDb } from "./smart-db";
|
|
3
|
-
import { SmartDbOptions } from "./smart-db-interfaces";
|
|
4
|
-
export declare class SmartDbUpgradeManager {
|
|
5
|
-
private db;
|
|
6
|
-
private log;
|
|
7
|
-
constructor(db: SmartDb);
|
|
8
|
-
hasDatabaseModule(module: string): Promise<boolean>;
|
|
9
|
-
prepareDatabase(options: SmartDbOptions): Promise<SmartDbVersionViewModel>;
|
|
10
|
-
private executeSqlScript;
|
|
11
|
-
private upgradeDatabase;
|
|
12
|
-
private executeScriptSequentially;
|
|
13
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import*as fs from"fs";import _ from"lodash";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(SmartDbVersionViewModel).then(o=>{o?this.db.getFirst(SmartDbVersionViewModel,{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 '${e.module}' doesn't exists - begin creation`),this.executeSqlScript(o).then(()=>{this.log.setDbLogging(!0),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){const t=fs.readFileSync(e,"utf8");return this.db.exec(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)})}}
|
package/smart-db.d.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { AbstractModel } from "./models/abstract-model";
|
|
2
|
-
import { SmartDbVersionViewModel } from "./models/smart-db-version-view-model";
|
|
3
|
-
import { GenericModelData, IndexedGenericModelData, SmartDbApi, SmartDbConnector, SmartDbDatabase, SmartDbOptions, SmartDbRunResult, SmartDbSqlOptions, SmartDbTableInfo, SqlFieldDescriptor, SqlLimit, SqlOrderBy, SqlUpdateValues, SqlValueType, SqlWhere } from "./smart-db-interfaces";
|
|
4
|
-
import { SmartDbLog } from "./smart-db-log";
|
|
5
|
-
import { SmartDbSqlBuildData } from "./smart-db-sql-build-data";
|
|
6
|
-
export declare abstract class SmartDb implements SmartDbApi {
|
|
7
|
-
abstract getDatabaseType(): string;
|
|
8
|
-
abstract hasConcurrentTransactions(): boolean;
|
|
9
|
-
abstract exists<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): Promise<boolean>;
|
|
10
|
-
abstract existsSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): boolean;
|
|
11
|
-
abstract exec(script: string): Promise<void>;
|
|
12
|
-
abstract execSync(script: string): SmartDbDatabase | false;
|
|
13
|
-
abstract close(): Promise<void>;
|
|
14
|
-
abstract closeSync(): boolean;
|
|
15
|
-
abstract getDbQuote(): string;
|
|
16
|
-
abstract getTableInfo(table: string): Promise<SmartDbTableInfo>;
|
|
17
|
-
abstract getDbConnector(): string | SmartDbConnector;
|
|
18
|
-
protected abstract statementRun(buildData: SmartDbSqlBuildData): Promise<SmartDbRunResult>;
|
|
19
|
-
protected abstract statementRunSync(buildData: SmartDbSqlBuildData): SmartDbRunResult;
|
|
20
|
-
protected abstract statementGet(buildData: SmartDbSqlBuildData): Promise<any>;
|
|
21
|
-
protected abstract statementGetSync(buildData: SmartDbSqlBuildData): any;
|
|
22
|
-
protected abstract statementGetAll(buildData: SmartDbSqlBuildData): Promise<any[]>;
|
|
23
|
-
protected abstract statementGetAllSync(buildData: SmartDbSqlBuildData): any[];
|
|
24
|
-
protected db: SmartDbDatabase;
|
|
25
|
-
protected dbConnector: SmartDbConnector;
|
|
26
|
-
protected lastError: Error;
|
|
27
|
-
protected lastBuildData: SmartDbSqlBuildData;
|
|
28
|
-
protected smartDbLog: SmartDbLog;
|
|
29
|
-
private dictionaries;
|
|
30
|
-
protected constructor(dbConnector: SmartDbConnector);
|
|
31
|
-
initDb(appOptions: SmartDbOptions): Promise<SmartDbVersionViewModel[]>;
|
|
32
|
-
getLogger(): SmartDbLog;
|
|
33
|
-
getDb(): SmartDbDatabase;
|
|
34
|
-
getLastBuildData(): SmartDbSqlBuildData;
|
|
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[]>;
|
|
36
|
-
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;
|
|
37
|
-
getFirst<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere, fields?: string | string[] | null, orderBy?: SqlOrderBy): Promise<T>;
|
|
38
|
-
getFirstSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere, fields?: string | string[] | null, orderBy?: SqlOrderBy): T | false;
|
|
39
|
-
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[]>;
|
|
40
|
-
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;
|
|
41
|
-
delete<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere): Promise<number>;
|
|
42
|
-
deleteSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere): number | false;
|
|
43
|
-
update<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: SqlUpdateValues | T, where?: SqlWhere): Promise<number>;
|
|
44
|
-
updateSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: SqlUpdateValues | T, where?: SqlWhere): number | false;
|
|
45
|
-
insert<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: SqlUpdateValues | T): Promise<number>;
|
|
46
|
-
insertSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: SqlUpdateValues | T): number | false;
|
|
47
|
-
getLastError(): Error;
|
|
48
|
-
buildSelectStatement<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), options: SmartDbSqlOptions<T, D>): SmartDbSqlBuildData;
|
|
49
|
-
toDate(d: Date | number | string): Date | null;
|
|
50
|
-
toDbTimestamp(d: Date | number): string;
|
|
51
|
-
toDbDate(d: Date | number): string;
|
|
52
|
-
protected buildWhere<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where: SqlWhere, op?: string): SmartDbSqlBuildData;
|
|
53
|
-
protected buildDeleteStatement<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), where?: SqlWhere): SmartDbSqlBuildData;
|
|
54
|
-
protected buildUpdateStatement<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: SqlUpdateValues | T, where?: SqlWhere): SmartDbSqlBuildData;
|
|
55
|
-
protected buildInsertStatement<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), values: SqlUpdateValues | T): SmartDbSqlBuildData;
|
|
56
|
-
protected prepareFieldValue<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), fieldOperation: SqlFieldDescriptor): string;
|
|
57
|
-
protected prepareField<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), field: SqlValueType | SqlFieldDescriptor, values?: SqlValueType[]): string;
|
|
58
|
-
protected buildFieldList<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), fields: (SqlValueType | SqlFieldDescriptor)[]): string[];
|
|
59
|
-
protected buildSelectSectionStatement<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), options: SmartDbSqlOptions<T, D>): SmartDbSqlBuildData;
|
|
60
|
-
protected translateFieldName<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), field: string): string;
|
|
61
|
-
protected makeDbValue(value: SqlValueType): SqlValueType;
|
|
62
|
-
protected makeArgumentDbValue(value: SqlValueType): SqlValueType;
|
|
63
|
-
protected saveExecute<T>(fn: () => T): T | false;
|
|
64
|
-
private prepareResultRow;
|
|
65
|
-
private prepareResultRows;
|
|
66
|
-
private getTableName;
|
|
67
|
-
}
|
package/smart-db.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import _ from"lodash";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){this.dictionaries=[],this.dbConnector=e,this.smartDbLog=new SmartDbLog(this)}initDb(e){return new Promise((t,a)=>{this.dictionaries.push(SmartDbDictionary);const r=new SmartDbUpgradeManager(this);let i;i=import.meta&&import.meta.url?import.meta.url.replace(/file:\/\//,"").replace(/\/[^/]*$/,""):__dirname;const s={module:"smart-db-core",sqlFilesDirectory:i+"/assets/"+this.getDatabaseType()};r.prepareDatabase(s).then(i=>{this.exists(SmartDbLogModel).then(s=>{this.smartDbLog.setDbLogging(s),r.prepareDatabase(e).then(e=>{t([i,e])},e=>{a(e)})})}).catch(e=>{a(e)})})}getLogger(){return this.smartDbLog}getDb(){return this.db}getLastBuildData(){return this.lastBuildData}get(e,t){return new Promise((a,r)=>{t||(t={});const i=this.buildSelectStatement(e,t);t.firstOnly||t.count?this.statementGet(i).then(r=>{a(this.prepareResultRow(e,r,t))}).catch(e=>{r(e)}):this.statementGetAll(i).then(r=>{a(this.prepareResultRows(e,r,t))}).catch(e=>{r(e)})})}getSync(e,t){return this.saveExecute(()=>{t||(t={});const a=this.buildSelectStatement(e,t);let r;if(t.firstOnly||t.count){const i=this.statementGetSync(a);r=this.prepareResultRow(e,i,t)}else{const i=this.statementGetAllSync(a);r=this.prepareResultRows(e,i,t)}return r})}getFirst(e,t,a,r){return this.get(e,{firstOnly:!0,where:t,fields:a,orderBy:r})}getFirstSync(e,t,a,r){return this.getSync(e,{firstOnly:!0,where:t,fields:a,orderBy:r})}getAll(e,t,a,r,i){return this.get(e,{where:t,fields:a,orderBy:r,limit:i})}getAllSync(e,t,a,r,i){return this.getSync(e,{where:t,fields:a,orderBy:r,limit:i})}delete(e,t){return new Promise((a,r)=>{const i=this.buildDeleteStatement(e,t);this.statementRun(i).then(e=>{e?a(e.changes):r(this.getLastError())}).catch(e=>{r(e)})})}deleteSync(e,t){return this.saveExecute(()=>{const a=this.buildDeleteStatement(e,t);return this.statementRunSync(a).changes})}update(e,t,a){return new Promise((r,i)=>{const s=this.buildUpdateStatement(e,t,a);this.statementRun(s).then(e=>{e?r(e.changes):i(this.getLastError())}).catch(e=>{i(e)})})}updateSync(e,t,a){return this.saveExecute(()=>{const r=this.buildUpdateStatement(e,t,a);return this.statementRunSync(r).changes})}insert(e,t){return new Promise((a,r)=>{const i=this.buildInsertStatement(e,t);this.statementRun(i).then(e=>{e?a(e.lastId):r(this.getLastError())}).catch(e=>{r(e)})})}insertSync(e,t){return this.saveExecute(()=>{const a=this.buildInsertStatement(e,t);return this.statementRunSync(a).lastId})}getLastError(){return this.lastError}buildSelectStatement(e,t){t||(t={});const a=this.buildSelectSectionStatement(e,t);if(_.forEach(["union","minus","intersect"],e=>{let r=_.get(t,e);r&&(_.isArray(r)||(r=[r]),_.forEach(r,t=>{const r=this.buildSelectSectionStatement(t.model,t);a.sql+=" "+e.toUpperCase()+" ",a.append(r)}))}),t.orderBy){a.sql+=" ORDER BY ";const r=_.isString(t.orderBy)?t.orderBy.split(/ *, */):t.orderBy;a.sql+=r.map(t=>{let a="";const r=t.match(/^(\w*) (asc|desc)$/i);return r&&(t=r[1],a=r[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 r=new SmartDbSqlBuildData;return t&&_.keys(t).length>0&&(a||(a="AND",r.sql+=" WHERE "),r.sql+=_.map(t,(t,i)=>{const s=i.toUpperCase();if("AND"==s||"OR"==s){let a="";return(_.isArray(t)?t:[t]).forEach((t,i)=>{const l=this.buildWhere(e,t,s);i>0&&(a+=" "+s+" "),a+=l.sql,r.values=_.concat(r.values,l.values)}),a="("+a+")",a}if("EXPRESSION"==s){let i=[];return _.forEach(t,t=>{const a=this.prepareField(e,t.compare,r.values),s=this.prepareField(e,t.with,r.values);let l;l=_.isString(t.operation)&&SqlOperationType[t.operation]?SqlOperationType[t.operation]:t.operation||SqlOperationType.EQ,i.push(`${a} ${l} ${s}`)}),i.join(" "+a+" ")}{let a,s,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:const t=new Array(e.value.length);t.fill("?"),a=SqlOperationType.IN+" ("+t.join(", ")+")",r.values=_.concat(r.values,e.value);break;case SqlOperationType.IS_NULL:case SqlOperationType.IS_NOT_NULL:a=e.operation;break;case SqlOperationType.LITERAL:i=e.key;const s=e.literalOperation||SqlOperationType.EQ;if(s==SqlOperationType.IN){const t=new Array(e.value.length);t.fill("?"),a=SqlOperationType.IN+" ("+t.join(", ")+")",r.values=_.concat(r.values,e.value)}else _.isUndefined(e.value)?a=s:(a=s+" ?",r.values.push(this.makeDbValue(e.value)));l=!1;break;default:a=e.operation+" ?",r.values.push(this.makeDbValue(e.value))}}else null===t?a=SqlOperationType.IS_NULL:void 0===t?(i="1",a="= 1",l=!1):(a=_.isString(t)&&t.match(/[%_]/)?SqlOperationType.LIKE+" ?":SqlOperationType.EQ+" ?",r.values.push(this.makeDbValue(t)));return s=l?this.translateFieldName(e,i)+" "+a:i+" "+a,s}}).join(" "+a+" ")),r}buildDeleteStatement(e,t){const a=this.getTableName(e),r=new SmartDbSqlBuildData("DELETE FROM");return r.sql+=" "+a,t&&r.append(this.buildWhere(e,t)),this.lastBuildData=r,r}buildUpdateStatement(e,t,a){const r=this.getTableName(e),i=new SmartDbSqlBuildData("UPDATE");i.sql+=" "+r+" SET ";const s=[];return t instanceof AbstractModel&&(t=t.getPlainObject(FieldNamingStyle.Database)),_.forOwn(t,(t,a)=>{s.push(this.translateFieldName(e,a)+" = ?"),i.values.push(this.makeDbValue(t))}),i.sql+=s.join(", "),a&&i.append(this.buildWhere(e,a)),this.lastBuildData=i,i}buildInsertStatement(e,t){const a=this.getTableName(e),r=new SmartDbSqlBuildData("INSERT");r.sql+=" INTO "+a;const i=[];t instanceof AbstractModel&&(t=t.getPlainObject(FieldNamingStyle.Database)),_.forOwn(t,(t,a)=>{a=this.translateFieldName(e,a),i.push(a),r.values.push(this.makeDbValue(t))});const s=new Array(i.length);return s.fill("?"),r.sql+=" ("+i.join(", ")+") VALUES ("+s.join(", ")+")",this.lastBuildData=r,r}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 r=_.isArray(t.value)?t.value:[t.value];a="COALESCE("+this.buildFieldList(e,r).join(",")+")"}if(t.alias){const e=this.getDbQuote();a+=` as ${e}${t.alias}${e}`}return a}prepareField(e,t,a){let r;if(null===t)r="NULL";else if(_.isString(t)){const i=t.match(/^'(.*)'$/);i?a?(r="?",a.push(i[1])):r=t:r=this.translateFieldName(e,t)}else t.operation?r=this.prepareFieldValue(e,t):a?(r="?",a.push(t)):r=this.makeArgumentDbValue(t).toString();return r}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 r,i;if(_.isArray(t.fields))r=t.fields;else if(_.isString(t.fields)){const e=t.fields.trim();r=""===e||"*"==e?[]:e.split(/,/)}else r=t.fields&&t.fields.operation?[t.fields]:[];if(r.length>0){i=this.buildFieldList(e,r).join(", ")}else i="*";t.distinct&&(i="DISTINCT "+i),t.count&&(i=`COUNT(${i})`);const s=new SmartDbSqlBuildData(`SELECT ${i} FROM ${a}`);if(t.where&&s.append(this.buildWhere(e,t.where)),t.groupBy){s.sql+=" GROUP BY ";const a=_.isArray(t.groupBy)?t.groupBy:[t.groupBy];s.sql+=a.map(t=>this.translateFieldName(e,t)).join(", ")}return s}translateFieldName(e,t){if(_.isString(e)){const t=e;let a=!1;_.forEach(this.dictionaries,r=>(r.models&&r.models[t]&&(e=r.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}'`),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 r;if(a.indexedBy&&this.smartDbLog.logWarning(SmartDbLogLocation.Database,"AbstractModel.get","option 'indexedBy' not supported without 'all'"),t)if(a.count)r=parseInt(_.values(t)[0],10);else if(a.collapseRow)r=_.values(t).join(",");else{r=e.from(t)}return r}prepareResultRows(e,t,a){let r;if(a.indexedBy||a.collapseRow||!_.isString(e)){const i=e;r=a.indexedBy?{}:new Array(t.length),_.forEach(t,(e,t)=>{const s=i.from?i.from(e):null;let l=null;if(a.indexedBy&&(l=s?s.getValue(a.indexedBy):e[a.indexedBy]),a.collapseRow){const a=_.values(e).join(",");l?r[l]=a:r[t]=a}else l?r[l]=s||e:r[t]=s||e})}else r=t;return r}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}}
|