mirror of
https://github.com/sqlchat/sqlchat.git
synced 2026-03-13 07:59:44 +08:00
feat: tidb cloud serverless tier support (#85)
* feat: tidb cloud serverless tier support * clearify: check the engine type before call the tidb connection change function * delete: unused type declare
This commit is contained in:
@@ -49,6 +49,7 @@
|
||||
"react-is": "^18.2.0",
|
||||
"react-loader-spinner": "^5.3.4",
|
||||
"react-markdown": "^8.0.6",
|
||||
"react-svg": "^16.1.11",
|
||||
"react-textarea-autosize": "^8.4.0",
|
||||
"react-use": "^17.4.0",
|
||||
"remark-gfm": "^3.0.1",
|
||||
|
||||
73
pnpm-lock.yaml
generated
73
pnpm-lock.yaml
generated
@@ -115,6 +115,9 @@ dependencies:
|
||||
react-markdown:
|
||||
specifier: ^8.0.6
|
||||
version: 8.0.6(@types/react@18.0.28)(react@18.2.0)
|
||||
react-svg:
|
||||
specifier: ^16.1.11
|
||||
version: 16.1.11(react-dom@18.2.0)(react@18.2.0)
|
||||
react-textarea-autosize:
|
||||
specifier: ^8.4.0
|
||||
version: 8.4.0(@types/react@18.0.28)(react@18.2.0)
|
||||
@@ -476,6 +479,13 @@ packages:
|
||||
dependencies:
|
||||
regenerator-runtime: 0.13.11
|
||||
|
||||
/@babel/runtime@7.21.5:
|
||||
resolution: {integrity: sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
regenerator-runtime: 0.13.11
|
||||
dev: false
|
||||
|
||||
/@babel/template@7.20.7:
|
||||
resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -648,7 +658,7 @@ packages:
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
debug: 4.3.4(supports-color@5.5.0)
|
||||
debug: 4.3.4
|
||||
espree: 9.5.0
|
||||
globals: 13.20.0
|
||||
ignore: 5.2.4
|
||||
@@ -709,7 +719,7 @@ packages:
|
||||
engines: {node: '>=10.10.0'}
|
||||
dependencies:
|
||||
'@humanwhocodes/object-schema': 1.2.1
|
||||
debug: 4.3.4(supports-color@5.5.0)
|
||||
debug: 4.3.4
|
||||
minimatch: 3.1.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -1577,6 +1587,14 @@ packages:
|
||||
tailwindcss: 3.2.7(postcss@8.4.21)(ts-node@10.9.1)
|
||||
dev: true
|
||||
|
||||
/@tanem/svg-injector@10.1.53:
|
||||
resolution: {integrity: sha512-tR2Kh0GcTk+7hFTUsCo7JcEsAxz7j28dvaeC77jDp+acgGVdWXtk1v6lY8G0v1g813sgBrBzUr3St8RPBSmjEQ==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.21.5
|
||||
content-type: 1.0.5
|
||||
tslib: 2.5.0
|
||||
dev: false
|
||||
|
||||
/@tediousjs/connection-string@0.4.2:
|
||||
resolution: {integrity: sha512-1R9UC7Qc5wief2oJL+c1+d7v1/oPBayL85u8L/jV2DzIKput1TZ8ZUjj2nxQaSfzu210zp0oFWUrYUiUs8NhBQ==}
|
||||
dev: true
|
||||
@@ -1745,7 +1763,7 @@ packages:
|
||||
'@typescript-eslint/scope-manager': 5.55.0
|
||||
'@typescript-eslint/types': 5.55.0
|
||||
'@typescript-eslint/typescript-estree': 5.55.0(typescript@4.9.5)
|
||||
debug: 4.3.4(supports-color@5.5.0)
|
||||
debug: 4.3.4
|
||||
eslint: 8.20.0
|
||||
typescript: 4.9.5
|
||||
transitivePeerDependencies:
|
||||
@@ -1776,7 +1794,7 @@ packages:
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 5.55.0
|
||||
'@typescript-eslint/visitor-keys': 5.55.0
|
||||
debug: 4.3.4(supports-color@5.5.0)
|
||||
debug: 4.3.4
|
||||
globby: 11.1.0
|
||||
is-glob: 4.0.3
|
||||
semver: 7.3.8
|
||||
@@ -1848,7 +1866,7 @@ packages:
|
||||
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
||||
engines: {node: '>= 6.0.0'}
|
||||
dependencies:
|
||||
debug: 4.3.4(supports-color@5.5.0)
|
||||
debug: 4.3.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@@ -2249,6 +2267,11 @@ packages:
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/content-type@1.0.5:
|
||||
resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/convert-source-map@1.9.0:
|
||||
resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
|
||||
dev: false
|
||||
@@ -2343,6 +2366,17 @@ packages:
|
||||
ms: 2.1.3
|
||||
dev: true
|
||||
|
||||
/debug@4.3.4:
|
||||
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
dependencies:
|
||||
ms: 2.1.2
|
||||
|
||||
/debug@4.3.4(supports-color@5.5.0):
|
||||
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
@@ -2354,6 +2388,7 @@ packages:
|
||||
dependencies:
|
||||
ms: 2.1.2
|
||||
supports-color: 5.5.0
|
||||
dev: false
|
||||
|
||||
/decode-named-character-reference@1.0.2:
|
||||
resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==}
|
||||
@@ -2666,7 +2701,7 @@ packages:
|
||||
eslint: '*'
|
||||
eslint-plugin-import: '*'
|
||||
dependencies:
|
||||
debug: 4.3.4(supports-color@5.5.0)
|
||||
debug: 4.3.4
|
||||
eslint: 8.20.0
|
||||
eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.55.0)(eslint-import-resolver-typescript@2.7.1)(eslint@8.20.0)
|
||||
glob: 7.2.3
|
||||
@@ -2836,7 +2871,7 @@ packages:
|
||||
ajv: 6.12.6
|
||||
chalk: 4.1.2
|
||||
cross-spawn: 7.0.3
|
||||
debug: 4.3.4(supports-color@5.5.0)
|
||||
debug: 4.3.4
|
||||
doctrine: 3.0.0
|
||||
escape-string-regexp: 4.0.0
|
||||
eslint-scope: 7.1.1
|
||||
@@ -3173,6 +3208,7 @@ packages:
|
||||
/has-flag@3.0.0:
|
||||
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
|
||||
engines: {node: '>=4'}
|
||||
dev: false
|
||||
|
||||
/has-flag@4.0.0:
|
||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||
@@ -3263,7 +3299,7 @@ packages:
|
||||
dependencies:
|
||||
'@tootallnate/once': 2.0.0
|
||||
agent-base: 6.0.2
|
||||
debug: 4.3.4(supports-color@5.5.0)
|
||||
debug: 4.3.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@@ -3273,7 +3309,7 @@ packages:
|
||||
engines: {node: '>= 6'}
|
||||
dependencies:
|
||||
agent-base: 6.0.2
|
||||
debug: 4.3.4(supports-color@5.5.0)
|
||||
debug: 4.3.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@@ -4138,7 +4174,7 @@ packages:
|
||||
resolution: {integrity: sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==}
|
||||
dependencies:
|
||||
'@types/debug': 4.1.7
|
||||
debug: 4.3.4(supports-color@5.5.0)
|
||||
debug: 4.3.4
|
||||
decode-named-character-reference: 1.0.2
|
||||
micromark-core-commonmark: 1.0.6
|
||||
micromark-factory-space: 1.0.0
|
||||
@@ -4205,7 +4241,7 @@ packages:
|
||||
dependencies:
|
||||
'@tediousjs/connection-string': 0.4.2
|
||||
commander: 9.5.0
|
||||
debug: 4.3.4(supports-color@5.5.0)
|
||||
debug: 4.3.4
|
||||
rfdc: 1.3.0
|
||||
tarn: 3.0.2
|
||||
tedious: 15.1.3
|
||||
@@ -4965,6 +5001,20 @@ packages:
|
||||
tslib: 2.5.0
|
||||
dev: false
|
||||
|
||||
/react-svg@16.1.11(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-Utrm1NATp/1PVML4g97yrFyLvbKZ9HhzFydSsUPuCd8eEYf8llj8sBaYgLO1d5UX5sJ9j2sLgSbOLrGGRhd8NQ==}
|
||||
peerDependencies:
|
||||
react: ^16.0.0 || ^17.0.0 || ^18.0.0
|
||||
react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.21.5
|
||||
'@tanem/svg-injector': 10.1.53
|
||||
'@types/prop-types': 15.7.5
|
||||
prop-types: 15.8.1
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/react-syntax-highlighter@15.5.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==}
|
||||
peerDependencies:
|
||||
@@ -5483,6 +5533,7 @@ packages:
|
||||
engines: {node: '>=4'}
|
||||
dependencies:
|
||||
has-flag: 3.0.0
|
||||
dev: false
|
||||
|
||||
/supports-color@7.2.0:
|
||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||
|
||||
6
public/tidb-cloud.svg
Normal file
6
public/tidb-cloud.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-20 -20 310 310" stroke="currentColor" fill="transparent" stroke-width="7">
|
||||
<path id="out_line" d="M202.51,79.58c-23.51-40.94-75.76-55.07-116.7-31.55-22.03,12.65-37.29,34.44-41.64,59.47C13.48,114.6-5.63,145.24,1.49,175.93c5.99,25.86,29.04,44.17,55.58,44.16,1.93,0,3.86-.1,5.78-.29h116.83c1.91,.15,3.83,.29,5.78,.29,39.37,0,71.29-31.92,71.29-71.29,0-32.8-22.38-61.37-54.23-69.22h0Z"/>
|
||||
<path id="t_line" d="M128.29,81.27l-44.16,25.5v25.49l22.09-12.75v51.32l22.08,12.73h0V106.75l22.08-12.75-22.08-12.74Z"/>
|
||||
<path id="i_line" d="M150.5,119.64v51.17l22.17-12.8v-51.19l-22.17,12.81Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 723 B |
@@ -231,6 +231,7 @@ const CreateConnectionModal = (props: Props) => {
|
||||
{ value: Engine.MySQL, label: "MySQL" },
|
||||
{ value: Engine.PostgreSQL, label: "PostgreSQL" },
|
||||
{ value: Engine.MSSQL, label: "MSSQL" },
|
||||
{ value: Engine.TiDBServerless, label: "TiDB Serverless Tier" },
|
||||
]}
|
||||
onValueChange={(value) =>
|
||||
setPartialConnection({ engineType: value as Engine })
|
||||
@@ -300,114 +301,123 @@ const CreateConnectionModal = (props: Props) => {
|
||||
onChange={(value) => setPartialConnection({ password: value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full flex flex-col">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
SSL
|
||||
</label>
|
||||
<div className="w-full flex flex-row justify-start items-start flex-wrap">
|
||||
{SSLTypeOptions.map((option) => (
|
||||
<label
|
||||
key={option.value}
|
||||
className="w-auto flex flex-row justify-start items-center cursor-pointer mr-3 mb-3"
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className="radio w-4 h-4 mr-1"
|
||||
value={option.value}
|
||||
checked={sslType === option.value}
|
||||
onChange={(e) => setSSLType(e.target.value as SSLType)}
|
||||
/>
|
||||
<span className="text-sm">{option.label}</span>
|
||||
</label>
|
||||
))}
|
||||
{connection.engineType === Engine.TiDBServerless ? (
|
||||
<div className="w-full flex flex-col">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
{t("connection.tidb-serverless-ssl-hint")}
|
||||
</label>
|
||||
</div>
|
||||
{sslType !== "none" && (
|
||||
<>
|
||||
<div className="text-sm space-x-3 mb-2">
|
||||
<span
|
||||
className={`leading-6 pb-1 border-b-2 border-transparent cursor-pointer opacity-60 hover:opacity-80 ${
|
||||
selectedSSLField === "ca" &&
|
||||
"!border-indigo-600 !opacity-100"
|
||||
} `}
|
||||
onClick={() => setSelectedSSLField("ca")}
|
||||
) : (
|
||||
<div className="w-full flex flex-col">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
SSL
|
||||
</label>
|
||||
<div className="w-full flex flex-row justify-start items-start flex-wrap">
|
||||
{SSLTypeOptions.map((option) => (
|
||||
<label
|
||||
key={option.value}
|
||||
className="w-auto flex flex-row justify-start items-center cursor-pointer mr-3 mb-3"
|
||||
>
|
||||
CA Certificate
|
||||
</span>
|
||||
{sslType === "full" && (
|
||||
<>
|
||||
<span
|
||||
className={`leading-6 pb-1 border-b-2 border-transparent cursor-pointer opacity-60 hover:opacity-80 ${
|
||||
selectedSSLField === "key" &&
|
||||
"!border-indigo-600 !opacity-100"
|
||||
}`}
|
||||
onClick={() => setSelectedSSLField("key")}
|
||||
>
|
||||
Client Key
|
||||
</span>
|
||||
<span
|
||||
className={`leading-6 pb-1 border-b-2 border-transparent cursor-pointer opacity-60 hover:opacity-80 ${
|
||||
selectedSSLField === "cert" &&
|
||||
"!border-indigo-600 !opacity-100"
|
||||
}`}
|
||||
onClick={() => setSelectedSSLField("cert")}
|
||||
>
|
||||
Client Certificate
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="w-full h-auto relative">
|
||||
<TextareaAutosize
|
||||
className="w-full border resize-none rounded-lg text-sm p-3"
|
||||
minRows={3}
|
||||
maxRows={3}
|
||||
value={
|
||||
(connection.ssl && connection.ssl[selectedSSLField]) ?? ""
|
||||
}
|
||||
onChange={handleSSLValueChange}
|
||||
/>
|
||||
<div
|
||||
className={`${
|
||||
connection.ssl &&
|
||||
connection.ssl[selectedSSLField] &&
|
||||
"hidden"
|
||||
} absolute top-3 left-4 text-gray-400 text-sm leading-6 pointer-events-none`}
|
||||
>
|
||||
<span className="">Input or </span>
|
||||
<label className="pointer-events-auto border border-dashed px-2 py-1 rounded-lg cursor-pointer hover:border-gray-600 hover:text-gray-600">
|
||||
upload file
|
||||
<input
|
||||
type="radio"
|
||||
className="radio w-4 h-4 mr-1"
|
||||
value={option.value}
|
||||
checked={sslType === option.value}
|
||||
onChange={(e) => setSSLType(e.target.value as SSLType)}
|
||||
/>
|
||||
<span className="text-sm">{option.label}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
{sslType !== "none" && (
|
||||
<>
|
||||
<div className="text-sm space-x-3 mb-2">
|
||||
<span
|
||||
className={`leading-6 pb-1 border-b-2 border-transparent cursor-pointer opacity-60 hover:opacity-80 ${
|
||||
selectedSSLField === "ca" &&
|
||||
"!border-indigo-600 !opacity-100"
|
||||
} `}
|
||||
onClick={() => setSelectedSSLField("ca")}
|
||||
>
|
||||
CA Certificate
|
||||
</span>
|
||||
{sslType === "full" && (
|
||||
<>
|
||||
<span
|
||||
className={`leading-6 pb-1 border-b-2 border-transparent cursor-pointer opacity-60 hover:opacity-80 ${
|
||||
selectedSSLField === "key" &&
|
||||
"!border-indigo-600 !opacity-100"
|
||||
}`}
|
||||
onClick={() => setSelectedSSLField("key")}
|
||||
>
|
||||
Client Key
|
||||
</span>
|
||||
<span
|
||||
className={`leading-6 pb-1 border-b-2 border-transparent cursor-pointer opacity-60 hover:opacity-80 ${
|
||||
selectedSSLField === "cert" &&
|
||||
"!border-indigo-600 !opacity-100"
|
||||
}`}
|
||||
onClick={() => setSelectedSSLField("cert")}
|
||||
>
|
||||
Client Certificate
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="w-full h-auto relative">
|
||||
<TextareaAutosize
|
||||
className="w-full border resize-none rounded-lg text-sm p-3"
|
||||
minRows={3}
|
||||
maxRows={3}
|
||||
value={
|
||||
(connection.ssl && connection.ssl[selectedSSLField]) ?? ""
|
||||
}
|
||||
onChange={handleSSLValueChange}
|
||||
/>
|
||||
<div
|
||||
className={`${
|
||||
connection.ssl &&
|
||||
connection.ssl[selectedSSLField] &&
|
||||
"hidden"
|
||||
} absolute top-3 left-4 text-gray-400 text-sm leading-6 pointer-events-none`}
|
||||
>
|
||||
<span className="">Input or </span>
|
||||
<label className="pointer-events-auto border border-dashed px-2 py-1 rounded-lg cursor-pointer hover:border-gray-600 hover:text-gray-600">
|
||||
upload file
|
||||
<input
|
||||
className="hidden"
|
||||
type="file"
|
||||
onChange={handleSSLFileInputChange}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{connection.engineType === Engine.MSSQL && (
|
||||
<div className="w-full flex flex-col">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Encrypt
|
||||
</label>
|
||||
<div className="w-full flex flex-row justify-start items-start flex-wrap">
|
||||
<label className="flex items-center">
|
||||
<input
|
||||
className="hidden"
|
||||
type="file"
|
||||
onChange={handleSSLFileInputChange}
|
||||
type="checkbox"
|
||||
className="form-checkbox h-4 w-4 text-indigo-600 transition duration-150 ease-in-out"
|
||||
checked={connection.encrypt}
|
||||
onChange={(e) =>
|
||||
setPartialConnection({ encrypt: e.target.checked })
|
||||
}
|
||||
/>
|
||||
<span className="ml-2 text-sm">Encrypt connection</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{connection.engineType === Engine.MSSQL && (
|
||||
<div className="w-full flex flex-col">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Encrypt
|
||||
</label>
|
||||
<div className="w-full flex flex-row justify-start items-start flex-wrap">
|
||||
<label className="flex items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="form-checkbox h-4 w-4 text-indigo-600 transition duration-150 ease-in-out"
|
||||
checked={connection.encrypt}
|
||||
onChange={(e) =>
|
||||
setPartialConnection({ encrypt: e.target.checked })
|
||||
}
|
||||
/>
|
||||
<span className="ml-2 text-sm">Encrypt connection</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="modal-action w-full flex flex-row justify-between items-center space-x-2">
|
||||
<div>
|
||||
{isEditing && (
|
||||
|
||||
@@ -15,6 +15,8 @@ const EngineIcon = (props: Props) => {
|
||||
return <Icon.DiPostgresql className={className} />;
|
||||
} else if (engine === Engine.MSSQL) {
|
||||
return <Icon.DiMsqlServer className={className} />;
|
||||
} else if (engine === Engine.TiDBServerless) {
|
||||
return <Icon.TiDBCloudIcon className={className}/>;
|
||||
} else {
|
||||
return <Icon.DiDatabase className={className} />;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,12 @@ import * as Fi from "react-icons/fi";
|
||||
import * as Gi from "react-icons/gi";
|
||||
import * as Io from "react-icons/io";
|
||||
import * as Io5 from "react-icons/io5";
|
||||
import {IconType, IconBaseProps} from "react-icons/lib";
|
||||
import {ReactSVG} from "react-svg";
|
||||
|
||||
const TiDBCloudIcon: IconType = (props: IconBaseProps) => (
|
||||
<ReactSVG src="tidb-cloud.svg" className={props.className} />
|
||||
);
|
||||
|
||||
const Icon = {
|
||||
...Ai,
|
||||
@@ -16,6 +22,7 @@ const Icon = {
|
||||
...Gi,
|
||||
...Io,
|
||||
...Io5,
|
||||
TiDBCloudIcon
|
||||
};
|
||||
|
||||
// Icon is a collection of all icons from react-icons.
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
"port": "Port",
|
||||
"database-name": "Database name",
|
||||
"username": "Username",
|
||||
"password": "Password"
|
||||
"password": "Password",
|
||||
"tidb-serverless-ssl-hint": "SSL is required and configured"
|
||||
},
|
||||
"assistant": {
|
||||
"self": "Bot",
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
"port": "Puerto",
|
||||
"database-name": "Nombre de Base de Datos",
|
||||
"username": "Usuario",
|
||||
"password": "Contraseña"
|
||||
"password": "Contraseña",
|
||||
"tidb-serverless-ssl-hint": "Se requiere SSL y ya está configurado"
|
||||
},
|
||||
"assistant": {
|
||||
"self": "Bot",
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
"port": "端口",
|
||||
"database-name": "数据库",
|
||||
"username": "用户名",
|
||||
"password": "密码"
|
||||
"password": "密码",
|
||||
"tidb-serverless-ssl-hint": "必需SSL且已配置"
|
||||
},
|
||||
"assistant": {
|
||||
"self": "机器人",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
import { newConnector } from "@/lib/connectors";
|
||||
import { Connection } from "@/types";
|
||||
import { changeTiDBConnectionToMySQL } from "@/utils";
|
||||
import { Engine } from "@/types/connection";
|
||||
|
||||
// POST /api/connection/db
|
||||
// req body: { connection: Connection }
|
||||
@@ -10,7 +12,11 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return res.status(405).json([]);
|
||||
}
|
||||
|
||||
const connection = req.body.connection as Connection;
|
||||
let connection = req.body.connection as Connection;
|
||||
if (connection.engineType === Engine.TiDBServerless) {
|
||||
connection = changeTiDBConnectionToMySQL(connection);
|
||||
}
|
||||
|
||||
try {
|
||||
const connector = newConnector(connection);
|
||||
const databaseNameList = await connector.getDatabases();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
import { newConnector } from "@/lib/connectors";
|
||||
import { Connection, Table } from "@/types";
|
||||
import { changeTiDBConnectionToMySQL } from "@/utils";
|
||||
import { Engine } from "@/types/connection";
|
||||
|
||||
// POST /api/connection/db_schema
|
||||
// req body: { connection: Connection, db: string }
|
||||
@@ -10,7 +12,11 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return res.status(405).json([]);
|
||||
}
|
||||
|
||||
const connection = req.body.connection as Connection;
|
||||
let connection = req.body.connection as Connection;
|
||||
if (connection.engineType === Engine.TiDBServerless) {
|
||||
connection = changeTiDBConnectionToMySQL(connection);
|
||||
}
|
||||
|
||||
const db = req.body.db as string;
|
||||
try {
|
||||
const connector = newConnector(connection);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
import { newConnector } from "@/lib/connectors";
|
||||
import { Connection } from "@/types";
|
||||
import { changeTiDBConnectionToMySQL } from "@/utils";
|
||||
import { Engine } from "@/types/connection";
|
||||
|
||||
// POST /api/connection/execute
|
||||
// req body: { connection: Connection, db: string, statement: string }
|
||||
@@ -9,7 +11,10 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return res.status(405).json(false);
|
||||
}
|
||||
|
||||
const connection = req.body.connection as Connection;
|
||||
let connection = req.body.connection as Connection;
|
||||
if (connection.engineType === Engine.TiDBServerless) {
|
||||
connection = changeTiDBConnectionToMySQL(connection);
|
||||
}
|
||||
const db = req.body.db as string;
|
||||
const statement = req.body.statement as string;
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
import { newConnector } from "@/lib/connectors";
|
||||
import { Connection } from "@/types";
|
||||
import { changeTiDBConnectionToMySQL } from "@/utils";
|
||||
import { Engine } from "@/types/connection";
|
||||
|
||||
// POST /api/connection/test
|
||||
// req body: { connection: Connection }
|
||||
@@ -10,7 +12,10 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return res.status(405).json(false);
|
||||
}
|
||||
|
||||
const connection = req.body.connection as Connection;
|
||||
let connection = req.body.connection as Connection;
|
||||
if (connection.engineType === Engine.TiDBServerless) {
|
||||
connection = changeTiDBConnectionToMySQL(connection);
|
||||
}
|
||||
try {
|
||||
const connector = newConnector(connection);
|
||||
await connector.testConnection();
|
||||
|
||||
@@ -4,12 +4,15 @@ export enum Engine {
|
||||
MySQL = "MYSQL",
|
||||
PostgreSQL = "POSTGRESQL",
|
||||
MSSQL = "MSSQL",
|
||||
TiDBServerless = "TiDBServerless",
|
||||
}
|
||||
|
||||
export interface SSLOptions {
|
||||
ca?: string;
|
||||
cert?: string;
|
||||
key?: string;
|
||||
minVersion?: string;
|
||||
rejectUnauthorized?: boolean;
|
||||
}
|
||||
|
||||
export interface Connection {
|
||||
|
||||
@@ -4,3 +4,4 @@ export * from "./sql";
|
||||
export * from "./execution";
|
||||
export * from "./model";
|
||||
export * from "./feature";
|
||||
export * from "./tidb";
|
||||
16
src/utils/tidb.ts
Normal file
16
src/utils/tidb.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { Connection } from "@/types";
|
||||
import { Engine } from "@/types/connection";
|
||||
|
||||
export const changeTiDBConnectionToMySQL = (connection: Connection) => {
|
||||
if (connection.engineType === Engine.TiDBServerless) {
|
||||
return {
|
||||
...connection,
|
||||
engineType: Engine.MySQL,
|
||||
ssl: {
|
||||
minVersion: 'TLSv1.2',
|
||||
rejectUnauthorized: true
|
||||
}
|
||||
};
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
Reference in New Issue
Block a user