nodecommons-esm-database 0.0.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.
Files changed (151) hide show
  1. package/dist/classes/commons-database-key.d.mts +24 -0
  2. package/dist/classes/commons-database-key.mjs +48 -0
  3. package/dist/classes/commons-database-key.mjs.map +1 -0
  4. package/dist/classes/commons-database-param.d.mts +10 -0
  5. package/dist/classes/commons-database-param.mjs +21 -0
  6. package/dist/classes/commons-database-param.mjs.map +1 -0
  7. package/dist/classes/commons-database-type-base62-big-id.d.mts +6 -0
  8. package/dist/classes/commons-database-type-base62-big-id.mjs +17 -0
  9. package/dist/classes/commons-database-type-base62-big-id.mjs.map +1 -0
  10. package/dist/classes/commons-database-type-base62-long-id.d.mts +6 -0
  11. package/dist/classes/commons-database-type-base62-long-id.mjs +17 -0
  12. package/dist/classes/commons-database-type-base62-long-id.mjs.map +1 -0
  13. package/dist/classes/commons-database-type-big-int.d.mts +10 -0
  14. package/dist/classes/commons-database-type-big-int.mjs +41 -0
  15. package/dist/classes/commons-database-type-big-int.mjs.map +1 -0
  16. package/dist/classes/commons-database-type-binary.d.mts +7 -0
  17. package/dist/classes/commons-database-type-binary.mjs +21 -0
  18. package/dist/classes/commons-database-type-binary.mjs.map +1 -0
  19. package/dist/classes/commons-database-type-boolean.d.mts +8 -0
  20. package/dist/classes/commons-database-type-boolean.mjs +25 -0
  21. package/dist/classes/commons-database-type-boolean.mjs.map +1 -0
  22. package/dist/classes/commons-database-type-date-time.d.mts +7 -0
  23. package/dist/classes/commons-database-type-date-time.mjs +32 -0
  24. package/dist/classes/commons-database-type-date-time.mjs.map +1 -0
  25. package/dist/classes/commons-database-type-date.d.mts +6 -0
  26. package/dist/classes/commons-database-type-date.mjs +22 -0
  27. package/dist/classes/commons-database-type-date.mjs.map +1 -0
  28. package/dist/classes/commons-database-type-double.d.mts +10 -0
  29. package/dist/classes/commons-database-type-double.mjs +43 -0
  30. package/dist/classes/commons-database-type-double.mjs.map +1 -0
  31. package/dist/classes/commons-database-type-email.d.mts +6 -0
  32. package/dist/classes/commons-database-type-email.mjs +17 -0
  33. package/dist/classes/commons-database-type-email.mjs.map +1 -0
  34. package/dist/classes/commons-database-type-encrypted.d.mts +9 -0
  35. package/dist/classes/commons-database-type-encrypted.mjs +38 -0
  36. package/dist/classes/commons-database-type-encrypted.mjs.map +1 -0
  37. package/dist/classes/commons-database-type-enum.d.mts +16 -0
  38. package/dist/classes/commons-database-type-enum.mjs +87 -0
  39. package/dist/classes/commons-database-type-enum.mjs.map +1 -0
  40. package/dist/classes/commons-database-type-fixed-date-time.d.mts +5 -0
  41. package/dist/classes/commons-database-type-fixed-date-time.mjs +15 -0
  42. package/dist/classes/commons-database-type-fixed-date-time.mjs.map +1 -0
  43. package/dist/classes/commons-database-type-fixed-date.d.mts +8 -0
  44. package/dist/classes/commons-database-type-fixed-date.mjs +36 -0
  45. package/dist/classes/commons-database-type-fixed-date.mjs.map +1 -0
  46. package/dist/classes/commons-database-type-fixed-time.d.mts +8 -0
  47. package/dist/classes/commons-database-type-fixed-time.mjs +36 -0
  48. package/dist/classes/commons-database-type-fixed-time.mjs.map +1 -0
  49. package/dist/classes/commons-database-type-float.d.mts +10 -0
  50. package/dist/classes/commons-database-type-float.mjs +38 -0
  51. package/dist/classes/commons-database-type-float.mjs.map +1 -0
  52. package/dist/classes/commons-database-type-hex-rgb.d.mts +8 -0
  53. package/dist/classes/commons-database-type-hex-rgb.mjs +28 -0
  54. package/dist/classes/commons-database-type-hex-rgb.mjs.map +1 -0
  55. package/dist/classes/commons-database-type-id-name.d.mts +6 -0
  56. package/dist/classes/commons-database-type-id-name.mjs +17 -0
  57. package/dist/classes/commons-database-type-id-name.mjs.map +1 -0
  58. package/dist/classes/commons-database-type-id.d.mts +9 -0
  59. package/dist/classes/commons-database-type-id.mjs +39 -0
  60. package/dist/classes/commons-database-type-id.mjs.map +1 -0
  61. package/dist/classes/commons-database-type-int.d.mts +10 -0
  62. package/dist/classes/commons-database-type-int.mjs +40 -0
  63. package/dist/classes/commons-database-type-int.mjs.map +1 -0
  64. package/dist/classes/commons-database-type-md5.d.mts +6 -0
  65. package/dist/classes/commons-database-type-md5.mjs +17 -0
  66. package/dist/classes/commons-database-type-md5.mjs.map +1 -0
  67. package/dist/classes/commons-database-type-number.d.mts +13 -0
  68. package/dist/classes/commons-database-type-number.mjs +60 -0
  69. package/dist/classes/commons-database-type-number.mjs.map +1 -0
  70. package/dist/classes/commons-database-type-serial-id.d.mts +9 -0
  71. package/dist/classes/commons-database-type-serial-id.mjs +48 -0
  72. package/dist/classes/commons-database-type-serial-id.mjs.map +1 -0
  73. package/dist/classes/commons-database-type-small-int.d.mts +10 -0
  74. package/dist/classes/commons-database-type-small-int.mjs +40 -0
  75. package/dist/classes/commons-database-type-small-int.mjs.map +1 -0
  76. package/dist/classes/commons-database-type-string-array.d.mts +11 -0
  77. package/dist/classes/commons-database-type-string-array.mjs +47 -0
  78. package/dist/classes/commons-database-type-string-array.mjs.map +1 -0
  79. package/dist/classes/commons-database-type-string.d.mts +9 -0
  80. package/dist/classes/commons-database-type-string.mjs +34 -0
  81. package/dist/classes/commons-database-type-string.mjs.map +1 -0
  82. package/dist/classes/commons-database-type-text.d.mts +8 -0
  83. package/dist/classes/commons-database-type-text.mjs +25 -0
  84. package/dist/classes/commons-database-type-text.mjs.map +1 -0
  85. package/dist/classes/commons-database-type-time.d.mts +7 -0
  86. package/dist/classes/commons-database-type-time.mjs +57 -0
  87. package/dist/classes/commons-database-type-time.mjs.map +1 -0
  88. package/dist/classes/commons-database-type-tiny-int-enum.d.mts +9 -0
  89. package/dist/classes/commons-database-type-tiny-int-enum.mjs +36 -0
  90. package/dist/classes/commons-database-type-tiny-int-enum.mjs.map +1 -0
  91. package/dist/classes/commons-database-type-tiny-int.d.mts +10 -0
  92. package/dist/classes/commons-database-type-tiny-int.mjs +44 -0
  93. package/dist/classes/commons-database-type-tiny-int.mjs.map +1 -0
  94. package/dist/classes/commons-database-type-url.d.mts +6 -0
  95. package/dist/classes/commons-database-type-url.mjs +17 -0
  96. package/dist/classes/commons-database-type-url.mjs.map +1 -0
  97. package/dist/classes/commons-database-type.d.mts +17 -0
  98. package/dist/classes/commons-database-type.mjs +63 -0
  99. package/dist/classes/commons-database-type.mjs.map +1 -0
  100. package/dist/classes/fixed-date.d.mts +8 -0
  101. package/dist/classes/fixed-date.mjs +33 -0
  102. package/dist/classes/fixed-date.mjs.map +1 -0
  103. package/dist/enums/ecommons-database-engine.d.mts +6 -0
  104. package/dist/enums/ecommons-database-engine.mjs +8 -0
  105. package/dist/enums/ecommons-database-engine.mjs.map +1 -0
  106. package/dist/enums/ecommons-database-insert-method.d.mts +4 -0
  107. package/dist/enums/ecommons-database-insert-method.mjs +6 -0
  108. package/dist/enums/ecommons-database-insert-method.mjs.map +1 -0
  109. package/dist/enums/ecommons-database-order-by.d.mts +5 -0
  110. package/dist/enums/ecommons-database-order-by.mjs +15 -0
  111. package/dist/enums/ecommons-database-order-by.mjs.map +1 -0
  112. package/dist/enums/ecommons-database-referential-action.d.mts +5 -0
  113. package/dist/enums/ecommons-database-referential-action.mjs +7 -0
  114. package/dist/enums/ecommons-database-referential-action.mjs.map +1 -0
  115. package/dist/enums/ecommons-database-type-null.d.mts +4 -0
  116. package/dist/enums/ecommons-database-type-null.mjs +6 -0
  117. package/dist/enums/ecommons-database-type-null.mjs.map +1 -0
  118. package/dist/enums/ecommons-database-type-signed.d.mts +4 -0
  119. package/dist/enums/ecommons-database-type-signed.mjs +6 -0
  120. package/dist/enums/ecommons-database-type-signed.mjs.map +1 -0
  121. package/dist/helpers/commons-database.d.mts +23 -0
  122. package/dist/helpers/commons-database.mjs +95 -0
  123. package/dist/helpers/commons-database.mjs.map +1 -0
  124. package/dist/helpers/commons-tallies.d.mts +11 -0
  125. package/dist/helpers/commons-tallies.mjs +225 -0
  126. package/dist/helpers/commons-tallies.mjs.map +1 -0
  127. package/dist/index.d.mts +50 -0
  128. package/dist/index.mjs +47 -0
  129. package/dist/index.mjs.map +1 -0
  130. package/dist/interfaces/icommons-credentials.d.mts +9 -0
  131. package/dist/interfaces/icommons-credentials.mjs +17 -0
  132. package/dist/interfaces/icommons-credentials.mjs.map +1 -0
  133. package/dist/services/commons-nosql-database.service.d.mts +8 -0
  134. package/dist/services/commons-nosql-database.service.mjs +7 -0
  135. package/dist/services/commons-nosql-database.service.mjs.map +1 -0
  136. package/dist/services/commons-sql-database.service.d.mts +65 -0
  137. package/dist/services/commons-sql-database.service.mjs +538 -0
  138. package/dist/services/commons-sql-database.service.mjs.map +1 -0
  139. package/dist/types/tcommons-database-foreign-keys.d.mts +4 -0
  140. package/dist/types/tcommons-database-foreign-keys.mjs +2 -0
  141. package/dist/types/tcommons-database-foreign-keys.mjs.map +1 -0
  142. package/dist/types/tcommons-database-params.d.mts +4 -0
  143. package/dist/types/tcommons-database-params.mjs +2 -0
  144. package/dist/types/tcommons-database-params.mjs.map +1 -0
  145. package/dist/types/tcommons-database-types.d.mts +4 -0
  146. package/dist/types/tcommons-database-types.mjs +2 -0
  147. package/dist/types/tcommons-database-types.mjs.map +1 -0
  148. package/dist/types/tcommons-database-unique-keys.d.mts +4 -0
  149. package/dist/types/tcommons-database-unique-keys.mjs +2 -0
  150. package/dist/types/tcommons-database-unique-keys.mjs.map +1 -0
  151. package/package.json +31 -0
