@m2k-5f/pgtx 1.3.11 → 1.4.0

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 (54) hide show
  1. package/README.md +55 -17
  2. package/dist/clauses/abstract.clause.d.ts +5 -0
  3. package/dist/clauses/abstract.clause.d.ts.map +1 -0
  4. package/dist/clauses/abstract.clause.js +6 -0
  5. package/dist/clauses/array.clause.d.ts +5 -5
  6. package/dist/clauses/array.clause.d.ts.map +1 -1
  7. package/dist/clauses/array.clause.js +15 -19
  8. package/dist/clauses/empty.clause.d.ts +3 -3
  9. package/dist/clauses/empty.clause.d.ts.map +1 -1
  10. package/dist/clauses/empty.clause.js +4 -6
  11. package/dist/clauses/exclude.clause.d.ts +5 -5
  12. package/dist/clauses/exclude.clause.d.ts.map +1 -1
  13. package/dist/clauses/exclude.clause.js +8 -9
  14. package/dist/clauses/fragment.clause.d.ts +7 -7
  15. package/dist/clauses/fragment.clause.d.ts.map +1 -1
  16. package/dist/clauses/fragment.clause.js +17 -11
  17. package/dist/clauses/iden.caluse.d.ts +4 -4
  18. package/dist/clauses/iden.caluse.d.ts.map +1 -1
  19. package/dist/clauses/iden.caluse.js +9 -13
  20. package/dist/clauses/insert.clause.d.ts +4 -4
  21. package/dist/clauses/insert.clause.d.ts.map +1 -1
  22. package/dist/clauses/insert.clause.js +21 -24
  23. package/dist/clauses/literal.clause.d.ts +4 -4
  24. package/dist/clauses/literal.clause.d.ts.map +1 -1
  25. package/dist/clauses/literal.clause.js +9 -10
  26. package/dist/clauses/update.clause.d.ts +4 -4
  27. package/dist/clauses/update.clause.d.ts.map +1 -1
  28. package/dist/clauses/update.clause.js +12 -13
  29. package/dist/clauses/where.clause.d.ts +3 -3
  30. package/dist/clauses/where.clause.d.ts.map +1 -1
  31. package/dist/clauses/where.clause.js +9 -9
  32. package/dist/connection.d.ts +1 -1
  33. package/dist/connection.d.ts.map +1 -1
  34. package/dist/connection.js +7 -14
  35. package/dist/index.d.ts +16 -16
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +15 -15
  38. package/dist/pool.d.ts +1 -1
  39. package/dist/pool.d.ts.map +1 -1
  40. package/dist/pool.js +2 -19
  41. package/dist/prepared.statement.d.ts +17 -0
  42. package/dist/prepared.statement.d.ts.map +1 -0
  43. package/dist/prepared.statement.js +41 -0
  44. package/dist/query.cacher.d.ts +2 -2
  45. package/dist/query.cacher.d.ts.map +1 -1
  46. package/dist/query.cacher.js +7 -7
  47. package/dist/transaction.d.ts.map +1 -1
  48. package/dist/transaction.js +3 -3
  49. package/dist/types.d.ts +15 -0
  50. package/dist/types.d.ts.map +1 -1
  51. package/dist/utils.d.ts +2 -6
  52. package/dist/utils.d.ts.map +1 -1
  53. package/dist/utils.js +17 -18
  54. package/package.json +1 -1
package/README.md CHANGED
@@ -5,17 +5,6 @@ Experience ORM-like convenience (auto-inserts, updates, recursive fragments) wit
5
5
 
6
6
  ---
7
7
 
8
- ## 🔥 Why Pgtx?
9
-
10
- * **Zero-Cost Abstraction**: Only ~2% - 0% overhead compared to raw `pg.query`.
11
- * **Structural Caching**: Uses `WeakMap` to cache SQL templates. Static parts are parsed only once.
12
- * **Explicit Prepared Statements**: Create and reuse prepared statements with type safety
13
- * **True Recursion**: Nest `sql.fragment` anywhere. Argument numbering ($1, $2) is managed automatically across all nesting levels.
14
- * **No Magic**: You write SQL, `Pgtx` handles the tedious parts (placeholders, identifiers, bulk inserts).
15
- * **ACID Transactions**: Reliable transaction management with automatic rollback on errors.
16
-
17
- ---
18
-
19
8
  ## 📦 Installation
