@fadhilp/stateql 0.12.0 → 0.13.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 +53 -749
- package/dist/src/adapters.d.ts +1 -0
- package/dist/src/adapters.js +60 -0
- package/dist/src/sql.d.ts +3 -1
- package/dist/src/sql.js +520 -26
- package/dist/src/sqlite-process.js +16 -0
- package/dist/src/stateql.js +14 -5
- package/docs/databases.md +225 -0
- package/docs/library.md +268 -0
- package/docs/usage.md +352 -0
- package/package.json +2 -1
package/dist/src/adapters.d.ts
CHANGED
|
@@ -32,6 +32,7 @@ export interface Adapter {
|
|
|
32
32
|
readonly confidence: StateConfidence;
|
|
33
33
|
ping(): Promise<void>;
|
|
34
34
|
read(sql: string, params: SqlParameters): Promise<ReadResult>;
|
|
35
|
+
readAutocommit?(sql: string, params: SqlParameters): Promise<ReadResult>;
|
|
35
36
|
write(sql: string, params: SqlParameters, expectedRows?: 1): Promise<WriteResult>;
|
|
36
37
|
writeAutocommit?(sql: string, params: SqlParameters): Promise<WriteResult>;
|
|
37
38
|
writeBatch(operations: BatchWriteOperation[], isolation: string): Promise<WriteResult[]>;
|
package/dist/src/adapters.js
CHANGED
|
@@ -51,6 +51,7 @@ export async function createAdapter(connection, context, input) {
|
|
|
51
51
|
throw new StateQLError("UNSUPPORTED_DRIVER", "Redis uses the native Redis adapter.");
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
+
const SQLITE_AUTOCOMMIT_STATEMENTS = new Set(["vacuum", "analyze", "reindex"]);
|
|
54
55
|
class SQLiteAdapter {
|
|
55
56
|
source;
|
|
56
57
|
readOnly;
|
|
@@ -101,7 +102,14 @@ class SQLiteAdapter {
|
|
|
101
102
|
async write(sql, params, expectedRows) {
|
|
102
103
|
return this.call("write", [sql, params, expectedRows], true, false);
|
|
103
104
|
}
|
|
105
|
+
async writeAutocommit(sql, params) {
|
|
106
|
+
return this.call("writeAutocommit", [sql, params], true, false);
|
|
107
|
+
}
|
|
104
108
|
async writeBatch(operations, isolation) {
|
|
109
|
+
const unsupported = operations.find((operation) => SQLITE_AUTOCOMMIT_STATEMENTS.has(operation.statement_type));
|
|
110
|
+
if (unsupported) {
|
|
111
|
+
throw new BatchWriteError(`SQLite transactions cannot include ${unsupported.statement_type.toUpperCase()} maintenance statements.`, false);
|
|
112
|
+
}
|
|
105
113
|
return this.call("writeBatch", [operations, isolation], true, true);
|
|
106
114
|
}
|
|
107
115
|
async signature() {
|
|
@@ -590,6 +598,16 @@ class MySqlAdapter {
|
|
|
590
598
|
throw error;
|
|
591
599
|
}
|
|
592
600
|
}
|
|
601
|
+
async readAutocommit(sql, params) {
|
|
602
|
+
const [result, fields] = await this.query(sql, mysqlParams(params), false, false);
|
|
603
|
+
return {
|
|
604
|
+
rows: toJsonSafe(mysqlRows(result)),
|
|
605
|
+
columns: fields.map((field) => ({
|
|
606
|
+
name: field.name,
|
|
607
|
+
type: mysqlFieldType(field),
|
|
608
|
+
})),
|
|
609
|
+
};
|
|
610
|
+
}
|
|
593
611
|
async write(sql, params, expectedRows) {
|
|
594
612
|
if (this.readOnly)
|
|
595
613
|
throw new Error("Connection is read-only.");
|
|
@@ -629,6 +647,35 @@ class MySqlAdapter {
|
|
|
629
647
|
throw new AdapterWriteError(errorText(error), true);
|
|
630
648
|
}
|
|
631
649
|
}
|
|
650
|
+
async writeAutocommit(sql, params) {
|
|
651
|
+
if (this.readOnly)
|
|
652
|
+
throw new AdapterWriteError("Connection is read-only.", false);
|
|
653
|
+
let values;
|
|
654
|
+
try {
|
|
655
|
+
values = mysqlParams(params);
|
|
656
|
+
await this.connect();
|
|
657
|
+
}
|
|
658
|
+
catch (error) {
|
|
659
|
+
if (error instanceof AdapterExecutionError)
|
|
660
|
+
throw error;
|
|
661
|
+
throw new AdapterWriteError(errorText(error), false);
|
|
662
|
+
}
|
|
663
|
+
try {
|
|
664
|
+
const [result] = await this.runQuery(sql, values, true, false);
|
|
665
|
+
const maintenanceError = mysqlMaintenanceError(result);
|
|
666
|
+
if (maintenanceError)
|
|
667
|
+
throw new AdapterWriteError(maintenanceError, false);
|
|
668
|
+
return {
|
|
669
|
+
affectedRows: Array.isArray(result) ? 0 : mysqlAffectedRows(result),
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
catch (error) {
|
|
673
|
+
if (error instanceof AdapterExecutionError || error instanceof AdapterWriteError) {
|
|
674
|
+
throw error;
|
|
675
|
+
}
|
|
676
|
+
throw new AdapterWriteError(errorText(error), true);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
632
679
|
async writeBatch(operations, isolation) {
|
|
633
680
|
if (this.readOnly)
|
|
634
681
|
throw new Error("Connection is read-only.");
|
|
@@ -901,6 +948,7 @@ const MYSQL_ISOLATION_LEVELS = new Set([
|
|
|
901
948
|
const MYSQL_TRANSACTIONAL_STATEMENTS = new Set([
|
|
902
949
|
"delete",
|
|
903
950
|
"insert",
|
|
951
|
+
"upsert",
|
|
904
952
|
"replace",
|
|
905
953
|
"update",
|
|
906
954
|
]);
|
|
@@ -927,6 +975,18 @@ function mysqlRows(result) {
|
|
|
927
975
|
}
|
|
928
976
|
return result;
|
|
929
977
|
}
|
|
978
|
+
function mysqlMaintenanceError(result) {
|
|
979
|
+
if (!Array.isArray(result))
|
|
980
|
+
return undefined;
|
|
981
|
+
for (const row of result) {
|
|
982
|
+
const typeEntry = Object.entries(row).find(([key]) => key.toLowerCase() === "msg_type");
|
|
983
|
+
if (String(typeEntry?.[1] ?? "").toLowerCase() !== "error")
|
|
984
|
+
continue;
|
|
985
|
+
const textEntry = Object.entries(row).find(([key]) => key.toLowerCase() === "msg_text");
|
|
986
|
+
return String(textEntry?.[1] ?? "MySQL maintenance failed.");
|
|
987
|
+
}
|
|
988
|
+
return undefined;
|
|
989
|
+
}
|
|
930
990
|
function mysqlAffectedRows(result) {
|
|
931
991
|
if (Array.isArray(result) || !("affectedRows" in result)) {
|
|
932
992
|
throw new Error("MySQL statement did not return a write result.");
|
package/dist/src/sql.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AST } from "node-sql-parser";
|
|
2
2
|
import type { Driver, SqlDriver } from "./types.js";
|
|
3
|
-
export type StatementType = "select" | "insert" | "replace" | "update" | "delete" | "create" | "alter" | "drop" | "truncate" | "explain" | "vacuum" | "analyze" | "reindex" | "cluster";
|
|
3
|
+
export type StatementType = "select" | "insert" | "upsert" | "replace" | "update" | "delete" | "create" | "alter" | "drop" | "truncate" | "values" | "show" | "explain" | "vacuum" | "analyze" | "reindex" | "optimize" | "check" | "cluster";
|
|
4
4
|
export interface SqlAnalysis {
|
|
5
5
|
ast: AST;
|
|
6
6
|
normalized: string;
|
|
@@ -12,6 +12,8 @@ export interface SqlAnalysis {
|
|
|
12
12
|
wrapForLimit: boolean;
|
|
13
13
|
cacheable: boolean;
|
|
14
14
|
requiresAutocommit: boolean;
|
|
15
|
+
/** Analysis-only SQL with trailing trivia removed when limit wrapping needs it. */
|
|
16
|
+
limitSql?: string;
|
|
15
17
|
}
|
|
16
18
|
export declare function analyzeSql(sql: string, driver: SqlDriver): SqlAnalysis;
|
|
17
19
|
/** @internal Compatibility for existing connection records during Mongo rollout. */
|