pg-query-sdk 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +94 -365
  2. package/dist/cjs/builders/ConditionBuilder.d.ts +34 -0
  3. package/dist/cjs/builders/ConditionBuilder.js +34 -0
  4. package/dist/cjs/builders/QueryBuilder.d.ts +112 -1
  5. package/dist/cjs/builders/QueryBuilder.js +94 -1
  6. package/dist/cjs/core/Database.d.ts +26 -0
  7. package/dist/cjs/core/Database.js +26 -0
  8. package/dist/cjs/core/ParamContext.d.ts +16 -0
  9. package/dist/cjs/core/ParamContext.js +16 -0
  10. package/dist/cjs/core/QueryExecutor.d.ts +26 -0
  11. package/dist/cjs/core/QueryExecutor.js +26 -0
  12. package/dist/cjs/core/TransactionManager.d.ts +13 -0
  13. package/dist/cjs/core/TransactionManager.js +13 -0
  14. package/dist/cjs/core/UnitOfWork.d.ts +19 -0
  15. package/dist/cjs/core/UnitOfWork.js +19 -0
  16. package/dist/cjs/dialects/Dialect.d.ts +13 -0
  17. package/dist/cjs/dialects/MysqlDialect.d.ts +12 -0
  18. package/dist/cjs/dialects/MysqlDialect.js +12 -0
  19. package/dist/cjs/dialects/PostgresDialect.d.ts +13 -0
  20. package/dist/cjs/dialects/PostgresDialect.js +13 -0
  21. package/dist/cjs/index.d.ts +28 -0
  22. package/dist/cjs/index.js +28 -0
  23. package/dist/cjs/orm/Repository.d.ts +34 -0
  24. package/dist/cjs/orm/Repository.js +34 -0
  25. package/dist/cjs/query/ConditionBuilder.d.ts +33 -0
  26. package/dist/cjs/query/ConditionBuilder.js +33 -0
  27. package/dist/cjs/query/QueryBuilder.d.ts +154 -0
  28. package/dist/cjs/query/QueryBuilder.js +136 -0
  29. package/dist/esm/builders/ConditionBuilder.d.ts +34 -0
  30. package/dist/esm/builders/ConditionBuilder.js +34 -0
  31. package/dist/esm/builders/QueryBuilder.d.ts +112 -1
  32. package/dist/esm/builders/QueryBuilder.js +94 -1
  33. package/dist/esm/core/Database.d.ts +26 -0
  34. package/dist/esm/core/Database.js +26 -0
  35. package/dist/esm/core/ParamContext.d.ts +16 -0
  36. package/dist/esm/core/ParamContext.js +16 -0
  37. package/dist/esm/core/QueryExecutor.d.ts +26 -0
  38. package/dist/esm/core/QueryExecutor.js +26 -0
  39. package/dist/esm/core/TransactionManager.d.ts +13 -0
  40. package/dist/esm/core/TransactionManager.js +13 -0
  41. package/dist/esm/core/UnitOfWork.d.ts +19 -0
  42. package/dist/esm/core/UnitOfWork.js +19 -0
  43. package/dist/esm/dialects/Dialect.d.ts +13 -0
  44. package/dist/esm/dialects/MysqlDialect.d.ts +12 -0
  45. package/dist/esm/dialects/MysqlDialect.js +12 -0
  46. package/dist/esm/dialects/PostgresDialect.d.ts +13 -0
  47. package/dist/esm/dialects/PostgresDialect.js +13 -0
  48. package/dist/esm/index.d.ts +28 -0
  49. package/dist/esm/index.js +28 -0
  50. package/dist/esm/orm/Repository.d.ts +34 -0
  51. package/dist/esm/orm/Repository.js +34 -0
  52. package/dist/esm/query/ConditionBuilder.d.ts +33 -0
  53. package/dist/esm/query/ConditionBuilder.js +33 -0
  54. package/dist/esm/query/QueryBuilder.d.ts +154 -0
  55. package/dist/esm/query/QueryBuilder.js +136 -0
  56. package/package.json +1 -1
package/README.md CHANGED
@@ -1,69 +1,54 @@
1
- # PG QUERY SDK (TypeScript)
1
+ # PG Query SDK (TypeScript)
2
2
 