20
9
 
21
10
  ```bash
@@ -24,7 +13,19 @@ npm install @m2k-5f/pgtx
24
13
  yarn add @m2k-5f/pgtx
25
14
  # or
26
15
  pnpm add @m2k-5f/pgtx
16
+ # or
17
+ bun add @m2k-5f/pgtx
27
18
  ```
19
+ ## 🔥 Why Pgtx?
20
+
21
+ ---
22
+
23
+ * **Zero-Cost Abstraction**: Only ~2% - 0% overhead compared to raw `pg.query`.
24
+ * **Structural Caching**: Uses `WeakMap` to cache SQL templates. Static parts are parsed only once.
25
+ * **Explicit Prepared Statements**: Create and reuse prepared statements with type safety
26
+ * **True Recursion**: Nest `sql.fragment` anywhere. Argument numbering ($1, $2) is managed automatically across all nesting levels.
27
+ * **No Magic**: You write SQL, `Pgtx` handles the tedious parts (placeholders, identifiers, bulk inserts).
28
+ * **ACID Transactions**: Reliable transaction management with automatic rollback on errors.
28
29
 
29
30
  ---
30
31
 
@@ -39,15 +40,19 @@ const pool = new Pool({ /* pg.PoolConfig */ })
39
40
  const [user] = await pool.query<User>`SELECT * FROM users WHERE id = ${1}`
40
41
  ```
41
42
 
43
+ ---
44
+
45
+
46
+
42
47
  ## ⚡ Performance Benchmark
43
48
 
44
- The following results were measured during sequential execution of 10,000 complex `UPSERT` queries.
49
+ The following results were measured during sequential execution of 2000 complex `UPSERT` queries.
45
50
 
46
51
 
47
52
  | Tool | RPS | Avg. Query Time | Performance Overhead |
48
53
  | :--- | :---: | :---: | :---: |
49
- | **Native `pg.query`** | **~176** | **5.696 ms** | **0% (Baseline)** |
50
- | **Pgtx** | **~177** | **5.664 ms** | **-0.56%(zero-cost)** |
54
+ | **Native `pg.query`** | **~209** | **4.791ms** | **0% (Baseline)** |
55
+ | **Pgtx** | **~207** | **4.827ms** | **0.76%(zero-cost)** |
51
56
  | Typical Node.js ORM | **~58** | 12.5+ ms | > 150% |
52
57
 
53
58
 
@@ -100,12 +105,23 @@ const users = [
100
105
  await pool.query`INSERT INTO users ${sql.insert(users)}`
101
106
  // SQL: INSERT INTO users (name, email) VALUES ($1, $2), ($3, $4)
102
107
  ```
108
+ #### 3.1 UPSERT Helper (sql.excluded)
109
+ Perfect for ON CONFLICT clauses to avoid re-typing column names.
110
+
111
+ ```typescript
112
+ await pool.query`
113
+ INSERT INTO users ${sql.insert(data)}
114
+ ON CONFLICT (id) DO UPDATE
115
+ SET ${sql.excluded(['name', 'email', 'updated_at'])}
116
+ `
117
+ // SQL: ... SET name = EXCLUDED.name, email = EXCLUDED.email, updated_at = EXCLUDED.updated_at
118
+ ```
103
119
 
104
120
  ### 4. Prepared Statements
105
121
  Pre-parse SQL on the database server for maximum performance in hot loops.
106
122
 
107
123
  ```typescript
108
- const stmt = await pool.prepare<User>("get_user_by_email", 'SELECT * FROM users WHERE email = ?')
124
+ const stmt = await pool.prepare<User, [string]>("get_user_by_email", 'SELECT * FROM users WHERE email = ?')
109
125
  // `Pgtx` automatically maps standard `?` placeholders to native `$1, $2` indexes.
110
126
 
111
127
  const users = await stmt.execute('test@example.com')
@@ -143,6 +159,28 @@ await pool.query`UPDATE users SET ${sql.update(data)} WHERE id = ${1}`
143
159
  // SQL: UPDATE users SET status = $1, last_login = $2 WHERE id = $3
144
160
  ```
145
161
 
