@m2k-5f/pgtx 1.4.12 → 2.0.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.
- package/README.md +225 -128
- package/dist/clauses/array.clause.js +1 -1
- package/dist/clauses/empty.clause.d.ts +1 -1
- package/dist/clauses/empty.clause.d.ts.map +1 -1
- package/dist/clauses/empty.clause.js +2 -2
- package/dist/clauses/fragment.clause.d.ts +1 -1
- package/dist/clauses/fragment.clause.d.ts.map +1 -1
- package/dist/clauses/fragment.clause.js +3 -5
- package/dist/clauses/iden.caluse.d.ts +1 -1
- package/dist/clauses/iden.caluse.d.ts.map +1 -1
- package/dist/clauses/index.d.ts +10 -0
- package/dist/clauses/index.d.ts.map +1 -0
- package/dist/clauses/index.js +25 -0
- package/dist/clauses/insert.clause.d.ts +1 -1
- package/dist/clauses/insert.clause.d.ts.map +1 -1
- package/dist/clauses/insert.clause.js +1 -1
- package/dist/clauses/literal.clause.d.ts +1 -1
- package/dist/clauses/literal.clause.d.ts.map +1 -1
- package/dist/clauses/update.clause.d.ts +1 -1
- package/dist/clauses/update.clause.d.ts.map +1 -1
- package/dist/clauses/update.clause.js +1 -1
- package/dist/clauses/where.clause.d.ts +1 -1
- package/dist/clauses/where.clause.d.ts.map +1 -1
- package/dist/clauses/where.clause.js +1 -1
- package/dist/connection.d.ts +135 -31
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +290 -59
- package/dist/index.d.ts +2 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -18
- package/dist/pool.d.ts +126 -32
- package/dist/pool.d.ts.map +1 -1
- package/dist/pool.js +203 -54
- package/dist/protocol/connection-request-writer.d.ts +38 -0
- package/dist/protocol/connection-request-writer.d.ts.map +1 -0
- package/dist/protocol/connection-request-writer.js +175 -0
- package/dist/protocol/connection-response-reader.d.ts +49 -0
- package/dist/protocol/connection-response-reader.d.ts.map +1 -0
- package/dist/protocol/connection-response-reader.js +185 -0
- package/dist/protocol/constants.d.ts +46 -0
- package/dist/protocol/constants.d.ts.map +1 -0
- package/dist/protocol/constants.js +43 -0
- package/dist/protocol/socket-authorization.d.ts +11 -0
- package/dist/protocol/socket-authorization.d.ts.map +1 -0
- package/dist/protocol/socket-authorization.js +95 -0
- package/dist/protocol/socket-connector.d.ts +17 -0
- package/dist/protocol/socket-connector.d.ts.map +1 -0
- package/dist/protocol/socket-connector.js +48 -0
- package/dist/queue.d.ts +10 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +27 -0
- package/dist/security/md5.d.ts +2 -0
- package/dist/security/md5.d.ts.map +1 -0
- package/dist/security/md5.js +12 -0
- package/dist/security/sasl.d.ts +6 -0
- package/dist/security/sasl.d.ts.map +1 -0
- package/dist/security/sasl.js +29 -0
- package/dist/transaction.d.ts +1 -2
- package/dist/transaction.d.ts.map +1 -1
- package/dist/transaction.js +4 -4
- package/dist/types.d.ts +6 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/template-compiler.d.ts +3 -0
- package/dist/utils/template-compiler.d.ts.map +1 -0
- package/dist/utils/template-compiler.js +64 -0
- package/dist/utils/value-parser.d.ts +6 -0
- package/dist/utils/value-parser.d.ts.map +1 -0
- package/dist/utils/value-parser.js +101 -0
- package/package.json +8 -9
package/README.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
## Pgtx
|
|
1
|
+
## 🚀 Pgtx
|
|
2
2
|
|
|
3
3
|
[](https://github.com/M2K-5F/pgtx/actions/workflows/tests.yaml)
|
|
4
|
+
[](https://www.npmjs.com/package/@m2k-5f/pgtx)
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
**Blazing-fast PostgreSQL driver** with pipeline support.
|
|
7
|
+
Zero deps, pure TypeScript.
|
|
7
8
|
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -11,92 +12,106 @@ Experience ORM-like convenience (auto-inserts, updates, recursive fragments) wit
|
|
|
11
12
|
|
|
12
13
|
```bash
|
|
13
14
|
npm install @m2k-5f/pgtx
|
|
14
|
-
#
|
|
15
|
-
|
|
16
|
-
#
|
|
17
|
-
pnpm add @m2k-5f/pgtx
|
|
18
|
-
# or
|
|
19
|
-
bun add @m2k-5f/pgtx
|
|
15
|
+
# yarn add @m2k-5f/pgtx
|
|
16
|
+
# pnpm add @m2k-5f/pgtx
|
|
17
|
+
# bun add @m2k-5f/pgtx
|
|
20
18
|
```
|
|
21
|
-
## 🔥 Why Pgtx?
|
|
22
19
|
|
|
23
20
|
---
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
* **Structural Caching**: Uses `WeakMap` to cache SQL templates. Static parts are parsed only once.
|
|
27
|
-
* **Explicit Prepared Statements**: Create and reuse prepared statements with type safety
|
|
28
|
-
* **True Recursion**: Nest `sql.fragment` anywhere. Argument numbering ($1, $2) is managed automatically across all nesting levels.
|
|
29
|
-
* **No Magic**: You write SQL, `Pgtx` handles the tedious parts (placeholders, identifiers, bulk inserts).
|
|
30
|
-
* **ACID Transactions**: Reliable transaction management with automatic rollback on errors.
|
|
22
|
+
## ⚡ Performance
|
|
31
23
|
|
|
32
|
-
|
|
24
|
+
**2000 concurrent UPSERT queries, 150 concurrency, connection pool:**
|
|
33
25
|
|
|
34
|
-
|
|
26
|
+
| Tool | RPS | Avg Time | Connections |
|
|
27
|
+
|------|-----|----------|-------------|
|
|
28
|
+
| **Pgtx** | **1584** | **0.631ms** | **20 (used only one)** |
|
|
29
|
+
| Native `pg` | 179 | 5.585ms | 20 |
|
|
35
30
|
|
|
36
|
-
|
|
37
|
-
import { sql, Pool } from "@m2k-5f/pgtx";
|
|
31
|
+
**9x faster**
|
|
38
32
|
|
|
39
|
-
const pool = new Pool({ /* pg.PoolConfig */ })
|
|
40
33
|
|
|
41
|
-
|
|
42
|
-
const [user] = await pool.query<User>`SELECT * FROM users WHERE id = ${1}`
|
|
43
|
-
```
|
|
34
|
+
> Benchmark source available in the [repository](https://github.com/M2K-5F/pgtx).
|
|
44
35
|
|
|
45
36
|
---
|
|
46
37
|
|
|
38
|
+
## ✨ Features
|
|
47
39
|
|
|
40
|
+
- **Pipeline queries** — 9x faster than `pg`
|
|
41
|
+
- **Tagged templates** — Natural SQL with type safety
|
|
42
|
+
- **Transactions & Savepoints** — Nested transactions with rollback
|
|
43
|
+
- **Bulk inserts** — Auto-extract columns from objects
|
|
44
|
+
- **Dynamic updates** — Generate SET clauses from objects
|
|
45
|
+
- **Recursive fragments** — Compose SQL like Lego
|
|
46
|
+
- **Prepared statements** — Pre-parse any SQL with parameters
|
|
47
|
+
- **Connection pool** — Auto-management connections with support for pipeline queries via the pool itself.
|
|
48
|
+
- **Zero dependencies** — Lightweight and blazing
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
The following results were measured during sequential execution of 2000 complex `UPSERT` queries.
|
|
50
|
+
---
|
|
52
51
|
|
|
52
|
+
## 🔥 Why Pgtx?
|
|
53
53
|
|
|
54
|
-
|
|
|
55
|
-
|
|
56
|
-
| **
|
|
57
|
-
| **
|
|
58
|
-
|
|
|
54
|
+
| Feature | Pgtx | pg | TypeORM | Prisma |
|
|
55
|
+
|---------|------|----|---------|--------|
|
|
56
|
+
| **Pipeline Queries** | ✅ | ❌ | ❌ | ❌ |
|
|
57
|
+
| **Tagged Templates** | ✅ | ❌ | ❌ | ❌ |
|
|
58
|
+
| **Transactions** | ✅ | ✅ | ✅ | ✅ |
|
|
59
|
+
| **Savepoints** | ✅ | ❌ | ✅ | ❌ |
|
|
60
|
+
| **Bulk Insert** | ✅ | ❌ | ✅ | ✅ |
|
|
61
|
+
| **Prepared Statements** | ✅ | ✅ | ✅ | ✅ |
|
|
62
|
+
| **TypeScript** | ✅ | ✅ | ✅ | ✅ |
|
|
63
|
+
| **Zero Dependencies** | ✅ | ❌ | ❌ | ❌ |
|
|
64
|
+
| **Connection Pool** | ✅ | ✅ | ✅ | ✅ |
|
|
59
65
|
|
|
66
|
+
---
|
|
60
67
|
|
|
61
|
-
## 📖 Feature Guide
|
|
62
68
|
|
|
63
|
-
|
|
64
|
-
Combine multiple SQL pieces. Perfect for dynamic filters or subqueries.
|
|
69
|
+
## 🚀 Quick Start
|
|
65
70
|
|
|
66
71
|
```typescript
|
|
67
|
-
|
|
68
|
-
const roleSub = sql.fragment`(SELECT id FROM roles WHERE name = ${'admin'})`
|
|
72
|
+
import { sql, Pool } from "@m2k-5f/pgtx";
|
|
69
73
|
|
|
74
|
+
const pool = new Pool({
|
|
75
|
+
host: 'localhost',
|
|
76
|
+
user: 'postgres',
|
|
77
|
+
password: 'postgres',
|
|
78
|
+
database: 'myapp'
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
// Type-safe query
|
|
82
|
+
const [user] = await pool.query<User>`SELECT * FROM users WHERE id = ${1}`
|
|
83
|
+
|
|
84
|
+
// Bulk insert
|
|
70
85
|
await pool.query`
|
|
71
|
-
INSERT INTO users (name,
|
|
72
|
-
VALUES (${'Ivan'}, (${roleSub}))
|
|
73
|
-
WHERE ${filter}
|
|
86
|
+
INSERT INTO users ${sql.insert([{ name: 'Alice', age: 25 }, { name: 'Bob', age: 30 }])}
|
|
74
87
|
`
|
|
75
|
-
|
|
88
|
+
|
|
89
|
+
// Transaction
|
|
90
|
+
await pool.begin(async (tx) => {
|
|
91
|
+
await tx.query`UPDATE accounts SET balance = balance - 100 WHERE id = ${1}`
|
|
92
|
+
await tx.query`UPDATE accounts SET balance = balance + 100 WHERE id = ${2}`
|
|
93
|
+
})
|
|
76
94
|
```
|
|
77
95
|
|
|
78
|
-
|
|
79
|
-
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 📖 Features
|
|
99
|
+
|
|
100
|
+
### Transactions & Savepoints
|
|
80
101
|
|
|
81
102
|
```typescript
|
|
82
103
|
await pool.begin(async (tx) => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
// Handle error
|
|
92
|
-
// tx still active & can be commited
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
// Main transaction commits or rolls back based on callback success
|
|
104
|
+
await tx.query`INSERT INTO orders (user_id) VALUES (${userId})`
|
|
105
|
+
|
|
106
|
+
// err: Error | null
|
|
107
|
+
const err = await tx.savepoint('update_stock', async (stx) => {
|
|
108
|
+
await stx.query`UPDATE stock SET count = count - 1 WHERE product_id = ${productId}`
|
|
109
|
+
if (outOfStock) throw new Error() // Only savepoint rolls back
|
|
110
|
+
})
|
|
111
|
+
})
|
|
96
112
|
```
|
|
97
113
|
|
|
98
|
-
###
|
|
99
|
-
Automatically extracts columns from the first object. Supports single objects and arrays.
|
|
114
|
+
### Bulk Inserts
|
|
100
115
|
|
|
101
116
|
```typescript
|
|
102
117
|
const users = [
|
|
@@ -104,125 +119,207 @@ const users = [
|
|
|
104
119
|
{ name: 'Bob', email: 'bob@test.com' }
|
|
105
120
|
]
|
|
106
121
|
|
|
107
|
-
await pool.query`INSERT INTO users ${sql.insert(users)}`
|
|
108
|
-
// SQL: INSERT INTO users (name, email) VALUES ($1, $2), ($3, $4)
|
|
109
|
-
```
|
|
110
|
-
#### 3.1 UPSERT Helper (sql.excluded)
|
|
111
|
-
Perfect for ON CONFLICT clauses to avoid re-typing column names.
|
|
112
|
-
|
|
113
|
-
```typescript
|
|
114
122
|
await pool.query`
|
|
115
|
-
INSERT INTO users ${sql.insert(
|
|
116
|
-
ON CONFLICT (id) DO UPDATE
|
|
117
|
-
SET ${sql.excluded(['name', 'email', 'updated_at'])}
|
|
123
|
+
INSERT INTO users ${sql.insert(users)}
|
|
118
124
|
`
|
|
119
|
-
//
|
|
125
|
+
// INSERT INTO users (name, email) VALUES ($1, $2), ($3, $4)
|
|
120
126
|
```
|
|
121
127
|
|
|
122
|
-
###
|
|
123
|
-
Pre-parse SQL on the database server for maximum performance in hot loops.
|
|
128
|
+
### Dynamic Updates
|
|
124
129
|
|
|
125
130
|
```typescript
|
|
126
|
-
const
|
|
127
|
-
// `Pgtx` automatically maps standard `?` placeholders to native `$1, $2` indexes.
|
|
131
|
+
const data = { status: 'active', last_login: new Date() }
|
|
128
132
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
133
|
+
await pool.query`
|
|
134
|
+
UPDATE users SET ${sql.update(data)} WHERE id = ${userId}
|
|
135
|
+
`
|
|
136
|
+
// UPDATE users SET status = $1, last_login = $2 WHERE id = $3
|
|
132
137
|
```
|
|
133
138
|
|
|
134
|
-
###
|
|
135
|
-
The ultimate tool for dynamic lists. Works for IN clauses, column lists, or joined conditions.
|
|
139
|
+
### Recursive Fragments
|
|
136
140
|
|
|
137
141
|
```typescript
|
|
138
|
-
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
await pool.query`SELECT ${sql.array(cols)} FROM users`
|
|
146
|
-
// SQL: SELECT "id", "name" FROM users
|
|
147
|
-
|
|
148
|
-
// 3. Dynamic WHERE conditions
|
|
149
|
-
const conds = [sql.fragment`active = true`, sql.fragment`age > ${18}`]
|
|
150
|
-
await pool.query`SELECT * FROM users WHERE ${sql.array(conds, ' AND ')}`
|
|
151
|
-
// SQL: SELECT * FROM users WHERE active = true AND age > $1
|
|
142
|
+
const filter = sql.fragment`status = ${'active'} AND age > ${21}`
|
|
143
|
+
const subquery = sql.fragment`(SELECT id FROM roles WHERE name = ${'admin'})`
|
|
144
|
+
|
|
145
|
+
await pool.query`
|
|
146
|
+
SELECT * FROM users
|
|
147
|
+
WHERE ${filter} AND role_id = (${subquery})
|
|
148
|
+
`
|
|
152
149
|
```
|
|
153
150
|
|
|
154
|
-
###
|
|
155
|
-
Easily generate SET clauses from plain JavaScript objects.
|
|
151
|
+
### Smart Lists
|
|
156
152
|
|
|
157
153
|
```typescript
|
|
158
|
-
const
|
|
154
|
+
const ids = [10, 20, 30]
|
|
155
|
+
await pool.query`
|
|
156
|
+
SELECT * FROM users WHERE id IN (${sql.array(ids)})
|
|
157
|
+
`
|
|
158
|
+
// SELECT * FROM users WHERE id IN ($1, $2, $3)
|
|
159
159
|
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
const conditions = [
|
|
161
|
+
sql.fragment`status = ${'active'}`,
|
|
162
|
+
sql.fragment`age > ${18}`
|
|
163
|
+
]
|
|
164
|
+
await pool.query`
|
|
165
|
+
SELECT * FROM users WHERE ${sql.array(conditions, ' AND ')}
|
|
166
|
+
`
|
|
162
167
|
```
|
|
163
168
|
|
|
164
|
-
###
|
|
165
|
-
Generates AND-separated conditions from an object. Skips undefined values for easy dynamic filtering.
|
|
169
|
+
### Clean WHERE Clauses
|
|
166
170
|
|
|
167
171
|
```typescript
|
|
168
|
-
const filters = { role: 'admin', age: undefined, active: true }
|
|
169
|
-
await pool.query`
|
|
170
|
-
|
|
172
|
+
const filters = { role: 'admin', age: undefined, active: true }
|
|
173
|
+
await pool.query`
|
|
174
|
+
SELECT * FROM users WHERE ${sql.where(filters)}
|
|
175
|
+
`
|
|
176
|
+
// SELECT * FROM users WHERE role = $1 AND active = $2
|
|
171
177
|
```
|
|
172
178
|
|
|
173
|
-
###
|
|
174
|
-
A safe "no-op" fragment for cleaner ternary operations in templates.
|
|
179
|
+
### Conditional Logic
|
|
175
180
|
|
|
176
181
|
```typescript
|
|
177
|
-
const search = ""
|
|
182
|
+
const search = ""
|
|
178
183
|
await pool.query`
|
|
179
184
|
SELECT * FROM posts
|
|
180
185
|
${search ? sql.fragment`WHERE title ILIKE ${search}` : sql.empty}
|
|
181
186
|
`
|
|
182
|
-
// Result if empty: SELECT * FROM posts
|
|
183
187
|
```
|
|
188
|
+
|
|
184
189
|
---
|
|
185
190
|
|
|
186
|
-
##
|
|
191
|
+
## 🛡️ Security
|
|
192
|
+
|
|
193
|
+
| Pattern | Protection |
|
|
194
|
+
|---------|------------|
|
|
195
|
+
| `sql.ident(name)` | Escapes identifiers: `user` → `"user"` |
|
|
196
|
+
| `sql.literal(value)` | Escapes string literals |
|
|
197
|
+
| Parameter binding | Uses native `$1, $2` placeholders |
|
|
198
|
+
| Template tags | Cannot be injected via user input |
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
// ✅ Safe - parameterized
|
|
202
|
+
await pool.query`SELECT * FROM users WHERE name = ${userInput}`
|
|
203
|
+
|
|
204
|
+
// ⚠️ Unsafe - raw interpolation (DON'T DO THIS)
|
|
205
|
+
await pool.query(`SELECT * FROM users WHERE name = '${userInput}'`)
|
|
187
206
|
|
|
188
|
-
|
|
207
|
+
// ✅ Safe - identifiers
|
|
208
|
+
await pool.query`SELECT * FROM ${sql.ident(tableName)}`
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
189
212
|
|
|
190
|
-
|
|
191
|
-
|
|
213
|
+
## 📊 Null & Undefined Handling
|
|
214
|
+
|
|
215
|
+
| Value | In INSERT | In UPDATE | In VALUES | In Arrays |
|
|
216
|
+
|-------|-----------|-----------|-----------|-----------|
|
|
192
217
|
| `null` | `NULL` | `NULL` | `NULL` | `NULL` |
|
|
193
|
-
| `undefined` | `DEFAULT` |
|
|
218
|
+
| `undefined` | `DEFAULT` | Skipped | `Error` | `Error` |
|
|
194
219
|
|
|
195
|
-
### Examples
|
|
196
220
|
|
|
197
221
|
```typescript
|
|
198
|
-
//
|
|
222
|
+
// undefined becomes DEFAULT
|
|
199
223
|
await pool.query`
|
|
200
224
|
INSERT INTO users ${sql.insert({
|
|
201
225
|
name: 'Alice',
|
|
202
|
-
age: undefined, //
|
|
203
|
-
email: null //
|
|
226
|
+
age: undefined, // → DEFAULT
|
|
227
|
+
email: null // → NULL
|
|
204
228
|
})}
|
|
205
229
|
`
|
|
206
|
-
//
|
|
230
|
+
// INSERT INTO users (name, age, email) VALUES ($1, DEFAULT, $2)
|
|
207
231
|
|
|
208
|
-
//
|
|
232
|
+
// undefined fields are skipped in UPDATE
|
|
209
233
|
await pool.query`
|
|
210
234
|
UPDATE users SET ${sql.update({
|
|
211
235
|
name: 'Bob',
|
|
212
|
-
age: undefined
|
|
213
|
-
deleted_at: null // explicitly set to NULL
|
|
236
|
+
age: undefined // Skipped - age remains unchanged
|
|
214
237
|
})} WHERE id = 1
|
|
215
238
|
`
|
|
216
|
-
//
|
|
239
|
+
// UPDATE users SET name = $1 WHERE id = 1
|
|
240
|
+
```
|
|
217
241
|
|
|
218
|
-
|
|
219
|
-
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## 🔧 API Reference
|
|
220
245
|
|
|
221
|
-
|
|
222
|
-
|
|
246
|
+
### Connection
|
|
247
|
+
```typescript
|
|
248
|
+
class Connection {
|
|
249
|
+
static new(params: ConnectionParams): Promise<Connection>
|
|
250
|
+
|
|
251
|
+
query<T>(strings: TemplateStringsArray, ...values: any[]): Promise<T[]>
|
|
252
|
+
begin<T>(callback: (tx: Transaction) => Promise<T>): Promise<T>
|
|
253
|
+
|
|
254
|
+
get isAlive(): boolean
|
|
255
|
+
close(): void
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
interface ConnectionParams {
|
|
259
|
+
user: string
|
|
260
|
+
password?: string
|
|
261
|
+
host: string
|
|
262
|
+
port: number
|
|
263
|
+
database: string
|
|
264
|
+
logLevel?: 'none' | 'error' | 'notice' | 'query' // defaul: "error"
|
|
265
|
+
}
|
|
223
266
|
```
|
|
224
267
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
268
|
+
### Pool
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
class Pool {
|
|
272
|
+
constructor(config: PoolConfig)
|
|
273
|
+
|
|
274
|
+
query<T>(strings: TemplateStringsArray, ...values: any[]): Promise<T[]>
|
|
275
|
+
begin<T>(callback: (tx: Transaction) => Promise<T>): Promise<T>
|
|
276
|
+
acquire(): Promise<Connection>
|
|
277
|
+
release(conn: Connection): void
|
|
278
|
+
close(): Promise<void>
|
|
279
|
+
|
|
280
|
+
get size(): number
|
|
281
|
+
get total(): number
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
interface PoolConfig extends ConnectionParams {
|
|
285
|
+
max?: number
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Transaction
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
class Transaction {
|
|
293
|
+
query<T>(strings: TemplateStringsArray, ...values: any[]): Promise<T[]>
|
|
294
|
+
commit(): Promise<void>
|
|
295
|
+
rollback(): Promise<void>
|
|
296
|
+
savepoint<T>(name: string, callback: (tx: Transaction) => Promise<T>): Promise<T>
|
|
297
|
+
|
|
298
|
+
get isActive(): boolean
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### **sql** helper
|
|
303
|
+
```typescript
|
|
304
|
+
const sql: {
|
|
305
|
+
ident<T extends string>(identificator: T): IdentifierClause<T>
|
|
306
|
+
literal<T extends string>(value: T): LiteralClause<T>
|
|
307
|
+
fragment(strings: TemplateStringsArray, ...values: any[]): FragmentClause
|
|
308
|
+
insert<T extends Record<string, any>>(...objects: NoInfer<T>[]): InsertClause<T>
|
|
309
|
+
update<T extends Record<string, any>>(object: T): UpdateClause<T>
|
|
310
|
+
where<T extends Record<string, any>>(whereMap: T): WhereClause<T>
|
|
311
|
+
excluded(fields: string[]): ExcludeUpdateClause
|
|
312
|
+
array(array: any[], separator?: string): ArrayClause
|
|
313
|
+
empty: EmptyClause
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## 📝 License
|
|
320
|
+
|
|
321
|
+
MIT © [M2K-5F](https://github.com/M2K-5F)
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
**Made with ❤️ and a bit of insanity**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ClauseStrategyParams } from "../types";
|
|
2
2
|
import { Clause } from "./abstract.clause";
|
|
3
3
|
export declare class EmptyClause extends Clause {
|
|
4
|
-
static
|
|
4
|
+
static create(): EmptyClause;
|
|
5
5
|
mapIntoQuery(params: ClauseStrategyParams): void;
|
|
6
6
|
}
|
|
7
7
|
export declare const emptyClause: EmptyClause;
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,MAAM;IAIb,YAAY,CAAC,MAAM,EAAE,oBAAoB;CAC5C;AAED,eAAO,MAAM,WAAW,aAAuB,CAAA"}
|
|
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.emptyClause = exports.EmptyClause = void 0;
|
|
4
4
|
const abstract_clause_1 = require("./abstract.clause");
|
|
5
5
|
class EmptyClause extends abstract_clause_1.Clause {
|
|
6
|
-
static
|
|
6
|
+
static create() {
|
|
7
7
|
return new EmptyClause();
|
|
8
8
|
}
|
|
9
9
|
mapIntoQuery(params) { }
|
|
10
10
|
}
|
|
11
11
|
exports.EmptyClause = EmptyClause;
|
|
12
|
-
exports.emptyClause = EmptyClause.
|
|
12
|
+
exports.emptyClause = EmptyClause.create();
|
|
@@ -3,7 +3,7 @@ import { ClauseStrategyParams } from "../types";
|
|
|
3
3
|
export declare class FragmentClause extends Clause {
|
|
4
4
|
readonly templates: TemplateStringsArray;
|
|
5
5
|
readonly args: any[];
|
|
6
|
-
constructor(
|
|
6
|
+
private constructor();
|
|
7
7
|
static create(strings: TemplateStringsArray, ...values: any[]): FragmentClause;
|
|
8
8
|
mapIntoQuery(params: ClauseStrategyParams): void;
|
|
9
9
|
}
|
|
@@ -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,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;
|
|
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;IAFxB,OAAO;IAKP,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE;IAIpD,YAAY,CAAC,MAAM,EAAE,oBAAoB;CASrD"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FragmentClause = void 0;
|
|
4
4
|
const abstract_clause_1 = require("./abstract.clause");
|
|
5
|
-
const
|
|
5
|
+
const template_compiler_1 = require("../utils/template-compiler");
|
|
6
6
|
class FragmentClause extends abstract_clause_1.Clause {
|
|
7
7
|
constructor(templates, args) {
|
|
8
8
|
super();
|
|
@@ -13,12 +13,10 @@ class FragmentClause extends abstract_clause_1.Clause {
|
|
|
13
13
|
return new FragmentClause(strings, values);
|
|
14
14
|
}
|
|
15
15
|
mapIntoQuery(params) {
|
|
16
|
-
const compiled = (0,
|
|
16
|
+
const compiled = (0, template_compiler_1.compileSqlTemplate)({
|
|
17
17
|
args: this.args,
|
|
18
|
-
counter: params.counter,
|
|
19
18
|
templates: this.templates
|
|
20
|
-
});
|
|
21
|
-
params.counter = compiled.counter;
|
|
19
|
+
}, params.args.length);
|
|
22
20
|
params.args.push(...compiled.args);
|
|
23
21
|
params.text.push(compiled.text);
|
|
24
22
|
}
|
|
@@ -2,7 +2,7 @@ import { ClauseStrategyParams } from "../types";
|
|
|
2
2
|
import { Clause } from "./abstract.clause";
|
|
3
3
|
export declare class IdentifierClause<T extends string> extends Clause {
|
|
4
4
|
readonly value: T;
|
|
5
|
-
constructor(
|
|
5
|
+
private constructor();
|
|
6
6
|
static create<T extends string>(identificator: T): IdentifierClause<T>;
|
|
7
7
|
mapIntoQuery(params: ClauseStrategyParams): void;
|
|
8
8
|
}
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;IADrB,OAAO;IAIP,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,aAAa,EAAE,CAAC;IAMvC,YAAY,CAAC,MAAM,EAAE,oBAAoB;CAGrD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './array.clause';
|
|
2
|
+
export * from './empty.clause';
|
|
3
|
+
export * from './exclude.clause';
|
|
4
|
+
export * from './fragment.clause';
|
|
5
|
+
export * from './iden.caluse';
|
|
6
|
+
export * from './insert.clause';
|
|
7
|
+
export * from './literal.clause';
|
|
8
|
+
export * from './update.clause';
|
|
9
|
+
export * from './where.clause';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/clauses/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./array.clause"), exports);
|
|
18
|
+
__exportStar(require("./empty.clause"), exports);
|
|
19
|
+
__exportStar(require("./exclude.clause"), exports);
|
|
20
|
+
__exportStar(require("./fragment.clause"), exports);
|
|
21
|
+
__exportStar(require("./iden.caluse"), exports);
|
|
22
|
+
__exportStar(require("./insert.clause"), exports);
|
|
23
|
+
__exportStar(require("./literal.clause"), exports);
|
|
24
|
+
__exportStar(require("./update.clause"), exports);
|
|
25
|
+
__exportStar(require("./where.clause"), exports);
|
|
@@ -2,7 +2,7 @@ import { Clause } from "./abstract.clause";
|
|
|
2
2
|
import { ClauseStrategyParams } from "../types";
|
|
3
3
|
export declare class InsertClause<T extends Record<string, any>> extends Clause {
|
|
4
4
|
readonly inserts: T[];
|
|
5
|
-
constructor(
|
|
5
|
+
private constructor();
|
|
6
6
|
static create<T extends Record<string, any>>(...objects: NoInfer<T>[]): InsertClause<T>;
|
|
7
7
|
mapIntoQuery(params: ClauseStrategyParams): void;
|
|
8
8
|
}
|
|
@@ -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,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;
|
|
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;IADzB,OAAO;IAIP,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"}
|
|
@@ -2,7 +2,7 @@ import { ClauseStrategyParams } from "../types";
|
|
|
2
2
|
import { Clause } from "./abstract.clause";
|
|
3
3
|
export declare class LiteralClause<T extends string> extends Clause {
|
|
4
4
|
readonly value: T;
|
|
5
|
-
constructor(
|
|
5
|
+
private constructor();
|
|
6
6
|
static create<T extends string>(value: T): LiteralClause<T>;
|
|
7
7
|
mapIntoQuery(params: ClauseStrategyParams): void;
|
|
8
8
|
}
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;IADrB,OAAO;IAMP,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;IAQlD,YAAY,CAAC,MAAM,EAAE,oBAAoB;CAGrD"}
|
|
@@ -2,7 +2,7 @@ import { ClauseStrategyParams } from "../types";
|
|
|
2
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
|
-
constructor(
|
|
5
|
+
private constructor();
|
|
6
6
|
static create<T extends Record<string, any>>(object: T): UpdateClause<T>;
|
|
7
7
|
mapIntoQuery(params: ClauseStrategyParams): void;
|
|
8
8
|
}
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;IADzB,OAAO;IAIP,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IAI7C,YAAY,CAAC,MAAM,EAAE,oBAAoB;CAarD"}
|