@medyll/idae-db 0.149.0 → 0.155.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +336 -177
- package/cli.js +46 -0
- package/dist/@types/pg.d.ts +1 -0
- package/dist/@types/types.d.ts +4 -1
- package/dist/@types/types.js +3 -0
- package/dist/IdaeDbAdapter.js +6 -0
- package/dist/adapters/MongoDBAdapter.d.ts +3 -3
- package/dist/adapters/PostgreSQLAdapter.d.ts +22 -0
- package/dist/adapters/PostgreSQLAdapter.js +127 -0
- package/dist/adapters/PouchDBAdapter.d.ts +14 -0
- package/dist/adapters/PouchDBAdapter.js +62 -0
- package/dist/adapters/SQLiteAdapter.d.ts +17 -0
- package/dist/adapters/SQLiteAdapter.js +113 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +5 -2
- package/package.json +28 -5
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024 medyll
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 medyll
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,178 +1,337 @@
|
|
|
1
|
-
# Idae Database Library
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
###
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
1
|
+
# Idae Database Library
|
|
2
|
+
|
|
3
|
+
**Idae Database Library** is a flexible, type-safe, event-driven database abstraction for Node.js and TypeScript. It supports MongoDB, MySQL, ChromaDB, PouchDB, SQLite, and PostgreSQL with a unified API, event hooks, and singleton connection management.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Multi-Database Support:** MongoDB, MySQL, ChromaDB, PouchDB, SQLite, PostgreSQL
|
|
8
|
+
- **Event-driven CRUD:** Pre/post/error hooks on all operations
|
|
9
|
+
- **Type Safety:** Full TypeScript generics, strict mode
|
|
10
|
+
- **Singleton Pattern:** One connection per URI+DbType
|
|
11
|
+
- **Adapter Pattern:** Easily extend to new databases
|
|
12
|
+
- **Auto-increment:** Native for MongoDB, extensible for others
|
|
13
|
+
- **Transaction Support:** Native in MongoDB/MySQL
|
|
14
|
+
|
|
15
|
+
## Supported Adapters
|
|
16
|
+
|
|
17
|
+
| DbType | Adapter Class | Peer Dependency |
|
|
18
|
+
|-------------- |----------------------|-----------------|
|
|
19
|
+
| MONGODB | MongoDBAdapter | mongodb |
|
|
20
|
+
| MYSQL | MySQLAdapter | mysql2 |
|
|
21
|
+
| CHROMADB | ChromaDBAdapter | chromadb |
|
|
22
|
+
| POUCHDB | PouchDBAdapter | pouchdb |
|
|
23
|
+
| SQLITE | SQLiteAdapter | sqlite3 |
|
|
24
|
+
| POSTGRESQL | PostgreSQLAdapter | pg |
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
Install the core library and the peer dependencies for your database(s):
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pnpm add @medyll/idae-db
|
|
32
|
+
# For MongoDB:
|
|
33
|
+
pnpm add mongodb
|
|
34
|
+
# For MySQL:
|
|
35
|
+
pnpm add mysql2
|
|
36
|
+
# For ChromaDB:
|
|
37
|
+
pnpm add chromadb
|
|
38
|
+
# For PouchDB:
|
|
39
|
+
pnpm add pouchdb
|
|
40
|
+
# For SQLite:
|
|
41
|
+
pnpm add sqlite3
|
|
42
|
+
# For PostgreSQL:
|
|
43
|
+
pnpm add pg
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Quick Start
|
|
47
|
+
|
|
48
|
+
### 1. Initialize a Database
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { IdaeDb } from '@medyll/idae-db';
|
|
52
|
+
import { DbType } from '@medyll/idae-db/lib/@types/types';
|
|
53
|
+
|
|
54
|
+
const db = IdaeDb.init('mongodb://localhost:27017', {
|
|
55
|
+
dbType: DbType.MONGODB,
|
|
56
|
+
dbScope: 'app',
|
|
57
|
+
});
|
|
58
|
+
await db.db('app');
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 2. Define a Model
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
interface User {
|
|
65
|
+
iduser: number;
|
|
66
|
+
name: string;
|
|
67
|
+
email: string;
|
|
68
|
+
age: number;
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 3. CRUD Operations
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
const users = db.collection<User>('user');
|
|
76
|
+
const newUser = await users.create({ name: 'Alice', email: 'alice@example.com', age: 25 });
|
|
77
|
+
const found = await users.findOne({ query: { email: 'alice@example.com' } });
|
|
78
|
+
await users.update(found.iduser, { age: 26 });
|
|
79
|
+
await users.deleteById(found.iduser);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 4. Event Hooks
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
users.registerEvents({
|
|
86
|
+
create: {
|
|
87
|
+
pre: (data) => console.log('Creating:', data),
|
|
88
|
+
post: (result, data) => console.log('Created:', result),
|
|
89
|
+
error: (err) => console.error(err)
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Adapter Usage Examples
|
|
95
|
+
|
|
96
|
+
### MongoDB
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
const mongoDb = IdaeDb.init('mongodb://localhost:27017', { dbType: DbType.MONGODB });
|
|
100
|
+
await mongoDb.db('app');
|
|
101
|
+
const users = mongoDb.collection<User>('user');
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### MySQL
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
const mysqlDb = IdaeDb.init('mysql://user:password@localhost:3306', { dbType: DbType.MYSQL });
|
|
108
|
+
await mysqlDb.db('app');
|
|
109
|
+
const users = mysqlDb.collection<User>('user');
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### ChromaDB
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
const chromaDb = IdaeDb.init('chromadb://localhost:8000', { dbType: DbType.CHROMADB });
|
|
116
|
+
await chromaDb.db('app');
|
|
117
|
+
const items = chromaDb.collection<any>('item');
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### PouchDB
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
const pouchDb = IdaeDb.init('pouchdb://./my-pouchdb-folder', { dbType: DbType.POUCHDB });
|
|
124
|
+
await pouchDb.db('app');
|
|
125
|
+
const docs = pouchDb.collection<any>('doc');
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### SQLite
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
const sqliteDb = IdaeDb.init('sqlite://./mydb.sqlite', { dbType: DbType.SQLITE });
|
|
132
|
+
await sqliteDb.db('app');
|
|
133
|
+
const users = sqliteDb.collection<User>('user');
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### PostgreSQL
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
const pgDb = IdaeDb.init('postgresql://user:password@localhost:5432/mydb', { dbType: DbType.POSTGRESQL });
|
|
140
|
+
await pgDb.db('app');
|
|
141
|
+
const users = pgDb.collection<User>('user');
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Event System
|
|
145
|
+
|
|
146
|
+
All CRUD methods emit `pre:method`, `post:method`, and `error:method` events. Register listeners with `registerEvents`:
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
users.registerEvents({
|
|
150
|
+
create: {
|
|
151
|
+
pre: (data) => console.log('Creating:', data),
|
|
152
|
+
post: (result, data) => console.log('Created:', result),
|
|
153
|
+
error: (err) => console.error(err)
|
|
154
|
+
},
|
|
155
|
+
update: {
|
|
156
|
+
pre: (id, data) => console.log('Updating:', id, data),
|
|
157
|
+
post: (result, id, data) => console.log('Updated:', result),
|
|
158
|
+
error: (err) => console.error(err)
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Type Safety
|
|
164
|
+
|
|
165
|
+
- All models are fully typed (`T extends object`)
|
|
166
|
+
- Query params: `IdaeDbParams<T>`
|
|
167
|
+
- MongoDB filters: use `Filter<T>`
|
|
168
|
+
- ID field: MongoDB uses `_id` or custom via `autoIncrementFormat`
|
|
169
|
+
|
|
170
|
+
## Singleton & Connection Management
|
|
171
|
+
|
|
172
|
+
- One instance per URI+DbType
|
|
173
|
+
- Use `.closeAllConnections()` to gracefully close all DBs:
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
await db.closeAllConnections();
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Scripts
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
pnpm run test # Run all tests
|
|
183
|
+
pnpm run build # Build the package
|
|
184
|
+
pnpm run lint # Lint code
|
|
185
|
+
pnpm run format # Format code
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## License
|
|
189
|
+
|
|
190
|
+
MIT License
|
|
191
|
+
import { DbType } from './lib/@types/types.js';
|
|
192
|
+
|
|
193
|
+
const pouchDb = IdaeDb.init('pouchdb://./my-pouchdb-folder', {
|
|
194
|
+
dbType: DbType.POUCHDB
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
#### SQLite
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
import { IdaeDb } from './lib/idaeDb.js';
|
|
202
|
+
import { DbType } from './lib/@types/types.js';
|
|
203
|
+
|
|
204
|
+
const sqliteDb = IdaeDb.init('sqlite://./mydb.sqlite', {
|
|
205
|
+
dbType: DbType.SQLITE
|
|
206
|
+
});
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
#### PostgreSQL
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
import { IdaeDb } from './lib/idaeDb.js';
|
|
213
|
+
import { DbType } from './lib/@types/types.js';
|
|
214
|
+
|
|
215
|
+
const pgDb = IdaeDb.init('postgresql://user:password@localhost:5432/mydb', {
|
|
216
|
+
dbType: DbType.POSTGRESQL
|
|
217
|
+
});
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Create a Connection
|
|
221
|
+
|
|
222
|
+
Create a connection to the database:
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
await mongoDb.db('app');
|
|
226
|
+
await mysqlDb.db('app');
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Define a Model
|
|
230
|
+
|
|
231
|
+
Define a model interface:
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
interface User {
|
|
235
|
+
iduser: number;
|
|
236
|
+
name: string;
|
|
237
|
+
email: string;
|
|
238
|
+
age: number;
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Register Event Listeners
|
|
243
|
+
|
|
244
|
+
Register event listeners for various operations:
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
const usersCollection = mongoDb.collection<User>('user');
|
|
248
|
+
|
|
249
|
+
usersCollection.registerEvents<any>({
|
|
250
|
+
findById: {
|
|
251
|
+
pre: (id) => console.log(`About to find document with id: ${id}`),
|
|
252
|
+
post: (result, id) => console.log(`Found document for id ${id}:`, result),
|
|
253
|
+
error: (error) => console.error('Error in findById:', error)
|
|
254
|
+
},
|
|
255
|
+
update: {
|
|
256
|
+
pre: (id, data) => console.log(`About to update document ${id} with:`, data),
|
|
257
|
+
post: (result, id, data) => console.log(`Updated document ${id}:`, result)
|
|
258
|
+
},
|
|
259
|
+
create: {
|
|
260
|
+
pre: (data) => console.log(`About to create document with:`, data),
|
|
261
|
+
post: (data, result) => console.log(`Created document `, data, result)
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### CRUD Operations
|
|
267
|
+
|
|
268
|
+
Perform CRUD operations:
|
|
269
|
+
|
|
270
|
+
#### MongoDB
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
// Create a new user
|
|
274
|
+
const newUser = await usersCollection.create({
|
|
275
|
+
name: 'John Doe',
|
|
276
|
+
email: 'john@example.com',
|
|
277
|
+
age: 30
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// Find a user by email
|
|
281
|
+
const user = await usersCollection.findOne({ query: { email: 'john@example.com' } });
|
|
282
|
+
|
|
283
|
+
// Update a user's age
|
|
284
|
+
const updateResult = await usersCollection.update(user.iduser, { age: 31 });
|
|
285
|
+
|
|
286
|
+
// Find users with age greater than 25
|
|
287
|
+
const users = await usersCollection.find({
|
|
288
|
+
query: { age: { $gt: 25 } },
|
|
289
|
+
sortBy: 'name:asc',
|
|
290
|
+
limit: 10
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
// Delete a user by ID
|
|
294
|
+
const deleteResult = await usersCollection.deleteById(5);
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
#### MySQL
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
const usersCollection = mysqlDb.collection<User>('user');
|
|
301
|
+
|
|
302
|
+
// Create a new user
|
|
303
|
+
const newUser = await usersCollection.create({
|
|
304
|
+
name: 'John Doe',
|
|
305
|
+
email: 'john@example.com',
|
|
306
|
+
age: 30
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
// Find a user by email
|
|
310
|
+
const user = await usersCollection.findOne({ query: { email: 'john@example.com' } });
|
|
311
|
+
|
|
312
|
+
// Update a user's age
|
|
313
|
+
const updateResult = await usersCollection.update(user.iduser, { age: 31 });
|
|
314
|
+
|
|
315
|
+
// Find users with age greater than 25
|
|
316
|
+
const users = await usersCollection.find({
|
|
317
|
+
query: { age: { $gt: 25 } },
|
|
318
|
+
sortBy: 'name:asc',
|
|
319
|
+
limit: 10
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
// Delete a user by ID
|
|
323
|
+
const deleteResult = await usersCollection.deleteById(5);
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Close Connections
|
|
327
|
+
|
|
328
|
+
Close all connections when done:
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
await mongoDb.closeAllConnections();
|
|
332
|
+
await mysqlDb.closeAllConnections();
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## License
|
|
336
|
+
|
|
178
337
|
This project is licensed under the MIT License.
|
package/cli.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const pkgJson = require(path.join(__dirname, 'package.json'));
|
|
8
|
+
const packageName = pkgJson.name.replace(/^@[^/]+\//, '');
|
|
9
|
+
const cmd = process.argv[2];
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
if (cmd === 'get-readme') {
|
|
13
|
+
const readmePath = path.join(__dirname, 'README.md');
|
|
14
|
+
if (fs.existsSync(readmePath)) {
|
|
15
|
+
const content = fs.readFileSync(readmePath, 'utf8');
|
|
16
|
+
console.log(content);
|
|
17
|
+
} else {
|
|
18
|
+
console.error('README.md not found in this package.');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
} else if (cmd === 'install-skill') {
|
|
22
|
+
const readline = require('readline');
|
|
23
|
+
const rl = readline.createInterface({
|
|
24
|
+
input: process.stdin,
|
|
25
|
+
output: process.stdout
|
|
26
|
+
});
|
|
27
|
+
const skillSrc = path.join(__dirname, 'SKILL.md');
|
|
28
|
+
const skillDest = path.resolve(__dirname, `../../../.github/skills/${packageName}/SKILL.md`);
|
|
29
|
+
if (!fs.existsSync(skillSrc)) {
|
|
30
|
+
console.error('SKILL.md not found in this package.');
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
rl.question(`This will copy SKILL.md to .github/skills/${packageName}/SKILL.md. Continue? (y/n): `, (answer) => {
|
|
34
|
+
if (answer.trim().toLowerCase() === 'y' || answer.trim().toLowerCase() === 'yes') {
|
|
35
|
+
fs.mkdirSync(path.dirname(skillDest), { recursive: true });
|
|
36
|
+
fs.copyFileSync(skillSrc, skillDest);
|
|
37
|
+
console.log(`SKILL.md installed to .github/skills/${packageName}/SKILL.md`);
|
|
38
|
+
} else {
|
|
39
|
+
console.log('Operation cancelled.');
|
|
40
|
+
}
|
|
41
|
+
rl.close();
|
|
42
|
+
});
|
|
43
|
+
} else {
|
|
44
|
+
console.log('Usage: <cli> get-readme | install-skill');
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module 'pg';
|
package/dist/@types/types.d.ts
CHANGED
|
@@ -33,7 +33,10 @@ export interface IdaeDbParamsSortOptions {
|
|
|
33
33
|
export declare enum DbType {
|
|
34
34
|
MONGODB = "mongodb",
|
|
35
35
|
MYSQL = "mysql",
|
|
36
|
-
CHROMADB = "chromaDb"
|
|
36
|
+
CHROMADB = "chromaDb",
|
|
37
|
+
POUCHDB = "pouchdb",
|
|
38
|
+
SQLITE = "sqlite",
|
|
39
|
+
POSTGRESQL = "postgresql"
|
|
37
40
|
}
|
|
38
41
|
export declare abstract class AbstractIdaeDbAdapter<T extends object> implements IdaeDbAdapterInterface<T> {
|
|
39
42
|
abstract createIndex(fieldOrSpec: unknown, options?: unknown): Promise<string>;
|
package/dist/@types/types.js
CHANGED
|
@@ -5,6 +5,9 @@ export var DbType;
|
|
|
5
5
|
DbType["MONGODB"] = "mongodb";
|
|
6
6
|
DbType["MYSQL"] = "mysql";
|
|
7
7
|
DbType["CHROMADB"] = "chromaDb";
|
|
8
|
+
DbType["POUCHDB"] = "pouchdb";
|
|
9
|
+
DbType["SQLITE"] = "sqlite";
|
|
10
|
+
DbType["POSTGRESQL"] = "postgresql";
|
|
8
11
|
})(DbType || (DbType = {}));
|
|
9
12
|
export class AbstractIdaeDbAdapter {
|
|
10
13
|
static connect(uri) {
|
package/dist/IdaeDbAdapter.js
CHANGED
|
@@ -14,6 +14,9 @@ import { IdaeDbConnection } from './IdaeDbConnection.js';
|
|
|
14
14
|
import { MongoDBAdapter } from './adapters/MongoDBAdapter.js';
|
|
15
15
|
import { MySQLAdapter } from './adapters/MySQLAdapter.js';
|
|
16
16
|
import { ChromaDBAdapter } from './adapters/ChromaDBAdapter.js';
|
|
17
|
+
import { PouchDBAdapter } from './adapters/PouchDBAdapter.js';
|
|
18
|
+
import { SQLiteAdapter } from './adapters/SQLiteAdapter.js';
|
|
19
|
+
import { PostgreSQLAdapter } from './adapters/PostgreSQLAdapter.js';
|
|
17
20
|
import { IdaeEventEmitter, withEmitter } from './IdaeEventEmitter.js';
|
|
18
21
|
/**
|
|
19
22
|
* IdaeDbAdapter class that extends IdaeEventEmitter and implements AbstractIdaeDbAdapter.
|
|
@@ -26,6 +29,9 @@ export class IdaeDbAdapter extends IdaeEventEmitter {
|
|
|
26
29
|
IdaeDbAdapter.addAdapter(DbType.MONGODB, MongoDBAdapter);
|
|
27
30
|
IdaeDbAdapter.addAdapter(DbType.MYSQL, MySQLAdapter);
|
|
28
31
|
IdaeDbAdapter.addAdapter(DbType.CHROMADB, ChromaDBAdapter);
|
|
32
|
+
IdaeDbAdapter.addAdapter(DbType.POUCHDB, PouchDBAdapter);
|
|
33
|
+
IdaeDbAdapter.addAdapter(DbType.SQLITE, SQLiteAdapter);
|
|
34
|
+
IdaeDbAdapter.addAdapter(DbType.POSTGRESQL, PostgreSQLAdapter);
|
|
29
35
|
}
|
|
30
36
|
/**
|
|
31
37
|
* Adds a new adapter for a specific database type.
|
|
@@ -14,9 +14,9 @@ export declare class MongoDBAdapter<T extends Document> implements AbstractIdaeD
|
|
|
14
14
|
find(params: IdaeDbParams<T>): Promise<T[]>;
|
|
15
15
|
findOne(params: IdaeDbParams<T>): Promise<T | null>;
|
|
16
16
|
create(data: Partial<T>): Promise<T>;
|
|
17
|
-
update(id: string, updateData: Partial<T>, options?: UpdateOptions): Promise<
|
|
18
|
-
updateWhere<OPT = never>(params: IdaeDbParams<T>, updateData: Partial<T>, options?: OPT): Promise<
|
|
19
|
-
deleteById(id: string | number): Promise<
|
|
17
|
+
update(id: string, updateData: Partial<T>, options?: UpdateOptions): Promise<import("mongodb").UpdateResult<T>>;
|
|
18
|
+
updateWhere<OPT = never>(params: IdaeDbParams<T>, updateData: Partial<T>, options?: OPT): Promise<import("mongodb").UpdateResult<T>>;
|
|
19
|
+
deleteById(id: string | number): Promise<import("mongodb").DeleteResult>;
|
|
20
20
|
deleteWhere(params: IdaeDbParams<T>): Promise<{
|
|
21
21
|
deletedCount?: number;
|
|
22
22
|
}>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { IdaeDbAdapterInterface, IdaeDbParams } from '../@types/types';
|
|
2
|
+
export declare class PostgreSQLAdapter<T extends object> implements IdaeDbAdapterInterface<T> {
|
|
3
|
+
private client;
|
|
4
|
+
private table;
|
|
5
|
+
private idField;
|
|
6
|
+
constructor(collection: string, connection: any);
|
|
7
|
+
static connect(uri: string, options?: any): Promise<any>;
|
|
8
|
+
static getDb(connection: any, dbName: string): Promise<any>;
|
|
9
|
+
static close(connection: any): Promise<void>;
|
|
10
|
+
create(data: Partial<T>): Promise<T>;
|
|
11
|
+
find(params?: IdaeDbParams<T>): Promise<T[]>;
|
|
12
|
+
findOne(params: IdaeDbParams<T>): Promise<T | null>;
|
|
13
|
+
update(id: string, data: Partial<T>): Promise<T | null>;
|
|
14
|
+
deleteById(id: string): Promise<boolean>;
|
|
15
|
+
transaction<TResult>(callback: (session: unknown) => Promise<TResult>): Promise<TResult>;
|
|
16
|
+
createIndex<F, O>(fieldOrSpec: F, options?: O): Promise<unknown>;
|
|
17
|
+
findById(id: string): Promise<T[]>;
|
|
18
|
+
updateWhere<OPT = never>(params: IdaeDbParams<T>, updateData: Partial<T>, options?: OPT): Promise<unknown>;
|
|
19
|
+
deleteWhere(params: IdaeDbParams<T>): Promise<{
|
|
20
|
+
deletedCount?: number;
|
|
21
|
+
}>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { Client } from 'pg';
|
|
2
|
+
export class PostgreSQLAdapter {
|
|
3
|
+
client;
|
|
4
|
+
table;
|
|
5
|
+
idField;
|
|
6
|
+
constructor(collection, connection) {
|
|
7
|
+
// connection est un IdaeDbConnection, on récupère la vraie connexion
|
|
8
|
+
this.client = connection.getDb();
|
|
9
|
+
this.table = collection;
|
|
10
|
+
this.idField = 'id';
|
|
11
|
+
}
|
|
12
|
+
static async connect(uri, options) {
|
|
13
|
+
const client = new Client({ connectionString: uri, ...options });
|
|
14
|
+
await client.connect();
|
|
15
|
+
return client;
|
|
16
|
+
}
|
|
17
|
+
static async getDb(connection, dbName) {
|
|
18
|
+
// PostgreSQL: pas de notion de dbName, retourne la connexion
|
|
19
|
+
return connection;
|
|
20
|
+
}
|
|
21
|
+
static async close(connection) {
|
|
22
|
+
await connection.end();
|
|
23
|
+
}
|
|
24
|
+
async create(data) {
|
|
25
|
+
const keys = Object.keys(data);
|
|
26
|
+
const values = keys.map((k) => data[k]);
|
|
27
|
+
const placeholders = keys.map((_, i) => `$${i + 1}`).join(',');
|
|
28
|
+
const sql = `INSERT INTO ${this.table} (${keys.join(',')}) VALUES (${placeholders}) RETURNING *`;
|
|
29
|
+
const result = await this.client.query(sql, values);
|
|
30
|
+
return result.rows[0];
|
|
31
|
+
}
|
|
32
|
+
async find(params) {
|
|
33
|
+
const { query = {}, limit, sortBy } = params || {};
|
|
34
|
+
let sql = `SELECT * FROM ${this.table}`;
|
|
35
|
+
const where = [];
|
|
36
|
+
const values = [];
|
|
37
|
+
let idx = 1;
|
|
38
|
+
for (const k in query) {
|
|
39
|
+
where.push(`${k} = $${idx}`);
|
|
40
|
+
values.push(query[k]);
|
|
41
|
+
idx++;
|
|
42
|
+
}
|
|
43
|
+
if (where.length)
|
|
44
|
+
sql += ' WHERE ' + where.join(' AND ');
|
|
45
|
+
if (sortBy)
|
|
46
|
+
sql += ` ORDER BY ${sortBy}`;
|
|
47
|
+
if (limit)
|
|
48
|
+
sql += ` LIMIT ${limit}`;
|
|
49
|
+
const result = await this.client.query(sql, values);
|
|
50
|
+
return result.rows;
|
|
51
|
+
}
|
|
52
|
+
async findOne(params) {
|
|
53
|
+
const results = await this.find({ ...params, limit: 1 });
|
|
54
|
+
return results[0] || null;
|
|
55
|
+
}
|
|
56
|
+
async update(id, data) {
|
|
57
|
+
const keys = Object.keys(data);
|
|
58
|
+
const values = keys.map((k) => data[k]);
|
|
59
|
+
const set = keys.map((k, i) => `${k} = $${i + 1}`).join(', ');
|
|
60
|
+
const sql = `UPDATE ${this.table} SET ${set} WHERE ${this.idField} = $${keys.length + 1} RETURNING *`;
|
|
61
|
+
const result = await this.client.query(sql, [...values, id]);
|
|
62
|
+
return result.rows[0];
|
|
63
|
+
}
|
|
64
|
+
async deleteById(id) {
|
|
65
|
+
const sql = `DELETE FROM ${this.table} WHERE ${this.idField} = $1`;
|
|
66
|
+
const result = await this.client.query(sql, [id]);
|
|
67
|
+
return result.rowCount > 0;
|
|
68
|
+
}
|
|
69
|
+
async transaction(callback) {
|
|
70
|
+
await this.client.query('BEGIN');
|
|
71
|
+
try {
|
|
72
|
+
// PostgreSQL n'expose pas de session explicite, on passe undefined
|
|
73
|
+
const result = await callback(undefined);
|
|
74
|
+
await this.client.query('COMMIT');
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
await this.client.query('ROLLBACK');
|
|
79
|
+
throw e;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async createIndex(fieldOrSpec, options) {
|
|
83
|
+
// Not implemented for PostgreSQL (no-op)
|
|
84
|
+
return Promise.resolve();
|
|
85
|
+
}
|
|
86
|
+
async findById(id) {
|
|
87
|
+
const sql = `SELECT * FROM ${this.table} WHERE ${this.idField} = $1`;
|
|
88
|
+
const result = await this.client.query(sql, [id]);
|
|
89
|
+
return result.rows;
|
|
90
|
+
}
|
|
91
|
+
async updateWhere(params, updateData, options) {
|
|
92
|
+
// Simple implementation: update all matching rows
|
|
93
|
+
const { query = {} } = params;
|
|
94
|
+
const keys = Object.keys(updateData);
|
|
95
|
+
const values = keys.map((k) => updateData[k]);
|
|
96
|
+
const set = keys.map((k, i) => `${k} = $${i + 1}`).join(', ');
|
|
97
|
+
const where = [];
|
|
98
|
+
const whereValues = [];
|
|
99
|
+
let idx = keys.length + 1;
|
|
100
|
+
for (const k in query) {
|
|
101
|
+
where.push(`${k} = $${idx}`);
|
|
102
|
+
whereValues.push(query[k]);
|
|
103
|
+
idx++;
|
|
104
|
+
}
|
|
105
|
+
let sql = `UPDATE ${this.table} SET ${set}`;
|
|
106
|
+
if (where.length)
|
|
107
|
+
sql += ' WHERE ' + where.join(' AND ');
|
|
108
|
+
const result = await this.client.query(sql, [...values, ...whereValues]);
|
|
109
|
+
return { rowCount: result.rowCount };
|
|
110
|
+
}
|
|
111
|
+
async deleteWhere(params) {
|
|
112
|
+
const { query = {} } = params;
|
|
113
|
+
const where = [];
|
|
114
|
+
const values = [];
|
|
115
|
+
let idx = 1;
|
|
116
|
+
for (const k in query) {
|
|
117
|
+
where.push(`${k} = $${idx}`);
|
|
118
|
+
values.push(query[k]);
|
|
119
|
+
idx++;
|
|
120
|
+
}
|
|
121
|
+
let sql = `DELETE FROM ${this.table}`;
|
|
122
|
+
if (where.length)
|
|
123
|
+
sql += ' WHERE ' + where.join(' AND ');
|
|
124
|
+
const result = await this.client.query(sql, values);
|
|
125
|
+
return { deletedCount: result.rowCount };
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { IdaiDbAdapterInterface, IdaeDbParams } from '../@types/types';
|
|
2
|
+
export declare class PouchDBAdapter<T extends object> implements IdaiDbAdapterInterface<T> {
|
|
3
|
+
private db;
|
|
4
|
+
constructor(collection: string, connection: any);
|
|
5
|
+
static connect(uri: string, options?: any): Promise<any>;
|
|
6
|
+
static getDb(connection: any, dbName: string): Promise<any>;
|
|
7
|
+
static close(connection: any): Promise<void>;
|
|
8
|
+
create(data: Partial<T>): Promise<T>;
|
|
9
|
+
find(params?: IdaeDbParams<T>): Promise<T[]>;
|
|
10
|
+
findOne(params: IdaeDbParams<T>): Promise<T | null>;
|
|
11
|
+
update(id: string, data: Partial<T>): Promise<T | null>;
|
|
12
|
+
deleteById(id: string): Promise<boolean>;
|
|
13
|
+
transaction(fn: () => Promise<any>): Promise<any>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import PouchDB from 'pouchdb';
|
|
2
|
+
export class PouchDBAdapter {
|
|
3
|
+
db;
|
|
4
|
+
constructor(collection, connection) {
|
|
5
|
+
// connection est un IdaeDbConnection, on récupère la vraie connexion
|
|
6
|
+
this.db = connection.getDb();
|
|
7
|
+
}
|
|
8
|
+
static async connect(uri, options) {
|
|
9
|
+
// uri: pouchdb://./folder or pouchdb://memory
|
|
10
|
+
let dbPath = uri.replace(/^pouchdb:\/\//, '');
|
|
11
|
+
if (!dbPath)
|
|
12
|
+
dbPath = 'idae-pouchdb';
|
|
13
|
+
return new PouchDB(dbPath, options);
|
|
14
|
+
}
|
|
15
|
+
static async getDb(connection, dbName) {
|
|
16
|
+
// PouchDB does not use dbName, just return the connection
|
|
17
|
+
return connection;
|
|
18
|
+
}
|
|
19
|
+
static async close(connection) {
|
|
20
|
+
await connection.close();
|
|
21
|
+
}
|
|
22
|
+
async create(data) {
|
|
23
|
+
const doc = { ...data };
|
|
24
|
+
const result = await this.db.post(doc);
|
|
25
|
+
return { ...doc, _id: result.id, _rev: result.rev };
|
|
26
|
+
}
|
|
27
|
+
async find(params) {
|
|
28
|
+
// Only supports simple query for now
|
|
29
|
+
const { query = {}, limit, sortBy } = params || {};
|
|
30
|
+
const result = await this.db.find({ selector: query, limit });
|
|
31
|
+
return result.docs;
|
|
32
|
+
}
|
|
33
|
+
async findOne(params) {
|
|
34
|
+
const docs = await this.find({ ...params, limit: 1 });
|
|
35
|
+
return docs[0] || null;
|
|
36
|
+
}
|
|
37
|
+
async update(id, data) {
|
|
38
|
+
try {
|
|
39
|
+
const doc = await this.db.get(id);
|
|
40
|
+
const updated = { ...doc, ...data };
|
|
41
|
+
const result = await this.db.put(updated);
|
|
42
|
+
return { ...updated, _rev: result.rev };
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async deleteById(id) {
|
|
49
|
+
try {
|
|
50
|
+
const doc = await this.db.get(id);
|
|
51
|
+
await this.db.remove(doc);
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async transaction(fn) {
|
|
59
|
+
// PouchDB natively does not support transactions
|
|
60
|
+
return fn();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IdaiDbAdapterInterface, IdaeDbParams } from '../@types/types';
|
|
2
|
+
import sqlite3 from 'sqlite3';
|
|
3
|
+
export declare class SQLiteAdapter<T extends object> implements IdaiDbAdapterInterface<T> {
|
|
4
|
+
private db;
|
|
5
|
+
private table;
|
|
6
|
+
private idField;
|
|
7
|
+
constructor(collection: string, connection: any);
|
|
8
|
+
static connect(uri: string, options?: any): Promise<sqlite3.Database>;
|
|
9
|
+
static getDb(connection: sqlite3.Database, dbName: string): Promise<sqlite3.Database>;
|
|
10
|
+
static close(connection: sqlite3.Database): Promise<void>;
|
|
11
|
+
create(data: Partial<T>): Promise<T>;
|
|
12
|
+
find(params?: IdaeDbParams<T>): Promise<T[]>;
|
|
13
|
+
findOne(params: IdaeDbParams<T>): Promise<T | null>;
|
|
14
|
+
update(id: string, data: Partial<T>): Promise<T | null>;
|
|
15
|
+
deleteById(id: string): Promise<boolean>;
|
|
16
|
+
transaction(fn: () => Promise<any>): Promise<any>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import sqlite3 from 'sqlite3';
|
|
2
|
+
export class SQLiteAdapter {
|
|
3
|
+
db;
|
|
4
|
+
table;
|
|
5
|
+
idField;
|
|
6
|
+
constructor(collection, connection) {
|
|
7
|
+
// connection est un IdaeDbConnection, on récupère la vraie connexion
|
|
8
|
+
this.db = connection.getDb();
|
|
9
|
+
this.table = collection;
|
|
10
|
+
this.idField = 'id';
|
|
11
|
+
}
|
|
12
|
+
static async connect(uri, options) {
|
|
13
|
+
// uri: sqlite://./mydb.sqlite
|
|
14
|
+
const dbPath = uri.replace(/^sqlite:\/\//, '');
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
const db = new sqlite3.Database(dbPath, (err) => {
|
|
17
|
+
if (err)
|
|
18
|
+
reject(err);
|
|
19
|
+
else
|
|
20
|
+
resolve(db);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
static async getDb(connection, dbName) {
|
|
25
|
+
// SQLite: pas de notion de dbName, retourne la connexion
|
|
26
|
+
return connection;
|
|
27
|
+
}
|
|
28
|
+
static async close(connection) {
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
connection.close((err) => (err ? reject(err) : resolve()));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
async create(data) {
|
|
34
|
+
const keys = Object.keys(data);
|
|
35
|
+
const values = keys.map((k) => data[k]);
|
|
36
|
+
const placeholders = keys.map(() => '?').join(',');
|
|
37
|
+
const sql = `INSERT INTO ${this.table} (${keys.join(',')}) VALUES (${placeholders})`;
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
this.db.run(sql, values, function (err) {
|
|
40
|
+
if (err)
|
|
41
|
+
return reject(err);
|
|
42
|
+
resolve({ ...data, id: this.lastID });
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
async find(params) {
|
|
47
|
+
const { query = {}, limit, sortBy } = params || {};
|
|
48
|
+
let sql = `SELECT * FROM ${this.table}`;
|
|
49
|
+
const where = [];
|
|
50
|
+
const values = [];
|
|
51
|
+
for (const k in query) {
|
|
52
|
+
where.push(`${k} = ?`);
|
|
53
|
+
values.push(query[k]);
|
|
54
|
+
}
|
|
55
|
+
if (where.length)
|
|
56
|
+
sql += ' WHERE ' + where.join(' AND ');
|
|
57
|
+
if (sortBy)
|
|
58
|
+
sql += ` ORDER BY ${sortBy}`;
|
|
59
|
+
if (limit)
|
|
60
|
+
sql += ` LIMIT ${limit}`;
|
|
61
|
+
return new Promise((resolve, reject) => {
|
|
62
|
+
this.db.all(sql, values, (err, rows) => {
|
|
63
|
+
if (err)
|
|
64
|
+
return reject(err);
|
|
65
|
+
resolve(rows);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
async findOne(params) {
|
|
70
|
+
const results = await this.find({ ...params, limit: 1 });
|
|
71
|
+
return results[0] || null;
|
|
72
|
+
}
|
|
73
|
+
async update(id, data) {
|
|
74
|
+
const keys = Object.keys(data);
|
|
75
|
+
const values = keys.map((k) => data[k]);
|
|
76
|
+
const sql = `UPDATE ${this.table} SET ${keys.map((k) => `${k} = ?`).join(',')} WHERE ${this.idField} = ?`;
|
|
77
|
+
return new Promise((resolve, reject) => {
|
|
78
|
+
this.db.run(sql, [...values, id], function (err) {
|
|
79
|
+
if (err)
|
|
80
|
+
return reject(err);
|
|
81
|
+
resolve({ ...data, id });
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
async deleteById(id) {
|
|
86
|
+
const sql = `DELETE FROM ${this.table} WHERE ${this.idField} = ?`;
|
|
87
|
+
return new Promise((resolve, reject) => {
|
|
88
|
+
this.db.run(sql, [id], function (err) {
|
|
89
|
+
if (err)
|
|
90
|
+
return reject(err);
|
|
91
|
+
resolve(this.changes > 0);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
async transaction(fn) {
|
|
96
|
+
await new Promise((resolve, reject) => {
|
|
97
|
+
this.db.run('BEGIN TRANSACTION', (err) => (err ? reject(err) : resolve(null)));
|
|
98
|
+
});
|
|
99
|
+
try {
|
|
100
|
+
const result = await fn();
|
|
101
|
+
await new Promise((resolve, reject) => {
|
|
102
|
+
this.db.run('COMMIT', (err) => (err ? reject(err) : resolve(null)));
|
|
103
|
+
});
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
catch (e) {
|
|
107
|
+
await new Promise((resolve, reject) => {
|
|
108
|
+
this.db.run('ROLLBACK', (err) => (err ? reject(err) : resolve(null)));
|
|
109
|
+
});
|
|
110
|
+
throw e;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
export * from './idaeDb.js';
|
|
2
1
|
export * from './IdaeEventEmitter.js';
|
|
2
|
+
export * from './IdaeDBModel.js';
|
|
3
3
|
export * from './IdaeDbConnection.js';
|
|
4
4
|
export * from './IdaeDbAdapter.js';
|
|
5
|
-
export * from './
|
|
5
|
+
export * from './idaeDb.js';
|
|
6
|
+
export * from './adapters/SQLiteAdapter.js';
|
|
7
|
+
export * from './adapters/PouchDBAdapter.js';
|
|
8
|
+
export * from './adapters/PostgreSQLAdapter.js';
|
|
6
9
|
export * from './adapters/MySQLAdapter.js';
|
|
7
10
|
export * from './adapters/MongoDBAdapter.js';
|
|
8
11
|
export * from './adapters/ChromaDBAdapter.js';
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
// auto exports of entry components
|
|
2
|
-
export * from './idaeDb.js';
|
|
3
2
|
export * from './IdaeEventEmitter.js';
|
|
3
|
+
export * from './IdaeDBModel.js';
|
|
4
4
|
export * from './IdaeDbConnection.js';
|
|
5
5
|
export * from './IdaeDbAdapter.js';
|
|
6
|
-
export * from './
|
|
6
|
+
export * from './idaeDb.js';
|
|
7
|
+
export * from './adapters/SQLiteAdapter.js';
|
|
8
|
+
export * from './adapters/PouchDBAdapter.js';
|
|
9
|
+
export * from './adapters/PostgreSQLAdapter.js';
|
|
7
10
|
export * from './adapters/MySQLAdapter.js';
|
|
8
11
|
export * from './adapters/MongoDBAdapter.js';
|
|
9
12
|
export * from './adapters/ChromaDBAdapter.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@medyll/idae-db",
|
|
3
|
-
"
|
|
3
|
+
"bin": {
|
|
4
|
+
"idae-db": "./cli.js"
|
|
5
|
+
},
|
|
6
|
+
"version": "0.155.2",
|
|
7
|
+
"author": "Lebrun Meddy",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/medyll/idae.git"
|
|
11
|
+
},
|
|
4
12
|
"description": "@medyll/idae-db is a flexible and powerful library for interacting with various databases, with a particular focus on MongoDB support. It offers robust connection management, an intuitive API, and simplified CRUD operations.",
|
|
5
13
|
"exports": {
|
|
6
14
|
".": {
|
|
@@ -15,38 +23,53 @@
|
|
|
15
23
|
"!dist/**/*.spec.*"
|
|
16
24
|
],
|
|
17
25
|
"peerDependencies": {
|
|
26
|
+
"pg": ">=8.0.0",
|
|
27
|
+
"pouchdb": ">=8.0.0",
|
|
28
|
+
"sqlite3": ">=5.1.0",
|
|
18
29
|
"svelte": "^5.0.0-next"
|
|
19
30
|
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public",
|
|
33
|
+
"directory": "."
|
|
34
|
+
},
|
|
20
35
|
"devDependencies": {
|
|
36
|
+
"@semantic-release/github": "^10.3.5",
|
|
21
37
|
"@sveltejs/adapter-auto": "^6.0.0",
|
|
22
38
|
"@sveltejs/kit": "^2.20.7",
|
|
23
39
|
"@sveltejs/package": "^2.3.11",
|
|
24
40
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
|
25
41
|
"@types/eslint": "^9.6.1",
|
|
42
|
+
"@types/pouchdb": "^6.4.2",
|
|
26
43
|
"@vitest/coverage-v8": "^3.1.1",
|
|
27
44
|
"eslint": "^9.25.0",
|
|
28
45
|
"eslint-config-prettier": "^10.1.2",
|
|
29
46
|
"eslint-plugin-svelte": "^3.5.1",
|
|
30
47
|
"globals": "^16.0.0",
|
|
31
48
|
"mongodb-memory-server": "^10.1.4",
|
|
49
|
+
"pg": "^8.17.2",
|
|
50
|
+
"pouchdb-adapter-memory": "^9.0.0",
|
|
51
|
+
"pouchdb-find": "^9.0.0",
|
|
32
52
|
"prettier": "^3.5.3",
|
|
33
53
|
"prettier-plugin-svelte": "^3.3.3",
|
|
34
54
|
"publint": "^0.3.12",
|
|
55
|
+
"sqlite3": "^5.1.7",
|
|
35
56
|
"svelte": "^5.28.1",
|
|
36
57
|
"svelte-check": "^4.1.6",
|
|
37
58
|
"typescript": "^5.8.3",
|
|
38
59
|
"typescript-eslint": "^8.30.1",
|
|
39
60
|
"vite": "^6.3.2",
|
|
40
61
|
"vitest": "^3.1.1",
|
|
41
|
-
"@medyll/idae-
|
|
42
|
-
"@medyll/idae-
|
|
62
|
+
"@medyll/idae-query": "0.186.2",
|
|
63
|
+
"@medyll/idae-eslint-config": "0.1.5"
|
|
43
64
|
},
|
|
44
65
|
"svelte": "./dist/index.js",
|
|
45
66
|
"types": "./dist/index.d.ts",
|
|
46
67
|
"type": "module",
|
|
47
68
|
"scope": "@medyll",
|
|
48
69
|
"dependencies": {
|
|
49
|
-
"chromadb": "^2.2.1"
|
|
70
|
+
"chromadb": "^2.2.1",
|
|
71
|
+
"mongodb": "^7.0.0",
|
|
72
|
+
"mysql2": "^3.16.0"
|
|
50
73
|
},
|
|
51
74
|
"scripts": {
|
|
52
75
|
"dev": "vite dev",
|
|
@@ -61,6 +84,6 @@
|
|
|
61
84
|
"test:watch": "vitest --watch",
|
|
62
85
|
"lint": "prettier --check . && eslint .",
|
|
63
86
|
"format": "prettier --write .",
|
|
64
|
-
"
|
|
87
|
+
"prepackage": "node scripts/package-pre.js"
|
|
65
88
|
}
|
|
66
89
|
}
|