@@ -0,0 +1,17 @@
1
+ import { commonsTypeHasPropertyString, commonsTypeHasPropertyStringOrUndefined, commonsTypeHasPropertyNumberOrUndefined } from 'tscommons-esm-core';
2
+ export function isICommonsCredentials(test) {
3
+ if (!commonsTypeHasPropertyString(test, 'name'))
4
+ return false;
5
+ if (!commonsTypeHasPropertyStringOrUndefined(test, 'user'))
6
+ return false;
7
+ if (!commonsTypeHasPropertyStringOrUndefined(test, 'password'))
8
+ return false;
9
+ if (!commonsTypeHasPropertyStringOrUndefined(test, 'host'))
10
+ return false;
11
+ if (!commonsTypeHasPropertyNumberOrUndefined(test, 'port'))
12
+ return false;
13
+ if (!commonsTypeHasPropertyStringOrUndefined(test, 'authSource'))
14
+ return false;
15
+ return true;
16
+ }
17
+ //# sourceMappingURL=icommons-credentials.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icommons-credentials.mjs","sourceRoot":"","sources":["../../src/interfaces/icommons-credentials.mts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,uCAAuC,EACvC,uCAAuC,EACxC,MAAM,oBAAoB,CAAC;AAW5B,MAAM,UAAU,qBAAqB,CAAC,IAAS;IAC9C,IAAI,CAAC,4BAA4B,CAAC,IAAI,EAAE,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9D,IAAI,CAAC,uCAAuC,CAAC,IAAI,EAAE,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACzE,IAAI,CAAC,uCAAuC,CAAC,IAAI,EAAE,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7E,IAAI,CAAC,uCAAuC,CAAC,IAAI,EAAE,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACzE,IAAI,CAAC,uCAAuC,CAAC,IAAI,EAAE,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACzE,IAAI,CAAC,uCAAuC,CAAC,IAAI,EAAE,YAAY,CAAC;QAAE,OAAO,KAAK,CAAC;IAE/E,OAAO,IAAI,CAAC;AACb,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { ICommonsCredentials } from '../interfaces/icommons-credentials.mjs';
2
+ export type TQueryParams = {
3
+ [name: string]: any;
4
+ };
5
+ export declare abstract class CommonsNosqlDatabaseService<CredentialsI extends ICommonsCredentials> {
6
+ protected credentials: CredentialsI;
7
+ constructor(credentials: CredentialsI);
8
+ }
@@ -0,0 +1,7 @@
1
+ export class CommonsNosqlDatabaseService {
2
+ credentials;
3
+ constructor(credentials) {
4
+ this.credentials = credentials;
5
+ }
6
+ }
7
+ //# sourceMappingURL=commons-nosql-database.service.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commons-nosql-database.service.mjs","sourceRoot":"","sources":["../../src/services/commons-nosql-database.service.mts"],"names":[],"mappings":"AAMA,MAAM,OAAgB,2BAA2B;IAEpC;IADZ,YACY,WAAyB;QAAzB,gBAAW,GAAX,WAAW,CAAc;IAClC,CAAC;CACJ"}
@@ -0,0 +1,65 @@
1
+ import { TPropertyObject } from 'tscommons-esm-core';
2
+ import { CommonsDatabaseType } from '../classes/commons-database-type.mjs';
3
+ import { CommonsDatabaseParam } from '../classes/commons-database-param.mjs';
4
+ import { CommonsDatabase } from '../helpers/commons-database.mjs';
5
+ import { ICommonsCredentials } from '../interfaces/icommons-credentials.mjs';
6
+ import { TCommonsDatabaseParams } from '../types/tcommons-database-params.mjs';
7
+ import { TCommonsDatabaseTypes } from '../types/tcommons-database-types.mjs';
8
+ import { ECommonsDatabaseEngine } from '../enums/ecommons-database-engine.mjs';
9
+ import { ECommonsDatabaseReferentialAction } from '../enums/ecommons-database-referential-action.mjs';
10
+ export declare function commonsDatabaseAssertField(field: string): string;
11
+ export declare abstract class CommonsSqlDatabaseService<CredentialsI extends ICommonsCredentials> extends CommonsDatabase {
12
+ protected credentials: CredentialsI;
13
+ private preprepared;
14
+ private transactionState;
15
+ constructor(engine: ECommonsDatabaseEngine, credentials: CredentialsI);
16
+ abstract connect(): Promise<void>;
17
+ preprepare(name: string, sql: string, params?: TCommonsDatabaseTypes, // this is deliberate, we don't have the param values yet
18
+ results?: TCommonsDatabaseTypes): void;
19
+ abstract doesTableExist(name: string): Promise<boolean>;
20
+ protected abstract internalSelect(sql: string, params?: TPropertyObject): Promise<TPropertyObject[]>;
21
+ protected abstract internalNone(sql: string, params?: TPropertyObject): Promise<void>;
22
+ protected abstract internalTransactionBegin(): Promise<void>;
23
+ protected abstract internalTransactionCommit(): Promise<void>;
24
+ protected abstract internalTransactionRollback(): Promise<void>;
25
+ transactionClaim(): Promise<boolean>;
26
+ transactionCommit(): Promise<void>;
27
+ transactionRollback(): Promise<void>;
28
+ private buildParams;
29
+ queryParams<T extends TPropertyObject>(sql: string, params?: TCommonsDatabaseParams, results?: TCommonsDatabaseTypes): Promise<T[]>;
30
+ noneParams(sql: string, params?: TCommonsDatabaseParams): Promise<void>;
31
+ queryParamsSingle<T extends TPropertyObject>(sql: string, params?: TCommonsDatabaseParams, results?: TCommonsDatabaseTypes): Promise<T | undefined>;
32
+ queryParamsList<U>(sql: string, params?: TCommonsDatabaseParams, field?: string, type?: CommonsDatabaseType): Promise<U[]>;
33
+ queryParamsValue<U>(sql: string, params?: TCommonsDatabaseParams, field?: string, type?: CommonsDatabaseType, allowNone?: boolean): Promise<U | undefined>;
34
+ queryParamsValueNoNone<U>(sql: string, params?: TCommonsDatabaseParams, field?: string, type?: CommonsDatabaseType): Promise<U>;
35
+ private buildPrepreparedParams;
36
+ executeParams<T extends TPropertyObject>(name: string, values?: TPropertyObject): Promise<T[]>;
37
+ executeParamsSingle<T extends TPropertyObject>(name: string, values?: TPropertyObject): Promise<T | undefined>;
38
+ executeParamsList<U>(name: string, values?: TPropertyObject): Promise<U[]>;
39
+ executeParamsValue<U>(name: string, values?: TPropertyObject, allowNone?: boolean): Promise<U | undefined>;
40
+ executeParamsValueNoNone<U>(name: string, values?: TPropertyObject): Promise<U>;
41
+ private generateCreateTableSql;
42
+ createTable(table: string, structure: TCommonsDatabaseTypes, ifNotExists?: boolean): Promise<void>;
43
+ dropTable(table: string, structure: TCommonsDatabaseTypes, ifExists?: boolean): Promise<void>;
44
+ createView(table: string, name: string, sql: string, ifNotExists?: boolean): Promise<void>;
45
+ dropView(table: string, name: string, ifExists?: boolean): Promise<void>;
46
+ createForeignKey(table: string, destTable: string, field: string, destId: string, onDelete?: ECommonsDatabaseReferentialAction, onUpdate?: ECommonsDatabaseReferentialAction, constraintName?: string): Promise<void>;
47
+ generateCreateForeignKeySql(table: string, destTable: string, field: string, destId: string, onDelete?: ECommonsDatabaseReferentialAction, onUpdate?: ECommonsDatabaseReferentialAction, constraintName?: string): string;
48
+ createUniqueKey(table: string, fields: string[], constraintName?: string): Promise<void>;
49
+ generateCreateUniqueKeySql(table: string, fields: string[], constraintName?: string): string;
50
+ createIndexKey(table: string, fields: string[], constraintName?: string): Promise<void>;
51
+ generateCreateIndexKeySql(table: string, fields: string[], indexName?: string): string;
52
+ private insertOrReplaceRow;
53
+ insertRow(table: string, values: {
54
+ [key: string]: CommonsDatabaseParam;
55
+ }, autoinc?: string): Promise<number | void>;
56
+ upsertRow(table: string, values: {
57
+ [key: string]: CommonsDatabaseParam;
58
+ }, conflictFields?: string[], autoinc?: string): Promise<number | void>;
59
+ private buildClause;
60
+ updateRowsByConditions(table: string, values: TCommonsDatabaseParams, conditions: TCommonsDatabaseParams, singular?: boolean): Promise<void>;
61
+ deleteRowsByConditions(table: string, conditions: TCommonsDatabaseParams, singular?: boolean): Promise<void>;
62
+ selectRowsByConditions<T extends TPropertyObject>(table: string, fields: TCommonsDatabaseTypes, conditions: TCommonsDatabaseParams): Promise<T[]>;
63
+ countRowsByConditions(table: string, conditions: TCommonsDatabaseParams): Promise<number>;
64
+ doesRowExistByConditions(table: string, conditions: TCommonsDatabaseParams): Promise<boolean>;
65
+ }
@@ -0,0 +1,538 @@
1
+ import { commonsTypeIsNumber, commonsObjectIsEmpty, commonsObjectMapObject } from 'tscommons-esm-core';
2
+ import { CommonsDatabaseType } from '../classes/commons-database-type.mjs';
3
+ import { CommonsDatabaseParam } from '../classes/commons-database-param.mjs';
4
+ import { CommonsDatabaseTypeEnum } from '../classes/commons-database-type-enum.mjs';
5
+ import { CommonsDatabaseTypeSerialId } from '../classes/commons-database-type-serial-id.mjs';
6
+ import { CommonsDatabaseTypeInt } from '../classes/commons-database-type-int.mjs';
7
+ import { CommonsDatabaseTypeNumber } from '../classes/commons-database-type-number.mjs';
8
+ import { CommonsDatabase } from '../helpers/commons-database.mjs';
9
+ import { ECommonsDatabaseEngine } from '../enums/ecommons-database-engine.mjs';
10
+ import { ECommonsDatabaseReferentialAction } from '../enums/ecommons-database-referential-action.mjs';
11
+ import { ECommonsDatabaseInsertMethod } from '../enums/ecommons-database-insert-method.mjs';
12
+ import { ECommonsDatabaseTypeNull } from '../enums/ecommons-database-type-null.mjs';
13
+ import { ECommonsDatabaseTypeSigned } from '../enums/ecommons-database-type-signed.mjs';
14
+ var ETransactionState;
15
+ (function (ETransactionState) {
16
+ ETransactionState[ETransactionState["FREE"] = 0] = "FREE";
17
+ ETransactionState[ETransactionState["PENDING"] = 1] = "PENDING";
18
+ ETransactionState[ETransactionState["RUNNING"] = 2] = "RUNNING";
19
+ })(ETransactionState || (ETransactionState = {}));
20
+ function strongTypeResult(value, type, engine) {
21
+ if (value !== undefined)
22
+ value = type.processOut(value, engine);
23
+ type.assert(value);
24
+ return value;
25
+ }
26
+ function singleRow(rows) {
27
+ if (rows.length === 0)
28
+ return undefined;
29
+ if (rows.length > 1)
30
+ throw new Error('execute/queryParamsSingle didn\'t return one exact row');
31
+ return rows[0];
32
+ }
33
+ function singleList(rows) {
34
+ return rows
35
+ .map((row) => {
36
+ const keys = Object.keys(row);
37
+ if (keys.length !== 1)
38
+ throw new Error('execute/queryParamsList returned more than one column');
39
+ return row[keys[0]]; // assume correct. if not, the results vs generic isn't correct, which is a programmer error and can't be detected at runtime.
40
+ });
41
+ }
42
+ export function commonsDatabaseAssertField(field) {
43
+ if (/[[\];/\\?'"\r\n\t\0`]/.test(field))
44
+ throw new Error(`Condition field contains an invalid character: ${field}`);
45
+ return field;
46
+ }
47
+ export class CommonsSqlDatabaseService extends CommonsDatabase {
48
+ credentials;
49
+ preprepared = new Map();
50
+ transactionState = ETransactionState.FREE;
51
+ constructor(engine, credentials) {
52
+ super(engine);
53
+ this.credentials = credentials;
54
+ }
55
+ preprepare(name, sql, params, // this is deliberate, we don't have the param values yet
56
+ results) {
57
+ if (this.preprepared.has(name))
58
+ throw new Error('Duplicate name for preprepared statement');
59
+ const prep = {
60
+ sql: sql,
61
+ isSelect: /^SELECT /i.test(sql),
62
+ params: params,
63
+ results: results
64
+ };
65
+ this.preprepared.set(name, prep);
66
+ }
67
+ async transactionClaim() {
68
+ if (this.transactionState !== ETransactionState.FREE)
69
+ return false;
70
+ this.transactionState = ETransactionState.PENDING;
71
+ try {
72
+ await this.internalTransactionBegin();
73
+ if (this.transactionState !== ETransactionState.PENDING)
74
+ throw new Error('Transaction clash');
75
+ this.transactionState = ETransactionState.RUNNING;
76
+ return true;
77
+ }
78
+ catch (e) {
79
+ console.log(e);
80
+ this.transactionState = ETransactionState.FREE;
81
+ return false;
82
+ }
83
+ }
84
+ async transactionCommit() {
85
+ if (this.transactionState !== ETransactionState.RUNNING)
86
+ throw new Error('No transaction is running');
87
+ try {
88
+ await this.internalTransactionCommit();
89
+ }
90
+ catch (e) {
91
+ console.log(e);
92
+ }
93
+ finally {
94
+ this.transactionState = ETransactionState.FREE;
95
+ }
96
+ }
97
+ async transactionRollback() {
98
+ if (this.transactionState !== ETransactionState.RUNNING)
99
+ throw new Error('No transaction is running');
100
+ try {
101
+ await this.internalTransactionRollback();
102
+ }
103
+ catch (e) {
104
+ console.log(e);
105
+ }
106
+ finally {
107
+ this.transactionState = ETransactionState.FREE;
108
+ }
109
+ }
110
+ buildParams(params) {
111
+ return commonsObjectMapObject(params, (object, _key) => {
112
+ const typecast = object;
113
+ typecast.process(this.getEngine());
114
+ return typecast.getValue();
115
+ });
116
+ }
117
+ async queryParams(sql, params, results) {
118
+ let internalData;
119
+ if (params)
120
+ internalData = this.buildParams(params);
121
+ const data = await this.internalSelect(sql.trim(), internalData);
122
+ if (data.length === 0)
123
+ return [];
124
+ if (!results)
125
+ return data; // can't check if not result definition to check against
126
+ const typecasted = [];
127
+ for (const row of data) {
128
+ const resultsKeys = Object.keys(results);
129
+ const rowKeys = Object.keys(row);
130
+ if (resultsKeys.length !== rowKeys.length)
131
+ throw new Error('Supplied result types is not the same length as actual results');
132
+ const extra = rowKeys
133
+ .filter((field) => !resultsKeys.includes(field));
134
+ if (extra.length > 0)
135
+ throw new Error('Returned row result field does not exist in the defined result structure');
136
+ const missing = resultsKeys
137
+ .filter((field) => !rowKeys.includes(field));
138
+ if (missing.length > 0)
139
+ throw new Error('Defined result structure field is missing from the returned row results');
140
+ const typecast = commonsObjectMapObject(row, (value, field) => strongTypeResult(value, results[field], this.getEngine()));
141
+ typecasted.push(typecast);
142
+ }
143
+ return typecasted; // assume correct. if not, the results vs generic isn't correct, which is a programmer error and can't be detected at runtime.
144
+ }
145
+ async noneParams(sql, params) {
146
+ let internalData;
147
+ if (params)
148
+ internalData = this.buildParams(params);
149
+ await this.internalNone(sql.trim(), internalData);
150
+ }
151
+ async queryParamsSingle(sql, params, results) {
152
+ const rows = await this.queryParams(sql, params, results);
153
+ return singleRow(rows);
154
+ }
155
+ async queryParamsList(sql, params, field, type) {
156
+ // can use TPropertyObject as we don't care about the mid-way structure types, only the end generic result.
157
+ // can assume the mid-way is correct. if not, the results vs generic isn't correct, which is a programmer error and can't be detected at runtime.
158
+ let results;
159
+ if (field && type) {
160
+ results = {};
161
+ results[field] = type;
162
+ }
163
+ const rows = await this.queryParams(sql, params, results);
164
+ return singleList(rows);
165
+ }
166
+ async queryParamsValue(sql, params, field, type, allowNone = false) {
167
+ // can use TPropertyObject as we don't care about the mid-way structure types, only the end generic result.
168
+ // can assume the mid-way is correct. if not, the results vs generic isn't correct, which is a programmer error and can't be detected at runtime.
169
+ const rows = await this.queryParamsList(sql, params, field, type);
170
+ if (rows.length === 0) {
171
+ if (allowNone)
172
+ return undefined;
173
+ throw new Error('queryParamsValue did not return a result and allowNone is false');
174
+ }
175
+ if (rows.length !== 1)
176
+ throw new Error('queryParamsValue returned more than one row');
177
+ return rows[0];
178
+ }
179
+ // helper method to avoid |undefined
180
+ async queryParamsValueNoNone(sql, params, field, type) {
181
+ return (await this.queryParamsValue(sql, params, field, type));
182
+ }
183
+ buildPrepreparedParams(values, types // intentional
184
+ ) {
185
+ const params = {};
186
+ for (const field of Object.keys(values)) {
187
+ params[field] = new CommonsDatabaseParam(values[field], types[field]);
188
+ params[field].process(this.getEngine());
189
+ }
190
+ return params;
191
+ }
192
+ async executeParams(name, values) {
193
+ if (!this.preprepared.has(name))
194
+ throw new Error('Preprepared statement does not exist');
195
+ const preprepared = this.preprepared.get(name);
196
+ let params;
197
+ if (values && preprepared.params) {
198
+ params = this.buildPrepreparedParams(values, preprepared.params);
199
+ }
200
+ return await this.queryParams(preprepared.sql, params, preprepared.results);
201
+ }
202
+ async executeParamsSingle(name, values) {
203
+ const rows = await this.executeParams(name, values);
204
+ return singleRow(rows);
205
+ }
206
+ async executeParamsList(name, values) {
207
+ // can use TPropertyObject as we don't care about the mid-way structure types, only the end generic result.
208
+ // can assume the mid-way is correct. if not, the results vs generic isn't correct, which is a programmer error and can't be detected at runtime.
209
+ const rows = await this.executeParams(name, values);
210
+ return singleList(rows);
211
+ }
212
+ async executeParamsValue(name, values, allowNone = false) {
213
+ // can use TPropertyObject as we don't care about the mid-way structure types, only the end generic result.
214
+ // can assume the mid-way is correct. if not, the results vs generic isn't correct, which is a programmer error and can't be detected at runtime.
215
+ const row = await this.executeParamsSingle(name, values);
216
+ if (allowNone && row === undefined)
217
+ return undefined;
218
+ if (row === undefined) {
219
+ if (allowNone)
220
+ return undefined;
221
+ throw new Error('executeParamsValue did not return a result and allowNone is false');
222
+ }
223
+ return singleList([row])[0];
224
+ }
225
+ // helper method to avoid |undefined
226
+ async executeParamsValueNoNone(name, values) {
227
+ return (await this.executeParamsValue(name, values));
228
+ }
229
+ // this has to be async as it might need to create enums for Postgres etc.
230
+ // can't use commonsObjectMapObject for the same reason
231
+ async generateCreateTableSql(table, structure, ifNotExists) {
232
+ const fields = [];
233
+ for (const field of Object.keys(structure)) {
234
+ commonsDatabaseAssertField(field);
235
+ const type = structure[field];
236
+ const build = [
237
+ this.delimit(field),
238
+ type.render(this.getEngine())
239
+ ];
240
+ if (type instanceof CommonsDatabaseTypeEnum) {
241
+ const createEnum = type.getCreateEnum(this.getEngine());
242
+ if (createEnum)
243
+ await this.noneParams(createEnum);
244
+ }
245
+ if (type instanceof CommonsDatabaseTypeNumber) {
246
+ type.renderAppendCheck(build, field, this.getEngine());
247
+ }
248
+ fields.push(build.join(' '));
249
+ }
250
+ const query = [
251
+ `CREATE TABLE ${ifNotExists ? 'IF NOT EXISTS' : ''}`,
252
+ this.table(table),
253
+ `(${fields.join(',')})`
254
+ ];
255
+ if (this.getEngine() === ECommonsDatabaseEngine.MYSQL)
256
+ query.push('ENGINE=InnoDB');
257
+ return query.join(' ');
258
+ }
259
+ async createTable(table, structure, ifNotExists = false) {
260
+ const sql = await this.generateCreateTableSql(table, structure, ifNotExists);
261
+ await this.noneParams(sql);
262
+ }
263
+ async dropTable(table, structure, ifExists = false) {
264
+ await this.noneParams(`DROP TABLE ${ifExists ? 'IF EXISTS' : ''} ${this.table(table)}`);
265
+ for (const field of Object.keys(structure)) {
266
+ commonsDatabaseAssertField(field);
267
+ const type = structure[field];
268
+ if (type instanceof CommonsDatabaseTypeEnum) {
269
+ const dropEnum = type.getDropEnum(this.getEngine());
270
+ if (dropEnum)
271
+ await this.noneParams(dropEnum);
272
+ }
273
+ }
274
+ }
275
+ async createView(table, name, sql, ifNotExists = false) {
276
+ await this.noneParams(`CREATE VIEW ${ifNotExists ? 'IF NOT EXISTS' : ''} ${this.view(table, name)} AS ${sql}`);
277
+ }
278
+ async dropView(table, name, ifExists = true // non-existant views aren't really much of an issue
279
+ ) {
280
+ await this.noneParams(`DROP VIEW ${ifExists ? 'IF EXISTS' : ''} ${this.view(table, name)} CASCADE`);
281
+ }
282
+ async createForeignKey(table, destTable, field, destId, onDelete = ECommonsDatabaseReferentialAction.CASCADE, onUpdate = ECommonsDatabaseReferentialAction.CASCADE, constraintName) {
283
+ const sql = this.generateCreateForeignKeySql(table, destTable, field, destId, onDelete, onUpdate, constraintName);
284
+ await this.noneParams(sql);
285
+ }
286
+ generateCreateForeignKeySql(table, destTable, field, destId, onDelete = ECommonsDatabaseReferentialAction.CASCADE, onUpdate = ECommonsDatabaseReferentialAction.CASCADE, constraintName) {
287
+ if (!constraintName)
288
+ constraintName = `f_${table}_${destTable}_${field}_${destId}`;
289
+ return `
290
+ ALTER TABLE ${this.table(table)}
291
+ ADD CONSTRAINT ${this.delimit(constraintName)}
292
+ FOREIGN KEY (${this.delimit(field)})
293
+ REFERENCES ${this.delimit(destTable)} (${this.delimit(destId)})
294
+ ON DELETE ${onDelete}
295
+ ON UPDATE ${onUpdate}
296
+ `;
297
+ }
298
+ async createUniqueKey(table, fields, constraintName) {
299
+ const sql = this.generateCreateUniqueKeySql(table, fields, constraintName);
300
+ await this.noneParams(sql);
301
+ }
302
+ generateCreateUniqueKeySql(table, fields, constraintName) {
303
+ const build = [];
304
+ const names = [];
305
+ for (const field of fields) {
306
+ commonsDatabaseAssertField(field);
307
+ build.push(this.delimit(field));
308
+ names.push(field);
309
+ }
310
+ if (!constraintName)
311
+ constraintName = `constraint_unique_${table}_${names.join('_')}`;
312
+ const query = [
313
+ 'ALTER TABLE',
314
+ this.table(table),
315
+ 'ADD CONSTRAINT',
316
+ this.delimit(constraintName),
317
+ 'UNIQUE'
318
+ ];
319
+ if (this.getEngine() !== ECommonsDatabaseEngine.POSTGRES)
320
+ query.push('KEY');
321
+ query.push(`(${build.join(',')})`);
322
+ return query.join(' ');
323
+ }
324
+ async createIndexKey(table, fields, constraintName) {
325
+ const sql = this.generateCreateIndexKeySql(table, fields, constraintName);
326
+ await this.noneParams(sql);
327
+ }
328
+ generateCreateIndexKeySql(table, fields, indexName) {
329
+ const build = [];
330
+ const names = [];
331
+ for (const field of fields) {
332
+ commonsDatabaseAssertField(field);
333
+ build.push(this.delimit(field));
334
+ names.push(field);
335
+ }
336
+ if (!indexName)
337
+ indexName = `index_${table}_${names.join('_')}`;
338
+ return `
339
+ CREATE INDEX ${this.delimit(indexName)}
340
+ ON ${this.delimit(table)} (${build.join(',')})
341
+ `;
342
+ }
343
+ async insertOrReplaceRow(method, table, values, conflictFields, autoinc) {
344
+ const params = {};
345
+ const fields = [];
346
+ const qs = [];
347
+ let i = 1;
348
+ for (const field of Object.keys(values)) {
349
+ commonsDatabaseAssertField(field);
350
+ if (this.getEngine() === ECommonsDatabaseEngine.POSTGRES
351
+ || this.getEngine() === ECommonsDatabaseEngine.SQLITE) {
352
+ fields.push(this.delimit(field)); // some databases don't like Table.Field syntax for some reason?
353
+ }
354
+ else {
355
+ fields.push(this.tableField(table, field));
356
+ }
357
+ qs.push(`:value${i}`);
358
+ params[`value${i}`] = values[field];
359
+ i++;
360
+ }
361
+ const query = [];
362
+ switch (this.getEngine()) {
363
+ case ECommonsDatabaseEngine.POSTGRES:
364
+ query.push('INSERT');
365
+ break;
366
+ case ECommonsDatabaseEngine.MYSQL:
367
+ case ECommonsDatabaseEngine.SQLITE:
368
+ switch (method) {
369
+ case ECommonsDatabaseInsertMethod.INSERT:
370
+ query.push('INSERT');
371
+ break;
372
+ case ECommonsDatabaseInsertMethod.UPSERT:
373
+ query.push('REPLACE');
374
+ break;
375
+ }
376
+ break;
377
+ }
378
+ query.push(`INTO ${this.table(table)}`);
379
+ query.push(`(${fields.join(',')})`);
380
+ query.push(`VALUES (${qs.join(',')})`);
381
+ if (method === ECommonsDatabaseInsertMethod.UPSERT && this.getEngine() === ECommonsDatabaseEngine.POSTGRES) {
382
+ if (!conflictFields || conflictFields.length === 0)
383
+ throw new Error('No conflict fields supplied for a Postgres upsert');
384
+ const excludeds = Object.keys(values)
385
+ .filter((field) => !conflictFields.includes(field))
386
+ .map((field) => `${this.delimit(field)} = EXCLUDED.${this.delimit(field)}`);
387
+ query.push(`ON CONFLICT (${conflictFields.map((field) => this.delimit(field)).join(',')})`);
388
+ if (excludeds.length === 0) {
389
+ query.push('DO NOTHING');
390
+ }
391
+ else {
392
+ query.push(`DO UPDATE SET ${excludeds.join(',')}`);
393
+ }
394
+ }
395
+ if (autoinc !== undefined && this.getEngine() === ECommonsDatabaseEngine.POSTGRES) {
396
+ query.push(`RETURNING "${autoinc}"`);
397
+ }
398
+ if (autoinc !== undefined) {
399
+ switch (this.getEngine()) {
400
+ case ECommonsDatabaseEngine.POSTGRES:
401
+ case ECommonsDatabaseEngine.MYSQL: {
402
+ const id = await this.queryParamsValue(query.join(' '), params, 'id', new CommonsDatabaseTypeSerialId());
403
+ if (!commonsTypeIsNumber(id) || id < 1)
404
+ throw new Error('Autoinc query failed');
405
+ return id;
406
+ }
407
+ case ECommonsDatabaseEngine.SQLITE: {
408
+ await this.noneParams(query.join(' '), params);
409
+ return (await this.queryParamsValue('SELECT last_insert_rowid() AS id', undefined, 'id', new CommonsDatabaseTypeInt(ECommonsDatabaseTypeSigned.UNSIGNED, ECommonsDatabaseTypeNull.NOT_NULL)));
410
+ }
411
+ default:
412
+ throw new Error('Unknown database type for autoincrement value return');
413
+ }
414
+ }
415
+ else {
416
+ await this.noneParams(query.join(' '), params);
417
+ }
418
+ }
419
+ async insertRow(table, values, autoinc) {
420
+ return await this.insertOrReplaceRow(ECommonsDatabaseInsertMethod.INSERT, table, values, undefined, autoinc);
421
+ }
422
+ async upsertRow(table, values, conflictFields, autoinc) {
423
+ return await this.insertOrReplaceRow(ECommonsDatabaseInsertMethod.UPSERT, table, values, conflictFields, autoinc);
424
+ }
425
+ buildClause(table, inParams, outParams, prefix, delimiter, write) {
426
+ if (commonsObjectIsEmpty(inParams))
427
+ throw new Error('No inParams');
428
+ const build = [];
429
+ let i = 1;
430
+ for (const field of Object.keys(inParams)) {
431
+ commonsDatabaseAssertField(field);
432
+ const param = inParams[field];
433
+ if (write
434
+ && (this.getEngine() === ECommonsDatabaseEngine.POSTGRES
435
+ || this.getEngine() === ECommonsDatabaseEngine.SQLITE)) {
436
+ // postgres and sqlite don't like Table.Field syntax for writing data for some reason?
437
+ build.push(`${this.delimit(field)} = :${prefix}${i}`);
438
+ }
439
+ else {
440
+ build.push(`${this.tableField(table, field)} = :${prefix}${i}`);
441
+ }
442
+ outParams[`${prefix}${i}`] = param;
443
+ i++;
444
+ }
445
+ return build.join(delimiter);
446
+ }
447
+ async updateRowsByConditions(table, values, conditions, singular = false) {
448
+ if (commonsObjectIsEmpty(values))
449
+ throw new Error('No update values');
450
+ if (commonsObjectIsEmpty(conditions))
451
+ throw new Error('No conditions supplied for update');
452
+ const isTransactionOwner = await this.transactionClaim();
453
+ try {
454
+ if (singular) {
455
+ const count = await this.countRowsByConditions(table, conditions);
456
+ if (1 !== count)
457
+ throw new Error(`Singular check failure: ${count} rows match`);
458
+ }
459
+ const params = {};
460
+ const setClauses = this.buildClause(table, values, params, 'value', ',', true);
461
+ const whereClauses = this.buildClause(table, conditions, params, 'condition', ' AND ', false);
462
+ await this.noneParams(`
463
+ UPDATE ${this.table(table)}
464
+ SET ${setClauses}
465
+ WHERE ${whereClauses}
466
+ `, params);
467
+ if (isTransactionOwner)
468
+ await this.transactionCommit();
469
+ }
470
+ catch (e) {
471
+ if (isTransactionOwner)
472
+ await this.transactionRollback();
473
+ console.error(e);
474
+ throw e;
475
+ }
476
+ }
477
+ async deleteRowsByConditions(table, conditions, singular = false) {
478
+ if (commonsObjectIsEmpty(conditions))
479
+ throw new Error('No conditions supplied for delete');
480
+ const isTransactionOwner = await this.transactionClaim();
481
+ try {
482
+ if (singular) {
483
+ const count = await this.countRowsByConditions(table, conditions);
484
+ if (1 !== count)
485
+ throw new Error(`Singular check failure: ${count} rows match`);
486
+ }
487
+ const params = {};
488
+ const whereClauses = this.buildClause(table, conditions, params, 'condition', ' AND ', false);
489
+ await this.noneParams(`
490
+ DELETE FROM ${this.table(table)}
491
+ WHERE ${whereClauses}
492
+ `, params);
493
+ if (isTransactionOwner)
494
+ await this.transactionCommit();
495
+ }
496
+ catch (e) {
497
+ if (isTransactionOwner)
498
+ await this.transactionRollback();
499
+ console.error(e);
500
+ throw e;
501
+ }
502
+ }
503
+ async selectRowsByConditions(table, fields, conditions) {
504
+ if (commonsObjectIsEmpty(fields))
505
+ throw new Error('Select rows by conditions supplied zero-length field array');
506
+ if (commonsObjectIsEmpty(conditions))
507
+ throw new Error('No conditions supplied for select rows by conditions');
508
+ const queryFields = [];
509
+ for (const field of Object.keys(fields)) {
510
+ commonsDatabaseAssertField(field);
511
+ if (!(fields[field] instanceof CommonsDatabaseType))
512
+ throw new Error('Field type is not an instance of CommonsDatabaseType');
513
+ queryFields.push(this.tableField(table, field));
514
+ }
515
+ const params = {};
516
+ const whereClauses = this.buildClause(table, conditions, params, 'condition', ' AND ', false);
517
+ return await this.queryParams(`
518
+ SELECT ${queryFields.join(',')}
519
+ FROM ${this.table(table)}
520
+ WHERE ${whereClauses}
521
+ `, params, fields);
522
+ }
523
+ async countRowsByConditions(table, conditions) {
524
+ if (commonsObjectIsEmpty(conditions))
525
+ throw new Error('No conditions supplied for count rows by conditions');
526
+ const params = {};
527
+ const whereClauses = this.buildClause(table, conditions, params, 'condition', ' AND ', false);
528
+ return (await this.queryParamsValue(`
529
+ SELECT COUNT(*) AS ${this.delimit('count')}
530
+ FROM ${this.table(table)}
531
+ WHERE ${whereClauses}
532
+ `, params, 'count', new CommonsDatabaseTypeInt(ECommonsDatabaseTypeSigned.UNSIGNED, ECommonsDatabaseTypeNull.NOT_NULL)));
533
+ }
534
+ async doesRowExistByConditions(table, conditions) {
535
+ return (await this.countRowsByConditions(table, conditions)) > 0;
536
+ }
537
+ }
538
+ //# sourceMappingURL=commons-sql-database.service.mjs.map