@pineliner/odb-client 1.0.0 → 1.0.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.
@@ -86,10 +86,10 @@ export declare class ServiceClient {
86
86
  * Create a new database
87
87
  *
88
88
  * @param name - Database name (should be unique)
89
- * @param nodeId - ID of the node to host the database
89
+ * @param nodeId - ID of the node to host the database (optional - server will select if null)
90
90
  * @returns Created database object with hash
91
91
  */
92
- createDatabase(name: string, nodeId: string): Promise<ODBLiteDatabase>;
92
+ createDatabase(name: string, nodeId?: string | null): Promise<ODBLiteDatabase>;
93
93
  /**
94
94
  * Get database details by hash
95
95
  *
@@ -97,6 +97,13 @@ export declare class ServiceClient {
97
97
  * @returns Database object
98
98
  */
99
99
  getDatabase(hash: string): Promise<ODBLiteDatabase>;
100
+ /**
101
+ * Get database details by name
102
+ *
103
+ * @param name - Database name
104
+ * @returns Database object or null if not found
105
+ */
106
+ getDatabaseByName(name: string): Promise<ODBLiteDatabase | null>;
100
107
  /**
101
108
  * Delete a database
102
109
  *
@@ -1 +1 @@
1
- {"version":3,"file":"service-client.d.ts","sourceRoot":"","sources":["../../src/service/service-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,aAAa,CAAsB;gBAE/B,MAAM,EAAE,mBAAmB;IAMvC;;;;;;;;;;;;;;;;;;OAkBG;IACG,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkDhF;;;;;;OAMG;IACG,aAAa,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAejD;;;;;;OAMG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAkB5E;;;;;OAKG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAezD;;;;OAIG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBjD;;;;OAIG;IACG,SAAS,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAezC;;;;;;;;;;;OAWG;IACG,KAAK,CAAC,CAAC,GAAG,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,GAAG,EAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAkBvF;;;;OAIG;IACH,UAAU,IAAI,IAAI;IAIlB;;;;;;OAMG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAKnE;;;;;;;;;OASG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;CAIpE"}
1
+ {"version":3,"file":"service-client.d.ts","sourceRoot":"","sources":["../../src/service/service-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,aAAa,CAAsB;gBAE/B,MAAM,EAAE,mBAAmB;IAMvC;;;;;;;;;;;;;;;;;;OAkBG;IACG,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiDhF;;;;;;OAMG;IACG,aAAa,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAejD;;;;;;OAMG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC;IAuBpF;;;;;OAKG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAezD;;;;;OAKG;IACG,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAmBtE;;;;OAIG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBjD;;;;OAIG;IACG,SAAS,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAezC;;;;;;;;;;;OAWG;IACG,KAAK,CAAC,CAAC,GAAG,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,GAAG,EAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAkBvF;;;;OAIG;IACH,UAAU,IAAI,IAAI;IAIlB;;;;;;OAMG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAKnE;;;;;;;;;OASG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;CAIpE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pineliner/odb-client",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Isomorphic client for ODB-Lite with postgres.js-like template string SQL support",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -14,11 +14,12 @@
14
14
  "deploy": "bun run build && npm publish --access public"
15
15
  },
16
16
  "dependencies": {
17
- "@libsql/client": "^0.15.15"
17
+ "@libsql/client": "^0.15.15",
18
+ "node-sql-parser": "^5.3.12"
18
19
  },
19
20
  "devDependencies": {
20
21
  "@types/bun": "latest",
21
- "@rslib/core": "^0.0.14",
22
+ "@rslib/core": "0.15.0",
22
23
  "typescript": "^5.9.2"
23
24
  },
24
25
  "exports": {
@@ -0,0 +1,170 @@
1
+ import { Database } from 'bun:sqlite'
2
+ import type {
3
+ DatabaseAdapter,
4
+ Connection,
5
+ QueryResult,
6
+ PreparedStatement,
7
+ BunSQLiteConfig,
8
+ } from '../types'
9
+
10
+ /**
11
+ * Bun SQLite adapter for DatabaseManager
12
+ * Wraps bun:sqlite with Connection interface
13
+ */
14
+ export class BunSQLiteAdapter implements DatabaseAdapter {
15
+ readonly type = 'bun-sqlite' as const
16
+ private config: BunSQLiteConfig
17
+
18
+ constructor(config: BunSQLiteConfig) {
19
+ this.config = config
20
+ }
21
+
22
+ async connect(config: BunSQLiteConfig): Promise<Connection> {
23
+ const db = new Database(config.databasePath, {
24
+ readonly: config.readonly,
25
+ create: config.create ?? true,
26
+ })
27
+
28
+ return new BunSQLiteConnection(db)
29
+ }
30
+
31
+ async disconnect(tenantId?: string): Promise<void> {
32
+ // bun:sqlite doesn't require explicit disconnection
33
+ // File handles are cleaned up by GC
34
+ }
35
+
36
+ async isHealthy(): Promise<boolean> {
37
+ try {
38
+ const db = new Database(this.config.databasePath, {
39
+ readonly: true,
40
+ create: false,
41
+ })
42
+ db.query('SELECT 1').get()
43
+ db.close()
44
+ return true
45
+ } catch {
46
+ return false
47
+ }
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Connection implementation for Bun SQLite
53
+ */
54
+ class BunSQLiteConnection implements Connection {
55
+ private db: Database
56
+ private inTransaction = false
57
+
58
+ constructor(db: Database) {
59
+ this.db = db
60
+ }
61
+
62
+ /**
63
+ * Template tag query (postgres.js-like)
64
+ */
65
+ async query<T = any>(
66
+ strings: TemplateStringsArray,
67
+ ...values: any[]
68
+ ): Promise<QueryResult<T>> {
69
+ // Build SQL from template
70
+ const sql = strings.reduce((acc, str, i) => {
71
+ return acc + str + (i < values.length ? '?' : '')
72
+ }, '')
73
+
74
+ return this.execute(sql, values)
75
+ }
76
+
77
+ /**
78
+ * Execute SQL with parameters
79
+ */
80
+ async execute(sql: string, params: any[] = []): Promise<QueryResult> {
81
+ try {
82
+ const stmt = this.db.query(sql)
83
+ const isSelect = sql.trim().toUpperCase().startsWith('SELECT')
84
+
85
+ if (isSelect) {
86
+ const rows = stmt.all(...params)
87
+ return {
88
+ rows: rows as any[],
89
+ rowsAffected: 0,
90
+ }
91
+ } else {
92
+ const result = stmt.run(...params)
93
+ return {
94
+ rows: [],
95
+ rowsAffected: result.changes || 0,
96
+ lastInsertRowid: result.lastInsertRowid,
97
+ }
98
+ }
99
+ } catch (error: any) {
100
+ throw new Error(`SQL execution failed: ${error.message}`)
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Prepare statement for repeated execution
106
+ */
107
+ prepare(sql: string): PreparedStatement {
108
+ const stmt = this.db.query(sql)
109
+
110
+ return {
111
+ execute: async (params: any[] = []) => {
112
+ const isSelect = sql.trim().toUpperCase().startsWith('SELECT')
113
+
114
+ if (isSelect) {
115
+ const rows = stmt.all(...params)
116
+ return {
117
+ rows: rows as any[],
118
+ rowsAffected: 0,
119
+ }
120
+ } else {
121
+ const result = stmt.run(...params)
122
+ return {
123
+ rows: [],
124
+ rowsAffected: result.changes || 0,
125
+ lastInsertRowid: result.lastInsertRowid,
126
+ }
127
+ }
128
+ },
129
+
130
+ all: async (params: any[] = []) => {
131
+ return stmt.all(...params) as any[]
132
+ },
133
+
134
+ get: async (params: any[] = []) => {
135
+ return stmt.get(...params) as any
136
+ },
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Execute function in transaction
142
+ */
143
+ async transaction<T>(fn: (tx: Connection) => Promise<T>): Promise<T> {
144
+ if (this.inTransaction) {
145
+ // Nested transaction - just execute the function
146
+ return fn(this)
147
+ }
148
+
149
+ this.inTransaction = true
150
+
151
+ try {
152
+ await this.execute('BEGIN')
153
+ const result = await fn(this)
154
+ await this.execute('COMMIT')
155
+ return result
156
+ } catch (error) {
157
+ await this.execute('ROLLBACK')
158
+ throw error
159
+ } finally {
160
+ this.inTransaction = false
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Close connection
166
+ */
167
+ async close(): Promise<void> {
168
+ this.db.close()
169
+ }
170
+ }
@@ -0,0 +1,156 @@
1
+ import { createClient, Client, Transaction as LibSQLTransaction } from '@libsql/client'
2
+ import type {
3
+ DatabaseAdapter,
4
+ Connection,
5
+ QueryResult,
6
+ PreparedStatement,
7
+ LibSQLConfig,
8
+ } from '../types'
9
+
10
+ /**
11
+ * LibSQL adapter for DatabaseManager
12
+ * Wraps @libsql/client with Connection interface
13
+ */
14
+ export class LibSQLAdapter implements DatabaseAdapter {
15
+ readonly type = 'libsql' as const
16
+ private config: LibSQLConfig
17
+
18
+ constructor(config: LibSQLConfig) {
19
+ this.config = config
20
+ }
21
+
22
+ async connect(config: LibSQLConfig): Promise<Connection> {
23
+ const client = createClient({
24
+ url: config.url,
25
+ authToken: config.authToken,
26
+ encryptionKey: config.encryptionKey,
27
+ })
28
+
29
+ return new LibSQLConnection(client)
30
+ }
31
+
32
+ async disconnect(tenantId?: string): Promise<void> {
33
+ // LibSQL clients don't require explicit disconnection
34
+ // Connections are pooled internally
35
+ }
36
+
37
+ async isHealthy(): Promise<boolean> {
38
+ try {
39
+ const client = createClient({
40
+ url: this.config.url,
41
+ authToken: this.config.authToken,
42
+ })
43
+ await client.execute('SELECT 1')
44
+ return true
45
+ } catch {
46
+ return false
47
+ }
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Connection implementation for LibSQL
53
+ */
54
+ class LibSQLConnection implements Connection {
55
+ private client: Client
56
+ private txClient?: LibSQLTransaction
57
+
58
+ constructor(client: Client) {
59
+ this.client = client
60
+ }
61
+
62
+ /**
63
+ * Template tag query (postgres.js-like)
64
+ */
65
+ async query<T = any>(
66
+ strings: TemplateStringsArray,
67
+ ...values: any[]
68
+ ): Promise<QueryResult<T>> {
69
+ // Build SQL from template
70
+ const sql = strings.reduce((acc, str, i) => {
71
+ return acc + str + (i < values.length ? '?' : '')
72
+ }, '')
73
+
74
+ return this.execute(sql, values)
75
+ }
76
+
77
+ /**
78
+ * Execute SQL with parameters
79
+ * Supports both formats: execute(sql, params) and execute({sql, args})
80
+ */
81
+ async execute(sql: string | { sql: string; args?: any[] }, params: any[] = []): Promise<QueryResult> {
82
+ try {
83
+ const target = this.txClient || this.client
84
+
85
+ // Support both execute(sql, params) and execute({sql, args}) formats
86
+ let query: { sql: string; args: any[] }
87
+ if (typeof sql === 'string') {
88
+ query = { sql, args: params }
89
+ } else {
90
+ query = { sql: sql.sql, args: sql.args || [] }
91
+ }
92
+
93
+ const result = await target.execute(query)
94
+
95
+ return {
96
+ rows: result.rows as any[],
97
+ rowsAffected: Number(result.rowsAffected),
98
+ lastInsertRowid: result.lastInsertRowid
99
+ ? BigInt(result.lastInsertRowid.toString())
100
+ : undefined,
101
+ }
102
+ } catch (error: any) {
103
+ throw new Error(`SQL execution failed: ${error.message}`)
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Prepare statement for repeated execution
109
+ */
110
+ prepare(sql: string): PreparedStatement {
111
+ return {
112
+ execute: async (params: any[] = []) => {
113
+ return this.execute(sql, params)
114
+ },
115
+
116
+ all: async (params: any[] = []) => {
117
+ const result = await this.execute(sql, params)
118
+ return result.rows
119
+ },
120
+
121
+ get: async (params: any[] = []) => {
122
+ const result = await this.execute(sql, params)
123
+ return result.rows[0] || null
124
+ },
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Execute function in transaction
130
+ */
131
+ async transaction<T>(fn: (tx: Connection) => Promise<T>): Promise<T> {
132
+ if (this.txClient) {
133
+ // Nested transaction - just execute the function
134
+ return fn(this)
135
+ }
136
+
137
+ // Use manual BEGIN/COMMIT/ROLLBACK for simplicity
138
+ try {
139
+ await this.execute('BEGIN')
140
+ const result = await fn(this)
141
+ await this.execute('COMMIT')
142
+ return result
143
+ } catch (error) {
144
+ await this.execute('ROLLBACK')
145
+ throw error
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Close connection
151
+ */
152
+ async close(): Promise<void> {
153
+ // LibSQL client.close() if available in future versions
154
+ // For now, connections are managed by the client pool
155
+ }
156
+ }
@@ -0,0 +1,181 @@
1
+ import { ServiceClient } from '../../service/service-client'
2
+ import { ODBLiteClient } from '../../core/client'
3
+ import type {
4
+ DatabaseAdapter,
5
+ Connection,
6
+ QueryResult,
7
+ PreparedStatement,
8
+ ODBLiteConfig,
9
+ } from '../types'
10
+
11
+ /**
12
+ * ODB-Lite adapter for DatabaseManager
13
+ * Wraps ServiceClient and ODBLiteClient with Connection interface
14
+ */
15
+ export class ODBLiteAdapter implements DatabaseAdapter {
16
+ readonly type = 'odblite' as const
17
+ private config: ODBLiteConfig
18
+ private serviceClient: ServiceClient
19
+
20
+ constructor(config: ODBLiteConfig) {
21
+ this.config = config
22
+ this.serviceClient = new ServiceClient({
23
+ baseUrl: config.serviceUrl,
24
+ apiKey: config.apiKey,
25
+ })
26
+ }
27
+
28
+ async connect(config: any): Promise<Connection> {
29
+ const databaseName = config.databaseName || 'default'
30
+
31
+ // Ensure database exists
32
+ const dbInfo = await this.serviceClient.getDatabaseByName(databaseName)
33
+
34
+ if (!dbInfo) {
35
+ // Create database - pass nodeId from config if provided, otherwise server selects
36
+ await this.serviceClient.createDatabase(databaseName, this.config.nodeId)
37
+ }
38
+
39
+ // Get fresh database info
40
+ const db = await this.serviceClient.getDatabaseByName(databaseName)
41
+ if (!db) {
42
+ throw new Error(`Database ${databaseName} not found after creation`)
43
+ }
44
+
45
+ // Create ODBLiteClient for this database
46
+ const client = new ODBLiteClient({
47
+ baseUrl: this.config.serviceUrl,
48
+ apiKey: this.config.apiKey,
49
+ databaseId: db.hash,
50
+ })
51
+
52
+ return new ODBLiteConnection(client, this.serviceClient, databaseName)
53
+ }
54
+
55
+ async disconnect(tenantId?: string): Promise<void> {
56
+ if (tenantId) {
57
+ const prefix = 'pipeline_tenant_' // TODO: make configurable
58
+ const databaseName = `${prefix}${tenantId}`
59
+
60
+ try {
61
+ await this.serviceClient.deleteDatabase(databaseName)
62
+ } catch (error: any) {
63
+ console.warn(`Failed to delete database ${databaseName}:`, error.message)
64
+ }
65
+ }
66
+ }
67
+
68
+ async isHealthy(): Promise<boolean> {
69
+ try {
70
+ await this.serviceClient.listDatabases()
71
+ return true
72
+ } catch {
73
+ return false
74
+ }
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Connection implementation for ODB-Lite
80
+ */
81
+ class ODBLiteConnection implements Connection {
82
+ private client: ODBLiteClient
83
+ private serviceClient: ServiceClient
84
+ private databaseName: string
85
+ private inTransaction = false
86
+
87
+ constructor(
88
+ client: ODBLiteClient,
89
+ serviceClient: ServiceClient,
90
+ databaseName: string
91
+ ) {
92
+ this.client = client
93
+ this.serviceClient = serviceClient
94
+ this.databaseName = databaseName
95
+ }
96
+
97
+ /**
98
+ * Template tag query (postgres.js-like)
99
+ */
100
+ async query<T = any>(
101
+ strings: TemplateStringsArray,
102
+ ...values: any[]
103
+ ): Promise<QueryResult<T>> {
104
+ // ODBLiteClient.sql is a function that returns a Promise
105
+ const result = await this.client.sql(strings, ...values)
106
+
107
+ return {
108
+ rows: result.rows as T[],
109
+ rowsAffected: result.rowsAffected || 0,
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Execute SQL with parameters
115
+ */
116
+ async execute(sql: string, params: any[] = []): Promise<QueryResult> {
117
+ try {
118
+ const result = await this.client.sql.execute(sql, params)
119
+
120
+ return {
121
+ rows: result.rows,
122
+ rowsAffected: result.rowsAffected || 0,
123
+ }
124
+ } catch (error: any) {
125
+ throw new Error(`SQL execution failed: ${error.message}`)
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Prepare statement for repeated execution
131
+ */
132
+ prepare(sql: string): PreparedStatement {
133
+ return {
134
+ execute: async (params: any[] = []) => {
135
+ return this.execute(sql, params)
136
+ },
137
+
138
+ all: async (params: any[] = []) => {
139
+ const result = await this.execute(sql, params)
140
+ return result.rows
141
+ },
142
+
143
+ get: async (params: any[] = []) => {
144
+ const result = await this.execute(sql, params)
145
+ return result.rows[0] || null
146
+ },
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Execute function in transaction
152
+ */
153
+ async transaction<T>(fn: (tx: Connection) => Promise<T>): Promise<T> {
154
+ if (this.inTransaction) {
155
+ // Nested transaction - just execute the function
156
+ return fn(this)
157
+ }
158
+
159
+ this.inTransaction = true
160
+
161
+ try {
162
+ await this.execute('BEGIN')
163
+ const result = await fn(this)
164
+ await this.execute('COMMIT')
165
+ return result
166
+ } catch (error) {
167
+ await this.execute('ROLLBACK')
168
+ throw error
169
+ } finally {
170
+ this.inTransaction = false
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Close connection
176
+ */
177
+ async close(): Promise<void> {
178
+ // ODBLiteClient connections are stateless HTTP requests
179
+ // No explicit close needed
180
+ }
181
+ }
@@ -0,0 +1,32 @@
1
+ // Database Manager - Unified database abstraction for all systems
2
+ export { DatabaseManager } from './manager'
3
+
4
+ // SQL Parser utilities
5
+ export { parseSQL, splitSQLStatements } from './sql-parser'
6
+ export type { ParsedStatements, SQLParserOptions } from './sql-parser'
7
+
8
+ // Backend adapters
9
+ export { BunSQLiteAdapter } from './adapters/bun-sqlite'
10
+ export { LibSQLAdapter } from './adapters/libsql'
11
+ export { ODBLiteAdapter } from './adapters/odblite'
12
+
13
+ // Export all types
14
+ export type {
15
+ // Core types
16
+ TenancyMode,
17
+ BackendType,
18
+ QueryResult,
19
+ Connection,
20
+ DatabaseAdapter,
21
+ PreparedStatement,
22
+
23
+ // Configuration types
24
+ DatabaseManagerConfig,
25
+ MigrationConfig,
26
+ BunSQLiteConfig,
27
+ LibSQLConfig,
28
+ ODBLiteConfig,
29
+
30
+ // Tenant management
31
+ TenantInfo,
32
+ } from './types'