jerkjs 2.3.0 → 2.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.
- package/CHANGELOG.md +5 -0
- package/README.md +3 -3
- package/index.js +6 -11
- package/jerk.webp +0 -0
- package/package.json +3 -2
- package/README_EN.md +0 -230
- package/README_PT.md +0 -230
- package/jerk-qbuilder/CHANGELOG.md +0 -71
- package/jerk-qbuilder/HOWTO.md +0 -325
- package/jerk-qbuilder/README.md +0 -52
- package/jerk.jpg +0 -0
- package/lib/query/MariaDBAdapter.js +0 -78
- package/lib/query/consoleAdapter.js +0 -184
- package/lib/query/queryBuilder.js +0 -953
- package/lib/query/queryBuilderHooks.js +0 -455
- package/lib/query/queryBuilderMiddleware.js +0 -332
package/jerk-qbuilder/HOWTO.md
DELETED
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
# Cómo usar el QueryBuilder
|
|
2
|
-
|
|
3
|
-
## Introducción
|
|
4
|
-
|
|
5
|
-
El QueryBuilder es una herramienta poderosa para construir consultas SQL de manera segura y eficiente. Este documento explica cómo utilizarlo en diferentes escenarios, incluyendo su integración con middlewares y el sistema de hooks de JERK.
|
|
6
|
-
|
|
7
|
-
## Instalación y configuración
|
|
8
|
-
|
|
9
|
-
### 1. Importar el QueryBuilder
|
|
10
|
-
|
|
11
|
-
```javascript
|
|
12
|
-
const QueryBuilder = require('./path/to/queryBuilder');
|
|
13
|
-
const MariaDBAdapter = require('./path/to/MariaDBAdapter');
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
### 2. Crear un adaptador
|
|
17
|
-
|
|
18
|
-
```javascript
|
|
19
|
-
// Adaptador para MariaDB
|
|
20
|
-
const adapter = new MariaDBAdapter({
|
|
21
|
-
host: 'localhost',
|
|
22
|
-
user: 'root',
|
|
23
|
-
password: '',
|
|
24
|
-
database: 'my_database'
|
|
25
|
-
});
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Uso básico
|
|
29
|
-
|
|
30
|
-
### 1. Crear una instancia del QueryBuilder
|
|
31
|
-
|
|
32
|
-
```javascript
|
|
33
|
-
// Opción 1: Sin adaptador (solo para construir consultas)
|
|
34
|
-
const qb = new QueryBuilder();
|
|
35
|
-
|
|
36
|
-
// Opción 2: Con adaptador (para ejecutar consultas)
|
|
37
|
-
const qb = new QueryBuilder(adapter);
|
|
38
|
-
|
|
39
|
-
// Opción 3: Configurar adaptador después (método setAdapter())
|
|
40
|
-
const qb = new QueryBuilder();
|
|
41
|
-
qb.setAdapter(adapter);
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### 2. Construir una consulta SELECT simple
|
|
45
|
-
|
|
46
|
-
```javascript
|
|
47
|
-
const result = await qb
|
|
48
|
-
.table('users')
|
|
49
|
-
.select('id', 'name', 'email')
|
|
50
|
-
.where('age', '>', 18)
|
|
51
|
-
.orderBy('name', 'ASC')
|
|
52
|
-
.limit(10)
|
|
53
|
-
.get();
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### 3. Usar SELECT *
|
|
57
|
-
|
|
58
|
-
```javascript
|
|
59
|
-
// Para seleccionar todos los campos
|
|
60
|
-
const result = await qb
|
|
61
|
-
.table('users')
|
|
62
|
-
.select('*') // Esto funciona correctamente
|
|
63
|
-
.where('status', 'active')
|
|
64
|
-
.get();
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## Operaciones CRUD
|
|
68
|
-
|
|
69
|
-
### SELECT
|
|
70
|
-
|
|
71
|
-
```javascript
|
|
72
|
-
// Consulta básica
|
|
73
|
-
const users = await qb
|
|
74
|
-
.table('users')
|
|
75
|
-
.select('id', 'name', 'email')
|
|
76
|
-
.where('active', true)
|
|
77
|
-
.get();
|
|
78
|
-
|
|
79
|
-
// Obtener un solo registro
|
|
80
|
-
const user = await qb
|
|
81
|
-
.table('users')
|
|
82
|
-
.select('*')
|
|
83
|
-
.where('id', 1)
|
|
84
|
-
.first();
|
|
85
|
-
|
|
86
|
-
// Consulta con JOIN
|
|
87
|
-
const result = await qb
|
|
88
|
-
.table('users')
|
|
89
|
-
.select('users.name', 'profiles.bio')
|
|
90
|
-
.join('profiles', 'users.id', '=', 'profiles.user_id')
|
|
91
|
-
.where('users.active', true)
|
|
92
|
-
.get();
|
|
93
|
-
|
|
94
|
-
// Consulta con múltiples condiciones
|
|
95
|
-
const result = await qb
|
|
96
|
-
.table('orders')
|
|
97
|
-
.select('*')
|
|
98
|
-
.where('status', 'completed')
|
|
99
|
-
.where('amount', '>', 100)
|
|
100
|
-
.whereBetween('created_at', '2023-01-01', '2023-12-31')
|
|
101
|
-
.get();
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### INSERT
|
|
105
|
-
|
|
106
|
-
```javascript
|
|
107
|
-
const result = await qb
|
|
108
|
-
.table('users')
|
|
109
|
-
.insert({
|
|
110
|
-
name: 'John Doe',
|
|
111
|
-
email: 'john@example.com',
|
|
112
|
-
age: 30
|
|
113
|
-
});
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### UPDATE
|
|
117
|
-
|
|
118
|
-
```javascript
|
|
119
|
-
const affectedRows = await qb
|
|
120
|
-
.table('users')
|
|
121
|
-
.where('id', 1)
|
|
122
|
-
.update({
|
|
123
|
-
name: 'Jane Doe',
|
|
124
|
-
email: 'jane@example.com'
|
|
125
|
-
});
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### DELETE
|
|
129
|
-
|
|
130
|
-
```javascript
|
|
131
|
-
const affectedRows = await qb
|
|
132
|
-
.table('users')
|
|
133
|
-
.where('status', 'inactive')
|
|
134
|
-
.delete();
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
## Condiciones WHERE
|
|
138
|
-
|
|
139
|
-
### WHERE simple
|
|
140
|
-
```javascript
|
|
141
|
-
qb.where('column', 'value')
|
|
142
|
-
qb.where('column', '=', 'value')
|
|
143
|
-
qb.where('column', '>', 18)
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
### WHERE con operadores
|
|
147
|
-
```javascript
|
|
148
|
-
qb.where('age', '>=', 18)
|
|
149
|
-
qb.where('status', '!=', 'inactive')
|
|
150
|
-
qb.where('name', 'LIKE', '%john%')
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### WHERE IN
|
|
154
|
-
```javascript
|
|
155
|
-
qb.whereIn('id', [1, 2, 3, 4])
|
|
156
|
-
qb.whereNotIn('category', ['deleted', 'spam'])
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### WHERE BETWEEN
|
|
160
|
-
```javascript
|
|
161
|
-
qb.whereBetween('age', 18, 65)
|
|
162
|
-
qb.whereNotBetween('amount', 100, 1000)
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### Condiciones complejas
|
|
166
|
-
```javascript
|
|
167
|
-
qb.where(function(qb) {
|
|
168
|
-
qb.where('status', 'active')
|
|
169
|
-
.orWhere('premium', true);
|
|
170
|
-
});
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
## Otras operaciones
|
|
174
|
-
|
|
175
|
-
### Agrupamiento y ordenamiento
|
|
176
|
-
```javascript
|
|
177
|
-
qb.groupBy('category')
|
|
178
|
-
qb.orderBy('created_at', 'DESC')
|
|
179
|
-
qb.orderBy('name', 'ASC')
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### Paginación
|
|
183
|
-
```javascript
|
|
184
|
-
qb.offset(10)
|
|
185
|
-
qb.limit(20)
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
### Funciones de agregación
|
|
189
|
-
```javascript
|
|
190
|
-
// Contar registros
|
|
191
|
-
const count = await qb.table('users').count();
|
|
192
|
-
|
|
193
|
-
// Máximo valor
|
|
194
|
-
const maxAge = await qb.table('users').max('age');
|
|
195
|
-
|
|
196
|
-
// Mínimo valor
|
|
197
|
-
const minAge = await qb.table('users').min('age');
|
|
198
|
-
|
|
199
|
-
// Suma
|
|
200
|
-
const totalAmount = await qb.table('orders').sum('amount');
|
|
201
|
-
|
|
202
|
-
// Promedio
|
|
203
|
-
const avgScore = await qb.table('students').avg('score');
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
## Uso con diferentes adaptadores
|
|
207
|
-
|
|
208
|
-
### 1. Adaptador de MariaDB/MySQL
|
|
209
|
-
```javascript
|
|
210
|
-
const MariaDBAdapter = require('./MariaDBAdapter');
|
|
211
|
-
|
|
212
|
-
const adapter = new MariaDBAdapter({
|
|
213
|
-
host: 'localhost',
|
|
214
|
-
user: 'root',
|
|
215
|
-
password: 'password',
|
|
216
|
-
database: 'myapp'
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
const qb = new QueryBuilder(adapter);
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
### 2. Adaptador de consola (para pruebas)
|
|
223
|
-
```javascript
|
|
224
|
-
const ConsoleAdapter = require('./ConsoleAdapter');
|
|
225
|
-
|
|
226
|
-
const adapter = new ConsoleAdapter();
|
|
227
|
-
const qb = new QueryBuilder(adapter);
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
### 3. Cambiar adaptador dinámicamente
|
|
231
|
-
```javascript
|
|
232
|
-
const qb = new QueryBuilder();
|
|
233
|
-
|
|
234
|
-
// Más tarde en el código
|
|
235
|
-
qb.setAdapter(mariaDBAdapter);
|
|
236
|
-
// Ahora puede ejecutar consultas en la base de datos
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
## Integración con Middleware
|
|
240
|
-
|
|
241
|
-
El QueryBuilder incluye un middleware para inyectar instancias del QueryBuilder en las solicitudes HTTP:
|
|
242
|
-
|
|
243
|
-
```javascript
|
|
244
|
-
const { APIServer } = require('jerkjs');
|
|
245
|
-
const { QueryBuilderMiddleware } = require('./queryBuilderMiddleware');
|
|
246
|
-
const MariaDBAdapter = require('./MariaDBAdapter');
|
|
247
|
-
|
|
248
|
-
const server = new APIServer({ port: 3000 });
|
|
249
|
-
|
|
250
|
-
// Crear middleware
|
|
251
|
-
const qbMiddleware = new QueryBuilderMiddleware();
|
|
252
|
-
const dbAdapter = new MariaDBAdapter(config);
|
|
253
|
-
|
|
254
|
-
// Agregar middleware para inyectar QueryBuilder
|
|
255
|
-
server.use(qbMiddleware.configureWithAdapter(dbAdapter));
|
|
256
|
-
server.use(qbMiddleware.injectQueryBuilder.bind(qbMiddleware));
|
|
257
|
-
|
|
258
|
-
// En un controlador
|
|
259
|
-
app.addRoute('GET', '/users', async (req, res) => {
|
|
260
|
-
const users = await req.queryBuilder('users')
|
|
261
|
-
.select('*')
|
|
262
|
-
.where('active', true)
|
|
263
|
-
.get();
|
|
264
|
-
|
|
265
|
-
res.json(users);
|
|
266
|
-
});
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
## Integración con el sistema de Hooks de JERK
|
|
270
|
-
|
|
271
|
-
Cuando se usa con el framework JERK, el QueryBuilder se puede integrar con el sistema de hooks:
|
|
272
|
-
|
|
273
|
-
```javascript
|
|
274
|
-
const { hooks } = require('jerkjs');
|
|
275
|
-
const { initializeQueryBuilderHooks, extendQueryBuilderWithHooks } = require('./queryBuilderHooks');
|
|
276
|
-
|
|
277
|
-
// Inicializar hooks
|
|
278
|
-
initializeQueryBuilderHooks(hooks);
|
|
279
|
-
extendQueryBuilderWithHooks(QueryBuilder, hooks);
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
## Ejemplo completo
|
|
283
|
-
|
|
284
|
-
```javascript
|
|
285
|
-
const QueryBuilder = require('./queryBuilder');
|
|
286
|
-
const MariaDBAdapter = require('./MariaDBAdapter');
|
|
287
|
-
|
|
288
|
-
// Crear adaptador
|
|
289
|
-
const dbAdapter = new MariaDBAdapter({
|
|
290
|
-
host: 'localhost',
|
|
291
|
-
user: 'root',
|
|
292
|
-
password: '',
|
|
293
|
-
database: 'otrack_db'
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
// Crear QueryBuilder
|
|
297
|
-
const qb = new QueryBuilder(dbAdapter);
|
|
298
|
-
|
|
299
|
-
// Ejemplo de uso: obtener usuarios activos con ciertos criterios
|
|
300
|
-
try {
|
|
301
|
-
const users = await qb
|
|
302
|
-
.table('users')
|
|
303
|
-
.select('id', 'name', 'email', 'created_at')
|
|
304
|
-
.where('status', 'active')
|
|
305
|
-
.where('created_at', '>', '2023-01-01')
|
|
306
|
-
.whereIn('role', ['admin', 'editor'])
|
|
307
|
-
.orderBy('created_at', 'DESC')
|
|
308
|
-
.limit(50)
|
|
309
|
-
.get();
|
|
310
|
-
|
|
311
|
-
console.log(`Encontrados ${users.length} usuarios`);
|
|
312
|
-
} catch (error) {
|
|
313
|
-
console.error('Error en la consulta:', error.message);
|
|
314
|
-
}
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
## Consejos de seguridad
|
|
318
|
-
|
|
319
|
-
1. **Siempre use parámetros**: El QueryBuilder utiliza placeholders (`?`) para prevenir inyección SQL
|
|
320
|
-
2. **Valide entradas**: Aunque el QueryBuilder ayuda con la seguridad, siempre valide y sane las entradas del usuario
|
|
321
|
-
3. **Use setAdapter() cuidadosamente**: Asegúrese de que los adaptadores provengan de fuentes confiables
|
|
322
|
-
|
|
323
|
-
## Resumen
|
|
324
|
-
|
|
325
|
-
El QueryBuilder proporciona una forma segura y fluida de construir consultas SQL. Con su método `setAdapter()`, puede trabajar con cualquier base de datos, y su API intuitiva facilita la creación de consultas complejas. Además, incluye middleware para integración fácil con frameworks web y soporte para el sistema de hooks de JERK.
|
package/jerk-qbuilder/README.md
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# QueryBuilder para JERK Framework
|
|
2
|
-
|
|
3
|
-
## Descripción
|
|
4
|
-
|
|
5
|
-
QueryBuilder es una biblioteca independiente para construir consultas SQL de manera fluida y segura. Está diseñada para trabajar con el framework JERK pero puede utilizarse de forma independiente con cualquier sistema Node.js.
|
|
6
|
-
|
|
7
|
-
## Características
|
|
8
|
-
|
|
9
|
-
- **API fluida**: Construcción intuitiva de consultas SQL
|
|
10
|
-
- **Seguridad**: Prevención de inyección SQL mediante el uso de parámetros
|
|
11
|
-
- **Flexibilidad**: Compatible con múltiples adaptadores de base de datos
|
|
12
|
-
- **Método setAdapter()**: Permite configurar dinámicamente cualquier adaptador
|
|
13
|
-
- **Soporte para múltiples bases de datos**: MariaDB, MySQL, PostgreSQL, SQLite, etc.
|
|
14
|
-
- **Middleware de integración**: Sistema completo para inyectar QueryBuilder en solicitudes HTTP
|
|
15
|
-
- **Integración con hooks**: Compatible con el sistema de hooks y filters de JERK
|
|
16
|
-
|
|
17
|
-
## Componentes
|
|
18
|
-
|
|
19
|
-
- `queryBuilder.js`: El QueryBuilder principal con todos sus métodos
|
|
20
|
-
- `MariaDBAdapter.js`: Adaptador para conexión con bases de datos MariaDB/MySQL
|
|
21
|
-
- `ConsoleAdapter.js`: Adaptador de ejemplo para mostrar consultas por consola
|
|
22
|
-
- `queryBuilderHooks.js`: Sistema de integración con los hooks y filters de JERK
|
|
23
|
-
- `queryBuilderMiddleware.js`: Middleware para integrar el QueryBuilder con el framework
|
|
24
|
-
|
|
25
|
-
## Instalación
|
|
26
|
-
|
|
27
|
-
Simplemente copie los archivos del QueryBuilder a su proyecto y utilice los módulos según sus necesidades.
|
|
28
|
-
|
|
29
|
-
## Uso básico
|
|
30
|
-
|
|
31
|
-
```javascript
|
|
32
|
-
const QueryBuilder = require('./queryBuilder');
|
|
33
|
-
const MariaDBAdapter = require('./MariaDBAdapter');
|
|
34
|
-
|
|
35
|
-
// Crear adaptador
|
|
36
|
-
const adapter = new MariaDBAdapter({
|
|
37
|
-
host: 'localhost',
|
|
38
|
-
user: 'root',
|
|
39
|
-
password: '',
|
|
40
|
-
database: 'my_database'
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// Crear QueryBuilder con adaptador
|
|
44
|
-
const qb = new QueryBuilder(adapter);
|
|
45
|
-
|
|
46
|
-
// Usar el QueryBuilder
|
|
47
|
-
const results = await qb
|
|
48
|
-
.table('users')
|
|
49
|
-
.select('id', 'name', 'email')
|
|
50
|
-
.where('active', true)
|
|
51
|
-
.get();
|
|
52
|
-
```
|
package/jerk.jpg
DELETED
|
Binary file
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Adaptador de MariaDB para el QueryBuilder
|
|
3
|
-
* MariaDBAdapter.js
|
|
4
|
-
*
|
|
5
|
-
* Este adaptador simplemente ejecuta las consultas SQL construidas por el QueryBuilder
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const mariadb = require('mariadb');
|
|
9
|
-
|
|
10
|
-
class MariaDBAdapter {
|
|
11
|
-
/**
|
|
12
|
-
* Constructor del adaptador MariaDB
|
|
13
|
-
* @param {Object} options - Opciones de configuración
|
|
14
|
-
*/
|
|
15
|
-
constructor(options = {}) {
|
|
16
|
-
// Configuración de la conexión a la base de datos
|
|
17
|
-
this.dbConfig = {
|
|
18
|
-
host: options.host || 'localhost',
|
|
19
|
-
user: options.user || 'root',
|
|
20
|
-
password: options.password || '',
|
|
21
|
-
database: options.database || 'otrack_db',
|
|
22
|
-
waitForConnections: options.waitForConnections !== false,
|
|
23
|
-
connectionLimit: options.connectionLimit || 10,
|
|
24
|
-
queueLimit: options.queueLimit || 0,
|
|
25
|
-
acquireTimeout: options.acquireTimeout || 60000,
|
|
26
|
-
timeout: options.timeout || 60000,
|
|
27
|
-
...options
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
// Crear pool de conexiones
|
|
31
|
-
this.pool = mariadb.createPool(this.dbConfig);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Método para ejecutar una consulta SQL
|
|
36
|
-
* @param {string} sql - Consulta SQL construida por el QueryBuilder
|
|
37
|
-
* @param {Array} params - Parámetros de la consulta
|
|
38
|
-
* @returns {Promise<Object>} - Resultado de la consulta
|
|
39
|
-
*/
|
|
40
|
-
async query(sql, params = []) {
|
|
41
|
-
const connection = await this.pool.getConnection();
|
|
42
|
-
try {
|
|
43
|
-
return await connection.query(sql, params);
|
|
44
|
-
} catch (error) {
|
|
45
|
-
throw error;
|
|
46
|
-
} finally {
|
|
47
|
-
connection.release();
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Método para cerrar la conexión
|
|
53
|
-
*/
|
|
54
|
-
async close() {
|
|
55
|
-
try {
|
|
56
|
-
await this.pool.end();
|
|
57
|
-
console.log('Conexión a MariaDB cerrada correctamente');
|
|
58
|
-
} catch (error) {
|
|
59
|
-
console.error('Error al cerrar la conexión a MariaDB:', error.message);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Método para verificar si el adaptador está conectado
|
|
65
|
-
* @returns {Promise<boolean>} - Verdadero si está conectado
|
|
66
|
-
*/
|
|
67
|
-
async isConnected() {
|
|
68
|
-
try {
|
|
69
|
-
const connection = await this.pool.getConnection();
|
|
70
|
-
connection.release();
|
|
71
|
-
return true;
|
|
72
|
-
} catch (error) {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
module.exports = MariaDBAdapter;
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Adaptador de ejemplo para mostrar consultas SQL por consola
|
|
3
|
-
* ConsoleAdapter.js
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
class ConsoleAdapter {
|
|
7
|
-
constructor(options = {}) {
|
|
8
|
-
this.options = options;
|
|
9
|
-
this.queriesExecuted = 0;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Método para ejecutar una consulta
|
|
14
|
-
* @param {string} sql - Consulta SQL
|
|
15
|
-
* @param {Array} params - Parámetros de la consulta
|
|
16
|
-
* @returns {Promise<Object>} - Resultado simulado
|
|
17
|
-
*/
|
|
18
|
-
async query(sql, params = []) {
|
|
19
|
-
this.queriesExecuted++;
|
|
20
|
-
|
|
21
|
-
console.log(`\n--- CONSULTA #${this.queriesExecuted} ---`);
|
|
22
|
-
console.log(`SQL: ${sql}`);
|
|
23
|
-
console.log(`Parámetros:`, params);
|
|
24
|
-
console.log('--- FIN CONSULTA ---\n');
|
|
25
|
-
|
|
26
|
-
// Simular un resultado dependiendo del tipo de consulta
|
|
27
|
-
if (sql.trim().toUpperCase().startsWith('SELECT')) {
|
|
28
|
-
// Para consultas SELECT, devolver un array vacío o con datos simulados
|
|
29
|
-
return [];
|
|
30
|
-
} else if (sql.trim().toUpperCase().startsWith('INSERT')) {
|
|
31
|
-
// Para INSERT, simular un ID insertado
|
|
32
|
-
return { insertId: Math.floor(Math.random() * 10000), affectedRows: 1 };
|
|
33
|
-
} else if (sql.trim().toUpperCase().startsWith('UPDATE') || sql.trim().toUpperCase().startsWith('DELETE')) {
|
|
34
|
-
// Para UPDATE/DELETE, simular filas afectadas
|
|
35
|
-
return { affectedRows: Math.floor(Math.random() * 5) + 1 };
|
|
36
|
-
} else {
|
|
37
|
-
// Para otros tipos de consulta, devolver un objeto vacío
|
|
38
|
-
return {};
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Método para crear un registro
|
|
44
|
-
* @param {string} tableName - Nombre de la tabla
|
|
45
|
-
* @param {Object} data - Datos a insertar
|
|
46
|
-
* @returns {Promise<Object>} - Resultado simulado
|
|
47
|
-
*/
|
|
48
|
-
async create(tableName, data) {
|
|
49
|
-
const columns = Object.keys(data).join(', ');
|
|
50
|
-
const placeholders = Object.keys(data).map(() => '?').join(', ');
|
|
51
|
-
const sql = `INSERT INTO \`${tableName}\` (${columns}) VALUES (${placeholders})`;
|
|
52
|
-
const params = Object.values(data);
|
|
53
|
-
|
|
54
|
-
return await this.query(sql, params);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Método para encontrar registros
|
|
59
|
-
* @param {string} tableName - Nombre de la tabla
|
|
60
|
-
* @param {Object} conditions - Condiciones de búsqueda
|
|
61
|
-
* @param {Object} options - Opciones adicionales
|
|
62
|
-
* @returns {Promise<Array>} - Resultados simulados
|
|
63
|
-
*/
|
|
64
|
-
async find(tableName, conditions, options = {}) {
|
|
65
|
-
let sql = `SELECT * FROM \`${tableName}\``;
|
|
66
|
-
const params = [];
|
|
67
|
-
|
|
68
|
-
if (conditions && Object.keys(conditions).length > 0) {
|
|
69
|
-
const conditionsList = [];
|
|
70
|
-
for (const [key, value] of Object.entries(conditions)) {
|
|
71
|
-
if (value !== undefined && value !== null) {
|
|
72
|
-
conditionsList.push(`${key} = ?`);
|
|
73
|
-
params.push(value);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
if (conditionsList.length > 0) {
|
|
77
|
-
sql += ' WHERE ' + conditionsList.join(' AND ');
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return await this.query(sql, params);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Método para encontrar un solo registro
|
|
86
|
-
* @param {string} tableName - Nombre de la tabla
|
|
87
|
-
* @param {Object} conditions - Condiciones de búsqueda
|
|
88
|
-
* @param {Object} options - Opciones adicionales
|
|
89
|
-
* @returns {Promise<Object|null>} - Resultado simulado o null
|
|
90
|
-
*/
|
|
91
|
-
async findOne(tableName, conditions, options = {}) {
|
|
92
|
-
const results = await this.find(tableName, conditions, { ...options, limit: 1 });
|
|
93
|
-
return results.length > 0 ? results[0] : null;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Método para actualizar registros
|
|
98
|
-
* @param {string} tableName - Nombre de la tabla
|
|
99
|
-
* @param {Object} conditions - Condiciones para seleccionar registros
|
|
100
|
-
* @param {Object} data - Datos a actualizar
|
|
101
|
-
* @returns {Promise<number>} - Número de filas afectadas simuladas
|
|
102
|
-
*/
|
|
103
|
-
async update(tableName, conditions, data) {
|
|
104
|
-
const dataEntries = Object.entries(data);
|
|
105
|
-
if (dataEntries.length === 0) {
|
|
106
|
-
return 0;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const setClause = dataEntries.map(([key]) => `${key} = ?`).join(', ');
|
|
110
|
-
const params = dataEntries.map(([, value]) => value);
|
|
111
|
-
|
|
112
|
-
const whereClause = [];
|
|
113
|
-
for (const [key, value] of Object.entries(conditions)) {
|
|
114
|
-
if (value !== undefined && value !== null) {
|
|
115
|
-
whereClause.push(`${key} = ?`);
|
|
116
|
-
params.push(value);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
let sql = `UPDATE \`${tableName}\` SET ${setClause}`;
|
|
121
|
-
if (whereClause.length > 0) {
|
|
122
|
-
sql += ' WHERE ' + whereClause.join(' AND ');
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const result = await this.query(sql, params);
|
|
126
|
-
return result.affectedRows || 0;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Método para eliminar registros
|
|
131
|
-
* @param {string} tableName - Nombre de la tabla
|
|
132
|
-
* @param {Object} conditions - Condiciones para seleccionar registros
|
|
133
|
-
* @returns {Promise<number>} - Número de filas afectadas simuladas
|
|
134
|
-
*/
|
|
135
|
-
async delete(tableName, conditions) {
|
|
136
|
-
let sql = `DELETE FROM \`${tableName}\``;
|
|
137
|
-
const params = [];
|
|
138
|
-
|
|
139
|
-
if (conditions && Object.keys(conditions).length > 0) {
|
|
140
|
-
const conditionsList = [];
|
|
141
|
-
for (const [key, value] of Object.entries(conditions)) {
|
|
142
|
-
if (value !== undefined && value !== null) {
|
|
143
|
-
conditionsList.push(`${key} = ?`);
|
|
144
|
-
params.push(value);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
if (conditionsList.length > 0) {
|
|
148
|
-
sql += ' WHERE ' + conditionsList.join(' AND ');
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const result = await this.query(sql, params);
|
|
153
|
-
return result.affectedRows || 0;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Método para contar registros
|
|
158
|
-
* @param {string} tableName - Nombre de la tabla
|
|
159
|
-
* @param {Object} conditions - Condiciones de conteo
|
|
160
|
-
* @returns {Promise<number>} - Número simulado de registros
|
|
161
|
-
*/
|
|
162
|
-
async count(tableName, conditions) {
|
|
163
|
-
let sql = `SELECT COUNT(*) as total FROM \`${tableName}\``;
|
|
164
|
-
const params = [];
|
|
165
|
-
|
|
166
|
-
if (conditions && Object.keys(conditions).length > 0) {
|
|
167
|
-
const conditionsList = [];
|
|
168
|
-
for (const [key, value] of Object.entries(conditions)) {
|
|
169
|
-
if (value !== undefined && value !== null) {
|
|
170
|
-
conditionsList.push(`${key} = ?`);
|
|
171
|
-
params.push(value);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
if (conditionsList.length > 0) {
|
|
175
|
-
sql += ' WHERE ' + conditionsList.join(' AND ');
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const result = await this.query(sql, params);
|
|
180
|
-
return result[0] ? result[0].total : 0;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
module.exports = ConsoleAdapter;
|