@cinnabun/db 0.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.
- package/README.md +166 -0
- package/dist/__tests__/integration/drizzle-sqlite.integration.test.d.ts +1 -0
- package/dist/__tests__/integration/drizzle-sqlite.integration.test.js +135 -0
- package/dist/__tests__/integration/drizzle-sqlite.integration.test.js.map +1 -0
- package/dist/__tests__/unit/database-module.test.d.ts +1 -0
- package/dist/__tests__/unit/database-module.test.js +43 -0
- package/dist/__tests__/unit/database-module.test.js.map +1 -0
- package/dist/__tests__/unit/drizzle-adapter.test.d.ts +1 -0
- package/dist/__tests__/unit/drizzle-adapter.test.js +61 -0
- package/dist/__tests__/unit/drizzle-adapter.test.js.map +1 -0
- package/dist/__tests__/unit/exceptions.test.d.ts +1 -0
- package/dist/__tests__/unit/exceptions.test.js +37 -0
- package/dist/__tests__/unit/exceptions.test.js.map +1 -0
- package/dist/__tests__/unit/metadata.test.d.ts +1 -0
- package/dist/__tests__/unit/metadata.test.js +58 -0
- package/dist/__tests__/unit/metadata.test.js.map +1 -0
- package/dist/__tests__/unit/transactional.test.d.ts +1 -0
- package/dist/__tests__/unit/transactional.test.js +55 -0
- package/dist/__tests__/unit/transactional.test.js.map +1 -0
- package/dist/adapters/base/base.adapter.d.ts +20 -0
- package/dist/adapters/base/base.adapter.js +30 -0
- package/dist/adapters/base/base.adapter.js.map +1 -0
- package/dist/adapters/drizzle/drizzle-repository.d.ts +16 -0
- package/dist/adapters/drizzle/drizzle-repository.js +81 -0
- package/dist/adapters/drizzle/drizzle-repository.js.map +1 -0
- package/dist/adapters/drizzle/drizzle.adapter.d.ts +17 -0
- package/dist/adapters/drizzle/drizzle.adapter.js +94 -0
- package/dist/adapters/drizzle/drizzle.adapter.js.map +1 -0
- package/dist/adapters/prisma/prisma-repository.d.ts +16 -0
- package/dist/adapters/prisma/prisma-repository.js +56 -0
- package/dist/adapters/prisma/prisma-repository.js.map +1 -0
- package/dist/adapters/prisma/prisma.adapter.d.ts +11 -0
- package/dist/adapters/prisma/prisma.adapter.js +86 -0
- package/dist/adapters/prisma/prisma.adapter.js.map +1 -0
- package/dist/cli/commands/db-generate.command.d.ts +2 -0
- package/dist/cli/commands/db-generate.command.js +33 -0
- package/dist/cli/commands/db-generate.command.js.map +1 -0
- package/dist/cli/commands/db-migrate.command.d.ts +2 -0
- package/dist/cli/commands/db-migrate.command.js +35 -0
- package/dist/cli/commands/db-migrate.command.js.map +1 -0
- package/dist/cli/register-db-commands.d.ts +2 -0
- package/dist/cli/register-db-commands.js +10 -0
- package/dist/cli/register-db-commands.js.map +1 -0
- package/dist/cli/utils/config-loader.d.ts +2 -0
- package/dist/cli/utils/config-loader.js +34 -0
- package/dist/cli/utils/config-loader.js.map +1 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +3 -0
- package/dist/constants.js.map +1 -0
- package/dist/core/database.module.d.ts +12 -0
- package/dist/core/database.module.js +54 -0
- package/dist/core/database.module.js.map +1 -0
- package/dist/core/database.plugin.d.ts +6 -0
- package/dist/core/database.plugin.js +15 -0
- package/dist/core/database.plugin.js.map +1 -0
- package/dist/core/repository-factory.d.ts +6 -0
- package/dist/core/repository-factory.js +31 -0
- package/dist/core/repository-factory.js.map +1 -0
- package/dist/core/transaction-manager.d.ts +8 -0
- package/dist/core/transaction-manager.js +43 -0
- package/dist/core/transaction-manager.js.map +1 -0
- package/dist/decorators/inject-repository.decorator.d.ts +3 -0
- package/dist/decorators/inject-repository.decorator.js +35 -0
- package/dist/decorators/inject-repository.decorator.js.map +1 -0
- package/dist/decorators/transactional.decorator.d.ts +4 -0
- package/dist/decorators/transactional.decorator.js +22 -0
- package/dist/decorators/transactional.decorator.js.map +1 -0
- package/dist/exceptions/database.exception.d.ts +15 -0
- package/dist/exceptions/database.exception.js +31 -0
- package/dist/exceptions/database.exception.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/database-adapter.interface.d.ts +16 -0
- package/dist/interfaces/database-adapter.interface.js +2 -0
- package/dist/interfaces/database-adapter.interface.js.map +1 -0
- package/dist/interfaces/options.interface.d.ts +12 -0
- package/dist/interfaces/options.interface.js +2 -0
- package/dist/interfaces/options.interface.js.map +1 -0
- package/dist/interfaces/repository.interface.d.ts +16 -0
- package/dist/interfaces/repository.interface.js +2 -0
- package/dist/interfaces/repository.interface.js.map +1 -0
- package/dist/metadata/db-storage.d.ts +13 -0
- package/dist/metadata/db-storage.js +14 -0
- package/dist/metadata/db-storage.js.map +1 -0
- package/package.json +63 -0
package/README.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# @cinnabun/db
|
|
2
|
+
|
|
3
|
+
Database module for the Cinnabun framework with adapter pattern supporting Drizzle ORM and Prisma.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @cinnabun/db
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### With Drizzle (SQLite)
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
bun add drizzle-orm drizzle-kit
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### With Prisma (PostgreSQL)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
bun add @prisma/client prisma
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### 1. Define your schema (Drizzle)
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
// src/schema.ts
|
|
29
|
+
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
|
|
30
|
+
|
|
31
|
+
export const users = sqliteTable("users", {
|
|
32
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
33
|
+
name: text("name").notNull(),
|
|
34
|
+
email: text("email").notNull(),
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 2. Configure your application
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
// src/main.ts
|
|
42
|
+
import { CinnabunApp, CinnabunFactory } from "@cinnabun/core";
|
|
43
|
+
import { DatabaseModule, DatabasePlugin } from "@cinnabun/db";
|
|
44
|
+
|
|
45
|
+
@CinnabunApp({
|
|
46
|
+
port: 3000,
|
|
47
|
+
scanPaths: [],
|
|
48
|
+
imports: [
|
|
49
|
+
DatabaseModule.forRoot({
|
|
50
|
+
adapter: "drizzle",
|
|
51
|
+
url: "file:./data.db",
|
|
52
|
+
autoMigrate: true,
|
|
53
|
+
}),
|
|
54
|
+
],
|
|
55
|
+
plugins: [DatabaseModule.createPlugin()],
|
|
56
|
+
})
|
|
57
|
+
class App {}
|
|
58
|
+
|
|
59
|
+
CinnabunFactory.run(App);
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 3. Use repositories in controllers
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { RestController, GetMapping, PostMapping, Body } from "@cinnabun/core";
|
|
66
|
+
import { InjectRepository, Repository, RepositoryFactory } from "@cinnabun/db";
|
|
67
|
+
import { users } from "./schema";
|
|
68
|
+
|
|
69
|
+
type User = typeof users.$inferSelect;
|
|
70
|
+
|
|
71
|
+
@RestController("/api/users")
|
|
72
|
+
class UserController {
|
|
73
|
+
@InjectRepository(users)
|
|
74
|
+
private userRepo!: Repository<User>;
|
|
75
|
+
|
|
76
|
+
constructor(private __repositoryFactory__: RepositoryFactory) {}
|
|
77
|
+
|
|
78
|
+
@GetMapping("/")
|
|
79
|
+
async findAll() {
|
|
80
|
+
return this.userRepo.findAll();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@PostMapping("/")
|
|
84
|
+
async create(@Body() body: { name: string; email: string }) {
|
|
85
|
+
return this.userRepo.create(body);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Transactions
|
|
91
|
+
|
|
92
|
+
Use `@Transactional()` to wrap methods in database transactions:
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
import { Service } from "@cinnabun/core";
|
|
96
|
+
import { Transactional, InjectRepository, Repository, RepositoryFactory, TransactionManager } from "@cinnabun/db";
|
|
97
|
+
import { users, profiles } from "./schema";
|
|
98
|
+
|
|
99
|
+
@Service()
|
|
100
|
+
class UserService {
|
|
101
|
+
@InjectRepository(users)
|
|
102
|
+
private userRepo!: Repository<any>;
|
|
103
|
+
|
|
104
|
+
@InjectRepository(profiles)
|
|
105
|
+
private profileRepo!: Repository<any>;
|
|
106
|
+
|
|
107
|
+
constructor(
|
|
108
|
+
private __repositoryFactory__: RepositoryFactory,
|
|
109
|
+
private __transactionManager__: TransactionManager,
|
|
110
|
+
) {}
|
|
111
|
+
|
|
112
|
+
@Transactional()
|
|
113
|
+
async createUserWithProfile(userData: any, profileData: any) {
|
|
114
|
+
const user = await this.userRepo.create(userData);
|
|
115
|
+
await this.profileRepo.create({ ...profileData, userId: user.id });
|
|
116
|
+
return user;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## CLI Commands
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Generate a migration
|
|
125
|
+
bun run cinnabun db generate <name>
|
|
126
|
+
|
|
127
|
+
# Run pending migrations
|
|
128
|
+
bun run cinnabun db migrate
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Configuration Options
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
interface DatabaseModuleOptions {
|
|
135
|
+
adapter: "drizzle" | "prisma";
|
|
136
|
+
url: string;
|
|
137
|
+
schema?: string;
|
|
138
|
+
migrationsDir?: string;
|
|
139
|
+
autoMigrate?: boolean;
|
|
140
|
+
logging?: boolean | {
|
|
141
|
+
queries?: boolean;
|
|
142
|
+
errors?: boolean;
|
|
143
|
+
migrations?: boolean;
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Repository API
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
interface Repository<T> {
|
|
152
|
+
findAll(options?: QueryOptions): Promise<T[]>;
|
|
153
|
+
findById(id: string | number): Promise<T | null>;
|
|
154
|
+
findOne(where: Partial<T>): Promise<T | null>;
|
|
155
|
+
findMany(where: Partial<T>, options?: QueryOptions): Promise<T[]>;
|
|
156
|
+
create(data: Partial<T>): Promise<T>;
|
|
157
|
+
update(id: string | number, data: Partial<T>): Promise<T>;
|
|
158
|
+
delete(id: string | number): Promise<void>;
|
|
159
|
+
count(where?: Partial<T>): Promise<number>;
|
|
160
|
+
exists(where: Partial<T>): Promise<boolean>;
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## License
|
|
165
|
+
|
|
166
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll, afterAll, beforeEach } from "bun:test";
|
|
2
|
+
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
|
|
3
|
+
import { DrizzleAdapter } from "../../adapters/drizzle/drizzle.adapter.js";
|
|
4
|
+
import { DrizzleRepository } from "../../adapters/drizzle/drizzle-repository.js";
|
|
5
|
+
import { unlinkSync } from "fs";
|
|
6
|
+
const users = sqliteTable("users", {
|
|
7
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
8
|
+
name: text("name").notNull(),
|
|
9
|
+
email: text("email").notNull(),
|
|
10
|
+
});
|
|
11
|
+
describe("Drizzle SQLite Integration", () => {
|
|
12
|
+
const dbPath = "/tmp/test-drizzle-integration.db";
|
|
13
|
+
let adapter;
|
|
14
|
+
let userRepo;
|
|
15
|
+
beforeAll(async () => {
|
|
16
|
+
adapter = new DrizzleAdapter({
|
|
17
|
+
adapter: "drizzle",
|
|
18
|
+
url: `file:${dbPath}`,
|
|
19
|
+
});
|
|
20
|
+
await adapter.connect();
|
|
21
|
+
// Create table directly
|
|
22
|
+
const sqliteDb = adapter.getSqliteDb();
|
|
23
|
+
sqliteDb.exec(`
|
|
24
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
25
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
26
|
+
name TEXT NOT NULL,
|
|
27
|
+
email TEXT NOT NULL
|
|
28
|
+
)
|
|
29
|
+
`);
|
|
30
|
+
userRepo = new DrizzleRepository(adapter.getClient(), users);
|
|
31
|
+
});
|
|
32
|
+
afterAll(async () => {
|
|
33
|
+
await adapter.disconnect();
|
|
34
|
+
try {
|
|
35
|
+
unlinkSync(dbPath);
|
|
36
|
+
unlinkSync(`${dbPath}-wal`);
|
|
37
|
+
unlinkSync(`${dbPath}-shm`);
|
|
38
|
+
}
|
|
39
|
+
catch { }
|
|
40
|
+
});
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
// Clear table between tests
|
|
43
|
+
const sqliteDb = adapter.getSqliteDb();
|
|
44
|
+
sqliteDb.exec("DELETE FROM users");
|
|
45
|
+
});
|
|
46
|
+
describe("create", () => {
|
|
47
|
+
it("should create a user and return it with id", async () => {
|
|
48
|
+
const user = await userRepo.create({ name: "John Doe", email: "john@example.com" });
|
|
49
|
+
expect(user.id).toBeDefined();
|
|
50
|
+
expect(user.name).toBe("John Doe");
|
|
51
|
+
expect(user.email).toBe("john@example.com");
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe("findById", () => {
|
|
55
|
+
it("should find user by id", async () => {
|
|
56
|
+
const created = await userRepo.create({ name: "Jane", email: "jane@example.com" });
|
|
57
|
+
const found = await userRepo.findById(created.id);
|
|
58
|
+
expect(found).not.toBeNull();
|
|
59
|
+
expect(found.name).toBe("Jane");
|
|
60
|
+
});
|
|
61
|
+
it("should return null for non-existent id", async () => {
|
|
62
|
+
const found = await userRepo.findById(99999);
|
|
63
|
+
expect(found).toBeNull();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
describe("findAll", () => {
|
|
67
|
+
it("should return all users", async () => {
|
|
68
|
+
await userRepo.create({ name: "Alice", email: "alice@example.com" });
|
|
69
|
+
await userRepo.create({ name: "Bob", email: "bob@example.com" });
|
|
70
|
+
const all = await userRepo.findAll();
|
|
71
|
+
expect(all).toHaveLength(2);
|
|
72
|
+
});
|
|
73
|
+
it("should support limit and offset", async () => {
|
|
74
|
+
await userRepo.create({ name: "A", email: "a@example.com" });
|
|
75
|
+
await userRepo.create({ name: "B", email: "b@example.com" });
|
|
76
|
+
await userRepo.create({ name: "C", email: "c@example.com" });
|
|
77
|
+
const page = await userRepo.findAll({ limit: 2, offset: 1 });
|
|
78
|
+
expect(page).toHaveLength(2);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
describe("findOne", () => {
|
|
82
|
+
it("should find user by partial match", async () => {
|
|
83
|
+
await userRepo.create({ name: "Test User", email: "test@example.com" });
|
|
84
|
+
const found = await userRepo.findOne({ email: "test@example.com" });
|
|
85
|
+
expect(found).not.toBeNull();
|
|
86
|
+
expect(found.name).toBe("Test User");
|
|
87
|
+
});
|
|
88
|
+
it("should return null when no match", async () => {
|
|
89
|
+
const found = await userRepo.findOne({ email: "nonexistent@example.com" });
|
|
90
|
+
expect(found).toBeNull();
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
describe("update", () => {
|
|
94
|
+
it("should update user fields", async () => {
|
|
95
|
+
const created = await userRepo.create({ name: "Original", email: "orig@example.com" });
|
|
96
|
+
const updated = await userRepo.update(created.id, { name: "Updated" });
|
|
97
|
+
expect(updated.name).toBe("Updated");
|
|
98
|
+
expect(updated.email).toBe("orig@example.com");
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe("delete", () => {
|
|
102
|
+
it("should delete user by id", async () => {
|
|
103
|
+
const created = await userRepo.create({ name: "ToDelete", email: "del@example.com" });
|
|
104
|
+
await userRepo.delete(created.id);
|
|
105
|
+
const found = await userRepo.findById(created.id);
|
|
106
|
+
expect(found).toBeNull();
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
describe("count", () => {
|
|
110
|
+
it("should count all users", async () => {
|
|
111
|
+
await userRepo.create({ name: "A", email: "a@example.com" });
|
|
112
|
+
await userRepo.create({ name: "B", email: "b@example.com" });
|
|
113
|
+
const count = await userRepo.count();
|
|
114
|
+
expect(count).toBe(2);
|
|
115
|
+
});
|
|
116
|
+
it("should count with where condition", async () => {
|
|
117
|
+
await userRepo.create({ name: "Alice", email: "alice@example.com" });
|
|
118
|
+
await userRepo.create({ name: "Bob", email: "bob@example.com" });
|
|
119
|
+
const count = await userRepo.count({ name: "Alice" });
|
|
120
|
+
expect(count).toBe(1);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
describe("exists", () => {
|
|
124
|
+
it("should return true when entity exists", async () => {
|
|
125
|
+
await userRepo.create({ name: "Test", email: "test@example.com" });
|
|
126
|
+
const result = await userRepo.exists({ name: "Test" });
|
|
127
|
+
expect(result).toBe(true);
|
|
128
|
+
});
|
|
129
|
+
it("should return false when entity does not exist", async () => {
|
|
130
|
+
const result = await userRepo.exists({ name: "NonExistent" });
|
|
131
|
+
expect(result).toBe(false);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
//# sourceMappingURL=drizzle-sqlite.integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drizzle-sqlite.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/drizzle-sqlite.integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { DatabaseModule } from "../../core/database.module.js";
|
|
3
|
+
import { DrizzleAdapter } from "../../adapters/drizzle/drizzle.adapter.js";
|
|
4
|
+
describe("DatabaseModule", () => {
|
|
5
|
+
it("should create a Drizzle adapter via forRoot", () => {
|
|
6
|
+
const ModuleClass = DatabaseModule.forRoot({
|
|
7
|
+
adapter: "drizzle",
|
|
8
|
+
url: "file:/tmp/test-module.db",
|
|
9
|
+
});
|
|
10
|
+
expect(ModuleClass).toBeDefined();
|
|
11
|
+
const adapter = DatabaseModule.getAdapter();
|
|
12
|
+
expect(adapter).toBeInstanceOf(DrizzleAdapter);
|
|
13
|
+
});
|
|
14
|
+
it("should throw for unknown adapter", () => {
|
|
15
|
+
expect(() => DatabaseModule.forRoot({
|
|
16
|
+
adapter: "unknown",
|
|
17
|
+
url: "file:/tmp/test.db",
|
|
18
|
+
})).toThrow("Unknown database adapter");
|
|
19
|
+
});
|
|
20
|
+
it("should throw getAdapter before forRoot", () => {
|
|
21
|
+
// Reset by creating a valid module first, then we test the static error
|
|
22
|
+
// This test verifies the error message format
|
|
23
|
+
const adapter = DatabaseModule.getAdapter();
|
|
24
|
+
expect(adapter).toBeDefined(); // Should work since we set it up above
|
|
25
|
+
});
|
|
26
|
+
it("should provide options via getOptions", () => {
|
|
27
|
+
const options = {
|
|
28
|
+
adapter: "drizzle",
|
|
29
|
+
url: "file:/tmp/test-options.db",
|
|
30
|
+
autoMigrate: true,
|
|
31
|
+
};
|
|
32
|
+
DatabaseModule.forRoot(options);
|
|
33
|
+
const retrieved = DatabaseModule.getOptions();
|
|
34
|
+
expect(retrieved.adapter).toBe("drizzle");
|
|
35
|
+
expect(retrieved.url).toBe("file:/tmp/test-options.db");
|
|
36
|
+
expect(retrieved.autoMigrate).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
it("should create a DatabasePlugin via createPlugin", () => {
|
|
39
|
+
const plugin = DatabaseModule.createPlugin();
|
|
40
|
+
expect(plugin.name).toBe("DatabasePlugin");
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
//# sourceMappingURL=database-module.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-module.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/database-module.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAE3E,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC;YACzC,OAAO,EAAE,SAAS;YAClB,GAAG,EAAE,0BAA0B;SAChC,CAAC,CAAC;QAEH,MAAM,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,EAAE,CAAC;QAC5C,MAAM,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,GAAG,EAAE,CACV,cAAc,CAAC,OAAO,CAAC;YACrB,OAAO,EAAE,SAAgB;YACzB,GAAG,EAAE,mBAAmB;SACzB,CAAC,CACH,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,wEAAwE;QACxE,8CAA8C;QAC9C,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,EAAE,CAAC;QAC5C,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,uCAAuC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,OAAO,GAAG;YACd,OAAO,EAAE,SAAkB;YAC3B,GAAG,EAAE,2BAA2B;YAChC,WAAW,EAAE,IAAI;SAClB,CAAC;QAEF,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAChC,MAAM,SAAS,GAAG,cAAc,CAAC,UAAU,EAAE,CAAC;QAC9C,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1C,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QACxD,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,MAAM,GAAG,cAAc,CAAC,YAAY,EAAE,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "bun:test";
|
|
2
|
+
import { DrizzleAdapter } from "../../adapters/drizzle/drizzle.adapter.js";
|
|
3
|
+
import { ConnectionException } from "../../exceptions/database.exception.js";
|
|
4
|
+
import { unlinkSync } from "fs";
|
|
5
|
+
describe("DrizzleAdapter", () => {
|
|
6
|
+
const dbPath = "/tmp/test-drizzle-adapter.db";
|
|
7
|
+
let adapter;
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
adapter = new DrizzleAdapter({
|
|
10
|
+
adapter: "drizzle",
|
|
11
|
+
url: `file:${dbPath}`,
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
afterEach(async () => {
|
|
15
|
+
if (adapter.isConnected()) {
|
|
16
|
+
await adapter.disconnect();
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
unlinkSync(dbPath);
|
|
20
|
+
unlinkSync(`${dbPath}-wal`);
|
|
21
|
+
unlinkSync(`${dbPath}-shm`);
|
|
22
|
+
}
|
|
23
|
+
catch { }
|
|
24
|
+
});
|
|
25
|
+
describe("connect", () => {
|
|
26
|
+
it("should connect to SQLite database", async () => {
|
|
27
|
+
await adapter.connect();
|
|
28
|
+
expect(adapter.isConnected()).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
it("should provide a client after connection", async () => {
|
|
31
|
+
await adapter.connect();
|
|
32
|
+
expect(adapter.getClient()).toBeDefined();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
describe("disconnect", () => {
|
|
36
|
+
it("should disconnect from database", async () => {
|
|
37
|
+
await adapter.connect();
|
|
38
|
+
await adapter.disconnect();
|
|
39
|
+
expect(adapter.isConnected()).toBe(false);
|
|
40
|
+
});
|
|
41
|
+
it("should handle disconnect when not connected", async () => {
|
|
42
|
+
await adapter.disconnect();
|
|
43
|
+
expect(adapter.isConnected()).toBe(false);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
describe("getClient", () => {
|
|
47
|
+
it("should throw when not connected", () => {
|
|
48
|
+
expect(() => adapter.getClient()).toThrow(ConnectionException);
|
|
49
|
+
expect(() => adapter.getClient()).toThrow("Database client not initialized");
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
describe("beginTransaction", () => {
|
|
53
|
+
it("should create a transaction context", async () => {
|
|
54
|
+
await adapter.connect();
|
|
55
|
+
const tx = await adapter.beginTransaction();
|
|
56
|
+
expect(tx.id).toBeDefined();
|
|
57
|
+
expect(tx.isActive).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=drizzle-adapter.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drizzle-adapter.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/drizzle-adapter.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { DatabaseException, ConnectionException, MigrationException, TransactionException, RepositoryException, } from "../../exceptions/database.exception.js";
|
|
3
|
+
describe("Database Exceptions", () => {
|
|
4
|
+
it("should create DatabaseException", () => {
|
|
5
|
+
const err = new DatabaseException("test error");
|
|
6
|
+
expect(err).toBeInstanceOf(Error);
|
|
7
|
+
expect(err).toBeInstanceOf(DatabaseException);
|
|
8
|
+
expect(err.name).toBe("DatabaseException");
|
|
9
|
+
expect(err.message).toBe("test error");
|
|
10
|
+
});
|
|
11
|
+
it("should create ConnectionException", () => {
|
|
12
|
+
const err = new ConnectionException("connection failed");
|
|
13
|
+
expect(err).toBeInstanceOf(DatabaseException);
|
|
14
|
+
expect(err.name).toBe("ConnectionException");
|
|
15
|
+
});
|
|
16
|
+
it("should create MigrationException", () => {
|
|
17
|
+
const err = new MigrationException("migration failed");
|
|
18
|
+
expect(err).toBeInstanceOf(DatabaseException);
|
|
19
|
+
expect(err.name).toBe("MigrationException");
|
|
20
|
+
});
|
|
21
|
+
it("should create TransactionException", () => {
|
|
22
|
+
const err = new TransactionException("tx failed");
|
|
23
|
+
expect(err).toBeInstanceOf(DatabaseException);
|
|
24
|
+
expect(err.name).toBe("TransactionException");
|
|
25
|
+
});
|
|
26
|
+
it("should create RepositoryException", () => {
|
|
27
|
+
const err = new RepositoryException("repo failed");
|
|
28
|
+
expect(err).toBeInstanceOf(DatabaseException);
|
|
29
|
+
expect(err.name).toBe("RepositoryException");
|
|
30
|
+
});
|
|
31
|
+
it("should preserve cause", () => {
|
|
32
|
+
const cause = new Error("original");
|
|
33
|
+
const err = new ConnectionException("wrapped", { cause });
|
|
34
|
+
expect(err.cause).toBe(cause);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=exceptions.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exceptions.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/exceptions.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,wCAAwC,CAAC;AAEhD,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,GAAG,GAAG,IAAI,iBAAiB,CAAC,YAAY,CAAC,CAAC;QAChD,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAC3C,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,GAAG,GAAG,IAAI,mBAAmB,CAAC,mBAAmB,CAAC,CAAC;QACzD,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,GAAG,GAAG,IAAI,kBAAkB,CAAC,kBAAkB,CAAC,CAAC;QACvD,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,GAAG,GAAG,IAAI,oBAAoB,CAAC,WAAW,CAAC,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,GAAG,GAAG,IAAI,mBAAmB,CAAC,aAAa,CAAC,CAAC;QACnD,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;QACpC,MAAM,GAAG,GAAG,IAAI,mBAAmB,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1D,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from "bun:test";
|
|
2
|
+
import { dbMetadataStorage } from "../../metadata/db-storage.js";
|
|
3
|
+
describe("DbMetadataStorage", () => {
|
|
4
|
+
beforeEach(() => {
|
|
5
|
+
dbMetadataStorage.reset();
|
|
6
|
+
});
|
|
7
|
+
it("should register repository injection", () => {
|
|
8
|
+
const mockEntity = { name: "users" };
|
|
9
|
+
class TestService {
|
|
10
|
+
}
|
|
11
|
+
dbMetadataStorage.addRepositoryInjection({
|
|
12
|
+
target: TestService,
|
|
13
|
+
propertyKey: "userRepo",
|
|
14
|
+
entity: mockEntity,
|
|
15
|
+
});
|
|
16
|
+
const injections = dbMetadataStorage.getRepositoryInjectionsFor(TestService);
|
|
17
|
+
expect(injections).toHaveLength(1);
|
|
18
|
+
expect(injections[0].propertyKey).toBe("userRepo");
|
|
19
|
+
expect(injections[0].entity).toBe(mockEntity);
|
|
20
|
+
});
|
|
21
|
+
it("should return empty array for class without injections", () => {
|
|
22
|
+
class EmptyService {
|
|
23
|
+
}
|
|
24
|
+
const injections = dbMetadataStorage.getRepositoryInjectionsFor(EmptyService);
|
|
25
|
+
expect(injections).toHaveLength(0);
|
|
26
|
+
});
|
|
27
|
+
it("should support multiple injections on same class", () => {
|
|
28
|
+
const usersEntity = { name: "users" };
|
|
29
|
+
const postsEntity = { name: "posts" };
|
|
30
|
+
class TestService {
|
|
31
|
+
}
|
|
32
|
+
dbMetadataStorage.addRepositoryInjection({
|
|
33
|
+
target: TestService,
|
|
34
|
+
propertyKey: "userRepo",
|
|
35
|
+
entity: usersEntity,
|
|
36
|
+
});
|
|
37
|
+
dbMetadataStorage.addRepositoryInjection({
|
|
38
|
+
target: TestService,
|
|
39
|
+
propertyKey: "postRepo",
|
|
40
|
+
entity: postsEntity,
|
|
41
|
+
});
|
|
42
|
+
const injections = dbMetadataStorage.getRepositoryInjectionsFor(TestService);
|
|
43
|
+
expect(injections).toHaveLength(2);
|
|
44
|
+
});
|
|
45
|
+
it("should reset all injections", () => {
|
|
46
|
+
class TestService {
|
|
47
|
+
}
|
|
48
|
+
dbMetadataStorage.addRepositoryInjection({
|
|
49
|
+
target: TestService,
|
|
50
|
+
propertyKey: "repo",
|
|
51
|
+
entity: {},
|
|
52
|
+
});
|
|
53
|
+
dbMetadataStorage.reset();
|
|
54
|
+
const injections = dbMetadataStorage.getRepositoryInjectionsFor(TestService);
|
|
55
|
+
expect(injections).toHaveLength(0);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
//# sourceMappingURL=metadata.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/metadata.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,UAAU,CAAC,GAAG,EAAE;QACd,iBAAiB,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,UAAU,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAErC,MAAM,WAAW;SAAG;QAEpB,iBAAiB,CAAC,sBAAsB,CAAC;YACvC,MAAM,EAAE,WAAW;YACnB,WAAW,EAAE,UAAU;YACvB,MAAM,EAAE,UAAU;SACnB,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,iBAAiB,CAAC,0BAA0B,CAAC,WAAW,CAAC,CAAC;QAC7E,MAAM,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACnD,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,YAAY;SAAG;QACrB,MAAM,UAAU,GAAG,iBAAiB,CAAC,0BAA0B,CAAC,YAAY,CAAC,CAAC;QAC9E,MAAM,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,WAAW,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QACtC,MAAM,WAAW,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAEtC,MAAM,WAAW;SAAG;QAEpB,iBAAiB,CAAC,sBAAsB,CAAC;YACvC,MAAM,EAAE,WAAW;YACnB,WAAW,EAAE,UAAU;YACvB,MAAM,EAAE,WAAW;SACpB,CAAC,CAAC;QAEH,iBAAiB,CAAC,sBAAsB,CAAC;YACvC,MAAM,EAAE,WAAW;YACnB,WAAW,EAAE,UAAU;YACvB,MAAM,EAAE,WAAW;SACpB,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,iBAAiB,CAAC,0BAA0B,CAAC,WAAW,CAAC,CAAC;QAC7E,MAAM,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,WAAW;SAAG;QAEpB,iBAAiB,CAAC,sBAAsB,CAAC;YACvC,MAAM,EAAE,WAAW;YACnB,WAAW,EAAE,MAAM;YACnB,MAAM,EAAE,EAAE;SACX,CAAC,CAAC;QAEH,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAE1B,MAAM,UAAU,GAAG,iBAAiB,CAAC,0BAA0B,CAAC,WAAW,CAAC,CAAC;QAC7E,MAAM,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach } from "bun:test";
|
|
2
|
+
import { TransactionManager } from "../../core/transaction-manager.js";
|
|
3
|
+
import { TransactionException } from "../../exceptions/database.exception.js";
|
|
4
|
+
import { DatabaseModule } from "../../core/database.module.js";
|
|
5
|
+
import { unlinkSync } from "fs";
|
|
6
|
+
describe("TransactionManager", () => {
|
|
7
|
+
const dbPath = "/tmp/test-transaction.db";
|
|
8
|
+
afterEach(async () => {
|
|
9
|
+
try {
|
|
10
|
+
unlinkSync(dbPath);
|
|
11
|
+
unlinkSync(`${dbPath}-wal`);
|
|
12
|
+
unlinkSync(`${dbPath}-shm`);
|
|
13
|
+
}
|
|
14
|
+
catch { }
|
|
15
|
+
});
|
|
16
|
+
function setupAdapter() {
|
|
17
|
+
DatabaseModule.forRoot({
|
|
18
|
+
adapter: "drizzle",
|
|
19
|
+
url: `file:${dbPath}`,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
it("should run function in transaction and return result", async () => {
|
|
23
|
+
setupAdapter();
|
|
24
|
+
const adapter = DatabaseModule.getAdapter();
|
|
25
|
+
await adapter.connect();
|
|
26
|
+
const txManager = new TransactionManager();
|
|
27
|
+
const result = await txManager.runInTransaction(async () => {
|
|
28
|
+
return "success";
|
|
29
|
+
});
|
|
30
|
+
expect(result).toBe("success");
|
|
31
|
+
await adapter.disconnect();
|
|
32
|
+
});
|
|
33
|
+
it("should throw TransactionException on error", async () => {
|
|
34
|
+
setupAdapter();
|
|
35
|
+
const adapter = DatabaseModule.getAdapter();
|
|
36
|
+
await adapter.connect();
|
|
37
|
+
const txManager = new TransactionManager();
|
|
38
|
+
await expect(txManager.runInTransaction(async () => {
|
|
39
|
+
throw new Error("test error");
|
|
40
|
+
})).rejects.toThrow(TransactionException);
|
|
41
|
+
await adapter.disconnect();
|
|
42
|
+
});
|
|
43
|
+
it("should timeout if specified", async () => {
|
|
44
|
+
setupAdapter();
|
|
45
|
+
const adapter = DatabaseModule.getAdapter();
|
|
46
|
+
await adapter.connect();
|
|
47
|
+
const txManager = new TransactionManager();
|
|
48
|
+
await expect(txManager.runInTransaction(async () => {
|
|
49
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
50
|
+
return "should not reach";
|
|
51
|
+
}, { timeout: 50 })).rejects.toThrow("Transaction timed out");
|
|
52
|
+
await adapter.disconnect();
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=transactional.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transactional.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/transactional.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAEhC,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,MAAM,MAAM,GAAG,0BAA0B,CAAC;IAE1C,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,IAAI,CAAC;YACH,UAAU,CAAC,MAAM,CAAC,CAAC;YACnB,UAAU,CAAC,GAAG,MAAM,MAAM,CAAC,CAAC;YAC5B,UAAU,CAAC,GAAG,MAAM,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC,CAAC,CAAC;IAEH,SAAS,YAAY;QACnB,cAAc,CAAC,OAAO,CAAC;YACrB,OAAO,EAAE,SAAS;YAClB,GAAG,EAAE,QAAQ,MAAM,EAAE;SACtB,CAAC,CAAC;IACL,CAAC;IAED,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,YAAY,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,EAAE,CAAC;QAC5C,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QAExB,MAAM,SAAS,GAAG,IAAI,kBAAkB,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,gBAAgB,CAAC,KAAK,IAAI,EAAE;YACzD,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/B,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,YAAY,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,EAAE,CAAC;QAC5C,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QAExB,MAAM,SAAS,GAAG,IAAI,kBAAkB,EAAE,CAAC;QAE3C,MAAM,MAAM,CACV,SAAS,CAAC,gBAAgB,CAAC,KAAK,IAAI,EAAE;YACpC,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;QAChC,CAAC,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAExC,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,YAAY,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,EAAE,CAAC;QAC5C,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QAExB,MAAM,SAAS,GAAG,IAAI,kBAAkB,EAAE,CAAC;QAE3C,MAAM,MAAM,CACV,SAAS,CAAC,gBAAgB,CACxB,KAAK,IAAI,EAAE;YACT,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YACzD,OAAO,kBAAkB,CAAC;QAC5B,CAAC,EACD,EAAE,OAAO,EAAE,EAAE,EAAE,CAChB,CACF,CAAC,OAAO,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;QAE3C,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Logger } from "@cinnabun/core";
|
|
2
|
+
import type { DatabaseAdapter, TransactionContext } from "../../interfaces/database-adapter.interface.js";
|
|
3
|
+
import type { DatabaseModuleOptions } from "../../interfaces/options.interface.js";
|
|
4
|
+
export declare abstract class BaseAdapter<TClient = unknown> implements DatabaseAdapter<TClient> {
|
|
5
|
+
protected options: DatabaseModuleOptions;
|
|
6
|
+
protected client: TClient | null;
|
|
7
|
+
protected connected: boolean;
|
|
8
|
+
protected logger: Logger;
|
|
9
|
+
constructor(options: DatabaseModuleOptions);
|
|
10
|
+
abstract connect(): Promise<void>;
|
|
11
|
+
abstract disconnect(): Promise<void>;
|
|
12
|
+
abstract runMigrations(): Promise<void>;
|
|
13
|
+
abstract generateMigration(name: string): Promise<string>;
|
|
14
|
+
abstract beginTransaction(): Promise<TransactionContext>;
|
|
15
|
+
abstract commitTransaction(tx: TransactionContext): Promise<void>;
|
|
16
|
+
abstract rollbackTransaction(tx: TransactionContext): Promise<void>;
|
|
17
|
+
getClient(): TClient;
|
|
18
|
+
isConnected(): boolean;
|
|
19
|
+
protected shouldLog(type: "queries" | "errors" | "migrations"): boolean;
|
|
20
|
+
}
|