mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-01 06:14:23 +01:00
serverless: Fix Connection.exec()
We need to use sequence requests to handle multiple SQL statements for exec():
```
DatabaseError {
message: 'SQL string contains more than one statement',
}
```
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Connection, connect, type Config as TursoConfig } from './connection.js';
|
||||
import { Session, type SessionConfig } from './session.js';
|
||||
import { DatabaseError } from './error.js';
|
||||
|
||||
/**
|
||||
@@ -127,17 +127,17 @@ export interface Client {
|
||||
}
|
||||
|
||||
class LibSQLClient implements Client {
|
||||
private connection: Connection;
|
||||
private session: Session;
|
||||
private _closed = false;
|
||||
|
||||
constructor(config: Config) {
|
||||
this.validateConfig(config);
|
||||
|
||||
const tursoConfig: TursoConfig = {
|
||||
const sessionConfig: SessionConfig = {
|
||||
url: config.url,
|
||||
authToken: config.authToken || ''
|
||||
};
|
||||
this.connection = connect(tursoConfig);
|
||||
this.session = new Session(sessionConfig);
|
||||
}
|
||||
|
||||
private validateConfig(config: Config): void {
|
||||
@@ -246,8 +246,15 @@ class LibSQLClient implements Client {
|
||||
normalizedStmt = this.normalizeStatement(stmtOrSql);
|
||||
}
|
||||
|
||||
const result = await this.connection.exec(normalizedStmt.sql, normalizedStmt.args);
|
||||
return this.convertResult(result);
|
||||
await this.session.sequence(normalizedStmt.sql);
|
||||
// Return empty result set for sequence execution
|
||||
return this.convertResult({
|
||||
columns: [],
|
||||
columnTypes: [],
|
||||
rows: [],
|
||||
rowsAffected: 0,
|
||||
lastInsertRowid: undefined
|
||||
});
|
||||
} catch (error: any) {
|
||||
throw new LibsqlError(error.message, "EXECUTE_ERROR");
|
||||
}
|
||||
@@ -264,7 +271,7 @@ class LibSQLClient implements Client {
|
||||
return normalized.sql; // For now, ignore args in batch
|
||||
});
|
||||
|
||||
const result = await this.connection.batch(sqlStatements, mode);
|
||||
const result = await this.session.batch(sqlStatements);
|
||||
|
||||
// Return array of result sets (simplified - actual implementation would be more complex)
|
||||
return [this.convertResult(result)];
|
||||
@@ -283,7 +290,15 @@ class LibSQLClient implements Client {
|
||||
}
|
||||
|
||||
async executeMultiple(sql: string): Promise<void> {
|
||||
throw new LibsqlError("Execute multiple not implemented", "NOT_IMPLEMENTED");
|
||||
try {
|
||||
if (this._closed) {
|
||||
throw new LibsqlError("Client is closed", "CLIENT_CLOSED");
|
||||
}
|
||||
|
||||
await this.session.sequence(sql);
|
||||
} catch (error: any) {
|
||||
throw new LibsqlError(error.message, "EXECUTE_MULTIPLE_ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
async sync(): Promise<any> {
|
||||
|
||||
@@ -44,7 +44,6 @@ export class Connection {
|
||||
* Execute a SQL statement and return all results.
|
||||
*
|
||||
* @param sql - The SQL statement to execute
|
||||
* @param args - Optional array of parameter values
|
||||
* @returns Promise resolving to the complete result set
|
||||
*
|
||||
* @example
|
||||
@@ -53,8 +52,8 @@ export class Connection {
|
||||
* console.log(result.rows);
|
||||
* ```
|
||||
*/
|
||||
async exec(sql: string, args: any[] = []): Promise<any> {
|
||||
return this.session.execute(sql, args);
|
||||
async exec(sql: string): Promise<any> {
|
||||
return this.session.sequence(sql);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -47,9 +47,14 @@ export interface BatchRequest {
|
||||
};
|
||||
}
|
||||
|
||||
export interface SequenceRequest {
|
||||
type: 'sequence';
|
||||
sql: string;
|
||||
}
|
||||
|
||||
export interface PipelineRequest {
|
||||
baton: string | null;
|
||||
requests: (ExecuteRequest | BatchRequest)[];
|
||||
requests: (ExecuteRequest | BatchRequest | SequenceRequest)[];
|
||||
}
|
||||
|
||||
export interface PipelineResponse {
|
||||
@@ -58,8 +63,8 @@ export interface PipelineResponse {
|
||||
results: Array<{
|
||||
type: 'ok' | 'error';
|
||||
response?: {
|
||||
type: 'execute' | 'batch';
|
||||
result: ExecuteResult;
|
||||
type: 'execute' | 'batch' | 'sequence';
|
||||
result?: ExecuteResult;
|
||||
};
|
||||
error?: {
|
||||
message: string;
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import {
|
||||
executeCursor,
|
||||
executePipeline,
|
||||
encodeValue,
|
||||
decodeValue,
|
||||
type CursorRequest,
|
||||
type CursorResponse,
|
||||
type CursorEntry
|
||||
type CursorEntry,
|
||||
type PipelineRequest,
|
||||
type SequenceRequest
|
||||
} from './protocol.js';
|
||||
import { DatabaseError } from './error.js';
|
||||
|
||||
@@ -214,4 +217,35 @@ export class Session {
|
||||
lastInsertRowid
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a sequence of SQL statements separated by semicolons.
|
||||
*
|
||||
* @param sql - SQL string containing multiple statements separated by semicolons
|
||||
* @returns Promise resolving when all statements are executed
|
||||
*/
|
||||
async sequence(sql: string): Promise<void> {
|
||||
const request: PipelineRequest = {
|
||||
baton: this.baton,
|
||||
requests: [{
|
||||
type: "sequence",
|
||||
sql: sql
|
||||
} as SequenceRequest]
|
||||
};
|
||||
|
||||
const response = await executePipeline(this.baseUrl, this.config.authToken, request);
|
||||
|
||||
this.baton = response.baton;
|
||||
if (response.base_url) {
|
||||
this.baseUrl = response.base_url;
|
||||
}
|
||||
|
||||
// Check for errors in the response
|
||||
if (response.results && response.results[0]) {
|
||||
const result = response.results[0];
|
||||
if (result.type === "error") {
|
||||
throw new DatabaseError(result.error?.message || 'Sequence execution failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user