@tursodatabase/serverless 0.1.1 → 0.1.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/dist/compat.js +27 -7
- package/dist/connection.d.ts +14 -2
- package/dist/connection.js +23 -3
- package/dist/error.d.ts +3 -0
- package/dist/error.js +7 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/protocol.d.ts +16 -4
- package/dist/protocol.js +39 -24
- package/dist/session.d.ts +18 -4
- package/dist/session.js +98 -6
- package/dist/statement.d.ts +29 -9
- package/dist/statement.js +80 -17
- package/dist/transaction.d.ts +131 -0
- package/dist/transaction.js +207 -0
- package/package.json +1 -1
- package/dist/client.d.ts +0 -31
- package/dist/client.js +0 -184
package/dist/compat.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Session } from './session.js';
|
|
2
2
|
/**
|
|
3
3
|
* libSQL-compatible error class with error codes.
|
|
4
4
|
*/
|
|
@@ -14,11 +14,11 @@ class LibSQLClient {
|
|
|
14
14
|
constructor(config) {
|
|
15
15
|
this._closed = false;
|
|
16
16
|
this.validateConfig(config);
|
|
17
|
-
const
|
|
17
|
+
const sessionConfig = {
|
|
18
18
|
url: config.url,
|
|
19
19
|
authToken: config.authToken || ''
|
|
20
20
|
};
|
|
21
|
-
this.
|
|
21
|
+
this.session = new Session(sessionConfig);
|
|
22
22
|
}
|
|
23
23
|
validateConfig(config) {
|
|
24
24
|
// Check for unsupported config options
|
|
@@ -108,8 +108,15 @@ class LibSQLClient {
|
|
|
108
108
|
else {
|
|
109
109
|
normalizedStmt = this.normalizeStatement(stmtOrSql);
|
|
110
110
|
}
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
await this.session.sequence(normalizedStmt.sql);
|
|
112
|
+
// Return empty result set for sequence execution
|
|
113
|
+
return this.convertResult({
|
|
114
|
+
columns: [],
|
|
115
|
+
columnTypes: [],
|
|
116
|
+
rows: [],
|
|
117
|
+
rowsAffected: 0,
|
|
118
|
+
lastInsertRowid: undefined
|
|
119
|
+
});
|
|
113
120
|
}
|
|
114
121
|
catch (error) {
|
|
115
122
|
throw new LibsqlError(error.message, "EXECUTE_ERROR");
|
|
@@ -124,7 +131,7 @@ class LibSQLClient {
|
|
|
124
131
|
const normalized = this.normalizeStatement(stmt);
|
|
125
132
|
return normalized.sql; // For now, ignore args in batch
|
|
126
133
|
});
|
|
127
|
-
const result = await this.
|
|
134
|
+
const result = await this.session.batch(sqlStatements);
|
|
128
135
|
// Return array of result sets (simplified - actual implementation would be more complex)
|
|
129
136
|
return [this.convertResult(result)];
|
|
130
137
|
}
|
|
@@ -140,13 +147,26 @@ class LibSQLClient {
|
|
|
140
147
|
throw new LibsqlError("Transactions not implemented", "NOT_IMPLEMENTED");
|
|
141
148
|
}
|
|
142
149
|
async executeMultiple(sql) {
|
|
143
|
-
|
|
150
|
+
try {
|
|
151
|
+
if (this._closed) {
|
|
152
|
+
throw new LibsqlError("Client is closed", "CLIENT_CLOSED");
|
|
153
|
+
}
|
|
154
|
+
await this.session.sequence(sql);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
throw new LibsqlError(error.message, "EXECUTE_MULTIPLE_ERROR");
|
|
158
|
+
}
|
|
144
159
|
}
|
|
145
160
|
async sync() {
|
|
146
161
|
throw new LibsqlError("Sync not supported for remote databases", "NOT_SUPPORTED");
|
|
147
162
|
}
|
|
148
163
|
close() {
|
|
149
164
|
this._closed = true;
|
|
165
|
+
// Note: The libSQL client interface expects synchronous close,
|
|
166
|
+
// but our underlying session needs async close. We'll fire and forget.
|
|
167
|
+
this.session.close().catch(error => {
|
|
168
|
+
console.error('Error closing session:', error);
|
|
169
|
+
});
|
|
150
170
|
}
|
|
151
171
|
}
|
|
152
172
|
/**
|
package/dist/connection.d.ts
CHANGED
|
@@ -35,7 +35,6 @@ export declare class Connection {
|
|
|
35
35
|
* Execute a SQL statement and return all results.
|
|
36
36
|
*
|
|
37
37
|
* @param sql - The SQL statement to execute
|
|
38
|
-
* @param args - Optional array of parameter values
|
|
39
38
|
* @returns Promise resolving to the complete result set
|
|
40
39
|
*
|
|
41
40
|
* @example
|
|
@@ -44,7 +43,7 @@ export declare class Connection {
|
|
|
44
43
|
* console.log(result.rows);
|
|
45
44
|
* ```
|
|
46
45
|
*/
|
|
47
|
-
|
|
46
|
+
exec(sql: string): Promise<any>;
|
|
48
47
|
/**
|
|
49
48
|
* Execute multiple SQL statements in a batch.
|
|
50
49
|
*
|
|
@@ -62,6 +61,19 @@ export declare class Connection {
|
|
|
62
61
|
* ```
|
|
63
62
|
*/
|
|
64
63
|
batch(statements: string[], mode?: string): Promise<any>;
|
|
64
|
+
/**
|
|
65
|
+
* Execute a pragma.
|
|
66
|
+
*
|
|
67
|
+
* @param pragma - The pragma to execute
|
|
68
|
+
* @returns Promise resolving to the result of the pragma
|
|
69
|
+
*/
|
|
70
|
+
pragma(pragma: string): Promise<any>;
|
|
71
|
+
/**
|
|
72
|
+
* Close the connection.
|
|
73
|
+
*
|
|
74
|
+
* This sends a close request to the server to properly clean up the stream.
|
|
75
|
+
*/
|
|
76
|
+
close(): Promise<void>;
|
|
65
77
|
}
|
|
66
78
|
/**
|
|
67
79
|
* Create a new connection to a Turso database.
|
package/dist/connection.js
CHANGED
|
@@ -8,6 +8,9 @@ import { Statement } from './statement.js';
|
|
|
8
8
|
*/
|
|
9
9
|
export class Connection {
|
|
10
10
|
constructor(config) {
|
|
11
|
+
if (!config.url) {
|
|
12
|
+
throw new Error("invalid config: url is required");
|
|
13
|
+
}
|
|
11
14
|
this.config = config;
|
|
12
15
|
this.session = new Session(config);
|
|
13
16
|
}
|
|
@@ -33,7 +36,6 @@ export class Connection {
|
|
|
33
36
|
* Execute a SQL statement and return all results.
|
|
34
37
|
*
|
|
35
38
|
* @param sql - The SQL statement to execute
|
|
36
|
-
* @param args - Optional array of parameter values
|
|
37
39
|
* @returns Promise resolving to the complete result set
|
|
38
40
|
*
|
|
39
41
|
* @example
|
|
@@ -42,8 +44,8 @@ export class Connection {
|
|
|
42
44
|
* console.log(result.rows);
|
|
43
45
|
* ```
|
|
44
46
|
*/
|
|
45
|
-
async
|
|
46
|
-
return this.session.
|
|
47
|
+
async exec(sql) {
|
|
48
|
+
return this.session.sequence(sql);
|
|
47
49
|
}
|
|
48
50
|
/**
|
|
49
51
|
* Execute multiple SQL statements in a batch.
|
|
@@ -64,6 +66,24 @@ export class Connection {
|
|
|
64
66
|
async batch(statements, mode) {
|
|
65
67
|
return this.session.batch(statements);
|
|
66
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Execute a pragma.
|
|
71
|
+
*
|
|
72
|
+
* @param pragma - The pragma to execute
|
|
73
|
+
* @returns Promise resolving to the result of the pragma
|
|
74
|
+
*/
|
|
75
|
+
async pragma(pragma) {
|
|
76
|
+
const sql = `PRAGMA ${pragma}`;
|
|
77
|
+
return this.session.execute(sql);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Close the connection.
|
|
81
|
+
*
|
|
82
|
+
* This sends a close request to the server to properly clean up the stream.
|
|
83
|
+
*/
|
|
84
|
+
async close() {
|
|
85
|
+
await this.session.close();
|
|
86
|
+
}
|
|
67
87
|
}
|
|
68
88
|
/**
|
|
69
89
|
* Create a new connection to a Turso database.
|
package/dist/error.d.ts
ADDED
package/dist/error.js
ADDED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/protocol.d.ts
CHANGED
|
@@ -13,12 +13,16 @@ export interface ExecuteResult {
|
|
|
13
13
|
affected_row_count: number;
|
|
14
14
|
last_insert_rowid?: string;
|
|
15
15
|
}
|
|
16
|
+
export interface NamedArg {
|
|
17
|
+
name: string;
|
|
18
|
+
value: Value;
|
|
19
|
+
}
|
|
16
20
|
export interface ExecuteRequest {
|
|
17
21
|
type: 'execute';
|
|
18
22
|
stmt: {
|
|
19
23
|
sql: string;
|
|
20
24
|
args: Value[];
|
|
21
|
-
named_args:
|
|
25
|
+
named_args: NamedArg[];
|
|
22
26
|
want_rows: boolean;
|
|
23
27
|
};
|
|
24
28
|
}
|
|
@@ -26,6 +30,7 @@ export interface BatchStep {
|
|
|
26
30
|
stmt: {
|
|
27
31
|
sql: string;
|
|
28
32
|
args: Value[];
|
|
33
|
+
named_args?: NamedArg[];
|
|
29
34
|
want_rows: boolean;
|
|
30
35
|
};
|
|
31
36
|
condition?: {
|
|
@@ -39,9 +44,16 @@ export interface BatchRequest {
|
|
|
39
44
|
steps: BatchStep[];
|
|
40
45
|
};
|
|
41
46
|
}
|
|
47
|
+
export interface SequenceRequest {
|
|
48
|
+
type: 'sequence';
|
|
49
|
+
sql: string;
|
|
50
|
+
}
|
|
51
|
+
export interface CloseRequest {
|
|
52
|
+
type: 'close';
|
|
53
|
+
}
|
|
42
54
|
export interface PipelineRequest {
|
|
43
55
|
baton: string | null;
|
|
44
|
-
requests: (ExecuteRequest | BatchRequest)[];
|
|
56
|
+
requests: (ExecuteRequest | BatchRequest | SequenceRequest | CloseRequest)[];
|
|
45
57
|
}
|
|
46
58
|
export interface PipelineResponse {
|
|
47
59
|
baton: string | null;
|
|
@@ -49,8 +61,8 @@ export interface PipelineResponse {
|
|
|
49
61
|
results: Array<{
|
|
50
62
|
type: 'ok' | 'error';
|
|
51
63
|
response?: {
|
|
52
|
-
type: 'execute' | 'batch';
|
|
53
|
-
result
|
|
64
|
+
type: 'execute' | 'batch' | 'sequence' | 'close';
|
|
65
|
+
result?: ExecuteResult;
|
|
54
66
|
};
|
|
55
67
|
error?: {
|
|
56
68
|
message: string;
|
package/dist/protocol.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DatabaseError } from './error.js';
|
|
1
2
|
export function encodeValue(value) {
|
|
2
3
|
if (value === null || value === undefined) {
|
|
3
4
|
return { type: 'null' };
|
|
@@ -62,55 +63,69 @@ export async function executeCursor(url, authToken, request) {
|
|
|
62
63
|
catch {
|
|
63
64
|
// If we can't parse the error body, use the default HTTP error message
|
|
64
65
|
}
|
|
65
|
-
throw new
|
|
66
|
+
throw new DatabaseError(errorMessage);
|
|
66
67
|
}
|
|
67
68
|
const reader = response.body?.getReader();
|
|
68
69
|
if (!reader) {
|
|
69
|
-
throw new
|
|
70
|
+
throw new DatabaseError('No response body');
|
|
70
71
|
}
|
|
71
72
|
const decoder = new TextDecoder();
|
|
72
73
|
let buffer = '';
|
|
73
|
-
let isFirstLine = true;
|
|
74
74
|
let cursorResponse;
|
|
75
|
+
// First, read until we get the cursor response (first line)
|
|
76
|
+
while (!cursorResponse) {
|
|
77
|
+
const { done, value } = await reader.read();
|
|
78
|
+
if (done)
|
|
79
|
+
break;
|
|
80
|
+
buffer += decoder.decode(value, { stream: true });
|
|
81
|
+
const newlineIndex = buffer.indexOf('\n');
|
|
82
|
+
if (newlineIndex !== -1) {
|
|
83
|
+
const line = buffer.slice(0, newlineIndex).trim();
|
|
84
|
+
buffer = buffer.slice(newlineIndex + 1);
|
|
85
|
+
if (line) {
|
|
86
|
+
cursorResponse = JSON.parse(line);
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (!cursorResponse) {
|
|
92
|
+
throw new DatabaseError('No cursor response received');
|
|
93
|
+
}
|
|
75
94
|
async function* parseEntries() {
|
|
76
95
|
try {
|
|
96
|
+
// Process any remaining data in the buffer
|
|
97
|
+
let newlineIndex;
|
|
98
|
+
while ((newlineIndex = buffer.indexOf('\n')) !== -1) {
|
|
99
|
+
const line = buffer.slice(0, newlineIndex).trim();
|
|
100
|
+
buffer = buffer.slice(newlineIndex + 1);
|
|
101
|
+
if (line) {
|
|
102
|
+
yield JSON.parse(line);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Continue reading from the stream
|
|
77
106
|
while (true) {
|
|
78
107
|
const { done, value } = await reader.read();
|
|
79
108
|
if (done)
|
|
80
109
|
break;
|
|
81
110
|
buffer += decoder.decode(value, { stream: true });
|
|
82
|
-
let newlineIndex;
|
|
83
111
|
while ((newlineIndex = buffer.indexOf('\n')) !== -1) {
|
|
84
112
|
const line = buffer.slice(0, newlineIndex).trim();
|
|
85
113
|
buffer = buffer.slice(newlineIndex + 1);
|
|
86
114
|
if (line) {
|
|
87
|
-
|
|
88
|
-
cursorResponse = JSON.parse(line);
|
|
89
|
-
isFirstLine = false;
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
yield JSON.parse(line);
|
|
93
|
-
}
|
|
115
|
+
yield JSON.parse(line);
|
|
94
116
|
}
|
|
95
117
|
}
|
|
96
118
|
}
|
|
119
|
+
// Process any remaining data in the buffer
|
|
120
|
+
if (buffer.trim()) {
|
|
121
|
+
yield JSON.parse(buffer.trim());
|
|
122
|
+
}
|
|
97
123
|
}
|
|
98
124
|
finally {
|
|
99
125
|
reader.releaseLock();
|
|
100
126
|
}
|
|
101
127
|
}
|
|
102
|
-
|
|
103
|
-
// Get the first entry to parse the cursor response
|
|
104
|
-
const firstEntry = await entries.next();
|
|
105
|
-
if (!firstEntry.done) {
|
|
106
|
-
// Put the first entry back
|
|
107
|
-
const generator = (async function* () {
|
|
108
|
-
yield firstEntry.value;
|
|
109
|
-
yield* entries;
|
|
110
|
-
})();
|
|
111
|
-
return { response: cursorResponse, entries: generator };
|
|
112
|
-
}
|
|
113
|
-
return { response: cursorResponse, entries };
|
|
128
|
+
return { response: cursorResponse, entries: parseEntries() };
|
|
114
129
|
}
|
|
115
130
|
export async function executePipeline(url, authToken, request) {
|
|
116
131
|
const response = await fetch(`${url}/v3/pipeline`, {
|
|
@@ -122,7 +137,7 @@ export async function executePipeline(url, authToken, request) {
|
|
|
122
137
|
body: JSON.stringify(request),
|
|
123
138
|
});
|
|
124
139
|
if (!response.ok) {
|
|
125
|
-
throw new
|
|
140
|
+
throw new DatabaseError(`HTTP error! status: ${response.status}`);
|
|
126
141
|
}
|
|
127
142
|
return response.json();
|
|
128
143
|
}
|
package/dist/session.d.ts
CHANGED
|
@@ -23,18 +23,18 @@ export declare class Session {
|
|
|
23
23
|
* Execute a SQL statement and return all results.
|
|
24
24
|
*
|
|
25
25
|
* @param sql - The SQL statement to execute
|
|
26
|
-
* @param args - Optional array of parameter values
|
|
26
|
+
* @param args - Optional array of parameter values or object with named parameters
|
|
27
27
|
* @returns Promise resolving to the complete result set
|
|
28
28
|
*/
|
|
29
|
-
execute(sql: string, args?: any[]): Promise<any>;
|
|
29
|
+
execute(sql: string, args?: any[] | Record<string, any>): Promise<any>;
|
|
30
30
|
/**
|
|
31
31
|
* Execute a SQL statement and return the raw response and entries.
|
|
32
32
|
*
|
|
33
33
|
* @param sql - The SQL statement to execute
|
|
34
|
-
* @param args - Optional array of parameter values
|
|
34
|
+
* @param args - Optional array of parameter values or object with named parameters
|
|
35
35
|
* @returns Promise resolving to the raw response and cursor entries
|
|
36
36
|
*/
|
|
37
|
-
executeRaw(sql: string, args?: any[]): Promise<{
|
|
37
|
+
executeRaw(sql: string, args?: any[] | Record<string, any>): Promise<{
|
|
38
38
|
response: CursorResponse;
|
|
39
39
|
entries: AsyncGenerator<CursorEntry>;
|
|
40
40
|
}>;
|
|
@@ -60,4 +60,18 @@ export declare class Session {
|
|
|
60
60
|
* @returns Promise resolving to batch execution results
|
|
61
61
|
*/
|
|
62
62
|
batch(statements: string[]): Promise<any>;
|
|
63
|
+
/**
|
|
64
|
+
* Execute a sequence of SQL statements separated by semicolons.
|
|
65
|
+
*
|
|
66
|
+
* @param sql - SQL string containing multiple statements separated by semicolons
|
|
67
|
+
* @returns Promise resolving when all statements are executed
|
|
68
|
+
*/
|
|
69
|
+
sequence(sql: string): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Close the session.
|
|
72
|
+
*
|
|
73
|
+
* This sends a close request to the server to properly clean up the stream
|
|
74
|
+
* before resetting the local state.
|
|
75
|
+
*/
|
|
76
|
+
close(): Promise<void>;
|
|
63
77
|
}
|
package/dist/session.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { executeCursor, encodeValue, decodeValue } from './protocol.js';
|
|
1
|
+
import { executeCursor, executePipeline, encodeValue, decodeValue } from './protocol.js';
|
|
2
|
+
import { DatabaseError } from './error.js';
|
|
2
3
|
function normalizeUrl(url) {
|
|
3
4
|
return url.replace(/^libsql:\/\//, 'https://');
|
|
4
5
|
}
|
|
@@ -21,7 +22,7 @@ export class Session {
|
|
|
21
22
|
* Execute a SQL statement and return all results.
|
|
22
23
|
*
|
|
23
24
|
* @param sql - The SQL statement to execute
|
|
24
|
-
* @param args - Optional array of parameter values
|
|
25
|
+
* @param args - Optional array of parameter values or object with named parameters
|
|
25
26
|
* @returns Promise resolving to the complete result set
|
|
26
27
|
*/
|
|
27
28
|
async execute(sql, args = []) {
|
|
@@ -33,17 +34,53 @@ export class Session {
|
|
|
33
34
|
* Execute a SQL statement and return the raw response and entries.
|
|
34
35
|
*
|
|
35
36
|
* @param sql - The SQL statement to execute
|
|
36
|
-
* @param args - Optional array of parameter values
|
|
37
|
+
* @param args - Optional array of parameter values or object with named parameters
|
|
37
38
|
* @returns Promise resolving to the raw response and cursor entries
|
|
38
39
|
*/
|
|
39
40
|
async executeRaw(sql, args = []) {
|
|
41
|
+
let positionalArgs = [];
|
|
42
|
+
let namedArgs = [];
|
|
43
|
+
if (Array.isArray(args)) {
|
|
44
|
+
positionalArgs = args.map(encodeValue);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// Check if this is an object with numeric keys (for ?1, ?2 style parameters)
|
|
48
|
+
const keys = Object.keys(args);
|
|
49
|
+
const isNumericKeys = keys.length > 0 && keys.every(key => /^\d+$/.test(key));
|
|
50
|
+
if (isNumericKeys) {
|
|
51
|
+
// Convert numeric-keyed object to positional args
|
|
52
|
+
// Sort keys numerically to ensure correct order
|
|
53
|
+
const sortedKeys = keys.sort((a, b) => parseInt(a) - parseInt(b));
|
|
54
|
+
const maxIndex = parseInt(sortedKeys[sortedKeys.length - 1]);
|
|
55
|
+
// Create array with undefined for missing indices
|
|
56
|
+
positionalArgs = new Array(maxIndex);
|
|
57
|
+
for (const key of sortedKeys) {
|
|
58
|
+
const index = parseInt(key) - 1; // Convert to 0-based index
|
|
59
|
+
positionalArgs[index] = encodeValue(args[key]);
|
|
60
|
+
}
|
|
61
|
+
// Fill any undefined values with null
|
|
62
|
+
for (let i = 0; i < positionalArgs.length; i++) {
|
|
63
|
+
if (positionalArgs[i] === undefined) {
|
|
64
|
+
positionalArgs[i] = { type: 'null' };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
// Convert object with named parameters to NamedArg array
|
|
70
|
+
namedArgs = Object.entries(args).map(([name, value]) => ({
|
|
71
|
+
name,
|
|
72
|
+
value: encodeValue(value)
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
40
76
|
const request = {
|
|
41
77
|
baton: this.baton,
|
|
42
78
|
batch: {
|
|
43
79
|
steps: [{
|
|
44
80
|
stmt: {
|
|
45
81
|
sql,
|
|
46
|
-
args:
|
|
82
|
+
args: positionalArgs,
|
|
83
|
+
named_args: namedArgs,
|
|
47
84
|
want_rows: true
|
|
48
85
|
}
|
|
49
86
|
}]
|
|
@@ -93,7 +130,7 @@ export class Session {
|
|
|
93
130
|
break;
|
|
94
131
|
case 'step_error':
|
|
95
132
|
case 'error':
|
|
96
|
-
throw new
|
|
133
|
+
throw new DatabaseError(entry.error?.message || 'SQL execution failed');
|
|
97
134
|
}
|
|
98
135
|
}
|
|
99
136
|
return {
|
|
@@ -141,6 +178,7 @@ export class Session {
|
|
|
141
178
|
stmt: {
|
|
142
179
|
sql,
|
|
143
180
|
args: [],
|
|
181
|
+
named_args: [],
|
|
144
182
|
want_rows: false
|
|
145
183
|
}
|
|
146
184
|
}))
|
|
@@ -165,7 +203,7 @@ export class Session {
|
|
|
165
203
|
break;
|
|
166
204
|
case 'step_error':
|
|
167
205
|
case 'error':
|
|
168
|
-
throw new
|
|
206
|
+
throw new DatabaseError(entry.error?.message || 'Batch execution failed');
|
|
169
207
|
}
|
|
170
208
|
}
|
|
171
209
|
return {
|
|
@@ -173,4 +211,58 @@ export class Session {
|
|
|
173
211
|
lastInsertRowid
|
|
174
212
|
};
|
|
175
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Execute a sequence of SQL statements separated by semicolons.
|
|
216
|
+
*
|
|
217
|
+
* @param sql - SQL string containing multiple statements separated by semicolons
|
|
218
|
+
* @returns Promise resolving when all statements are executed
|
|
219
|
+
*/
|
|
220
|
+
async sequence(sql) {
|
|
221
|
+
const request = {
|
|
222
|
+
baton: this.baton,
|
|
223
|
+
requests: [{
|
|
224
|
+
type: "sequence",
|
|
225
|
+
sql: sql
|
|
226
|
+
}]
|
|
227
|
+
};
|
|
228
|
+
const response = await executePipeline(this.baseUrl, this.config.authToken, request);
|
|
229
|
+
this.baton = response.baton;
|
|
230
|
+
if (response.base_url) {
|
|
231
|
+
this.baseUrl = response.base_url;
|
|
232
|
+
}
|
|
233
|
+
// Check for errors in the response
|
|
234
|
+
if (response.results && response.results[0]) {
|
|
235
|
+
const result = response.results[0];
|
|
236
|
+
if (result.type === "error") {
|
|
237
|
+
throw new DatabaseError(result.error?.message || 'Sequence execution failed');
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Close the session.
|
|
243
|
+
*
|
|
244
|
+
* This sends a close request to the server to properly clean up the stream
|
|
245
|
+
* before resetting the local state.
|
|
246
|
+
*/
|
|
247
|
+
async close() {
|
|
248
|
+
// Only send close request if we have an active baton
|
|
249
|
+
if (this.baton) {
|
|
250
|
+
try {
|
|
251
|
+
const request = {
|
|
252
|
+
baton: this.baton,
|
|
253
|
+
requests: [{
|
|
254
|
+
type: "close"
|
|
255
|
+
}]
|
|
256
|
+
};
|
|
257
|
+
await executePipeline(this.baseUrl, this.config.authToken, request);
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
// Ignore errors during close, as the connection might already be closed
|
|
261
|
+
console.error('Error closing session:', error);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// Reset local state
|
|
265
|
+
this.baton = null;
|
|
266
|
+
this.baseUrl = '';
|
|
267
|
+
}
|
|
176
268
|
}
|
package/dist/statement.d.ts
CHANGED
|
@@ -11,11 +11,26 @@ import { type SessionConfig } from './session.js';
|
|
|
11
11
|
export declare class Statement {
|
|
12
12
|
private session;
|
|
13
13
|
private sql;
|
|
14
|
+
private presentationMode;
|
|
14
15
|
constructor(sessionConfig: SessionConfig, sql: string);
|
|
16
|
+
/**
|
|
17
|
+
* Enable raw mode to return arrays instead of objects.
|
|
18
|
+
*
|
|
19
|
+
* @param raw Enable or disable raw mode. If you don't pass the parameter, raw mode is enabled.
|
|
20
|
+
* @returns This statement instance for chaining
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const stmt = client.prepare("SELECT * FROM users WHERE id = ?");
|
|
25
|
+
* const row = await stmt.raw().get([1]);
|
|
26
|
+
* console.log(row); // [1, "Alice", "alice@example.org"]
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
raw(raw?: boolean): Statement;
|
|
15
30
|
/**
|
|
16
31
|
* Executes the prepared statement.
|
|
17
32
|
*
|
|
18
|
-
* @param args - Optional array of parameter values
|
|
33
|
+
* @param args - Optional array of parameter values or object with named parameters
|
|
19
34
|
* @returns Promise resolving to the result of the statement
|
|
20
35
|
*
|
|
21
36
|
* @example
|
|
@@ -25,12 +40,12 @@ export declare class Statement {
|
|
|
25
40
|
* console.log(`Inserted user with ID ${result.lastInsertRowid}`);
|
|
26
41
|
* ```
|
|
27
42
|
*/
|
|
28
|
-
run(args?: any
|
|
43
|
+
run(args?: any): Promise<any>;
|
|
29
44
|
/**
|
|
30
45
|
* Execute the statement and return the first row.
|
|
31
46
|
*
|
|
32
|
-
* @param args - Optional array of parameter values
|
|
33
|
-
* @returns Promise resolving to the first row or
|
|
47
|
+
* @param args - Optional array of parameter values or object with named parameters
|
|
48
|
+
* @returns Promise resolving to the first row or undefined if no results
|
|
34
49
|
*
|
|
35
50
|
* @example
|
|
36
51
|
* ```typescript
|
|
@@ -41,11 +56,11 @@ export declare class Statement {
|
|
|
41
56
|
* }
|
|
42
57
|
* ```
|
|
43
58
|
*/
|
|
44
|
-
get(args?: any
|
|
59
|
+
get(args?: any): Promise<any>;
|
|
45
60
|
/**
|
|
46
61
|
* Execute the statement and return all rows.
|
|
47
62
|
*
|
|
48
|
-
* @param args - Optional array of parameter values
|
|
63
|
+
* @param args - Optional array of parameter values or object with named parameters
|
|
49
64
|
* @returns Promise resolving to an array of all result rows
|
|
50
65
|
*
|
|
51
66
|
* @example
|
|
@@ -55,14 +70,14 @@ export declare class Statement {
|
|
|
55
70
|
* console.log(`Found ${activeUsers.length} active users`);
|
|
56
71
|
* ```
|
|
57
72
|
*/
|
|
58
|
-
all(args?: any
|
|
73
|
+
all(args?: any): Promise<any[]>;
|
|
59
74
|
/**
|
|
60
75
|
* Execute the statement and return an async iterator for streaming results.
|
|
61
76
|
*
|
|
62
77
|
* This method provides memory-efficient processing of large result sets
|
|
63
78
|
* by streaming rows one at a time instead of loading everything into memory.
|
|
64
79
|
*
|
|
65
|
-
* @param args - Optional array of parameter values
|
|
80
|
+
* @param args - Optional array of parameter values or object with named parameters
|
|
66
81
|
* @returns AsyncGenerator that yields individual rows
|
|
67
82
|
*
|
|
68
83
|
* @example
|
|
@@ -74,5 +89,10 @@ export declare class Statement {
|
|
|
74
89
|
* }
|
|
75
90
|
* ```
|
|
76
91
|
*/
|
|
77
|
-
iterate(args?: any
|
|
92
|
+
iterate(args?: any): AsyncGenerator<any>;
|
|
93
|
+
/**
|
|
94
|
+
* Normalize arguments to handle both single values and arrays.
|
|
95
|
+
* Matches the behavior of the native bindings.
|
|
96
|
+
*/
|
|
97
|
+
private normalizeArgs;
|
|
78
98
|
}
|