Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c0b952a

Browse files
author
Connell, Joseph
committed
Base Databricks API and Frontend Integration
1 parent e5078ae commit c0b952a

33 files changed

+1369
-1
lines changed

‎client/packages/lowcoder-design/src/icons/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ export { ReactComponent as MongoIcon } from "./v1/icon-query-MongoDB.svg";
144144
export { ReactComponent as PostgresIcon } from "./v1/icon-query-postgres.svg";
145145
export { ReactComponent as RedisIcon } from "./v1/icon-query-Redis.svg";
146146
export { ReactComponent as MSSQLIcon } from "./v1/icon-query-mssql.svg";
147+
export { ReactComponent as DatabricksIcon } from "./v1/icon-query-databricks.svg";
147148
export { ReactComponent as SMTPIcon } from "./v1/icon-query-SMTP.svg";
148149
export { ReactComponent as OracleIcon } from "./v1/icon-query-OracleDB.svg";
149150
export { ReactComponent as ClickHouseIcon } from "./v1/icon-query-ClickHouse.svg";
Lines changed: 10 additions & 0 deletions
Loading

‎client/packages/lowcoder/src/api/datasourceApi.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ export interface SQLConfig extends PreparedStatementConfig {
2727
usingSsl: boolean;
2828
}
2929

30+
export interface DatabricksConfig extends SQLConfig {
31+
authMechanism: string; // 3: Personal Access Token, 11: OAuth
32+
usingUri: boolean;
33+
jdbcUri: string;
34+
httpPath: string;
35+
catalog: string;
36+
}
3037
export interface MongoConfig extends SQLConfig {
3138
uri: string;
3239
usingUri: boolean;
@@ -123,6 +130,7 @@ export type DatasourceConfigType =
123130
| SQLConfig
124131
| HttpConfig
125132
| MongoConfig
133+
| DatabricksConfig
126134
| OAuthBasicConfig
127135
| EsConfig
128136
| OracleConfig
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import {
2+
DataSourceTypeConfig,
3+
FullColumnInfo,
4+
generateInsertSql,
5+
QueryDataType,
6+
} from "./dataSourceCommon";
7+
import {
8+
CompSelection,
9+
dateCompSelection,
10+
allCompSelection,
11+
numberCompSelection,
12+
timeCompSelection,
13+
dateTimeCompSelection,
14+
} from "./comp";
15+
16+
function getCompSelection(columnType: string): CompSelection | undefined {
17+
if (!columnType) {
18+
return undefined;
19+
}
20+
switch (columnType.toLowerCase()) {
21+
case "bit":
22+
case "tinyint":
23+
case "smallint":
24+
case "int":
25+
case "bigint":
26+
case "dec":
27+
case "decimal":
28+
case "numeric":
29+
case "smallmoney":
30+
case "money":
31+
case "float":
32+
case "real":
33+
return numberCompSelection(true);
34+
case "date":
35+
return dateCompSelection();
36+
case "datetime":
37+
case "smalldatetime":
38+
return dateTimeCompSelection();
39+
case "time":
40+
return timeCompSelection();
41+
}
42+
return allCompSelection();
43+
}
44+
45+
function getQueryInitData(
46+
formName: string,
47+
tableName: string,
48+
infos: FullColumnInfo[]
49+
): QueryDataType {
50+
return {
51+
compType: "databricks",
52+
comp: {
53+
sql: generateInsertSql(tableName, infos),
54+
commandType: "INSERT",
55+
mode: "SQL",
56+
},
57+
};
58+
}
59+
60+
export const databricksConfig: DataSourceTypeConfig = {
61+
type: "databricks",
62+
getCompSelection,
63+
getQueryInitData,
64+
};

‎client/packages/lowcoder/src/comps/comps/formComp/generate/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { msSqlConfig } from "./mssql";
33
import { mysqlConfig } from "./mysql";
44
import { oracleSqlConfig } from "./oracle";
55
import { postgreSqlConfig } from "./postgresql";
6+
import { databricksConfig } from "./databricks";
67
import { DatasourceType } from "@lowcoder-ee/constants/queryConstants";
78

89
export function getDataSourceTypeConfig(
@@ -14,6 +15,8 @@ export function getDataSourceTypeConfig(
1415
return mysqlConfig;
1516
case "postgres":
1617
return postgreSqlConfig;
18+
case "databricks":
19+
return databricksConfig;
1720
case "mssql":
1821
return msSqlConfig;
1922
case "oracle":

‎client/packages/lowcoder/src/comps/queries/queryComp/queryPropertyView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ export const QueryGeneralPropertyView = (props: {
444444

445445
<br/>
446446

447-
{["postgres", "mysql", "mssql", "oracle", "mariadb"].includes(datasourceType) && (
447+
{["databricks", "postgres", "mysql", "mssql", "oracle", "mariadb"].includes(datasourceType) && (
448448
<SupaDemoDisplay
449449
url={trans("supademos.dataquery2table")}
450450
modalWidth="80%"

‎client/packages/lowcoder/src/constants/datasourceConstants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export const databasePlugins: Partial<DatasourceType>[] = [
88
"mysql",
99
"mongodb",
1010
"postgres",
11+
"databricks",
1112
"redis",
1213
"es",
1314
"mssql",

‎client/packages/lowcoder/src/constants/queryConstants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export type DatasourceType =
2424
| "redis"
2525
| "es"
2626
| "mssql"
27+
| "databricks"
2728
| "smtp"
2829
| "oracle"
2930
| "clickHouse"
@@ -46,6 +47,7 @@ export const QueryMap = {
4647
redis: RedisQuery,
4748
es: EsQuery,
4849
mssql: SQLQuery,
50+
databricks: SQLQuery,
4951
smtp: SMTPQuery,
5052
oracle: SQLQuery,
5153
clickHouse: SQLQuery,
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import React, { useState, useEffect } from "react";
2+
import { DatasourceForm, FormInputItem, FormSection, FormSelectItem, FormInputPasswordItem, FormNumberInputItem, FormCheckboxItem } from "lowcoder-design";
3+
import { DatabricksConfig } from "api/datasourceApi";
4+
import { DatasourceFormProps } from "./datasourceFormRegistry";
5+
import { useHostCheck } from "./useHostCheck";
6+
import { trans } from "i18n";
7+
import {
8+
DatabaseFormInputItem,
9+
DatasourceNameFormInputItem,
10+
encryptedPlaceholder,
11+
HostFormInputItem,
12+
PasswordFormInputItem,
13+
PortFormInputItem,
14+
SSLFormCheckboxItem,
15+
// UserNameFormInputItem, // removed
16+
} from "../form";
17+
18+
export const DatabricksDatasourceForm = (props: DatasourceFormProps) => {
19+
const { form, datasource, size } = props;
20+
const datasourceConfig = datasource?.datasourceConfig as DatabricksConfig;
21+
const [usingUri, setUsingUri] = useState(datasourceConfig?.usingUri);
22+
const hostRule = useHostCheck();
23+
24+
// Set username to "token" if Auth Mechanism is PAT (3)
25+
useEffect(() => {
26+
if (!usingUri && form.getFieldValue("authMechanism") === "3") {
27+
form.setFieldsValue({ username: "token" });
28+
}
29+
}, [usingUri, form.getFieldValue("authMechanism"), form]);
30+
31+
return (
32+
<DatasourceForm form={form} preserve={false}>
33+
<FormSection $size={size}>
34+
<DatasourceNameFormInputItem
35+
placeholder={"My DatabricksDB1"}
36+
initialValue={datasource?.name}
37+
/>
38+
</FormSection>
39+
40+
<FormSection $size={size}>
41+
<FormSelectItem
42+
name={"usingUri"}
43+
label={trans("query.connectionType")}
44+
options={[
45+
{ label: trans("query.regular"), value: "false" },
46+
{ label: "JDBC URI", value: "true" },
47+
]}
48+
initialValue={datasourceConfig?.usingUri ? "true" : "false"}
49+
afterChange={(value) => setUsingUri(value === "true")}
50+
/>
51+
</FormSection>
52+
53+
<FormSection $size={size}>
54+
{usingUri ? (
55+
<FormInputItem
56+
name={"jdbcUri"}
57+
label="JDBC URI"
58+
required={true}
59+
placeholder={encryptedPlaceholder}
60+
rules={[
61+
{
62+
required: !datasourceConfig?.usingUri && true,
63+
message: trans("query.uriRequiredMessage"),
64+
},
65+
{
66+
pattern: new RegExp(
67+
"^jdbc:databricks:\/\/([a-zA-Z0-9\.-]+):([0-9]{2,5});httpPath=(?:sql\/1\.0\/warehouses\/[a-zA-Z0-9]+|sql\/protocolv1\/o\/[0-9]+\/[0-9]{4}-[0-9]{6}-[a-zA-Z0-9]+);AuthMech=(?:[0-9]+)(?:;[a-zA-Z0-9_]+=[^;]+)*;$"
68+
),
69+
message: trans("query.uriErrorMessage"),
70+
},
71+
hostRule,
72+
]}
73+
/>
74+
) : (
75+
<>
76+
77+
<HostFormInputItem initialValue={datasourceConfig?.host} />
78+
<PortFormInputItem initialValue={"443"} port={datasourceConfig?.port} />
79+
80+
81+
<FormInputItem
82+
name={"httpPath"}
83+
label="Http Path"
84+
required={true}
85+
placeholder="/sql/1.0/warehouses/xxxxxxxxxxxxxxxx"
86+
initialValue={datasourceConfig?.httpPath}
87+
rules={[
88+
{
89+
required: true,
90+
message: "Http Path is required",
91+
},
92+
]}
93+
/>
94+
95+
<FormSelectItem
96+
name={"authMechanism"}
97+
label={"Auth Mechanism"}
98+
options={[
99+
{ label: "Personal Access Token", value: "3" }
100+
]}
101+
initialValue={"3"}
102+
// Only one option, so no onChange needed
103+
/>
104+
105+
<FormInputPasswordItem
106+
name={"password"}
107+
label="Access Token"
108+
required={true}
109+
placeholder={encryptedPlaceholder}
110+
initialValue={datasourceConfig?.password}
111+
rules={[
112+
{
113+
required: true,
114+
message: "Personal Access Token is required",
115+
},
116+
]}
117+
/>
118+
119+
<FormInputItem
120+
name={"catalog"}
121+
label="Catalog"
122+
required={false}
123+
placeholder="hive_metastore"
124+
initialValue={datasourceConfig?.catalog}
125+
rules={[]}
126+
/>
127+
128+
<DatabaseFormInputItem
129+
database={datasourceConfig?.database}
130+
label="Schema"
131+
/>
132+
133+
<SSLFormCheckboxItem usingSSl={datasourceConfig?.usingSsl} />
134+
</>
135+
)}
136+
</FormSection>
137+
</DatasourceForm>
138+
);
139+
};

‎client/packages/lowcoder/src/pages/datasource/form/datasourceFormRegistry.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { GoogleSheetsDatasourceForm } from "./googleSheetsDatasourceForm";
99
import { DatasourceType } from "@lowcoder-ee/constants/queryConstants";
1010
import { Datasource } from "@lowcoder-ee/constants/datasourceConstants";
1111
import { sqlDatasourceForm } from "./sqlDatasourceForm";
12+
import { DatabricksDatasourceForm } from "./databricksDatasourceForm";
1213
import { GraphqlDatasourceForm } from "./graphqlDatasourceForm";
1314
import { OracleDatasourceForm } from "./oracleDatasourceForm";
1415
import { DataSourceTypeInfo } from "api/datasourceApi";
@@ -55,4 +56,5 @@ export const DatasourceFormRegistry: Partial<Record<DatasourceType, DatasourceFo
5556
form: sqlDatasourceForm({ placeholder: "My MariaDB1", port: "3306" }),
5657
whitelist: true,
5758
},
59+
databricks: { form: DatabricksDatasourceForm, whitelist: true }
5860
};

‎client/packages/lowcoder/src/pages/setting/environments/components/DataSourcesTab.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ const DataSourcesTab: React.FC<DataSourcesTabProps> = ({ environment, workspaceI
239239
'elasticsearch': '#005571',
240240
'oracle': '#F80000',
241241
'mssql': '#CC2927',
242+
'databricks': '#F55322',
242243
'snowflake': '#29B5E8'
243244
};
244245

‎client/packages/lowcoder/src/util/bottomResUtils.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
MariaDBIcon,
1515
MongoIcon,
1616
MSSQLIcon,
17+
DatabricksIcon,
1718
MysqlIcon,
1819
OptionsApiIcon,
1920
OracleIcon,
@@ -124,6 +125,8 @@ export const getBottomResIcon = (
124125
return <EsIcon />;
125126
case "mssql":
126127
return <MSSQLIcon />;
128+
case "databricks":
129+
return <DatabricksIcon />;
127130
case "smtp":
128131
return <SMTPIcon />;
129132
case "oracle":

‎server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/plugin/service/impl/DatasourceMetaInfoServiceImpl.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ public class DatasourceMetaInfoServiceImpl implements DatasourceMetaInfoService
9393
.connectionPool(ClientBasedConnectionPool.class)
9494
.build();
9595

96+
private static final DatasourceMetaInfo DATABRICKS = DatasourceMetaInfo.builder()
97+
.type("databricks")
98+
.displayName("Databricks")
99+
.pluginExecutorKey("databricks-plugin")
100+
.hasStructureInfo(true)
101+
.connectionPool(ClientBasedConnectionPool.class)
102+
.build();
103+
96104
private static final DatasourceMetaInfo ORACLE = DatasourceMetaInfo.builder()
97105
.type("oracle")
98106
.displayName("Oracle")

0 commit comments

Comments
 (0)