@grest-ts/db-postgre 0.0.5
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/LICENSE +21 -0
- package/dist/src/GGPostgres.d.ts +30 -0
- package/dist/src/GGPostgres.d.ts.map +1 -0
- package/dist/src/GGPostgres.js +118 -0
- package/dist/src/GGPostgres.js.map +1 -0
- package/dist/src/GGPostgresConfig.d.ts +26 -0
- package/dist/src/GGPostgresConfig.d.ts.map +1 -0
- package/dist/src/GGPostgresConfig.js +32 -0
- package/dist/src/GGPostgresConfig.js.map +1 -0
- package/dist/src/GGPostgresConnection.d.ts +82 -0
- package/dist/src/GGPostgresConnection.d.ts.map +1 -0
- package/dist/src/GGPostgresConnection.js +135 -0
- package/dist/src/GGPostgresConnection.js.map +1 -0
- package/dist/src/index-node.d.ts +5 -0
- package/dist/src/index-node.d.ts.map +1 -0
- package/dist/src/index-node.js +4 -0
- package/dist/src/index-node.js.map +1 -0
- package/dist/src/tsconfig.json +16 -0
- package/dist/testkit/GGPostgresSchemaCloner.d.ts +13 -0
- package/dist/testkit/GGPostgresSchemaCloner.d.ts.map +1 -0
- package/dist/testkit/GGPostgresSchemaCloner.js +51 -0
- package/dist/testkit/GGPostgresSchemaCloner.js.map +1 -0
- package/dist/testkit/GGPostgresSchemaOperations.d.ts +20 -0
- package/dist/testkit/GGPostgresSchemaOperations.d.ts.map +1 -0
- package/dist/testkit/GGPostgresSchemaOperations.js +111 -0
- package/dist/testkit/GGPostgresSchemaOperations.js.map +1 -0
- package/dist/testkit/GGPostgresTestMethods.d.ts +44 -0
- package/dist/testkit/GGPostgresTestMethods.d.ts.map +1 -0
- package/dist/testkit/GGPostgresTestMethods.js +103 -0
- package/dist/testkit/GGPostgresTestMethods.js.map +1 -0
- package/dist/testkit/index-testkit.d.ts +3 -0
- package/dist/testkit/index-testkit.d.ts.map +1 -0
- package/dist/testkit/index-testkit.js +3 -0
- package/dist/testkit/index-testkit.js.map +1 -0
- package/dist/tsconfig.publish.tsbuildinfo +1 -0
- package/package.json +62 -0
- package/src/GGPostgres.ts +138 -0
- package/src/GGPostgresConfig.ts +39 -0
- package/src/GGPostgresConnection.ts +146 -0
- package/src/index-node.ts +4 -0
- package/src/tsconfig.json +16 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Grest Games OÜ
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { QueryResult, QueryResultRow } from 'pg';
|
|
2
|
+
import { GGPostgresConnection } from './GGPostgresConnection';
|
|
3
|
+
import type { GGPostgresConfig } from "./GGPostgresConfig";
|
|
4
|
+
export declare class GGPostgres {
|
|
5
|
+
private readonly config;
|
|
6
|
+
private started;
|
|
7
|
+
private pool;
|
|
8
|
+
private unwatchHost;
|
|
9
|
+
private unwatchUser;
|
|
10
|
+
constructor(config: GGPostgresConfig);
|
|
11
|
+
private connect;
|
|
12
|
+
private start;
|
|
13
|
+
private teardown;
|
|
14
|
+
private getPool;
|
|
15
|
+
query<T extends QueryResultRow = QueryResultRow>(sql: string, params?: unknown[]): Promise<T[]>;
|
|
16
|
+
execute(sql: string, params?: unknown[]): Promise<QueryResult>;
|
|
17
|
+
/**
|
|
18
|
+
* Get a dedicated connection from the pool.
|
|
19
|
+
* Use this for transactions or when you need multiple queries on the same connection.
|
|
20
|
+
*
|
|
21
|
+
* IMPORTANT: Always call release() on the connection when done.
|
|
22
|
+
*/
|
|
23
|
+
getConnection(): Promise<GGPostgresConnection>;
|
|
24
|
+
/**
|
|
25
|
+
* Run a callback within a transaction.
|
|
26
|
+
* Automatically handles connection lifecycle, commits on success, rolls back on failure.
|
|
27
|
+
*/
|
|
28
|
+
runInTransaction<T>(callback: (conn: GGPostgresConnection) => Promise<T>): Promise<T>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=GGPostgres.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGPostgres.d.ts","sourceRoot":"","sources":["../../src/GGPostgres.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,WAAW,EAAE,cAAc,EAAC,MAAM,IAAI,CAAC;AAGrD,OAAO,EAAC,oBAAoB,EAAC,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAEzD,qBAAa,UAAU;IAEnB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAE1C,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,IAAI,CAA+B;IAC3C,OAAO,CAAC,WAAW,CAAuC;IAC1D,OAAO,CAAC,WAAW,CAAuC;gBAE9C,MAAM,EAAE,gBAAgB;YAatB,OAAO;YA6CP,KAAK;YAKL,QAAQ;IAYtB,OAAO,CAAC,OAAO;IAOF,KAAK,CAAC,CAAC,SAAS,cAAc,GAAG,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAO/F,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAS3E;;;;;OAKG;IACU,aAAa,IAAI,OAAO,CAAC,oBAAoB,CAAC;IAK3D;;;OAGG;IACU,gBAAgB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAQrG"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Pool } from 'pg';
|
|
2
|
+
import { GGLocator, GGLocatorServiceType } from '@grest-ts/locator';
|
|
3
|
+
import { GGLog } from '@grest-ts/logger';
|
|
4
|
+
import { GGPostgresConnection } from './GGPostgresConnection.js';
|
|
5
|
+
export class GGPostgres {
|
|
6
|
+
config;
|
|
7
|
+
started = false;
|
|
8
|
+
pool = undefined;
|
|
9
|
+
unwatchHost = undefined;
|
|
10
|
+
unwatchUser = undefined;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
this.unwatchHost = this.config.host.watch(() => this.connect());
|
|
14
|
+
this.unwatchUser = this.config.user.watch(() => this.connect());
|
|
15
|
+
GGLocator.getScope().setWithLifecycle(this.config.token, this, {
|
|
16
|
+
type: GGLocatorServiceType.DATABASE,
|
|
17
|
+
start: () => this.start(),
|
|
18
|
+
teardown: () => this.teardown(),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async connect() {
|
|
22
|
+
if (!this.started) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const config = this.config.host.get();
|
|
26
|
+
const user = this.config.user.reveal();
|
|
27
|
+
const connectionsLimit = config.connectionLimit ?? 20;
|
|
28
|
+
const newPool = new Pool({
|
|
29
|
+
host: config.host ?? "localhost",
|
|
30
|
+
port: config.port ?? 5432,
|
|
31
|
+
user: user.username,
|
|
32
|
+
password: user.password,
|
|
33
|
+
database: config.database,
|
|
34
|
+
max: connectionsLimit,
|
|
35
|
+
});
|
|
36
|
+
try {
|
|
37
|
+
const client = await newPool.connect();
|
|
38
|
+
await client.query('SELECT 1');
|
|
39
|
+
client.release();
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
GGLog.critical(this, 'Failed to connect to pool! Must resolve immediately, new services will fail to start!', {
|
|
43
|
+
database: config.database,
|
|
44
|
+
host: config.host,
|
|
45
|
+
error: err instanceof Error ? err.message : String(err)
|
|
46
|
+
});
|
|
47
|
+
await newPool.end();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (this.pool) {
|
|
51
|
+
this.pool.end().catch(err => {
|
|
52
|
+
GGLog.warn(this, 'Config change: error closing old pool', {
|
|
53
|
+
error: err instanceof Error ? err.message : String(err)
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
this.pool = newPool;
|
|
58
|
+
GGLog.info(this, 'Postgres connected!', { database: config.database });
|
|
59
|
+
}
|
|
60
|
+
async start() {
|
|
61
|
+
this.started = true;
|
|
62
|
+
await this.connect();
|
|
63
|
+
}
|
|
64
|
+
async teardown() {
|
|
65
|
+
this.unwatchHost?.();
|
|
66
|
+
this.unwatchHost = undefined;
|
|
67
|
+
this.unwatchUser?.();
|
|
68
|
+
this.unwatchUser = undefined;
|
|
69
|
+
if (this.pool) {
|
|
70
|
+
await this.pool.end();
|
|
71
|
+
this.pool = undefined;
|
|
72
|
+
GGLog.debug(this, 'disconnected');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
getPool() {
|
|
76
|
+
if (!this.pool) {
|
|
77
|
+
throw new Error(`Postgres '${this.config.name}' not connected. Are you calling this before runtime.start()?`);
|
|
78
|
+
}
|
|
79
|
+
return this.pool;
|
|
80
|
+
}
|
|
81
|
+
async query(sql, params) {
|
|
82
|
+
GGLog.debug(this, 'query', { sql, params });
|
|
83
|
+
const result = await this.getPool().query(sql, params);
|
|
84
|
+
GGLog.debug(this, 'query result', { rowCount: result.rowCount });
|
|
85
|
+
return result.rows;
|
|
86
|
+
}
|
|
87
|
+
async execute(sql, params) {
|
|
88
|
+
GGLog.debug(this, 'execute', { sql, params });
|
|
89
|
+
const result = await this.getPool().query(sql, params);
|
|
90
|
+
GGLog.debug(this, 'execute result', { rowCount: result.rowCount });
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
// ==================== Connection for transactions ====================
|
|
94
|
+
/**
|
|
95
|
+
* Get a dedicated connection from the pool.
|
|
96
|
+
* Use this for transactions or when you need multiple queries on the same connection.
|
|
97
|
+
*
|
|
98
|
+
* IMPORTANT: Always call release() on the connection when done.
|
|
99
|
+
*/
|
|
100
|
+
async getConnection() {
|
|
101
|
+
const client = await this.getPool().connect();
|
|
102
|
+
return new GGPostgresConnection(client);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Run a callback within a transaction.
|
|
106
|
+
* Automatically handles connection lifecycle, commits on success, rolls back on failure.
|
|
107
|
+
*/
|
|
108
|
+
async runInTransaction(callback) {
|
|
109
|
+
const conn = await this.getConnection();
|
|
110
|
+
try {
|
|
111
|
+
return await conn.runInTransaction(() => callback(conn));
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
conn.release();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=GGPostgres.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGPostgres.js","sourceRoot":"","sources":["../../src/GGPostgres.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { GGResource, GGSecret } from "@grest-ts/config";
|
|
2
|
+
import { GGPostgres } from "./GGPostgres";
|
|
3
|
+
import { GGLocatorKey } from "@grest-ts/locator";
|
|
4
|
+
declare const IsPostgresResource: import("@grest-ts/schema").ObjectSchema<{
|
|
5
|
+
database: string;
|
|
6
|
+
host?: string;
|
|
7
|
+
port?: number;
|
|
8
|
+
connectionLimit?: number;
|
|
9
|
+
}>;
|
|
10
|
+
export type GGPostgresHostData = typeof IsPostgresResource.infer;
|
|
11
|
+
declare const IsPostgresUserData: import("@grest-ts/schema").ObjectSchema<{
|
|
12
|
+
username?: string;
|
|
13
|
+
password?: string;
|
|
14
|
+
}>;
|
|
15
|
+
export type GGPostgresUserData = typeof IsPostgresUserData.infer;
|
|
16
|
+
export declare class GGPostgresConfig {
|
|
17
|
+
readonly name: string;
|
|
18
|
+
readonly token: GGLocatorKey<GGPostgres>;
|
|
19
|
+
readonly host: GGResource<GGPostgresHostData>;
|
|
20
|
+
readonly user: GGSecret<GGPostgresUserData>;
|
|
21
|
+
readonly schemaFile?: string;
|
|
22
|
+
constructor(name: string, schemaFile?: string);
|
|
23
|
+
newPostgresPool(): GGPostgres;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=GGPostgresConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGPostgresConfig.d.ts","sourceRoot":"","sources":["../../src/GGPostgresConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AAExC,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAE/C,QAAA,MAAM,kBAAkB;;;;;EAKtB,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,kBAAkB,CAAC,KAAK,CAAA;AAEhE,QAAA,MAAM,kBAAkB;;;EAGtB,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,kBAAkB,CAAC,KAAK,CAAA;AAEhE,qBAAa,gBAAgB;IAEzB,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,KAAK,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IAChD,SAAgB,IAAI,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAC;IACrD,SAAgB,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IACnD,SAAgB,UAAU,CAAC,EAAE,MAAM,CAAC;gBAExB,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;IAQtC,eAAe;CAGzB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { GGResource, GGSecret } from "@grest-ts/config";
|
|
2
|
+
import { GGPostgres } from "./GGPostgres.js";
|
|
3
|
+
import { IsNumber, IsObject, IsString } from "@grest-ts/schema";
|
|
4
|
+
import { GGLocatorKey } from "@grest-ts/locator";
|
|
5
|
+
const IsPostgresResource = IsObject({
|
|
6
|
+
host: IsString.orUndefined,
|
|
7
|
+
port: IsNumber.orUndefined,
|
|
8
|
+
database: IsString,
|
|
9
|
+
connectionLimit: IsNumber.orUndefined
|
|
10
|
+
});
|
|
11
|
+
const IsPostgresUserData = IsObject({
|
|
12
|
+
username: IsString.orUndefined,
|
|
13
|
+
password: IsString.orUndefined
|
|
14
|
+
});
|
|
15
|
+
export class GGPostgresConfig {
|
|
16
|
+
name;
|
|
17
|
+
token;
|
|
18
|
+
host;
|
|
19
|
+
user;
|
|
20
|
+
schemaFile;
|
|
21
|
+
constructor(name, schemaFile) {
|
|
22
|
+
this.name = name;
|
|
23
|
+
this.token = new GGLocatorKey(`Postgres:${name}`);
|
|
24
|
+
this.host = new GGResource(name + "/host", IsPostgresResource, "Postgres host configuration");
|
|
25
|
+
this.user = new GGSecret(name + "/user", IsPostgresUserData, "Postgres user credentials");
|
|
26
|
+
this.schemaFile = schemaFile;
|
|
27
|
+
}
|
|
28
|
+
newPostgresPool() {
|
|
29
|
+
return new GGPostgres(this);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=GGPostgresConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGPostgresConfig.js","sourceRoot":"","sources":["../../src/GGPostgresConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AACxC,OAAO,EAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAE/C,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IAChC,IAAI,EAAE,QAAQ,CAAC,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC,WAAW;IAC1B,QAAQ,EAAE,QAAQ;IAClB,eAAe,EAAE,QAAQ,CAAC,WAAW;CACxC,CAAC,CAAC;AAGH,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IAChC,QAAQ,EAAE,QAAQ,CAAC,WAAW;IAC9B,QAAQ,EAAE,QAAQ,CAAC,WAAW;CACjC,CAAC,CAAC;AAGH,MAAM,OAAO,gBAAgB;IAET,IAAI,CAAS;IACb,KAAK,CAA2B;IAChC,IAAI,CAAiC;IACrC,IAAI,CAA+B;IACnC,UAAU,CAAU;IAEpC,YAAY,IAAY,EAAE,UAAmB;QACzC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,IAAI,YAAY,CAAa,YAAY,IAAI,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,GAAG,OAAO,EAAE,kBAAkB,EAAE,6BAA6B,CAAC,CAAA;QAC7F,IAAI,CAAC,IAAI,GAAG,IAAI,QAAQ,CAAC,IAAI,GAAG,OAAO,EAAE,kBAAkB,EAAE,2BAA2B,CAAC,CAAA;QACzF,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IACjC,CAAC;IAEM,eAAe;QAClB,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;CACJ"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { PoolClient, QueryResult, QueryResultRow } from 'pg';
|
|
2
|
+
/**
|
|
3
|
+
* PostgresConnection - A single connection from the pool.
|
|
4
|
+
*
|
|
5
|
+
* Use this when you need:
|
|
6
|
+
* - Transactions (BEGIN, COMMIT, ROLLBACK)
|
|
7
|
+
* - Multiple queries that must use the same connection
|
|
8
|
+
*
|
|
9
|
+
* IMPORTANT: Always call release() when done to return the connection to the pool.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const conn = await db.getConnection();
|
|
14
|
+
* try {
|
|
15
|
+
* await conn.beginTransaction();
|
|
16
|
+
* await conn.execute('INSERT INTO users ...', [...]);
|
|
17
|
+
* await conn.execute('INSERT INTO profiles ...', [...]);
|
|
18
|
+
* await conn.commit();
|
|
19
|
+
* } catch (err) {
|
|
20
|
+
* await conn.rollback();
|
|
21
|
+
* throw err;
|
|
22
|
+
* } finally {
|
|
23
|
+
* conn.release();
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare class GGPostgresConnection {
|
|
28
|
+
private client;
|
|
29
|
+
private released;
|
|
30
|
+
constructor(client: PoolClient);
|
|
31
|
+
/**
|
|
32
|
+
* Execute a SELECT query and return rows.
|
|
33
|
+
*/
|
|
34
|
+
query<T extends QueryResultRow = QueryResultRow>(sql: string, params?: unknown[]): Promise<T[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Execute an INSERT, UPDATE, or DELETE query.
|
|
37
|
+
*/
|
|
38
|
+
execute(sql: string, params?: unknown[]): Promise<QueryResult>;
|
|
39
|
+
/**
|
|
40
|
+
* Run a callback within a transaction.
|
|
41
|
+
* Automatically commits on success, rolls back on failure.
|
|
42
|
+
*
|
|
43
|
+
* Note: Does NOT release the connection. Call release() when done.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* const conn = await db.getConnection();
|
|
48
|
+
* try {
|
|
49
|
+
* const result = await conn.runInTransaction(async () => {
|
|
50
|
+
* await conn.execute('INSERT INTO orders ...', [...]);
|
|
51
|
+
* await conn.execute('UPDATE inventory ...', [...]);
|
|
52
|
+
* return orderId;
|
|
53
|
+
* });
|
|
54
|
+
* } finally {
|
|
55
|
+
* conn.release();
|
|
56
|
+
* }
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
runInTransaction<T>(callback: () => Promise<T>): Promise<T>;
|
|
60
|
+
/**
|
|
61
|
+
* Start a transaction.
|
|
62
|
+
*/
|
|
63
|
+
beginTransaction(): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Commit the current transaction.
|
|
66
|
+
*/
|
|
67
|
+
commit(): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Rollback the current transaction.
|
|
70
|
+
*/
|
|
71
|
+
rollback(): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Release this connection back to the pool.
|
|
74
|
+
* MUST be called when done with the connection.
|
|
75
|
+
*/
|
|
76
|
+
release(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Check if connection has been released.
|
|
79
|
+
*/
|
|
80
|
+
private checkReleased;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=GGPostgresConnection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGPostgresConnection.d.ts","sourceRoot":"","sources":["../../src/GGPostgresConnection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,WAAW,EAAE,cAAc,EAAC,MAAM,IAAI,CAAC;AAG3D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,oBAAoB;IAC7B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,QAAQ,CAAS;gBAEb,MAAM,EAAE,UAAU;IAI9B;;OAEG;IACG,KAAK,CAAC,CAAC,SAAS,cAAc,GAAG,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAQrG;;OAEG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAUpE;;;;;;;;;;;;;;;;;;;OAmBG;IACG,gBAAgB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAgBjE;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAMvC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAM7B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ/B;;;OAGG;IACH,OAAO,IAAI,IAAI;IAQf;;OAEG;IACH,OAAO,CAAC,aAAa;CAKxB"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { GGLog } from '@grest-ts/logger';
|
|
2
|
+
/**
|
|
3
|
+
* PostgresConnection - A single connection from the pool.
|
|
4
|
+
*
|
|
5
|
+
* Use this when you need:
|
|
6
|
+
* - Transactions (BEGIN, COMMIT, ROLLBACK)
|
|
7
|
+
* - Multiple queries that must use the same connection
|
|
8
|
+
*
|
|
9
|
+
* IMPORTANT: Always call release() when done to return the connection to the pool.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const conn = await db.getConnection();
|
|
14
|
+
* try {
|
|
15
|
+
* await conn.beginTransaction();
|
|
16
|
+
* await conn.execute('INSERT INTO users ...', [...]);
|
|
17
|
+
* await conn.execute('INSERT INTO profiles ...', [...]);
|
|
18
|
+
* await conn.commit();
|
|
19
|
+
* } catch (err) {
|
|
20
|
+
* await conn.rollback();
|
|
21
|
+
* throw err;
|
|
22
|
+
* } finally {
|
|
23
|
+
* conn.release();
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export class GGPostgresConnection {
|
|
28
|
+
client;
|
|
29
|
+
released = false;
|
|
30
|
+
constructor(client) {
|
|
31
|
+
this.client = client;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Execute a SELECT query and return rows.
|
|
35
|
+
*/
|
|
36
|
+
async query(sql, params) {
|
|
37
|
+
this.checkReleased();
|
|
38
|
+
GGLog.debug(this, 'query', { sql, params });
|
|
39
|
+
const result = await this.client.query(sql, params);
|
|
40
|
+
GGLog.debug(this, 'query result', { rowCount: result.rowCount });
|
|
41
|
+
return result.rows;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Execute an INSERT, UPDATE, or DELETE query.
|
|
45
|
+
*/
|
|
46
|
+
async execute(sql, params) {
|
|
47
|
+
this.checkReleased();
|
|
48
|
+
GGLog.debug(this, 'execute', { sql, params });
|
|
49
|
+
const result = await this.client.query(sql, params);
|
|
50
|
+
GGLog.debug(this, 'execute result', { rowCount: result.rowCount });
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
// ==================== Transaction methods ====================
|
|
54
|
+
/**
|
|
55
|
+
* Run a callback within a transaction.
|
|
56
|
+
* Automatically commits on success, rolls back on failure.
|
|
57
|
+
*
|
|
58
|
+
* Note: Does NOT release the connection. Call release() when done.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* const conn = await db.getConnection();
|
|
63
|
+
* try {
|
|
64
|
+
* const result = await conn.runInTransaction(async () => {
|
|
65
|
+
* await conn.execute('INSERT INTO orders ...', [...]);
|
|
66
|
+
* await conn.execute('UPDATE inventory ...', [...]);
|
|
67
|
+
* return orderId;
|
|
68
|
+
* });
|
|
69
|
+
* } finally {
|
|
70
|
+
* conn.release();
|
|
71
|
+
* }
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
async runInTransaction(callback) {
|
|
75
|
+
this.checkReleased();
|
|
76
|
+
await this.client.query('BEGIN');
|
|
77
|
+
GGLog.debug(this, 'beginTransaction');
|
|
78
|
+
try {
|
|
79
|
+
const result = await callback();
|
|
80
|
+
await this.client.query('COMMIT');
|
|
81
|
+
GGLog.debug(this, 'commit');
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
await this.client.query('ROLLBACK');
|
|
86
|
+
GGLog.debug(this, 'rollback', { error: err });
|
|
87
|
+
throw err;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Start a transaction.
|
|
92
|
+
*/
|
|
93
|
+
async beginTransaction() {
|
|
94
|
+
this.checkReleased();
|
|
95
|
+
GGLog.debug(this, 'beginTransaction');
|
|
96
|
+
await this.client.query('BEGIN');
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Commit the current transaction.
|
|
100
|
+
*/
|
|
101
|
+
async commit() {
|
|
102
|
+
this.checkReleased();
|
|
103
|
+
GGLog.debug(this, 'commit');
|
|
104
|
+
await this.client.query('COMMIT');
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Rollback the current transaction.
|
|
108
|
+
*/
|
|
109
|
+
async rollback() {
|
|
110
|
+
this.checkReleased();
|
|
111
|
+
GGLog.debug(this, 'rollback');
|
|
112
|
+
await this.client.query('ROLLBACK');
|
|
113
|
+
}
|
|
114
|
+
// ==================== Lifecycle ====================
|
|
115
|
+
/**
|
|
116
|
+
* Release this connection back to the pool.
|
|
117
|
+
* MUST be called when done with the connection.
|
|
118
|
+
*/
|
|
119
|
+
release() {
|
|
120
|
+
if (!this.released) {
|
|
121
|
+
this.client.release();
|
|
122
|
+
this.released = true;
|
|
123
|
+
GGLog.debug(this, 'released');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Check if connection has been released.
|
|
128
|
+
*/
|
|
129
|
+
checkReleased() {
|
|
130
|
+
if (this.released) {
|
|
131
|
+
throw new Error('Connection has been released. Cannot perform operations on a released connection.');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=GGPostgresConnection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGPostgresConnection.js","sourceRoot":"","sources":["../../src/GGPostgresConnection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-node.d.ts","sourceRoot":"","sources":["../../src/index-node.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,YAAY,EAAC,WAAW,EAAE,cAAc,EAAC,MAAM,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-node.js","sourceRoot":"","sources":["../../src/index-node.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { GGPostgresHostData, GGPostgresUserData } from "../src/GGPostgresConfig";
|
|
2
|
+
export interface GGPostgresCloneOptions {
|
|
3
|
+
/** SQL files to seed the test schema after cloning */
|
|
4
|
+
seedFiles?: string[];
|
|
5
|
+
/** SQL schema file to create the source schema if it doesn't exist */
|
|
6
|
+
schemaFile?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class GGPostgresSchemaCloner {
|
|
9
|
+
static clone(sourceConfig: GGPostgresHostData, credentials: GGPostgresUserData, schemaName: string, options?: GGPostgresCloneOptions | string[]): Promise<GGPostgresHostData>;
|
|
10
|
+
static cleanup(testConfig: GGPostgresHostData, credentials: GGPostgresUserData): Promise<void>;
|
|
11
|
+
private static getSchemaOps;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=GGPostgresSchemaCloner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGPostgresSchemaCloner.d.ts","sourceRoot":"","sources":["../../testkit/GGPostgresSchemaCloner.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,kBAAkB,EAAE,kBAAkB,EAAC,MAAM,yBAAyB,CAAC;AAE/E,MAAM,WAAW,sBAAsB;IACnC,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,sBAAsB;WAEX,KAAK,CAAC,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC;WAiCtK,OAAO,CAAC,UAAU,EAAE,kBAAkB,EAAE,WAAW,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;mBAStF,YAAY;CAWpC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { GGPostgresSchemaOperations } from './GGPostgresSchemaOperations.js';
|
|
2
|
+
export class GGPostgresSchemaCloner {
|
|
3
|
+
static async clone(sourceConfig, credentials, schemaName, options) {
|
|
4
|
+
// Handle backward compatibility: if options is an array, treat it as sqlFiles
|
|
5
|
+
const opts = Array.isArray(options)
|
|
6
|
+
? { seedFiles: options }
|
|
7
|
+
: (options ?? {});
|
|
8
|
+
const ops = await this.getSchemaOps(sourceConfig, credentials);
|
|
9
|
+
try {
|
|
10
|
+
// If schemaFile is provided, ensure source database exists first
|
|
11
|
+
if (opts.schemaFile) {
|
|
12
|
+
const exists = await ops.schemaExists(sourceConfig.database);
|
|
13
|
+
if (!exists) {
|
|
14
|
+
await ops.createSchema(sourceConfig.database);
|
|
15
|
+
await ops.runSeedFiles(sourceConfig.database, [opts.schemaFile]);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
await ops.cloneSchema(sourceConfig.database, schemaName);
|
|
19
|
+
if (opts.seedFiles?.length) {
|
|
20
|
+
await ops.runSeedFiles(schemaName, opts.seedFiles);
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
...sourceConfig,
|
|
24
|
+
database: schemaName,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
await ops.disconnect();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
static async cleanup(testConfig, credentials) {
|
|
32
|
+
const ops = await this.getSchemaOps(testConfig, credentials);
|
|
33
|
+
try {
|
|
34
|
+
await ops.dropSchema(testConfig.database);
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
await ops.disconnect();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
static async getSchemaOps(config, credentials) {
|
|
41
|
+
const schemaOps = new GGPostgresSchemaOperations({
|
|
42
|
+
host: config.host,
|
|
43
|
+
port: config.port,
|
|
44
|
+
user: credentials.username,
|
|
45
|
+
password: credentials.password,
|
|
46
|
+
});
|
|
47
|
+
await schemaOps.connect();
|
|
48
|
+
return schemaOps;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=GGPostgresSchemaCloner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGPostgresSchemaCloner.js","sourceRoot":"","sources":["../../testkit/GGPostgresSchemaCloner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,0BAA0B,EAAC,MAAM,8BAA8B,CAAC;AAUxE,MAAM,OAAO,sBAAsB;IAExB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,YAAgC,EAAE,WAA+B,EAAE,UAAkB,EAAE,OAA2C;QACxJ,8EAA8E;QAC9E,MAAM,IAAI,GAA2B,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YACvD,CAAC,CAAC,EAAC,SAAS,EAAE,OAAO,EAAC;YACtB,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAEtB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAE/D,IAAI,CAAC;YACD,iEAAiE;YACjE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBAClB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;gBAC7D,IAAI,CAAC,MAAM,EAAE,CAAC;oBACV,MAAM,GAAG,CAAC,YAAY,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;oBAC9C,MAAM,GAAG,CAAC,YAAY,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;gBACrE,CAAC;YACL,CAAC;YAED,MAAM,GAAG,CAAC,WAAW,CAAC,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAEzD,IAAI,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC;gBACzB,MAAM,GAAG,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YACvD,CAAC;YAED,OAAO;gBACH,GAAG,YAAY;gBACf,QAAQ,EAAE,UAAU;aACvB,CAAC;QACN,CAAC;gBAAS,CAAC;YACP,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC;QAC3B,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,UAA8B,EAAE,WAA+B;QACvF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QAC7D,IAAI,CAAC;YACD,MAAM,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC9C,CAAC;gBAAS,CAAC;YACP,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC;QAC3B,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,MAA0B,EAAE,WAA+B;QACzF,MAAM,SAAS,GAAG,IAAI,0BAA0B,CAAC;YAC7C,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,WAAW,CAAC,QAAQ;YAC1B,QAAQ,EAAE,WAAW,CAAC,QAAQ;SACjC,CAAC,CAAC;QAEH,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC;IACrB,CAAC;CACJ"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface GGPostgresSchemaOperationsConfig {
|
|
2
|
+
host: string;
|
|
3
|
+
port: number;
|
|
4
|
+
user: string;
|
|
5
|
+
password: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class GGPostgresSchemaOperations {
|
|
8
|
+
private client;
|
|
9
|
+
private config;
|
|
10
|
+
constructor(config: GGPostgresSchemaOperationsConfig);
|
|
11
|
+
connect(): Promise<void>;
|
|
12
|
+
disconnect(): Promise<void>;
|
|
13
|
+
private getClient;
|
|
14
|
+
schemaExists(schema: string): Promise<boolean>;
|
|
15
|
+
createSchema(schema: string): Promise<void>;
|
|
16
|
+
dropSchema(schema: string): Promise<void>;
|
|
17
|
+
cloneSchema(sourceSchema: string, targetSchema: string): Promise<void>;
|
|
18
|
+
runSeedFiles(schema: string, seedFiles: string[]): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=GGPostgresSchemaOperations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGPostgresSchemaOperations.d.ts","sourceRoot":"","sources":["../../testkit/GGPostgresSchemaOperations.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gCAAgC;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,0BAA0B;IACnC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAmC;gBAErC,MAAM,EAAE,gCAAgC;IAI9C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAcxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAOjC,OAAO,CAAC,SAAS;IASX,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ9C,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa3C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYzC,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBtE,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAyCzE"}
|