@chidchanun/bcp 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -20
- package/docs/api-manifest.json +2 -2
- package/docs/api-reference.md +21 -2
- package/docs/database-migrations.md +79 -19
- package/docs/database.md +197 -28
- package/docs/docs-web-manifest.json +4 -3
- package/docs/platform-manifest.json +14 -4
- package/docs/releases/0.2.3.md +77 -0
- package/package.json +1 -1
- package/packages/cli/src/database-migrations.ts +91 -21
- package/packages/client/src/database-mysql.ts +291 -0
- package/packages/client/src/database-postgresql.ts +355 -0
- package/packages/client/src/database-sqlite.ts +445 -0
- package/packages/client/src/database.mjs +709 -57
- package/packages/client/src/database.ts +347 -182
package/README.md
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
BCP Framework is a React full-stack framework for file-based routing, SSR, SPA navigation, server data loading, guarded application flows, API routes, authentication, database access, validation, uploads, storage and standalone Node.js production deployment.
|
|
4
4
|
|
|
5
|
-
> **Development target:** `0.2.
|
|
5
|
+
> **Development target:** `0.2.3 — Database Platform v2`
|
|
6
6
|
>
|
|
7
|
-
> `0.2.
|
|
7
|
+
> `0.2.3` is an unreleased development target until local validation, RC checks, tagging and npm publication complete.
|
|
8
8
|
|
|
9
9
|
## 0.2 platform
|
|
10
10
|
|
|
11
|
-
`0.2.0` established the Framework Platform baseline, `0.2.1` added the Documentation Platform, and `0.2.
|
|
11
|
+
`0.2.0` established the Framework Platform baseline, `0.2.1` added the Documentation Platform, `0.2.2` added Configuration & Environment v2, and `0.2.3` adds a provider-neutral SQL database platform with MySQL, PostgreSQL and SQLite support without intentionally removing public application entrypoints.
|
|
12
12
|
|
|
13
13
|
Machine-readable platform contracts:
|
|
14
14
|
|
|
@@ -36,7 +36,7 @@ docs/api-manifest.json
|
|
|
36
36
|
| Middleware | Middleware System v2 with onion execution |
|
|
37
37
|
| Validation | Typed validators and structured validation errors |
|
|
38
38
|
| Error handling | HTTP error helpers and consistent error responses |
|
|
39
|
-
| Database | MySQL
|
|
39
|
+
| Database | Provider-neutral MySQL, PostgreSQL and SQLite adapters, transactions, lifecycle and migrations |
|
|
40
40
|
| Logging | Structured logger, request logger and request IDs |
|
|
41
41
|
| Uploads | Buffered multipart helpers and production multipart streaming |
|
|
42
42
|
| Storage | Local + S3-compatible storage, streaming, list/copy/move, metadata, bulk delete and signed URLs |
|
|
@@ -52,7 +52,13 @@ docs/api-manifest.json
|
|
|
52
52
|
- React `19`
|
|
53
53
|
- npm
|
|
54
54
|
|
|
55
|
-
Database
|
|
55
|
+
Database drivers are optional and provider-specific:
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
MySQL mysql2
|
|
59
|
+
PostgreSQL pg
|
|
60
|
+
SQLite better-sqlite3
|
|
61
|
+
```
|
|
56
62
|
|
|
57
63
|
## Quick start
|
|
58
64
|
|
|
@@ -224,6 +230,53 @@ must not use `BCP_PUBLIC_`. BCP reports this as a configuration error.
|
|
|
224
230
|
|
|
225
231
|
Read more: [Environment Validation](docs/environment-validation.md)
|
|
226
232
|
|
|
233
|
+
## Database Platform v2 — 0.2.3
|
|
234
|
+
|
|
235
|
+
Application code uses the same server-only entrypoint across supported SQL providers:
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
import {
|
|
239
|
+
db,
|
|
240
|
+
createDatabase,
|
|
241
|
+
} from "bcp/database";
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Built-in providers:
|
|
245
|
+
|
|
246
|
+
```text
|
|
247
|
+
mysql
|
|
248
|
+
postgresql
|
|
249
|
+
sqlite
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Connections remain lazy, while explicit lifecycle control is available when needed:
|
|
253
|
+
|
|
254
|
+
```ts
|
|
255
|
+
await db.connect();
|
|
256
|
+
|
|
257
|
+
// application work
|
|
258
|
+
|
|
259
|
+
await db.disconnect();
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
`db.close()` remains available for backward-compatible shutdown handling.
|
|
263
|
+
|
|
264
|
+
Database migrations use the same CLI across providers:
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
bcp db create create_users
|
|
268
|
+
bcp db migrate
|
|
269
|
+
bcp db status
|
|
270
|
+
bcp db rollback
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
BCP makes its internal migration bookkeeping provider-aware. Application SQL itself is not automatically translated between SQL dialects.
|
|
274
|
+
|
|
275
|
+
Read more:
|
|
276
|
+
|
|
277
|
+
- [Database](docs/database.md)
|
|
278
|
+
- [Database Migrations](docs/database-migrations.md)
|
|
279
|
+
|
|
227
280
|
## Public entrypoints
|
|
228
281
|
|
|
229
282
|
The current `0.2.x` platform contract recognizes:
|
|
@@ -383,7 +436,7 @@ npm run test:e2e
|
|
|
383
436
|
npm run rc:check
|
|
384
437
|
```
|
|
385
438
|
|
|
386
|
-
`0.2.
|
|
439
|
+
`0.2.3` adds Database Platform v2 unit/package checks covering the adapter contract, MySQL/PostgreSQL/SQLite provider resolution, explicit connection lifecycle, failed-initialization retry behavior and provider-specific migration bookkeeping.
|
|
387
440
|
|
|
388
441
|
Do not tag or publish until the final release commit passes the complete RC sequence.
|
|
389
442
|
|
|
@@ -400,24 +453,13 @@ Do not tag or publish until the final release commit passes the complete RC sequ
|
|
|
400
453
|
| `0.2.0` | Framework Platform |
|
|
401
454
|
| `0.2.1` | Documentation Platform |
|
|
402
455
|
| `0.2.2` | Configuration & Environment v2 |
|
|
456
|
+
| `0.2.3` | Database Platform v2 |
|
|
403
457
|
|
|
404
458
|
## Roadmap
|
|
405
459
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
```text
|
|
409
|
-
0.2.3 — Database Platform v2
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
Planned focus:
|
|
413
|
-
|
|
414
|
-
- database adapter contract,
|
|
415
|
-
- PostgreSQL support,
|
|
416
|
-
- SQLite support,
|
|
417
|
-
- connection lifecycle improvements,
|
|
418
|
-
- migration consistency across providers.
|
|
460
|
+
`0.2.3 — Database Platform v2` completes the planned database adapter contract, PostgreSQL support, SQLite support, connection lifecycle improvements and migration consistency across the built-in SQL providers.
|
|
419
461
|
|
|
420
|
-
|
|
462
|
+
The next planned `0.2.x` focus is application packaging. Native `.exe`, desktop and mobile compilation remain later roadmap work.
|
|
421
463
|
|
|
422
464
|
## License
|
|
423
465
|
|
package/docs/api-manifest.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"framework": "bcp",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.3",
|
|
5
5
|
"releaseState": "unreleased",
|
|
6
6
|
"coverage": "public-entrypoints",
|
|
7
7
|
"entrypoints": [
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"source": "packages/client/src/database.ts",
|
|
75
75
|
"environment": "server",
|
|
76
76
|
"route": "/docs/api-reference#bcp-database",
|
|
77
|
-
"summary": "
|
|
77
|
+
"summary": "Provider-neutral MySQL, PostgreSQL and SQLite query, transaction, lifecycle and migration primitives.",
|
|
78
78
|
"guides": [
|
|
79
79
|
"/docs/database",
|
|
80
80
|
"/docs/database-migrations"
|
package/docs/api-reference.md
CHANGED
|
@@ -130,16 +130,35 @@ Related guide: [Error Handling](error-handling.md).
|
|
|
130
130
|
|
|
131
131
|
## `bcp/database`
|
|
132
132
|
|
|
133
|
-
Server-only
|
|
133
|
+
Server-only Database Platform v2 APIs.
|
|
134
134
|
|
|
135
135
|
```ts
|
|
136
136
|
import {
|
|
137
137
|
createDatabase,
|
|
138
138
|
db,
|
|
139
|
+
resolveDatabaseOptions,
|
|
140
|
+
type DatabaseAdapter,
|
|
141
|
+
type DatabaseAdapterFactory,
|
|
142
|
+
type DatabaseConnectionOptions,
|
|
143
|
+
type DatabaseDriver,
|
|
144
|
+
type DatabaseOptions,
|
|
145
|
+
type DatabaseParameters,
|
|
146
|
+
type ResolvedDatabaseOptions,
|
|
147
|
+
type TransactionDatabase,
|
|
139
148
|
} from "bcp/database";
|
|
140
149
|
```
|
|
141
150
|
|
|
142
|
-
|
|
151
|
+
Built-in SQL providers are:
|
|
152
|
+
|
|
153
|
+
```text
|
|
154
|
+
mysql
|
|
155
|
+
postgresql
|
|
156
|
+
sqlite
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`BcpDatabase` instances expose lazy query/execute/transaction operations plus explicit `connect()`, `disconnect()` and backward-compatible `close()` lifecycle methods.
|
|
160
|
+
|
|
161
|
+
Use the public database helpers and adapter types instead of importing framework-internal provider/pool runtime modules.
|
|
143
162
|
|
|
144
163
|
Related guides: [Database](database.md), [Database Migrations](database-migrations.md).
|
|
145
164
|
|
|
@@ -1,14 +1,33 @@
|
|
|
1
1
|
# Database Migrations
|
|
2
2
|
|
|
3
|
-
BCP
|
|
3
|
+
BCP `0.2.3` extends framework-managed SQL migrations across MySQL, PostgreSQL and SQLite.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Supported providers
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Migration bookkeeping uses the same provider selection as `bcp/database`:
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
```text
|
|
10
|
+
mysql
|
|
11
|
+
postgresql
|
|
12
|
+
sqlite
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Install the optional driver used by the application:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install mysql2
|
|
19
|
+
npm install pg
|
|
20
|
+
npm install better-sqlite3
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Only one driver is required when the project uses one database provider.
|
|
24
|
+
|
|
25
|
+
## Provider configuration
|
|
26
|
+
|
|
27
|
+
MySQL:
|
|
10
28
|
|
|
11
29
|
```env
|
|
30
|
+
DB_DRIVER=mysql
|
|
12
31
|
DB_HOST=localhost
|
|
13
32
|
DB_PORT=3306
|
|
14
33
|
DB_USER=root
|
|
@@ -16,7 +35,20 @@ DB_PASSWORD=
|
|
|
16
35
|
DB_NAME=bcp_app
|
|
17
36
|
```
|
|
18
37
|
|
|
19
|
-
|
|
38
|
+
PostgreSQL:
|
|
39
|
+
|
|
40
|
+
```env
|
|
41
|
+
DATABASE_URL=postgresql://postgres:password@localhost:5432/bcp_app
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
SQLite:
|
|
45
|
+
|
|
46
|
+
```env
|
|
47
|
+
DB_DRIVER=sqlite
|
|
48
|
+
DATABASE_URL=./data/bcp.sqlite
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Database commands load the development environment before connecting, so migration commands and `bcp dev` use the same provider selection.
|
|
20
52
|
|
|
21
53
|
## Create a migration
|
|
22
54
|
|
|
@@ -24,14 +56,14 @@ A project using migrations must have `mysql2` installed. Applications created wi
|
|
|
24
56
|
bcp db create create_users
|
|
25
57
|
```
|
|
26
58
|
|
|
27
|
-
BCP creates an ordered TypeScript file
|
|
59
|
+
BCP creates an ordered TypeScript file:
|
|
28
60
|
|
|
29
61
|
```text
|
|
30
62
|
migrations/
|
|
31
|
-
|
|
63
|
+
20260829090000_create_users.ts
|
|
32
64
|
```
|
|
33
65
|
|
|
34
|
-
|
|
66
|
+
Generated migrations export `up()` and `down()`:
|
|
35
67
|
|
|
36
68
|
```ts
|
|
37
69
|
import type {
|
|
@@ -43,9 +75,9 @@ export async function up(
|
|
|
43
75
|
): Promise<void> {
|
|
44
76
|
await db.execute(`
|
|
45
77
|
CREATE TABLE users (
|
|
46
|
-
id
|
|
78
|
+
id INTEGER PRIMARY KEY,
|
|
47
79
|
email VARCHAR(255) NOT NULL UNIQUE
|
|
48
|
-
)
|
|
80
|
+
)
|
|
49
81
|
`);
|
|
50
82
|
}
|
|
51
83
|
|
|
@@ -58,7 +90,24 @@ export async function down(
|
|
|
58
90
|
}
|
|
59
91
|
```
|
|
60
92
|
|
|
61
|
-
Migration filenames use a UTC timestamp prefix
|
|
93
|
+
Migration filenames use a UTC timestamp prefix for stable execution order.
|
|
94
|
+
|
|
95
|
+
## SQL dialect responsibility
|
|
96
|
+
|
|
97
|
+
BCP keeps its own `_bcp_migrations` bookkeeping provider-aware, but it does not translate application migration SQL.
|
|
98
|
+
|
|
99
|
+
This means migrations should either:
|
|
100
|
+
|
|
101
|
+
- use SQL supported by every database target used by the application, or
|
|
102
|
+
- intentionally target one provider and use that provider's SQL syntax.
|
|
103
|
+
|
|
104
|
+
Parameter placeholders also follow the active provider:
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
MySQL ?
|
|
108
|
+
SQLite ?
|
|
109
|
+
PostgreSQL $1, $2, ...
|
|
110
|
+
```
|
|
62
111
|
|
|
63
112
|
## Run pending migrations
|
|
64
113
|
|
|
@@ -66,9 +115,15 @@ Migration filenames use a UTC timestamp prefix so migrations have a stable execu
|
|
|
66
115
|
bcp db migrate
|
|
67
116
|
```
|
|
68
117
|
|
|
69
|
-
BCP creates
|
|
118
|
+
BCP creates `_bcp_migrations` with provider-specific DDL, detects pending migration files, and executes them in filename order.
|
|
119
|
+
|
|
120
|
+
All migrations applied by one command share the same batch number. Each migration runs inside its own transaction and its bookkeeping record is written in that same transaction.
|
|
70
121
|
|
|
71
|
-
|
|
122
|
+
Provider-specific bookkeeping includes:
|
|
123
|
+
|
|
124
|
+
- MySQL `AUTO_INCREMENT`,
|
|
125
|
+
- PostgreSQL `BIGSERIAL`,
|
|
126
|
+
- SQLite `INTEGER PRIMARY KEY AUTOINCREMENT`.
|
|
72
127
|
|
|
73
128
|
## Check status
|
|
74
129
|
|
|
@@ -84,22 +139,27 @@ The command reports applied and pending migration files together with the batch
|
|
|
84
139
|
bcp db rollback
|
|
85
140
|
```
|
|
86
141
|
|
|
87
|
-
Rollback reverses only the latest migration batch. Migrations
|
|
142
|
+
Rollback reverses only the latest migration batch. Migrations run from newest to oldest and each `down()` executes in a transaction together with deletion of its migration record.
|
|
88
143
|
|
|
89
144
|
BCP refuses to roll back an applied migration when its migration file is missing.
|
|
90
145
|
|
|
91
146
|
## Project root
|
|
92
147
|
|
|
93
|
-
All database commands support the normal
|
|
148
|
+
All database commands support the normal project-root option:
|
|
94
149
|
|
|
95
150
|
```bash
|
|
96
151
|
bcp db status --root ./apps/admin
|
|
97
152
|
```
|
|
98
153
|
|
|
99
|
-
##
|
|
154
|
+
## Database Platform v2 behavior
|
|
100
155
|
|
|
101
|
-
|
|
156
|
+
`0.2.3` keeps migration commands consistent across the built-in SQL providers:
|
|
102
157
|
|
|
103
|
-
|
|
158
|
+
```text
|
|
159
|
+
bcp db create
|
|
160
|
+
bcp db migrate
|
|
161
|
+
bcp db status
|
|
162
|
+
bcp db rollback
|
|
163
|
+
```
|
|
104
164
|
|
|
105
|
-
|
|
165
|
+
The command names and migration file contract stay the same regardless of whether the application uses MySQL, PostgreSQL or SQLite.
|
package/docs/database.md
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
# Database
|
|
2
2
|
|
|
3
|
-
BCP `0.
|
|
3
|
+
BCP `0.2.3` completes Database Platform v2 behind the server-only `bcp/database` entrypoint.
|
|
4
4
|
|
|
5
|
-
The
|
|
5
|
+
The public database facade is provider-neutral and currently includes built-in adapters for:
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- MySQL,
|
|
8
|
+
- PostgreSQL,
|
|
9
|
+
- SQLite.
|
|
10
|
+
|
|
11
|
+
Applications can keep the same `db.query()`, `db.execute()`, `db.transaction()` and lifecycle API while selecting the provider through environment or explicit options.
|
|
12
|
+
|
|
13
|
+
## MySQL
|
|
14
|
+
|
|
15
|
+
Install the optional driver:
|
|
8
16
|
|
|
9
17
|
```bash
|
|
10
|
-
|
|
18
|
+
npm install mysql2
|
|
11
19
|
```
|
|
12
20
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
## Environment
|
|
21
|
+
Environment:
|
|
16
22
|
|
|
17
23
|
```env
|
|
18
24
|
DB_DRIVER=mysql
|
|
@@ -22,20 +28,105 @@ DB_USER=root
|
|
|
22
28
|
DB_PASSWORD=
|
|
23
29
|
DB_NAME=bcp_app
|
|
24
30
|
DB_CONNECTION_LIMIT=10
|
|
25
|
-
DB_WAIT_FOR_CONNECTIONS=1
|
|
26
|
-
DB_QUEUE_LIMIT=0
|
|
27
|
-
DB_CHARSET=utf8mb4
|
|
28
31
|
```
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
MySQL remains the default when no provider can be inferred.
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
Parameterized query:
|
|
33
36
|
|
|
34
37
|
```ts
|
|
35
38
|
import {
|
|
36
39
|
db,
|
|
37
40
|
} from "bcp/database";
|
|
38
41
|
|
|
42
|
+
const users =
|
|
43
|
+
await db.query(
|
|
44
|
+
"SELECT id, email FROM users WHERE active = ?",
|
|
45
|
+
[
|
|
46
|
+
1,
|
|
47
|
+
]
|
|
48
|
+
);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## PostgreSQL
|
|
52
|
+
|
|
53
|
+
Install the optional driver:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm install pg
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
BCP can infer PostgreSQL from a connection URL:
|
|
60
|
+
|
|
61
|
+
```env
|
|
62
|
+
DATABASE_URL=postgresql://postgres:password@localhost:5432/bcp_app
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
or use explicit fields:
|
|
66
|
+
|
|
67
|
+
```env
|
|
68
|
+
DB_DRIVER=postgresql
|
|
69
|
+
DB_HOST=localhost
|
|
70
|
+
DB_PORT=5432
|
|
71
|
+
DB_USER=postgres
|
|
72
|
+
DB_PASSWORD=password
|
|
73
|
+
DB_NAME=bcp_app
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
PostgreSQL parameters use `$1`, `$2`, and later placeholders:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
const users =
|
|
80
|
+
await db.query(
|
|
81
|
+
"SELECT id, email FROM users WHERE active = $1",
|
|
82
|
+
[
|
|
83
|
+
true,
|
|
84
|
+
]
|
|
85
|
+
);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`postgres` and `pg` are accepted as environment aliases for the PostgreSQL driver and are normalized to `postgresql`.
|
|
89
|
+
|
|
90
|
+
## SQLite
|
|
91
|
+
|
|
92
|
+
Install the optional driver:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npm install better-sqlite3
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Recommended environment:
|
|
99
|
+
|
|
100
|
+
```env
|
|
101
|
+
DB_DRIVER=sqlite
|
|
102
|
+
DATABASE_URL=./data/bcp.sqlite
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
BCP also recognizes `:memory:`, `sqlite:` / `file:` URLs and common `.sqlite`, `.sqlite3`, and `.db` file names.
|
|
106
|
+
|
|
107
|
+
Example:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import {
|
|
111
|
+
createDatabase,
|
|
112
|
+
} from "bcp/database";
|
|
113
|
+
|
|
114
|
+
const database =
|
|
115
|
+
createDatabase({
|
|
116
|
+
driver:
|
|
117
|
+
"sqlite",
|
|
118
|
+
database:
|
|
119
|
+
"./data/app.sqlite",
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
SQLite operations are serialized by the built-in adapter so async transaction callbacks cannot interleave unrelated queries on the same native connection.
|
|
124
|
+
|
|
125
|
+
## Query and execute
|
|
126
|
+
|
|
127
|
+
`query<T>()` is intended for row-returning statements:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
39
130
|
interface UserRow {
|
|
40
131
|
id: number;
|
|
41
132
|
email: string;
|
|
@@ -43,28 +134,27 @@ interface UserRow {
|
|
|
43
134
|
|
|
44
135
|
const users =
|
|
45
136
|
await db.query<UserRow[]>(
|
|
46
|
-
"SELECT id, email FROM users
|
|
47
|
-
[
|
|
48
|
-
1,
|
|
49
|
-
]
|
|
137
|
+
"SELECT id, email FROM users"
|
|
50
138
|
);
|
|
51
139
|
```
|
|
52
140
|
|
|
53
|
-
|
|
141
|
+
`execute<T>()` is intended for mutations and DDL:
|
|
54
142
|
|
|
55
143
|
```ts
|
|
56
144
|
const result =
|
|
57
145
|
await db.execute(
|
|
58
|
-
"
|
|
146
|
+
"DELETE FROM sessions WHERE expired_at < ?",
|
|
59
147
|
[
|
|
60
|
-
|
|
148
|
+
new Date(),
|
|
61
149
|
]
|
|
62
150
|
);
|
|
63
151
|
```
|
|
64
152
|
|
|
65
|
-
Use
|
|
153
|
+
Use the placeholder syntax of the active database provider. BCP does not rewrite application SQL between dialects.
|
|
66
154
|
|
|
67
|
-
##
|
|
155
|
+
## Transactions
|
|
156
|
+
|
|
157
|
+
The transaction callback receives a provider-scoped `TransactionDatabase`:
|
|
68
158
|
|
|
69
159
|
```ts
|
|
70
160
|
await db.transaction(
|
|
@@ -88,7 +178,33 @@ await db.transaction(
|
|
|
88
178
|
);
|
|
89
179
|
```
|
|
90
180
|
|
|
91
|
-
|
|
181
|
+
The example above uses MySQL/SQLite placeholders. PostgreSQL migrations and application statements should use `$1`, `$2`, and so on.
|
|
182
|
+
|
|
183
|
+
BCP commits when the callback resolves and rolls back when it throws.
|
|
184
|
+
|
|
185
|
+
## Connection lifecycle
|
|
186
|
+
|
|
187
|
+
Database instances remain lazy by default. Importing `bcp/database` does not connect to a provider.
|
|
188
|
+
|
|
189
|
+
BCP `0.2.3` adds explicit lifecycle methods:
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
await db.connect();
|
|
193
|
+
|
|
194
|
+
// application work
|
|
195
|
+
|
|
196
|
+
await db.disconnect();
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
`close()` remains available as the backward-compatible shutdown method and is equivalent to `disconnect()`:
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
await db.close();
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
After disconnecting, the next operation or `connect()` call creates a fresh adapter connection/pool.
|
|
206
|
+
|
|
207
|
+
If adapter initialization fails, BCP resets the pending lifecycle state so a later attempt can retry cleanly. Calling `close()` after a failed initialization is safe.
|
|
92
208
|
|
|
93
209
|
## Custom database instance
|
|
94
210
|
|
|
@@ -99,6 +215,8 @@ import {
|
|
|
99
215
|
|
|
100
216
|
export const reportingDb =
|
|
101
217
|
createDatabase({
|
|
218
|
+
driver:
|
|
219
|
+
"postgresql",
|
|
102
220
|
host:
|
|
103
221
|
"reporting-db.internal",
|
|
104
222
|
database:
|
|
@@ -110,18 +228,69 @@ export const reportingDb =
|
|
|
110
228
|
|
|
111
229
|
Explicit options override environment values for that database instance.
|
|
112
230
|
|
|
113
|
-
##
|
|
231
|
+
## Database adapter contract
|
|
114
232
|
|
|
115
|
-
|
|
233
|
+
Provider implementations use the shared adapter contract:
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
import type {
|
|
237
|
+
DatabaseAdapter,
|
|
238
|
+
TransactionDatabase,
|
|
239
|
+
} from "bcp/database";
|
|
116
240
|
|
|
117
|
-
|
|
241
|
+
const adapter: DatabaseAdapter = {
|
|
242
|
+
driver: "custom",
|
|
243
|
+
|
|
244
|
+
async connect() {},
|
|
245
|
+
|
|
246
|
+
async query<T>(sql, parameters) {
|
|
247
|
+
throw new Error("Not implemented");
|
|
248
|
+
},
|
|
249
|
+
|
|
250
|
+
async execute<T>(sql, parameters) {
|
|
251
|
+
throw new Error("Not implemented");
|
|
252
|
+
},
|
|
253
|
+
|
|
254
|
+
async transaction<T>(
|
|
255
|
+
callback: (
|
|
256
|
+
database: TransactionDatabase
|
|
257
|
+
) => Promise<T>
|
|
258
|
+
) {
|
|
259
|
+
throw new Error("Not implemented");
|
|
260
|
+
},
|
|
261
|
+
|
|
262
|
+
async disconnect() {},
|
|
263
|
+
};
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Inject an adapter directly or through a lazy factory:
|
|
118
267
|
|
|
119
268
|
```ts
|
|
120
|
-
|
|
269
|
+
export const customDb =
|
|
270
|
+
createDatabase({
|
|
271
|
+
adapter: () => adapter,
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
The contract lets future providers integrate without changing application-facing database calls.
|
|
276
|
+
|
|
277
|
+
## Migrations
|
|
278
|
+
|
|
279
|
+
Framework migration bookkeeping supports MySQL, PostgreSQL and SQLite in `0.2.3`.
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
bcp db create create_users
|
|
283
|
+
bcp db migrate
|
|
284
|
+
bcp db status
|
|
285
|
+
bcp db rollback
|
|
121
286
|
```
|
|
122
287
|
|
|
288
|
+
BCP selects the internal migration-table dialect from the same active database environment. Migration files themselves remain normal provider SQL and are not automatically translated between SQL dialects.
|
|
289
|
+
|
|
290
|
+
Read more: [Database Migrations](database-migrations.md)
|
|
291
|
+
|
|
123
292
|
## Server-only boundary
|
|
124
293
|
|
|
125
|
-
`bcp/database` is a server-only package export. Importing it into a browser bundle is blocked by the framework
|
|
294
|
+
`bcp/database` is a server-only package export. Importing it into a browser bundle is blocked by the framework browser export boundary.
|
|
126
295
|
|
|
127
|
-
|
|
296
|
+
Provider drivers are optional and loaded lazily. Projects only need to install the driver they actually use.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"framework": "bcp",
|
|
4
|
-
"versionTarget": "0.2.
|
|
4
|
+
"versionTarget": "0.2.3",
|
|
5
5
|
"releaseState": "unreleased",
|
|
6
6
|
"sections": [
|
|
7
7
|
{
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
{
|
|
46
46
|
"id": "database",
|
|
47
47
|
"title": "Database",
|
|
48
|
-
"description": "
|
|
48
|
+
"description": "Provider-neutral MySQL, PostgreSQL and SQLite primitives, lifecycle and migrations.",
|
|
49
49
|
"pages": [
|
|
50
50
|
{ "route": "/docs/database", "source": "database.md", "title": "Database" },
|
|
51
51
|
{ "route": "/docs/database-migrations", "source": "database-migrations.md", "title": "Database Migrations" }
|
|
@@ -104,7 +104,8 @@
|
|
|
104
104
|
}
|
|
105
105
|
],
|
|
106
106
|
"releases": [
|
|
107
|
-
{ "route": "/releases/0.2.
|
|
107
|
+
{ "route": "/releases/0.2.3", "source": "releases/0.2.3.md", "version": "0.2.3", "state": "unreleased" },
|
|
108
|
+
{ "route": "/releases/0.2.2", "source": "releases/0.2.2.md", "version": "0.2.2" },
|
|
108
109
|
{ "route": "/releases/0.2.1", "source": "releases/0.2.1.md", "version": "0.2.1" },
|
|
109
110
|
{ "route": "/releases/0.2.0", "source": "releases/0.2.0.md", "version": "0.2.0" },
|
|
110
111
|
{ "route": "/releases/0.1.29", "source": "releases/0.1.29.md", "version": "0.1.29" },
|