@bitblit/ratchet-rdbms 6.0.146-alpha → 6.0.148-alpha

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 (56) hide show
  1. package/package.json +4 -3
  2. package/src/build/ratchet-rdbms-info.ts +19 -0
  3. package/src/model/connection-and-tunnel.ts +7 -0
  4. package/src/model/database-access-provider.ts +11 -0
  5. package/src/model/database-access.ts +30 -0
  6. package/src/model/database-config-list.ts +3 -0
  7. package/src/model/database-request-type.ts +6 -0
  8. package/src/model/group-by-count-result.ts +4 -0
  9. package/src/model/modify-results.ts +9 -0
  10. package/src/model/named-parameter-database-service-config.ts +13 -0
  11. package/src/model/paginated-results.ts +5 -0
  12. package/src/model/pagination-bounds.ts +12 -0
  13. package/src/model/paginator.ts +20 -0
  14. package/src/model/query-defaults.ts +4 -0
  15. package/src/model/query-text-provider.ts +4 -0
  16. package/src/model/request-results.ts +4 -0
  17. package/src/model/simple-query-text-provider.ts +18 -0
  18. package/src/model/sort-direction.ts +4 -0
  19. package/src/model/ssh/ssh-tunnel-config.ts +8 -0
  20. package/src/model/ssh/ssh-tunnel-container.ts +13 -0
  21. package/src/model/transaction-isolation-level.ts +4 -0
  22. package/src/mysql/model/mysql-db-config.ts +14 -0
  23. package/src/mysql/model/mysql-master-status.ts +6 -0
  24. package/src/mysql/model/mysql-slave-status.ts +52 -0
  25. package/src/mysql/mysql-style-database-access.ts +85 -0
  26. package/src/mysql/rds-mysql-style-connection-provider.ts +265 -0
  27. package/src/postgres/model/postgres-db-config.ts +8 -0
  28. package/src/postgres/postgres-style-connection-provider.ts +270 -0
  29. package/src/postgres/postgres-style-database-access.spec.ts +76 -0
  30. package/src/postgres/postgres-style-database-access.ts +110 -0
  31. package/src/query-builder/query-builder-result.ts +21 -0
  32. package/src/query-builder/query-builder.spec.ts +194 -0
  33. package/src/query-builder/query-builder.ts +445 -0
  34. package/src/query-builder/query-util.spec.ts +20 -0
  35. package/src/query-builder/query-util.ts +162 -0
  36. package/src/rds-data-api/model/rds-data-api-connection-config.ts +8 -0
  37. package/src/rds-data-api/rds-data-api-connection-provider.ts +39 -0
  38. package/src/rds-data-api/rds-data-api-database-access.spec.ts +139 -0
  39. package/src/rds-data-api/rds-data-api-database-access.ts +209 -0
  40. package/src/service/named-parameter-database-service.ts +421 -0
  41. package/src/service/ssh-tunnel-service.ts +62 -0
  42. package/src/service/transactional-named-parameter-database-service.ts +171 -0
  43. package/src/sqlite/model/fetch-remote-mode.ts +4 -0
  44. package/src/sqlite/model/flush-remote-mode.ts +4 -0
  45. package/src/sqlite/model/sqlite-connection-config-flag.ts +3 -0
  46. package/src/sqlite/model/sqlite-connection-config.ts +11 -0
  47. package/src/sqlite/model/sqlite-local-file-config.ts +3 -0
  48. package/src/sqlite/model/sqlite-remote-file-sync-config.ts +9 -0
  49. package/src/sqlite/sqlite-database-access.spec.ts +158 -0
  50. package/src/sqlite/sqlite-database-access.ts +126 -0
  51. package/src/sqlite/sqlite-remote-sync-database-access.ts +152 -0
  52. package/src/sqlite/sqlite-style-connection-provider.ts +181 -0
  53. package/src/util/aws-rds-cert-2023.ts +502 -0
  54. package/src/util/named-parameter-adapter/named-parameter-adapter.ts +51 -0
  55. package/src/util/named-parameter-adapter/query-and-params.ts +4 -0
  56. package/src/util/relational-database-utils.ts +54 -0
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@bitblit/ratchet-rdbms",
3
- "version": "6.0.146-alpha",
3
+ "version": "6.0.148-alpha",
4
4
  "description": "Ratchet tooling for working with relational databases",
