Skip to content

Commit 86ca61e

Browse files
author
FalkWolsky
committed
Updating Node-Service and Activate DuckDB
1 parent 870a6e6 commit 86ca61e

File tree

7 files changed

+22824
-6
lines changed

7 files changed

+22824
-6
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// @server/node-service/src/plugins/duckdb/dataSourceConfig.ts
2+
import { ConfigToType } from "lowcoder-sdk/dataSource";
3+
4+
const dataSourceConfig = {
5+
type: "dataSource",
6+
params: [
7+
{
8+
key: "databaseFile",
9+
type: "textInput",
10+
label: "Database File",
11+
rules: [{ required: true, message: "Please provide a database file path 'db.duckdb' or ':memory:' for an in-memory database" }],
12+
tooltip: "Please provide a database file path 'db.duckdb' or ':memory:' for an in-memory database",
13+
defaultValue: ":memory:",
14+
},
15+
{
16+
key: "options",
17+
type: "textInput",
18+
label: "Database Options",
19+
tooltip: "Additional options to pass to the DuckDB constructor (in JSON format)",
20+
defaultValue: `{"access_mode": "READ_WRITE","max_memory": "512MB","threads": "4"}`,
21+
},
22+
],
23+
} as const;
24+
25+
export default dataSourceConfig;
26+
27+
export type DataSourceDataType = ConfigToType<typeof dataSourceConfig>;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { DataSourcePlugin } from "lowcoder-sdk/dataSource";
2+
import dataSourceConfig, { DataSourceDataType } from "./dataSourceConfig";
3+
import queryConfig, { ActionDataType } from "./queryConfig";
4+
import { Database } from "duckdb-async";
5+
import { ServiceError } from "../../common/error";
6+
7+
// Helper function to handle BigInt serialization
8+
function serializeBigInts(row: any): any {
9+
const newRow: { [key: string]: any } = {}; // Add index signature
10+
for (const [key, value] of Object.entries(row)) {
11+
newRow[key] = typeof value === 'bigint' ? value.toString() : value;
12+
}
13+
return newRow;
14+
}
15+
16+
const duckdbPlugin: DataSourcePlugin<ActionDataType, DataSourceDataType> = {
17+
id: "duckdb",
18+
name: "DuckDB",
19+
category: "database",
20+
icon: "duckdb.svg",
21+
dataSourceConfig,
22+
queryConfig,
23+
run: async function (actionData, dataSourceConfig): Promise<any> {
24+
const { databaseFile, options } = dataSourceConfig;
25+
const parsedOptions = JSON.parse(options);
26+
const db = await Database.create(databaseFile, parsedOptions);
27+
28+
if (actionData.actionName === "Query") {
29+
try {
30+
const result = await db.all(actionData.queryString);
31+
// Apply BigInt serialization to each row
32+
return result.map(serializeBigInts);
33+
} catch (error) {
34+
throw new ServiceError((error as Error).message);
35+
} finally {
36+
await db.close();
37+
}
38+
}
39+
},
40+
};
41+
42+
export default duckdbPlugin;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// @server/node-service/src/plugins/duckdb/queryConfig.ts
2+
import { ConfigToType } from "lowcoder-sdk/dataSource";
3+
4+
const queryConfig = {
5+
type: "query",
6+
label: "Action",
7+
actions: [
8+
{
9+
actionName: "Query",
10+
label: "Query",
11+
params: [
12+
{
13+
label: "Query String",
14+
key: "queryString",
15+
type: "sqlInput",
16+
},
17+
],
18+
},
19+
],
20+
} as const;
21+
22+
export type ActionDataType = ConfigToType<typeof queryConfig>;
23+
24+
export default queryConfig;

server/node-service/src/plugins/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import couchdbPlugin from "./couchdb";
88
import wooCommercePlugin from "./woocommerce";
99
import openAiPlugin from "./openAi";
1010
import athenaPlugin from "./athena";
11-
// import duckdbPlugin from "./duckdb";
11+
import duckdbPlugin from "./duckdb";
1212
import lambdaPlugin from "./lambda";
1313
import googleCloudStorage from "./googleCloudStorage";
1414
import stripePlugin from "./stripe";
@@ -46,7 +46,7 @@ let plugins: (DataSourcePlugin | DataSourcePluginFactory)[] = [
4646
// Databases
4747
dynamoDBPlugin,
4848
couchdbPlugin,
49-
// duckdbPlugin,
49+
duckdbPlugin,
5050
faunaPlugin,
5151
tursoPlugin,
5252
firebirdsqlPlugin,

server/node-service/src/plugins/openAi/index.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import path from "path";
44
import { OpenAPIV3, OpenAPI } from "openapi-types";
55
import { ConfigToType, DataSourcePlugin } from "lowcoder-sdk/dataSource";
66
import { runOpenApi } from "../openApi";
7-
import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse";
7+
import { parseOpenApi, parseMultiOpenApi, ParseOpenApiOptions } from "../openApi/parse";
88

9-
const spec_1_2_0 = readYaml(path.join(__dirname, "./openAI_v1.2.0.yaml"));
10-
const spec_2_3_0 = readYaml(path.join(__dirname, "./openAI_v2.3.0.yaml"));
9+
import spec_1_2_0 from "./openAI_v1.2.0.json";
10+
import spec_2_3_0 from "./openAI_v2.3.0.json";
1111

1212
const specs = {
1313
"v1.0": spec_1_2_0,
@@ -46,8 +46,14 @@ const dataSourceConfig = {
4646
} as const;
4747

4848
const parseOptions: ParseOpenApiOptions = {
49-
actionLabel: (method: string, path: string, operation: OpenAPI.Operation) => {
49+
/* actionLabel: (method: string, path: string, operation: OpenAPI.Operation) => {
5050
return _.upperFirst(operation.operationId || "");
51+
}, */
52+
actionLabel: (method: string, path: string, operation: OpenAPI.Operation) => {
53+
return _.upperFirst(operation.operationId) || operation.summary || "";
54+
},
55+
actionDescription(method, path, operation) {
56+
return operation.description || "";
5157
},
5258
};
5359

0 commit comments

Comments
 (0)