162
+ ### 7. Clean Filtering (sql.where)
163
+ Generates AND-separated conditions from an object. Skips undefined values for easy dynamic filtering.
164
+
165
+ ```typescript
166
+ const filters = { role: 'admin', age: undefined, active: true };
167
+ await pool.query`SELECT * FROM users WHERE ${sql.where(filters)}`
168
+ // SQL: SELECT * FROM users WHERE role = $1 AND active = $2
169
+ ```
170
+
171
+ ### 8. Conditional Logic (sql.empty)
172
+ A safe "no-op" fragment for cleaner ternary operations in templates.
173
+
174
+ ```typescript
175
+ const search = "";
176
+ await pool.query`
177
+ SELECT * FROM posts
178
+ ${search ? sql.fragment`WHERE title ILIKE ${search}` : sql.empty}
179
+ `
180
+ // Result if empty: SELECT * FROM posts
181
+ ```
182
+ ---
183
+
146
184
  ## 🔄 Null & Undefined Handling
147
185
 
148
186
  Pgtx treats `null` and `undefined` differently to match SQL semantics and JavaScript expectations:
@@ -184,5 +222,5 @@ sql.array([]) // ❌ Error: Array clause is empty. Use sql.array([null])...
184
222
 
185
223
  ## 🛡️ Security
186
224
  * **SQL Injection**: Automatically uses native placeholders ($1, $2) for all values.
187
- * **Identifiers**: `sql.ident` safely escapes table and column names using double quotes.
188
- * **Connection Leaks**: `pool.query` uses try...finally internally to ensure connections are always returned to the pool.
225
+ * **Identifiers**: `sql.ident` escapes names (e.g., user -> "user") to prevent conflicts with SQL keywords and identifier injection.
226
+ * **Connection Leaks**: `pool.begin` and `pool.query` use `try...finally` internally. Prepared statements created via Pool also automatically release connections.
@@ -0,0 +1,5 @@
1
+ import { ClauseStrategyParams } from "../types";
2
+ export declare abstract class Clause {
3
+ abstract mapIntoQuery(params: ClauseStrategyParams): void;
4
+ }
5
+ //# sourceMappingURL=abstract.clause.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abstract.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/abstract.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAsC,MAAM,UAAU,CAAC;AAEpF,8BAAsB,MAAM;IACxB,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI;CAC5D"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Clause = void 0;
4
+ class Clause {
5
+ }
6
+ exports.Clause = Clause;
@@ -1,10 +1,10 @@
1
- import { Clause } from "../clauses/base.clause";
2
- import { CompiledSqlQuery } from "../utils";
1
+ import { ClauseStrategyParams } from "../types";
2
+ import { Clause } from "./abstract.clause";
3
3
  export declare class ArrayClause extends Clause {
4
4
  private readonly array;
5
5
  private readonly separator;
6
- constructor(array: any[], separator?: string);
7
- map(argCounter: number): CompiledSqlQuery;
6
+ private constructor();
7
+ static create(array: any[], separator?: string): ArrayClause;
8
+ mapIntoQuery(params: ClauseStrategyParams): void;
8
9
  }
9
- export declare function arrayClause(array: any[], separator?: string): ArrayClause;
10
10
  //# sourceMappingURL=array.clause.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"array.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/array.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,qBAAa,WAAY,SAAQ,MAAM;IAE/B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBADT,KAAK,EAAE,GAAG,EAAE,EACZ,SAAS,GAAE,MAAa;IAGpC,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB;CAyBrD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,SAAS,GAAE,MAAa,GAAG,WAAW,CAE/E"}