5
5
  "sideEffects": false,
6
6
  "type": "module",
7
7
  "files": [
8
+ "src/**",
8
9
  "lib/**",
9
10
  "bin/**"
10
11
  ],
@@ -47,7 +48,7 @@
47
48
  },
48
49
  "license": "Apache-2.0",
49
50
  "dependencies": {
50
- "@bitblit/ratchet-common": "6.0.146-alpha"
51
+ "@bitblit/ratchet-common": "6.0.148-alpha"
51
52
  },
52
53
  "optionalDependencies": {
53
54
  "@aws-sdk/client-rds-data": "3.922.0",
@@ -60,7 +61,7 @@
60
61
  },
61
62
  "peerDependencies": {
62
63
  "@aws-sdk/client-rds-data": "^3.922.0",
63
- "@bitblit/ratchet-common": "6.0.146-alpha",
64
+ "@bitblit/ratchet-common": "6.0.148-alpha",
64
65
  "better-sqlite3": "^12.4.1",
65
66
  "get-port": "^7.1.0",
66
67
  "mysql2": "^3.15.3",
@@ -0,0 +1,19 @@
1
+ import { BuildInformation } from '@bitblit/ratchet-common/build/build-information';
2
+
3
+ export class RatchetRdbmsInfo {
4
+ // Empty constructor prevents instantiation
5
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
6
+ private constructor() {}
7
+
8
+ public static buildInformation(): BuildInformation {
9
+ const val: BuildInformation = {
10
+ version: 'LOCAL-SNAPSHOT',
11
+ hash: 'LOCAL-HASH',
12
+ branch: 'LOCAL-BRANCH',
13
+ tag: 'LOCAL-TAG',
14
+ timeBuiltISO: 'LOCAL-TIME-ISO',
15
+ notes: 'LOCAL-NOTES',
16
+ };
17
+ return val;
18
+ }
19
+ }
@@ -0,0 +1,7 @@
1
+ import { SshTunnelContainer } from './ssh/ssh-tunnel-container.js';
2
+
3
+ export interface ConnectionAndTunnel<T, R> {
4
+ config: R;
5
+ db: T;
6
+ ssh: SshTunnelContainer;
7
+ }
@@ -0,0 +1,11 @@
1
+ import { DatabaseAccess } from './database-access.js';
2
+ import { QueryDefaults } from './query-defaults.js';
3
+
4
+ export interface DatabaseAccessProvider {
5
+ /**
6
+ * @param name if omitted, returns the default connection
7
+ */
8
+ getDatabaseAccess(name?: string): Promise<DatabaseAccess | undefined>;
9
+ clearDatabaseAccessCache(): Promise<boolean>;
10
+ createNonPooledDatabaseAccess?(queryDefaults: QueryDefaults, additionalConfig?: Record<string, any>): Promise<DatabaseAccess | undefined>;
11
+ }
@@ -0,0 +1,30 @@
1
+ // Represents the object used to actually talk to the database, such
2
+ // as a Connection object in mysql/maria, an HTTP wrapper for an HTTP db,
3
+ // or a AsyncDatabase object in sqlite. Usually it'll be a wrapper around
4
+ // the actual object to act as an adapter
5
+ import { RequestResults } from './request-results.js';
6
+ import { ModifyResults } from './modify-results.js';
7
+ import { DatabaseRequestType } from './database-request-type.js';
8
+
9
+ // T = Class of the connection
10
+ // R = Class of any extra connection configuration props
11
+ // S = Class of the object returned by a query (data)
12
+ export interface DatabaseAccess {
13
+ // Force the connection closed
14
+ close(): Promise<boolean>;
15
+ escape(value: any): string;
16
+
17
+ testConnection(logTestResults?: boolean): Promise<number>; // Should be a fast test like 'select 1'
18
+
19
+ preQuery?(): Promise<void>;
20
+ query<S>(query: string, fields: Record<string, any>): Promise<RequestResults<S>>;
21
+ modify(query: string, fields: Record<string, any>): Promise<RequestResults<ModifyResults>>;
22
+ // TODO: Handle DDL specially?
23
+ onRequestSuccessOnly?(type: DatabaseRequestType): Promise<void>;
24
+ onRequestFailureOnly?(type: DatabaseRequestType): Promise<void>;
25
+ onRequestSuccessOrFailure?(type: DatabaseRequestType): Promise<void>;
26
+
27
+ beginTransaction?(): Promise<void>;
28
+ commitTransaction?(): Promise<void>;
29
+ rollbackTransaction?(): Promise<void>;
30
+ }
@@ -0,0 +1,3 @@
1
+ export interface DatabaseConfigList<T> {
2
+ dbList: T[];
3
+ }
@@ -0,0 +1,6 @@
1
+ export enum DatabaseRequestType {
2
+ Query = 'Query', // eg Select
3
+ Modify = 'Modify', // eg Insert/Update/Delete
4
+ Definition = 'Definition', // eg, DDL
5
+ Meta = 'Meta', // eg - set transation isolation level
6
+ }
@@ -0,0 +1,4 @@
1
+ export interface GroupByCountResult {
2
+ groupByField: string;
3
+ count: number;
4
+ }
@@ -0,0 +1,9 @@
1
+ export interface ModifyResults {
2
+ changedRows: number;
3
+ insertId?: number;
4
+ fieldCount?: number;
5
+ affectedRows?: number;
6
+ info?: string;
7
+ serverStatus?: number;
8
+ warningStatus?: number;
9
+ }
@@ -0,0 +1,13 @@
1
+ import { QueryTextProvider } from './query-text-provider.js';
2
+ import { DatabaseAccessProvider } from './database-access-provider.js';
3
+ import { QueryDefaults } from './query-defaults.js';
4
+ import { LoggerInstance } from '@bitblit/ratchet-common/logger/logger-instance';
5
+
6
+ export interface NamedParameterDatabaseServiceConfig {
7
+ serviceName: string;
8
+ queryProvider: QueryTextProvider;
9
+ connectionProvider: DatabaseAccessProvider;
10
+ queryDefaults: QueryDefaults;
11
+ longQueryTimeMs: number;
12
+ logger?: LoggerInstance;
13
+ }
@@ -0,0 +1,5 @@
1
+ export interface PaginatedResults<T> {
2
+ results: T[];
3
+ nextPageToken: string;
4
+ prevPageToken: string;
5
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Defines the bounds of a paginator.
3
+ *
4
+ * Returns the min and max values for the column specified and the total count - can
5
+ * be used to roughly predict page values
6
+ */
7
+ export interface PaginationBounds<T> {
8
+ cn: string;
9
+ min: T;
10
+ max: T;
11
+ count: number;
12
+ }
@@ -0,0 +1,20 @@
1
+ import { SortDirection } from './sort-direction.js';
2
+ import { JwtTokenBase } from '@bitblit/ratchet-common/jwt/jwt-token-base';
3
+
4
+ /**
5
+ * Defines a paginator.
6
+ *
7
+ * Field names are short in here because this gets serialized when passed back and forth. They are:
8
+ * cn: ColumnName (required)
9
+ * min: min value for that column (optional)
10
+ * max: max value for that column (optional)
11
+ * s: sort direction for the column (optional, defaults to Asc)
12
+ * l: limit (optional)
13
+ */
14
+ export interface Paginator<T> extends JwtTokenBase {
15
+ cn: string;
16
+ min?: T;
17
+ max?: T;
18
+ s?: SortDirection;
19
+ l?: number;
20
+ }
@@ -0,0 +1,4 @@
1
+ export interface QueryDefaults {
2
+ databaseName: string;
3
+ timeoutMS: number;
4
+ }
@@ -0,0 +1,4 @@
1
+ export interface QueryTextProvider {
2
+ fetchQuery(queryDottedPath: string): string;
3
+ fetchAllQueries(): Record<string, string>;
4
+ }
@@ -0,0 +1,4 @@
1
+ export interface RequestResults<R> {
2
+ results: R;
3
+ fields?: Record<string, any>[];
4
+ }
@@ -0,0 +1,18 @@
1
+ import { QueryTextProvider } from './query-text-provider.js';
2
+ import { StringRatchet } from '@bitblit/ratchet-common/lang/string-ratchet';
3
+
4
+ export class SimpleQueryTextProvider implements QueryTextProvider {
5
+ constructor(private values: Record<string, string>) {}
6
+
7
+ public fetchQuery(queryDottedPath: string): string {
8
+ let rval: string = null;
9
+ if (StringRatchet.trimToNull(queryDottedPath)) {
10
+ rval = (this.values ?? {})[queryDottedPath];
11
+ }
12
+ return rval;
13
+ }
14
+
15
+ public fetchAllQueries(): Record<string, string> {
16
+ return Object.assign({}, this.values ?? {});
17
+ }
18
+ }
@@ -0,0 +1,4 @@
1
+ export enum SortDirection {
2
+ Asc = 'Asc',
3
+ Desc = 'Desc',
4
+ }
@@ -0,0 +1,8 @@
1
+ export interface SshTunnelConfig {
2
+ forceLocalPort?: number;
3
+ keepAlive: boolean;
4
+ username: string;
5
+ host: string;
6
+ port: number;
7
+ privateKey: string;
8
+ }
@@ -0,0 +1,13 @@
1
+ import type { ListenOptions, Server } from 'net';
2
+ import type { ConnectConfig, Connection } from 'ssh2';
3
+ import * as TunnelSsh from 'tunnel-ssh';
4
+
5
+ export interface SshTunnelContainer {
6
+ tunnelOptions: TunnelSsh.TunnelOptions;
7
+ serverOptions: ListenOptions;
8
+ sshOptions: ConnectConfig;
9
+ forwardOptions: TunnelSsh.ForwardOptions;
10
+ server: Server;
11
+ localPort: number;
12
+ connection?: Connection;
13
+ }
@@ -0,0 +1,4 @@
1
+ export enum TransactionIsolationLevel {
2
+ Default = 'Default',
3
+ ReadUncommitted = 'READ UNCOMMITTED',
4
+ }
@@ -0,0 +1,14 @@
1
+ import { SshTunnelConfig } from '../../model/ssh/ssh-tunnel-config.js';
2
+
3
+ export interface MysqlDbConfig {
4
+ label: string;
5
+ host: string;
6
+ port: number;
7
+ user: string;
8
+ password: string;
9
+ database: string;
10
+ sshTunnelConfig?: SshTunnelConfig;
11
+
12
+ ssl?: string | Record<string, any>;
13
+ decimalNumbers?: boolean;
14
+ }
@@ -0,0 +1,6 @@
1
+ export interface MysqlMasterStatus {
2
+ File: string;
3
+ Position: number;
4
+ Binlog_Do_DB: string;
5
+ Binlog_Ignore_DB: string;
6
+ }
@@ -0,0 +1,52 @@
1
+ export interface MysqlSlaveStatus {
2
+ Slave_IO_State: string;
3
+ Master_Host: string;
4
+ Master_User: string;
5
+ Master_Port: number;
6
+ Connect_Retry: number;
7
+ Master_Log_File: string;
8
+ Read_Master_Log_Pos: number;
9
+ Relay_Log_File: string;
10
+ Relay_Log_Pos: number;
11
+ Relay_Master_Log_File: string;
12
+ Slave_IO_Running: string;
13
+ Slave_SQL_Running: string;
14
+ Replicate_Do_DB: string;
15
+ Replicate_Ignore_DB: string;
16
+ Replicate_Do_Table: string;
17
+ Replicate_Ignore_Table: string;
18
+ Replicate_Wild_Do_Table: string;
19
+ Replicate_Wild_Ignore_Table: string;
20
+ Last_Errno: number;
21
+ Last_Error: string;
22
+ Skip_Counter: number;
23
+ Exec_Master_Log_Pos: number;
24
+ Relay_Log_Space: number;
25
+ Until_Condition: string;
26
+ Until_Log_File: string;
27
+ Until_Log_Pos: number;
28
+ Master_SSL_Allowed: string;
29
+ Master_SSL_CA_File: string;
30
+ Master_SSL_CA_Path: string;
31
+ Master_SSL_Cert: string;
32
+ Master_SSL_Cipher: string;
33
+ Master_SSL_Key: string;
34
+ Seconds_Behind_Master: number;
35
+ Master_SSL_Verify_Server_Cert: string;
36
+ Last_IO_Errno: number;
37
+ Last_IO_Error: string;
38
+ Last_SQL_Errno: number;
39
+ Last_SQL_Error: string;
40
+ Replicate_Ignore_Server_Ids: string;
41
+ Master_Server_Id: number;
42
+ Master_SSL_Crl: string;
43
+ Master_SSL_Crlpath: string;
44
+ Using_Gtid: string;
45
+ Gtid_IO_Pos: string;
46
+ Replicate_Do_Domain_Ids: string;
47
+ Replicate_Ignore_Domain_Ids: string;
48
+ Parallel_Mode: string;
49
+ SQL_Delay: number;
50
+ SQL_Remaining_Delay: string;
51
+ Slave_SQL_Running_State: string;
52
+ }
@@ -0,0 +1,85 @@
1
+ import { Connection, ConnectionOptions, FieldPacket, RowDataPacket } from 'mysql2/promise';
2
+ import { DatabaseAccess } from '../model/database-access.js';
3
+ import { RequestResults } from '../model/request-results.js';
4
+ import { ModifyResults } from '../model/modify-results.js';
5
+ import { DatabaseRequestType } from '../model/database-request-type.js';
6
+ import { Logger } from '@bitblit/ratchet-common/logger/logger';
7
+
8
+ export class MysqlStyleDatabaseAccess implements DatabaseAccess {
9
+ constructor(
10
+ private _connection: Connection,
11
+ private _connectionOptions: ConnectionOptions,
12
+ ) {}
13
+
14
+ public async testConnection(logTestResults?: boolean): Promise<number | null> {
15
+ if (logTestResults) {
16
+ Logger.info('Running connection test');
17
+ }
18
+
19
+ const res: RequestResults<any> = await this.query('SELECT UNIX_TIMESTAMP(now())*1000 AS test', {});
20
+ const rows = res.results as { test: number }[];
21
+ const timestamp = rows.length === 1 ? rows[0].test : null;
22
+ if (logTestResults) {
23
+ Logger.info('Test returned : %j', timestamp);
24
+ }
25
+ return timestamp;
26
+ }
27
+
28
+ public getRawDatabase(): Connection {
29
+ return this._connection;
30
+ }
31
+
32
+ public getRawDatabaseConfig(): ConnectionOptions {
33
+ return this._connectionOptions;
34
+ }
35
+
36
+ public testConnectionQueryString(): string {
37
+ return 'SELECT UNIX_TIMESTAMP(now())*1000 AS test';
38
+ }
39
+
40
+ public async close(): Promise<boolean> {
41
+ return Promise.resolve(false);
42
+ }
43
+
44
+ public escape(query: any): string {
45
+ return this._connection.escape(query);
46
+ }
47
+
48
+ public async preQuery(): Promise<void> {
49
+ this._connection.config.namedPlaceholders = true;
50
+ }
51
+
52
+ public async query<R>(query, fields): Promise<RequestResults<R>> {
53
+ const [rows, outFields] = await this._connection.query(query, fields);
54
+
55
+ const castRows: RowDataPacket[] = rows as RowDataPacket[];
56
+ const castFields: FieldPacket[] = outFields;
57
+
58
+ const rval: RequestResults<R> = {
59
+ results: castRows as R,
60
+ fields: castFields,
61
+ };
62
+
63
+ return rval;
64
+ }
65
+
66
+ public async modify(query: string, fields: Record<string, any>): Promise<RequestResults<ModifyResults>> {
67
+ const tmp: RequestResults<ModifyResults> = await this.query(query, fields);
68
+ return tmp;
69
+ }
70
+
71
+ public async onRequestSuccessOrFailure(_type: DatabaseRequestType): Promise<void> {
72
+ this._connection.config.namedPlaceholders = false;
73
+ }
74
+
75
+ /*
76
+ public async onQueryFailureOnly(): Promise<void> {
77
+ return Promise.resolve(undefined);
78
+ }
79
+
80
+ public async onQuerySuccessOnly(): Promise<void> {
81
+ return Promise.resolve(undefined);
82
+ }
83
+
84
+ */
85
+ }