Skip to content

Commit 8c7348a

Browse files
added alasql query comp
1 parent c08019a commit 8c7348a

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import { QueryConfigItemWrapper, QueryConfigLabel, QueryConfigWrapper } from "components/query";
2+
import { simpleMultiComp } from "comps/generators/multi";
3+
import { JSONValue } from "../../../util/jsonTypes";
4+
import { ParamsStringControl } from "../../controls/paramsControl";
5+
import { dropdownControl } from "@lowcoder-ee/comps/controls/dropdownControl";
6+
import { QueryResult } from "../queryComp";
7+
import { QUERY_EXECUTION_ERROR, QUERY_EXECUTION_OK } from "@lowcoder-ee/constants/queryConstants";
8+
import { getDynamicStringSegments, isDynamicSegment } from "lowcoder-core";
9+
import alasql from "alasql";
10+
import { trans } from "i18n";
11+
12+
const childrenMap = {
13+
databaseType: dropdownControl(
14+
[
15+
{ label: "Data Query", value: "dataQuery" },
16+
{ label: "Local Database", value: "localDB" },
17+
] as const,
18+
"dataQuery"
19+
),
20+
database: dropdownControl(
21+
[
22+
{ label: "Local Storage", value: "LOCALSTORAGE" },
23+
{ label: "IndexedDB", value: "INDEXEDDB" },
24+
] as const,
25+
"LOCALSTORAGE"
26+
),
27+
sql: ParamsStringControl,
28+
};
29+
30+
const AlaSqlTmpQuery = simpleMultiComp(childrenMap);
31+
32+
// TODO: Support multiple queries
33+
export class AlaSqlQuery extends AlaSqlTmpQuery {
34+
override getView() {
35+
const children = this.children;
36+
const params = [ ...children.sql.getQueryParams() ];
37+
const databaseType = children.databaseType.getView();
38+
const selectedDB = children.database.getView();
39+
const paramsMap: Record<string, any> = {};
40+
params.forEach(({key, value}) => {
41+
paramsMap[key] = value();
42+
});
43+
44+
const sqlQuery = children.sql.children.text.unevaledValue.replace(/ +/g, ' ');
45+
const isCreateDBQuery = sqlQuery.toUpperCase().startsWith('CREATE DATABASE');
46+
47+
return async (p: { args?: Record<string, unknown> }): Promise<QueryResult> => {
48+
try {
49+
let result: JSONValue;
50+
const timer = performance.now();
51+
52+
if (databaseType === 'localDB' && isCreateDBQuery) {
53+
const updatedQuery = `${sqlQuery.slice(0, 6)} ${selectedDB} ${sqlQuery.slice(6)}`;
54+
const tableName = updatedQuery.split(' ').pop()?.replace(';', '');
55+
result = alasql(updatedQuery);
56+
result = alasql(`ATTACH ${selectedDB} DATABASE ${tableName};`);
57+
} else {
58+
let segments = getDynamicStringSegments(sqlQuery);
59+
let dataArr: any = [];
60+
segments = segments.map((segment) => {
61+
if (isDynamicSegment(segment)) {
62+
const key = segment.replace('{{','').replace('}}','');
63+
dataArr.push(paramsMap[key]);
64+
return '?';
65+
}
66+
return segment;
67+
})
68+
result = alasql(segments.join(' '), dataArr);
69+
}
70+
71+
return {
72+
data: result as JSONValue,
73+
code: QUERY_EXECUTION_OK,
74+
success: true,
75+
runTime: Number((performance.now() - timer).toFixed()),
76+
};
77+
} catch (e) {
78+
return {
79+
success: false,
80+
data: "",
81+
code: QUERY_EXECUTION_ERROR,
82+
message: (e as any).message || "",
83+
};
84+
}
85+
};
86+
}
87+
88+
propertyView(props: { datasourceId: string }) {
89+
return <PropertyView {...props} comp={this} />;
90+
}
91+
}
92+
93+
const PropertyView = (props: { comp: InstanceType<typeof AlaSqlQuery>; datasourceId: string }) => {
94+
const { comp } = props;
95+
const { children } = comp;
96+
97+
return (
98+
<>
99+
<QueryConfigWrapper>
100+
<QueryConfigLabel>{trans("query.databaseType")}</QueryConfigLabel>
101+
<QueryConfigItemWrapper>
102+
{children.databaseType.propertyView({
103+
styleName: "medium",
104+
width: "100%",
105+
})}
106+
</QueryConfigItemWrapper>
107+
</QueryConfigWrapper>
108+
109+
{children.databaseType.getView() === 'localDB' && (
110+
<QueryConfigWrapper>
111+
<QueryConfigLabel>{trans("query.chooseDatabase")}</QueryConfigLabel>
112+
<QueryConfigItemWrapper>
113+
{children.database.propertyView({
114+
styleName: "medium",
115+
width: "100%",
116+
})}
117+
</QueryConfigItemWrapper>
118+
</QueryConfigWrapper>
119+
)}
120+
121+
<QueryConfigWrapper>
122+
<QueryConfigItemWrapper>
123+
{children.sql.propertyView({
124+
placement: "bottom",
125+
placeholder: "SELECT * FROM users WHERE user_id = {{userId}}::uuid",
126+
styleName: "medium",
127+
language: "sql",
128+
enableMetaCompletion: true,
129+
})}
130+
</QueryConfigItemWrapper>
131+
</QueryConfigWrapper>
132+
</>
133+
);
134+
};

0 commit comments

Comments
 (0)