3
3
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue.svg)](https://www.typescriptlang.org/)
5
- [![Architecture: Hexagonal](https://img.shields.io/badge/Architecture-Hexagonal-green.svg)](#-arquitetura)
4
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue.svg)](https://www.typescriptlang.com/)
6
5
 
7
- Uma biblioteca robusta e tipada para integração com banco de dados **PostgresSQL**. Construída sob os princípios da **Arquitetura Hexagonal**, garantindo que sua integração seja escalável, testável e fácil de manter.
6
+ ## A Robust and Type-Safe PostgreSQL Integration Library for TypeScript
8
7
 
9
- **PostgreSQL** SDK com suporte a:
8
+ The PG Query SDK is a comprehensive TypeScript library designed to facilitate seamless and type-safe interaction with PostgreSQL databases. It provides a structured approach to query construction, execution, and transaction management, enhancing developer productivity and reducing common database-related errors.
10
9
 
11
- - **`Database`**: Ponto de entrada central para todas as operações.
12
- - **`QueryBuilder`**: Construtor de queries SQL fluente para **SELECT**.
13
- - **`ConditionBuilder`**: Construtor de cláusulas `WHERE` e `HAVING` complexas.
14
- - **`QueryExecutor`**: Executor de queries baseado em Pool de conexões.
15
- - **ORM Básico**: Com `Repository` para abstração de acesso a dados (atualmente apenas `findById` implementado na base).
16
- - **Transações**: Gerenciamento de transações ACID.
17
- - Compatível com CommonJS e ESM.
18
- - Dual build (CJS + ESM).
10
+ ### Key Features:
19
11
 
20
- ---
12
+ * **`Database`**: The central entry point for database operations, managing connections and configurations.
13
+ * **`QueryBuilder`**: A fluent interface for constructing complex SQL `SELECT` queries programmatically.
14
+ * **`ConditionBuilder`**: Specialized builder for crafting intricate `WHERE` and `HAVING` clauses.
15
+ * **`QueryExecutor`**: Manages database connection pooling and executes raw SQL queries securely.
16
+ * **Basic ORM Capabilities**: Includes an abstract `Repository` class for data access abstraction, with extensible methods for DML operations.
17
+ * **Transaction Management**: Robust support for ACID-compliant database transactions.
21
18
 
22
- # 📦 Instalação
19
+ ---
23
20
 
24
- ```bash
25
- npm install pg-query-sdk
26
- ```
21
+ ## 📦 Installation
27
22
 
28
- Ou localmente:
23
+ To integrate the PG Query SDK into your project, execute the following command:
29
24
 
30
25
  ```bash
31
- npm install .
26
+ npm install pg-query-sdk
32
27
  ```
33
28
 
34
29
  ---
35
30
 
36
- # 🚀 Primeiros Passos
31
+ ## 🚀 Getting Started
37
32
 
38
- O ponto de entrada principal para interagir com o SDK é a classe `Database`. Ela gerencia a conexão, o dialeto SQL e fornece acesso a todas as funcionalidades.
33
+ ### Initializing the Database
39
34
 
40
- ## Inicializando o Database
35
+ The `Database` class serves as the primary interface for all database interactions. Instantiate it with your PostgreSQL connection string.
41
36
 
42
37
  ```typescript
43
38
  import Database from 'pg-query-sdk';
44
39
 
45
40
  const db = new Database({
46
41
  connectionString: 'postgres://user:pass@localhost:5432/your_database',
47
- // Opcional: Você pode especificar um dialeto diferente se necessário
48
- // dialect: new MyCustomDialect(),
49
- // Opcional: TTL padrão para cache de queries (em segundos). Use 0 para desativar.
50
- // defaultCacheTTL: 300
51
42
  });
52
-
53
- // Agora 'db' está pronto para ser usado!
54
43
  ```
55
44
 
56
45
  ---
57
46
 
58
- # 🛠 Funcionalidades Principais
59
-
60
- ## 1️⃣ QueryBuilder: Construindo Queries SQL (SELECT)
47
+ ## 🛠 Core Functionalities
61
48
 
62
- O `QueryBuilder` permite construir queries SQL de forma programática e segura, **focando em operações de seleção de dados**. Ele é acessado através do método `table()` da sua instância `Database`.
49
+ ### 1️⃣ QueryBuilder: Fluent SQL `SELECT` Query Construction
63
50
 
64
- Ele **não executa nada**, apenas retorna a string SQL e os parâmetros. Para executar a query, você deve encadear `.execute()` no final.
65
-
66
- ### Selecionando Dados
51
+ The `QueryBuilder` enables the programmatic construction of SQL `SELECT` statements, accessible via the `db.table()` method.
67
52
 
68
53
  ```typescript
69
54
  import Database from 'pg-query-sdk';
@@ -73,28 +58,12 @@ const db = new Database({
73
58
  });
74
59
 
75
60
  async function selectExample() {
76
- // Construindo a query
77
- const { query, params } = db.table('users')
78
- .select(['id', 'name', 'email'])
79
- .where({ active: true })
80
- .limit(10)
81
- .offset(0)
82
- .orderBy('name', 'ASC')
83
- .build(); // Apenas constrói a query, não executa
84
-
85
- console.log('SELECT Query:', query);
86
- // Ex: SELECT id, name, email FROM users WHERE active = $1 ORDER BY name ASC LIMIT 10 OFFSET 0
87
- console.log('SELECT Params:', params);
88
- // Ex: [true]
89
-
90
- // Executando a query
91
61
  const users = await db.table('users')
92
62
  .select(['id', 'name', 'email'])
93
63
  .where({ active: true })
94
64
  .limit(10)
95
- .offset(0)
96
65
  .orderBy('name', 'ASC')
97
- .execute(); // Executa a query e retorna os resultados
66
+ .execute();
98
67
 
99
68
  console.log('Selected Users:', users);
100
69
  }
@@ -102,119 +71,9 @@ async function selectExample() {
102
71
  selectExample();
103
72
  ```
104
73
 
105
- ### Joins
106
-
107
- ```typescript
108
- import Database from 'pg-query-sdk';
109
-
110
- const db = new Database({
111
- connectionString: 'postgres://user:pass@localhost:5432/your_database',
112
- });
113
-
114
- async function joinExample() {
115
- const usersWithOrders = await db.table('users')
116
- .select(['users.name', 'orders.amount', 'orders.status'])
117
- .join('orders', 'users.id', 'orders.user_id') // INNER JOIN
118
- .where({ 'orders.status': 'completed' })
119
- .execute();
120
-
121
- console.log('Users with completed orders:', usersWithOrders);
74
+ ### 2️⃣ ConditionBuilder: Advanced `WHERE` and `HAVING` Clauses
122
75
 
123
- const usersAndTheirOrders = await db.table('users')
124
- .select(['users.name', 'orders.amount', 'orders.status'])
125
- .leftJoin('orders', 'users.id', 'orders.user_id') // LEFT JOIN
126
- .orderBy('users.name', 'ASC')
127
- .execute();
128
-
129
- console.log('Users and all their orders (if any):', usersAndTheirOrders);
130
- }
131
-
132
- joinExample();
133
- ```
134
-
135
- ### Group By e Having
136
-
137
- ```typescript
138
- import Database from 'pg-query-sdk';
139
-
140
- const db = new Database({
141
- connectionString: 'postgres://user:pass@localhost:5432/your_database',
142
- });
143
-
144
- async function groupByHavingExample() {
145
- const categorySales = await db.table('products')
146
- .select(['category', 'COUNT(id) as total_products', 'SUM(price) as total_value'])
147
- .groupBy('category')
148
- .having({ 'SUM(price)': { op: '>', value: 1000 } }) // HAVING SUM(price) > 1000
149
- .orderBy('total_value', 'DESC')
150
- .execute();
151
-
152
- console.log('Category sales over 1000:', categorySales);
153
- }
154
-
155
- groupByHavingExample();
156
- ```
157
-
158
- ### Common Table Expressions (CTEs)
159
-
160
- ```typescript
161
- import Database from 'pg-query-sdk';
162
-
163
- const db = new Database({
164
- connectionString: 'postgres://user:pass@localhost:5432/your_database',
165
- });
166
-
167
- async function cteExample() {
168
- // Subquery para usuários ativos
169
- const activeUsersSubquery = db.table('users')
170
- .select(['id', 'name'])
171
- .where({ active: true });
172
-
173
- // Query principal usando a CTE
174
- const result = await db.table('active_users') // Referencia a CTE pelo nome
175
- .with('active_users', activeUsersSubquery) // Define a CTE
176
- .select(['name'])
177
- .orderBy('name', 'ASC')
178
- .execute();
179
-
180
- console.log('Users from CTE:', result);
181
- }
182
-
183
- cteExample();
184
- ```
185
-
186
- ### Subqueries na Cláusula FROM
187
-
188
- ```typescript
189
- import Database from 'pg-query-sdk';
190
-
191
- const db = new Database({
192
- connectionString: 'postgres://user:pass@localhost:5432/your_database',
193
- });
194
-
195
- async function fromSubqueryExample() {
196
- // Subquery para obter o total de pedidos por usuário
197
- const userOrderCounts = db.table('orders')
198
- .select(['user_id', 'COUNT(id) as order_count'])
199
- .groupBy('user_id');
200
-
201
- // Query principal usando a subquery como tabela
202
- const usersWithOrderCounts = await db.table('users')
203
- .select(['users.name', 'uoc.order_count'])
204
- .fromSubquery(userOrderCounts, 'uoc') // Usa a subquery 'userOrderCounts' como 'uoc'
205
- .join('users', 'users.id', 'uoc.user_id') // JOIN com a tabela original de usuários
206
- .where({ 'uoc.order_count': { op: '>', value: 5 } })
207
- .execute();
208
-
209
- console.log('Users with more than 5 orders:', usersWithOrderCounts);
210
- }
211
-
212
- fromSubqueryExample();
213
- ```
214
-
215
- ## 2️⃣ ConditionBuilder: Cláusulas WHERE e HAVING Avançadas
216
-
217
- O `ConditionBuilder` é usado dentro dos métodos `where()` e `having()` do `QueryBuilder` para construir condições complexas, incluindo operadores, `NULL` checks, expressões raw e agrupamentos `AND`/`OR`.
76
+ The `ConditionBuilder` facilitates the creation of complex conditional logic within `WHERE` and `HAVING` clauses, typically used in conjunction with the `QueryBuilder`.
218
77
 
219
78
  ```typescript
220
79
  import Database from 'pg-query-sdk';
@@ -225,69 +84,49 @@ const db = new Database({
225
84
 
226
85
  async function complexWhereExample() {
227
86
  const products = await db.table('products')
228
- .select(['name', 'price', 'stock', 'category'])
87
+ .select(['name', 'price'])
229
88
  .where(conditions => {
230
89
  conditions
231
- .where({ category: 'electronics' }) // category = $1
232
- .andGroup(group1 => { // AND (...)
233
- group1
234
- .where({ stock: { op: '>', value: 0 } }) // stock > $2
235
- .orGroup(group2 => { // OR (...)
236
- group2
237
- .where({ price: { op: '<', value: 100 } }) // price < $3
238
- .raw('created_at > NOW() - INTERVAL \'1 year\''); // created_at > ...
239
- });
240
- })
241
- .where({ manufacturer: null }); // manufacturer IS NULL
90
+ .where({ category: 'electronics' })
91
+ .orGroup(group => {
92
+ group
93
+ .where({ price: { op: '<', value: 100 } })
94
+ .where({ stock: { op: '>', value: 0 } });
95
+ });
242
96
  })
243
97
  .execute();
244
98
 
245
99
  console.log('Complex WHERE Products:', products);
246
- // A query gerada seria algo como:
247
- // SELECT name, price, stock, category FROM products
248
- // WHERE category = $1 AND (stock > $2 OR (price < $3 AND created_at > NOW() - INTERVAL '1 year')) AND manufacturer IS NULL
249
100
  }
250
101
 
251
102
  complexWhereExample();
252
103
  ```
253
104
 
254
- ## 3️⃣ QueryExecutor: Execução Direta de Queries
105
+ ### 3️⃣ QueryExecutor: Direct Query Execution
255
106
 
256
- O `QueryExecutor` é a camada responsável por interagir diretamente com o driver `pg` para executar queries. Embora o `QueryBuilder` seja preferível para a maioria dos casos, você pode acessar o `QueryExecutor` diretamente através da instância `Database` para queries SQL customizadas, procedimentos armazenados ou comandos DDL.
107
+ For scenarios requiring direct execution of raw SQL queries, the `QueryExecutor` can be instantiated and utilized.
257
108
 
258
109
  ```typescript
259
- import Database from 'pg-query-sdk';
110
+ import { QueryExecutor } from 'pg-query-sdk';
260
111
 
261
- const db = new Database({
112
+ const executor = new QueryExecutor({
262
113
  connectionString: 'postgres://user:pass@localhost:5432/your_database',
263
114
  });
264
115
 
265
116
  async function directExecuteExample() {
266
- // Executando uma query simples
267
- const result = await db.executor.execute(
268
- 'SELECT version(), NOW() as current_time',
117
+ const result = await executor.execute(
118
+ 'SELECT version()',
269
119
  []
270
120
  );
271
121
  console.log('Direct Execution Result:', result.rows);
272
-
273
- // Executando uma query com parâmetros
274
- const specificUser = await db.executor.execute(
275
- 'SELECT * FROM users WHERE id = $1',
276
- [1]
277
- );
278
- console.log('Specific User (Direct):', specificUser.rows[0]);
279
-
280
- // Exemplo de DDL (Data Definition Language) - CUIDADO ao usar em produção!
281
- // await db.executor.execute('CREATE TABLE IF NOT EXISTS temp_table (id SERIAL PRIMARY KEY, name VARCHAR(255))', []);
282
- // console.log('temp_table created (if not exists).');
283
122
  }
284
123
 
285
124
  directExecuteExample();
286
125
  ```
287
126
 
288
- ## 4️⃣ Transações ACID
127
+ ### 4️⃣ ACID Transactions
289
128
 
290
- O SDK oferece um gerenciador de transações robusto para garantir a atomicidade (ACID) das suas operações de banco de dados. Se qualquer operação dentro da transação falhar, todas as alterações serão revertidas (rollback).
129
+ The SDK provides robust support for managing ACID-compliant transactions, ensuring data integrity.
291
130
 
292
131
  ```typescript
293
132
  import Database from 'pg-query-sdk';
@@ -299,255 +138,145 @@ const db = new Database({
299
138
  async function transactionExample() {
300
139
  try {
301
140
  const result = await db.transaction(async trxDb => {
302
- // Dentro desta callback, 'trxDb' é uma instância de Database
303
- // que está vinculada à transação atual.
304
- // Todas as operações feitas com 'trxDb' farão parte da mesma transação.
305
-
306
- // Exemplo: Transferir fundos entre contas
307
- const senderId = 1;
308
- const receiverId = 2;
309
- const amount = 100.00;
310
-
311
- // 1. Decrementar saldo do remetente
312
- // Nota: Para INSERT/UPDATE/DELETE, você precisará usar db.executor.execute() diretamente
313
- // ou implementar esses métodos em um repositório customizado.
141
+ // 'trxDb' is a Database instance bound to the current transaction.
142
+ // Use 'trxDb.executor.execute()' for DML operations within the transaction.
314
143
  await trxDb.executor.execute(
315
- 'UPDATE accounts SET balance = balance - $1 WHERE id = $2 AND balance >= $1 RETURNING id, balance',
316
- [amount, senderId]
144
+ 'UPDATE accounts SET balance = balance - $1 WHERE id = $2',
145
+ [100.00, 1]
317
146
  );
318
- console.log(`Decremented balance for account ${senderId}`);
319
-
320
- // Simular uma falha para testar o rollback
321
- // if (true) throw new Error('Simulated failure');
322
-
323
- // 2. Incrementar saldo do destinatário
324
147
  await trxDb.executor.execute(
325
- 'UPDATE accounts SET balance = balance + $1 WHERE id = $2 RETURNING id, balance',
326
- [amount, receiverId]
148
+ 'UPDATE accounts SET balance = balance + $1 WHERE id = $2',
149
+ [100.00, 2]
327
150
  );
328
- console.log(`Incremented balance for account ${receiverId}`);
329
-
330
- // Se tudo ocorrer bem, a transação será commitada automaticamente.
331
- return `Transaction successful: ${amount} transferred from ${senderId} to ${receiverId}`;
151
+ return 'Transaction completed successfully.';
332
152
  });
333
-
334
153
  console.log(result);
335
- } catch (error) {
154
+ } catch (error: any) {
336
155
  console.error('Transaction failed:', error.message);
337
- // Se uma exceção for lançada, a transação será automaticamente revertida (rollback).
338
156
  }
339
157
  }
340
158
 
341
159
  transactionExample();
342
160
  ```
343
161
 
344
- ## 5️⃣ ORM Básico com Repositórios
345
-
346
- O SDK fornece uma base para construir um ORM simples usando a classe `Repository`. Isso ajuda a organizar o código de acesso a dados por entidade.
162
+ ### 5️⃣ Basic ORM with Repositories
347
163
 
348
- ### Definindo um Repositório Customizado
349
-
350
- A classe base `Repository<T>` oferece um método `findById` e um `qb()` que retorna um `QueryBuilder` pré-configurado para a tabela. Para operações de `INSERT`, `UPDATE` e `DELETE`, você precisará implementá-las em seus repositórios customizados, utilizando o `QueryExecutor` ou o `QueryBuilder` (para `SELECT` após a operação).
164
+ The abstract `Repository<T>` class offers a foundational ORM layer, providing methods like `findById` and a pre-configured `QueryBuilder` (`qb()`). Custom DML operations (`insert`, `update`, `delete`) should be implemented in concrete repository classes.
351
165
 
352
166
  ```typescript
353
- import { Repository, QueryExecutor, Dialect } from 'pg-query-sdk';
167
+ import Database, { Repository } from 'pg-query-sdk';
168
+ import { QueryExecutor, Dialect } from 'pg-query-sdk';
354
169
 
355
- // 1. Defina a interface para sua entidade
356
170
  interface User {
357
171
  id: number;
358
172
  name: string;
359
173
  email: string;
360
- age?: number;
361
- active: boolean;
362
174
  }
363
175
 
364
- // 2. Crie sua classe de repositório estendendo Repository<T>
365
176
  class UserRepository extends Repository<User> {
366
177
  constructor(executor: QueryExecutor, dialect: Dialect) {
367
- // O construtor base requer o nome da tabela, o executor e o dialeto
368
178
  super('users', executor, dialect);
369
179
  }
370
180
 
371
- // Método implementado na classe base
372
- // async findById(id: number): Promise<User | null> { ... }
373
-
374
- // Exemplo de método customizado para o repositório de usuários
375
- async findActiveUsers(): Promise<User[]> {
376
- return this.qb() // 'this.qb()' retorna um QueryBuilder pré-configurado para a tabela 'users'
377
- .where({ active: true })
378
- .execute();
379
- }
380
-
381
- async findUsersByAgeRange(minAge: number, maxAge: number): Promise<User[]> {
181
+ async findByName(name: string): Promise<User[]> {
382
182
  return this.qb()
383
- .where(conditions => {
384
- conditions
385
- .where({ age: { op: '>=', value: minAge } })
386
- .where({ age: { op: '<=', value: maxAge } });
387
- })
183
+ .where({ name })
388
184
  .execute();
389
185
  }
390
186
 
391
- // Exemplo de implementação de INSERT em um repositório customizado
392
- async createUser(data: Omit<User, 'id'>): Promise<User> {
393
- const { query, params } = this.dialect.createInsertQuery(this.table, data as Record<string, any>, ['id', 'name', 'email', 'age', 'active']);
394
- const result = await this.executor.execute(query, params);
395
- return result.rows[0];
396
- }
397
-
398
- // Exemplo de implementação de UPDATE em um repositório customizado
399
- async updateUser(id: number, data: Partial<User>): Promise<User | null> {
400
- const { query, params } = this.dialect.createUpdateQuery(this.table, data as Record<string, any>, { id }, ['id', 'name', 'email', 'age', 'active']);
401
- const result = await this.executor.execute(query, params);
402
- return result.rows[0] || null;
403
- }
404
-
405
- // Exemplo de implementação de DELETE em um repositório customizado
406
- async deleteUser(id: number): Promise<boolean> {
407
- const { query, params } = this.dialect.createDeleteQuery(this.table, { id });
408
- const result = await this.executor.execute(query, params);
409
- return result.rowCount > 0;
410
- }
187
+ // Implement DML operations as needed.
188
+ // Example: async insert(data: Partial<User>): Promise<User> { /* ... */ }
411
189
  }
412
- ```
413
-
414
- ### Usando o Repositório Customizado
415
-
416
- ```typescript
417
- import Database from 'pg-query-sdk';
418
- // Importe seu UserRepository definido acima
419
- import { UserRepository } from './path/to/UserRepository'; // Ajuste o caminho conforme necessário
420
190
 
421
191
  const db = new Database({
422
192
  connectionString: 'postgres://user:pass@localhost:5432/your_database',
423
193
  });
424
194
 
425
195
  async function repositoryExample() {
426
- // Obtenha uma instância do seu repositório através do método .repository() do Database
427
196
  const userRepository = db.repository(UserRepository);
428
197
 
429
- // Usando métodos do repositório base
430
198
  const userById = await userRepository.findById(1);
431
199
  console.log('User by ID:', userById);
432
200
 
433
- // Usando métodos customizados
434
- const activeUsers = await userRepository.findActiveUsers();
435
- console.log('Active Users:', activeUsers);
436
-
437
- const usersInAgeRange = await userRepository.findUsersByAgeRange(25, 35);
438
- console.log('Users in age range 25-35:', usersInAgeRange);
439
-
440
- // Criando um novo usuário
441
- const newUser = await userRepository.createUser({
442
- name: 'Charlie',
443
- email: 'charlie@example.com',
444
- age: 29,
445
- active: true
446
- });
447
- console.log('Created new user:', newUser);
448
-
449
- // Atualizando um usuário
450
- const updatedUser = await userRepository.updateUser(newUser.id, { age: 30, active: false });
451
- console.log('Updated user:', updatedUser);
452
-
453
- // Deletando um usuário
454
- const deleted = await userRepository.deleteUser(newUser.id);
455
- console.log(`User ${newUser.id} deleted: ${deleted}`);
201
+ const usersByName = await userRepository.findByName('Alice');
202
+ console.log('Users by Name:', usersByName);
456
203
  }
457
204
 
458
205
  repositoryExample();
459
206
  ```
460
207
 
461
- ### EntityManager (Planejado)
462
-
463
- O `EntityManager` é um componente planejado para gerenciar múltiplos repositórios e unidades de trabalho, oferecendo uma interface centralizada para operações de persistência mais complexas. Atualmente, esta classe está vazia e será desenvolvida em futuras iterações.
464
-
465
208
  ---
466
209
 
467
- # ⚙️ Dual Module Support
210
+ ## ⚙️ Dual Module Support
468
211
 
469
- O pacote suporta tanto CommonJS quanto ES Modules, permitindo flexibilidade na sua configuração de projeto.
212
+ The package provides support for both CommonJS and ES Modules environments.
470
213
 
471
- ## CommonJS
214
+ ### CommonJS
472
215
 
473
216
  ```javascript
474
- const Database = require('pg-query-sdk').default; // Note o .default para a exportação padrão
475
-
217
+ const Database = require('pg-query-sdk').default;
476
218
  const db = new Database({ /* ... */ });
477
219
  ```
478
220
 
479
- ## ESM
221
+ ### ESM
480
222
 
481
223
  ```typescript
482
224
  import Database from 'pg-query-sdk';
483
-
484
225
  const db = new Database({ /* ... */ });
485
226
  ```
486
227
 
487
- Isso funciona graças ao campo `exports` no `package.json`:
488
-
489
- ```json
490
- {
491
- "exports": {
492
- ".": {
493
- "require": "./dist/cjs/index.js",
494
- "import": "./dist/esm/index.js"
495
- }
496
- }
497
- }
498
- ```
499
-
500
228
  ---
501
229
 
502
- # 🧱 Estrutura do Projeto
230
+ ## 🧱 Project Structure
231
+
232
+ The project is organized into distinct modules, each responsible for a specific aspect of database interaction:
503
233
 
504
234
  ```
505
235
  pg-query-sdk/
506
236
  src/
507
237
  core/
508
- Database.ts # Ponto de entrada principal
509
- ParamContext.ts # Gerencia parâmetros para queries seguras
510
- QueryExecutor.ts # Executa queries no PostgreSQL
511
- TransactionManager.ts # Gerencia transações
238
+ Database.ts # Central database interface
239
+ ParamContext.ts # Manages query parameters
240
+ QueryExecutor.ts # Executes SQL queries
241
+ TransactionManager.ts # Handles database transactions
512
242
  builders/
513
- ConditionBuilder.ts # Constrói cláusulas WHERE e HAVING
514
- QueryBuilder.ts # Constrói queries SQL (apenas SELECT)
243
+ ConditionBuilder.ts # Builds WHERE/HAVING clauses
244
+ QueryBuilder.ts # Builds SELECT queries
515
245
  orm/
516
- EntityManager.ts # (Planejado) Gerenciador de entidades
517
- Repository.ts # Classe base para repositórios ORM
246
+ EntityManager.ts # (Planned) Entity management
247
+ Repository.ts # Abstract base for data access
518
248
  dialects/
519
- Dialect.ts # Interface para dialetos SQL
520
- PostgresDialect.ts # Implementação do dialeto PostgreSQL
521
- index.ts # Exportações principais do SDK
522
- test/ # Testes unitários e de integração
523
- dist/ # Saída da compilação (CJS e ESM)
249
+ Dialect.ts # Interface for database dialects
250
+ PostgresDialect.ts # PostgreSQL specific dialect implementation
251
+ index.ts # Main entry point for module exports
524
252
  ```
525
253
 
526
254
  ---
527
255
 
528
- # 📌 Responsabilidades das Camadas
256
+ ## 📌 Responsibilities of Layers
529
257
 
530
- | Camada | Responsabilidade |
531
- |--------------------|--------------------------------------------------------------------------------------------------------------|
532
- | `Database` | Ponto de entrada, gerencia conexão, dialeto, transações e acesso a builders/repositórios. |
533
- | `QueryBuilder` | Construção fluente de queries SQL **apenas para seleção de dados** (SELECT, JOIN, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT, OFFSET, CTEs, Subqueries). |
534
- | `ConditionBuilder` | Construção de cláusulas `WHERE` e `HAVING` complexas e aninhadas. |
535
- | `QueryExecutor` | Execução de queries no PostgreSQL e gerenciamento do pool de conexões. |
536
- | `Repository` | Abstração de acesso a dados para uma entidade específica. A classe base implementa `findById`. Métodos como `insert`, `update`, `delete` devem ser implementados nos repositórios customizados. |
537
- | `TransactionManager`| Gerenciamento de transações ACID. |
538
- | `EntityManager` | (Planejado) Gerenciamento de múltiplos repositórios e unidade de trabalho. |
539
- | `pg` (driver) | Comunicação de baixo nível com o banco de dados PostgreSQL. |
258
+ | Layer | Responsibility |
259
+ | :-------------------- | :------------------------------------------------------------------------------------------------------------- |
260
+ | `Database` | Serves as the primary entry point, managing connection configurations, dialect, transactions, and access to builders and repositories. |
261
+ | `QueryBuilder` | Provides a fluent API for constructing SQL `SELECT` queries. |
262
+ | `ConditionBuilder` | Facilitates the construction of complex `WHERE` and `HAVING` clauses. |
263
+ | `QueryExecutor` | Manages the PostgreSQL connection pool and executes SQL queries, ensuring resource efficiency. |
264
+ | `Repository` | Offers an abstract layer for data access operations for a specific entity. Includes `findById` and a pre-configured `QueryBuilder`. Custom DML operations are to be implemented by concrete classes. |
265
+ | `TransactionManager` | Orchestrates ACID-compliant database transactions, ensuring atomicity, consistency, isolation, and durability. |
266
+ | `EntityManager` | (Planned) Will manage multiple repositories and coordinate units of work for complex persistence scenarios. |
540
267
 
541
268
  ---
542
269
 
543
- # 🔐 Segurança
270
+ ## 🔐 Security Considerations
271
+
272
+ The PG Query SDK prioritizes security through several mechanisms:
544
273
 
545
- - **Parâmetros Preparados**: Todas as queries construídas pelo `QueryBuilder` e `ConditionBuilder` utilizam parâmetros preparados, prevenindo ataques de SQL Injection. O `QueryExecutor` também suporta parâmetros para queries diretas.
546
- - **Pool de Conexões**: O `QueryExecutor` gerencia um pool de conexões, otimizando o uso de recursos e garantindo que as conexões sejam reutilizadas de forma eficiente.
547
- - **Liberação de Conexões**: As conexões são sempre liberadas de volta ao pool no bloco `finally` após a execução da query ou transação, evitando vazamentos de conexão.
274
+ * **Prepared Statements**: All queries utilize prepared statements with parameterized values, effectively mitigating SQL injection vulnerabilities.
275
+ * **Connection Pooling**: The `QueryExecutor` employs connection pooling to manage database connections efficiently and securely, reducing overhead and preventing resource exhaustion.
276
+ * **Resource Management**: Database connections are meticulously released in `finally` blocks within transaction and execution contexts, preventing connection leaks and ensuring system stability.
548
277
 
549
278
  ---
550
279
 
551
- ## 📄 Licença
280
+ ## 📄 License
552
281
 
553
- Distribuído sob a licença MIT. Veja `LICENSE` para mais informações.
282
+ This project is distributed under the MIT License. For more details, please refer to the `LICENSE` file.