1
+ {"version":3,"file":"array.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/array.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,qBAAa,WAAY,SAAQ,MAAM;IAE/B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAF9B,OAAO;IAKP,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,SAAS,GAAE,MAAa,GAAG,WAAW;IAQzD,YAAY,CAAC,MAAM,EAAE,oBAAoB;CAiBrD"}
@@ -1,37 +1,33 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ArrayClause = void 0;
4
- exports.arrayClause = arrayClause;
5
- const base_clause_1 = require("../clauses/base.clause");
6
- class ArrayClause extends base_clause_1.Clause {
4
+ const abstract_clause_1 = require("./abstract.clause");
5
+ class ArrayClause extends abstract_clause_1.Clause {
7
6
  constructor(array, separator = ", ") {
8
7
  super();
9
8
  this.array = array;
10
9
  this.separator = separator;
11
10
  }
12
- map(argCounter) {
13
- if (this.array.length === 0)
11
+ static create(array, separator = ", ") {
12
+ if (array.length === 0)
14
13
  throw new Error('Array clause is empty.\n Use sql.array([null]) if you want no results, or check your data.');
15
- const args = [];
16
- const text = `${this.array.map((value, index) => {
14
+ return new ArrayClause(array, separator);
15
+ }
16
+ mapIntoQuery(params) {
17
+ this.array.forEach((value, index) => {
17
18
  if (value === undefined) {
18
19
  throw new TypeError(`Array item at index ${index} is undefined`);
19
20
  }
20
- if (value instanceof base_clause_1.Clause) {
21
- const result = value.map(argCounter);
22
- args.push(...result.args);
23
- argCounter = result.argCounter;
24
- return result.text;
21
+ if (index)
22
+ params.text.push(this.separator);
23
+ if (value instanceof abstract_clause_1.Clause) {
24
+ value.mapIntoQuery(params);
25
25
  }
26
26
  else {
27
- args.push(value);
28
- return `$${argCounter++}`;
27
+ params.args.push(value);
28
+ params.text.push(`$${params.counter++}`);
29
29
  }
30
- }).join(this.separator)}`;
31
- return { text, args, argCounter };
30
+ });
32
31
  }
33
32
  }
34
33
  exports.ArrayClause = ArrayClause;
35
- function arrayClause(array, separator = ", ") {
36
- return new ArrayClause(array, separator);
37
- }
@@ -1,8 +1,8 @@
1
- import { CompiledSqlQuery } from "../utils";
2
- import { Clause } from "./base.clause";
1
+ import { ClauseStrategyParams } from "../types";
2
+ import { Clause } from "./abstract.clause";
3
3
  export declare class EmptyClause extends Clause {
4
4
  static new(): EmptyClause;
5
- map(argCounter: number): CompiledSqlQuery;
5
+ mapIntoQuery(params: ClauseStrategyParams): void;
6
6
  }
7
7
  export declare const emptyClause: EmptyClause;
8
8
  //# sourceMappingURL=empty.clause.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"empty.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/empty.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAGvC,qBAAa,WAAY,SAAQ,MAAM;IACnC,MAAM,CAAC,GAAG;IAIV,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB;CAG5C;AAED,eAAO,MAAM,WAAW,aAAoB,CAAA"}
1
+ {"version":3,"file":"empty.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/empty.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,qBAAa,WAAY,SAAQ,MAAM;IACnC,MAAM,CAAC,GAAG;IAIV,YAAY,CAAC,MAAM,EAAE,oBAAoB;CAC5C;AAED,eAAO,MAAM,WAAW,aAAoB,CAAA"}
@@ -1,14 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.emptyClause = exports.EmptyClause = void 0;
4
- const base_clause_1 = require("./base.clause");
5
- class EmptyClause extends base_clause_1.Clause {
4
+ const abstract_clause_1 = require("./abstract.clause");
5
+ class EmptyClause extends abstract_clause_1.Clause {
6
6
  static new() {
7
- return new this();
8
- }
9
- map(argCounter) {
10
- return { argCounter, args: [], text: "" };
7
+ return new EmptyClause();
11
8
  }
9
+ mapIntoQuery(params) { }
12
10
  }
13
11
  exports.EmptyClause = EmptyClause;
14
12
  exports.emptyClause = EmptyClause.new();
@@ -1,9 +1,9 @@
1
- import { CompiledSqlQuery } from "../utils";
2
- import { Clause } from "./base.clause";
1
+ import { ClauseStrategyParams } from "../types";
2
+ import { Clause } from "./abstract.clause";
3
3
  export declare class ExcludeUpdateClause extends Clause {
4
4
  readonly fields: string[];
5
- constructor(fields: string[]);
6
- map(argCounter: number): CompiledSqlQuery;
5
+ private constructor();
6
+ static create(fields: string[]): ExcludeUpdateClause;
7
+ mapIntoQuery(params: ClauseStrategyParams): void;
7
8
  }
8
- export declare function excludeClause(fields: string[]): ExcludeUpdateClause;
9
9
  //# sourceMappingURL=exclude.clause.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"exclude.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/exclude.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,qBAAa,mBAAoB,SAAQ,MAAM;IAEvC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE;gBAAhB,MAAM,EAAE,MAAM,EAAE;IAGtB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB;CAInD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,mBAAmB,CAEnE"}
1
+ {"version":3,"file":"exclude.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/exclude.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,qBAAa,mBAAoB,SAAQ,MAAM;IAEvC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE;IAD7B,OAAO;IAIP,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,mBAAmB;IAI7C,YAAY,CAAC,MAAM,EAAE,oBAAoB;CAMnD"}
@@ -1,19 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ExcludeUpdateClause = void 0;
4
- exports.excludeClause = excludeClause;
5
- const base_clause_1 = require("./base.clause");
6
- class ExcludeUpdateClause extends base_clause_1.Clause {
4
+ const abstract_clause_1 = require("./abstract.clause");
5
+ class ExcludeUpdateClause extends abstract_clause_1.Clause {
7
6
  constructor(fields) {
8
7
  super();
9
8
  this.fields = fields;
10
9
  }
11
- map(argCounter) {
12
- const text = this.fields.map(f => `${f} = EXCLUDED.${f}`).join(', ');
13
- return { argCounter, args: [], text };
10
+ static create(fields) {
11
+ return new ExcludeUpdateClause(fields);
12
+ }
13
+ mapIntoQuery(params) {
14
+ params.text.push(this.fields.map(f => `${f} = EXCLUDED.${f}`)
15
+ .join(', '));
14
16
  }
15
17
  }
16
18
  exports.ExcludeUpdateClause = ExcludeUpdateClause;
17
- function excludeClause(fields) {
18
- return new ExcludeUpdateClause(fields);
19
- }
@@ -1,10 +1,10 @@
1
- import { Clause } from "./base.clause";
2
- import { CompiledSqlQuery } from "../utils";
1
+ import { Clause } from "./abstract.clause";
2
+ import { ClauseStrategyParams } from "../types";
3
3
  export declare class FragmentClause extends Clause {
4
- readonly strings: TemplateStringsArray;
5
- readonly values: any[];
6
- constructor(strings: TemplateStringsArray, values: any[]);
7
- map(currentArgCounter: number): CompiledSqlQuery;
4
+ readonly templates: TemplateStringsArray;
5
+ readonly args: any[];
6
+ constructor(templates: TemplateStringsArray, args: any[]);
7
+ static create(strings: TemplateStringsArray, ...values: any[]): FragmentClause;
8
+ mapIntoQuery(params: ClauseStrategyParams): void;
8
9
  }
9
- export declare function fragmentClause(strings: TemplateStringsArray, ...values: any[]): FragmentClause;
10
10
  //# sourceMappingURL=fragment.clause.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fragment.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/fragment.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAI,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAsB,MAAM,UAAU,CAAC;AAEhE,qBAAa,cAAe,SAAQ,MAAM;IAElC,QAAQ,CAAC,OAAO,EAAE,oBAAoB;IACtC,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;gBADb,OAAO,EAAE,oBAAoB,EAC7B,MAAM,EAAE,GAAG,EAAE;IAGjB,GAAG,CAAC,iBAAiB,EAAE,MAAM,GAAG,gBAAgB;CAG5D;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE,kBAE7E"}
1
+ {"version":3,"file":"fragment.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/fragment.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAI,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,oBAAoB,EAAoB,MAAM,UAAU,CAAC;AAElE,qBAAa,cAAe,SAAQ,MAAM;IAElC,QAAQ,CAAC,SAAS,EAAE,oBAAoB;IACxC,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE;gBADX,SAAS,EAAE,oBAAoB,EAC/B,IAAI,EAAE,GAAG,EAAE;IAGxB,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE;IAIpD,YAAY,CAAC,MAAM,EAAE,oBAAoB;CAWrD"}
@@ -1,20 +1,26 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FragmentClause = void 0;
4
- exports.fragmentClause = fragmentClause;
5
- const base_clause_1 = require("./base.clause");
4
+ const abstract_clause_1 = require("./abstract.clause");
6
5
  const utils_1 = require("../utils");
7
- class FragmentClause extends base_clause_1.Clause {
8
- constructor(strings, values) {
6
+ class FragmentClause extends abstract_clause_1.Clause {
7
+ constructor(templates, args) {
9
8
  super();
10
- this.strings = strings;
11
- this.values = values;
9
+ this.templates = templates;
10
+ this.args = args;
12
11
  }
13
- map(currentArgCounter) {
14
- return (0, utils_1.compileSqlTemplate)(this.strings, this.values, currentArgCounter);
12
+ static create(strings, ...values) {
13
+ return new FragmentClause(strings, values);
14
+ }
15
+ mapIntoQuery(params) {
16
+ const compiled = (0, utils_1.compileSqlTemplate)({
17
+ args: this.args,
18
+ counter: params.counter,
19
+ templates: this.templates
20
+ });
21
+ params.counter = compiled.counter;
22
+ params.args.push(...compiled.args);
23
+ params.text.push(compiled.text);
15
24
  }
16
25
  }
17
26
  exports.FragmentClause = FragmentClause;
18
- function fragmentClause(strings, ...values) {
19
- return new FragmentClause(strings, values);
20
- }
@@ -1,9 +1,9 @@
1
- import { Clause } from "./base.clause";
2
- import { CompiledSqlQuery } from "../utils";
1
+ import { ClauseStrategyParams } from "../types";
2
+ import { Clause } from "./abstract.clause";
3
3
  export declare class IdentifierClause<T extends string> extends Clause {
4
4
  readonly value: T;
5
5
  constructor(value: T);
6
- map(argCounter: number): CompiledSqlQuery;
6
+ static create<T extends string>(identificator: T): IdentifierClause<T>;
7
+ mapIntoQuery(params: ClauseStrategyParams): void;
7
8
  }
8
- export declare function identClause<T extends string>(identificator: T): IdentifierClause<T>;
9
9
  //# sourceMappingURL=iden.caluse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"iden.caluse.d.ts","sourceRoot":"","sources":["../../src/clauses/iden.caluse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,qBAAa,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAE,SAAQ,MAAM;IAEtD,QAAQ,CAAC,KAAK,EAAE,CAAC;gBAAR,KAAK,EAAE,CAAC;IAGZ,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB;CASrD;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,aAAa,EAAE,CAAC,uBAE7D"}
1
+ {"version":3,"file":"iden.caluse.d.ts","sourceRoot":"","sources":["../../src/clauses/iden.caluse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE1C,qBAAa,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAE,SAAQ,MAAM;IAEtD,QAAQ,CAAC,KAAK,EAAE,CAAC;gBAAR,KAAK,EAAE,CAAC;IAGrB,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,aAAa,EAAE,CAAC;IAMvC,YAAY,CAAC,MAAM,EAAE,oBAAoB;CAGrD"}
@@ -1,23 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.IdentifierClause = void 0;
4
- exports.identClause = identClause;
5
- const base_clause_1 = require("./base.clause");
6
- class IdentifierClause extends base_clause_1.Clause {
4
+ const abstract_clause_1 = require("./abstract.clause");
5
+ class IdentifierClause extends abstract_clause_1.Clause {
7
6
  constructor(value) {
8
7
  super();
9
8
  this.value = value;
10
9
  }
11
- map(argCounter) {
12
- if (this.value === undefined) {
13
- throw new TypeError(`Query parameter undefined at position ${argCounter}`);
14
- }
15
- const text = `"${this.value}"`;
16
- const args = [];
17
- return { text, args, argCounter };
10
+ static create(identificator) {
11
+ if (identificator === undefined)
12
+ throw new TypeError("Identificator undefined");
13
+ return new IdentifierClause(identificator);
14
+ }
15
+ mapIntoQuery(params) {
16
+ params.text.push(`"${this.value}"`);
18
17
  }
19
18
  }
20
19
  exports.IdentifierClause = IdentifierClause;
21
- function identClause(identificator) {
22
- return new IdentifierClause(identificator);
23
- }
@@ -1,9 +1,9 @@
1
- import { Clause } from "./base.clause";
2
- import { CompiledSqlQuery } from "../utils";
1
+ import { Clause } from "./abstract.clause";
2
+ import { ClauseStrategyParams } from "../types";
3
3
  export declare class InsertClause<T extends Record<string, any>> extends Clause {
4
4
  readonly inserts: T[];
5
5
  constructor(inserts: T[]);
6
- map(argCounter: number): CompiledSqlQuery;
6
+ static create<T extends Record<string, any>>(...objects: NoInfer<T>[]): InsertClause<T>;
7
+ mapIntoQuery(params: ClauseStrategyParams): void;
7
8
  }
8
- export declare function insertClause<T extends Record<string, any>>(...objects: NoInfer<T>[]): InsertClause<T>;
9
9
  //# sourceMappingURL=insert.clause.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"insert.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/insert.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,qBAAa,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAE,SAAQ,MAAM;IAE/D,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE;gBAAZ,OAAO,EAAE,CAAC,EAAE;IAGhB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB;CAgCrD;AAED,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,mBAEnF"}
1
+ {"version":3,"file":"insert.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/insert.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAEhD,qBAAa,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAE,SAAQ,MAAM;IAE/D,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE;gBAAZ,OAAO,EAAE,CAAC,EAAE;IAGzB,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE;IAO5D,YAAY,CAAC,MAAM,EAAE,oBAAoB;CAyBrD"}
@@ -1,39 +1,36 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.InsertClause = void 0;
4
- exports.insertClause = insertClause;
5
- const base_clause_1 = require("./base.clause");
6
- class InsertClause extends base_clause_1.Clause {
4
+ const abstract_clause_1 = require("./abstract.clause");
5
+ class InsertClause extends abstract_clause_1.Clause {
7
6
  constructor(inserts) {
8
7
  super();
9
8
  this.inserts = inserts;
10
9
  }
11
- map(argCounter) {
12
- if (this.inserts.length === 0) {
13
- throw new Error('Insert clause has no rows to insert.\n' +
14
- 'Provide at least one object with data.');
10
+ static create(...objects) {
11
+ if (objects.length === 0) {
12
+ throw new Error('Insert clause has no rows to insert.\n Provide at least one object with data.');
15
13
  }
14
+ return new InsertClause(objects);
15
+ }
16
+ mapIntoQuery(params) {
16
17
  const columns = Object.keys(this.inserts[0]);
17
18
  const columnsCount = columns.length;
18
- let text = `(${columns.join(', ')}) VALUES `;
19
- let args = [];
20
- const valuesText = this.inserts.map(values => {
21
- if (Object.keys(values).length !== columnsCount)
22
- throw new Error(`
23
- all rows must have the same columns
24
- `);
25
- return `(${Object.values(values).map(value => {
19
+ params.text.push(`(${columns.join(', ')}) VALUES `);
20
+ this.inserts.forEach((object, index) => {
21
+ if (Object.keys(object).length !== columnsCount) {
22
+ throw new Error(`all rows must have the same columns`);
23
+ }
24
+ if (index)
25
+ params.text.push(', ');
26
+ params.text.push(`(${Object.values(object).map(value => {
26
27
  if (value === undefined)
27
28
  return "DEFAULT";
28
- args.push(value);
29
- return `$${argCounter++}`;
30
- }).join(", ")})`;
31
- }).join(", ");
32
- text += valuesText;
33
- return { text, args, argCounter };
29
+ params.args.push(value);
30
+ return `$${params.counter++}`;
31
+ })
32
+ .join(", ")})`);
33
+ });
34
34
  }
35
35
  }
36
36
  exports.InsertClause = InsertClause;
37
- function insertClause(...objects) {
38
- return new InsertClause(objects);
39
- }
@@ -1,9 +1,9 @@
1
- import { Clause } from "./base.clause";
2
- import { CompiledSqlQuery } from "../utils";
1
+ import { ClauseStrategyParams } from "../types";
2
+ import { Clause } from "./abstract.clause";
3
3
  export declare class LiteralClause<T extends string> extends Clause {
4
4
  readonly value: T;
5
5
  constructor(value: T);
6
- map(argCounter: number): CompiledSqlQuery;
6
+ static create<T extends string>(value: T): LiteralClause<T>;
7
+ mapIntoQuery(params: ClauseStrategyParams): void;
7
8
  }
8
- export declare function literalClause<T extends string>(value: T): LiteralClause<T>;
9
9
  //# sourceMappingURL=literal.clause.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"literal.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/literal.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,qBAAa,aAAa,CAAC,CAAC,SAAS,MAAM,CAAE,SAAQ,MAAM;IAEnD,QAAQ,CAAC,KAAK,EAAE,CAAC;gBAAR,KAAK,EAAE,CAAC;IAKZ,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB;CAMrD;AAGD,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAE1E"}
1
+ {"version":3,"file":"literal.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/literal.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,MAAM,EAAC,MAAM,mBAAmB,CAAC;AAE1C,qBAAa,aAAa,CAAC,CAAC,SAAS,MAAM,CAAE,SAAQ,MAAM;IAEnD,QAAQ,CAAC,KAAK,EAAE,CAAC;gBAAR,KAAK,EAAE,CAAC;IAKrB,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;IAQlD,YAAY,CAAC,MAAM,EAAE,oBAAoB;CAGrD"}
@@ -1,21 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LiteralClause = void 0;
4
- exports.literalClause = literalClause;
5
- const base_clause_1 = require("./base.clause");
6
- class LiteralClause extends base_clause_1.Clause {
4
+ const abstract_clause_1 = require("./abstract.clause");
5
+ class LiteralClause extends abstract_clause_1.Clause {
7
6
  constructor(value) {
8
7
  super();
9
8
  this.value = value;
10
9
  }
11
- map(argCounter) {
12
- if (this.value === undefined) {
13
- throw new TypeError(`Query parameter undefined at position ${argCounter}`);
10
+ static create(value) {
11
+ if (value === undefined) {
12
+ throw new TypeError(`Literal undefined`);
14
13
  }
15
- return { text: this.value, args: [], argCounter };
14
+ return new LiteralClause(value);
15
+ }
16
+ mapIntoQuery(params) {
17
+ params.text.push(this.value);
16
18
  }
17
19
  }
18
20
  exports.LiteralClause = LiteralClause;
19
- function literalClause(value) {
20
- return new LiteralClause(value);
21
- }
@@ -1,9 +1,9 @@
1
- import { Clause } from "./base.clause";
2
- import { CompiledSqlQuery } from "../utils";
1
+ import { ClauseStrategyParams } from "../types";
2
+ import { Clause } from "./abstract.clause";
3
3
  export declare class UpdateClause<T extends Record<string, any>> extends Clause {
4
4
  readonly updateMap: T;
5
5
  constructor(updateMap: T);
6
- map(argCounter: number): CompiledSqlQuery;
6
+ static create<T extends Record<string, any>>(object: T): UpdateClause<T>;
7
+ mapIntoQuery(params: ClauseStrategyParams): void;
7
8
  }
8
- export declare function updateClause<T extends Record<string, any>>(object: T): UpdateClause<T>;
9
9
  //# sourceMappingURL=update.clause.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"update.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/update.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,qBAAa,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAE,SAAQ,MAAM;IAE/D,QAAQ,CAAC,SAAS,EAAE,CAAC;gBAAZ,SAAS,EAAE,CAAC;IAGhB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB;CAcrD;AAED,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,mBAEpE"}
1
+ {"version":3,"file":"update.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/update.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,qBAAa,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAE,SAAQ,MAAM;IAE/D,QAAQ,CAAC,SAAS,EAAE,CAAC;gBAAZ,SAAS,EAAE,CAAC;IAGzB,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IAI7C,YAAY,CAAC,MAAM,EAAE,oBAAoB;CAarD"}
@@ -1,26 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.UpdateClause = void 0;
4
- exports.updateClause = updateClause;
5
- const base_clause_1 = require("./base.clause");
6
- class UpdateClause extends base_clause_1.Clause {
4
+ const abstract_clause_1 = require("./abstract.clause");
5
+ class UpdateClause extends abstract_clause_1.Clause {
7
6
  constructor(updateMap) {
8
7
  super();
9
8
  this.updateMap = updateMap;
10
9
  }
11
- map(argCounter) {
12
- const args = [];
10
+ static create(object) {
11
+ return new UpdateClause(object);
12
+ }
13
+ mapIntoQuery(params) {
13
14
  const entries = Object.entries(this.updateMap).filter(([_, value]) => value !== undefined);
14
15
  if (entries.length === 0)
15
16
  throw new Error('Update clause has no data to update. All values are `undefined`');
16
- const text = entries.map(([key, value]) => {
17
- args.push(value);
18
- return `${key} = $${argCounter++}`;
19
- }).join(', ');
20
- return { text, args, argCounter };
17
+ entries.forEach(([key, value], index) => {
18
+ if (index)
19
+ params.text.push(', ');
20
+ params.args.push(value);
21
+ params.text.push(`${key} = $${params.counter++}`);
22
+ });
21
23
  }
22
24
  }
23
25
  exports.UpdateClause = UpdateClause;
24
- function updateClause(object) {
25
- return new UpdateClause(object);
26
- }