Skip to content

Commit

Permalink
Merge pull request #9 from tidbcloud/playground
Browse files Browse the repository at this point in the history
feat: playground
  • Loading branch information
baurine authored Jun 21, 2024
2 parents b452e85 + 7f4d64d commit 1002b8d
Show file tree
Hide file tree
Showing 32 changed files with 1,472 additions and 387 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
node_modules
dist
build

# Local Netlify folder
.netlify
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
### Setup

- node.js >18.16.0
- pnpm >9.3.0
- [use corepack](https://www.totaltypescript.com/how-to-use-corepack): `corepack enable && corepack enable npm`

### Local Development

- `echo 'link-workspace-packages=true' >> ~/.npmrc`
- `pnpm i`
- `pnpm dev`
- `echo 'link-workspace-packages=true' >> ~/.npmrc`

### Production Build

Expand Down
3 changes: 3 additions & 0 deletions netlify/edge-functions/hello.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default () => new Response('Hello world')

export const config = { path: '/api/hello' }
105 changes: 105 additions & 0 deletions netlify/edge-functions/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { connect } from 'https://esm.sh/@tidbcloud/serverless'

type SchemaRes = {
name: string
tables: {
name: string
columns: {
col: string
data_type: string
nullable: boolean
}[]
}[]
}[]

export default async () => {
// url:
// mysql://[user]:[pwd]@[host]/
// database is skipped and its default value is `test`
const conn = connect({
url: Netlify.env.get('TIDBCLOUD_DATABASE_URL')
})

let schema: SchemaRes = []

// step 1: get all databases
let dbs = await conn.execute('show databases')
// responses:
// [
// {
// "Database": "INFORMATION_SCHEMA"
// },
// {
// "Database": "PERFORMANCE_SCHEMA"
// },
// {
// "Database": "game"
// },
// ...
// ]
schema = dbs
.map((db) => db.Database)
.filter(
(db) =>
![
'INFORMATION_SCHEMA',
'PERFORMANCE_SCHEMA',
'lightning_task_info',
'mysql'
].includes(db)
)
.sort()
.map((db) => ({ name: db, tables: [] }))
console.log('dbs:', schema)

// step 2: get tables for each db
for (let i = 0; i < schema.length; i++) {
const db = schema[i]
const tables = await conn.execute(
`
SELECT
TABLE_NAME as name
FROM
information_schema.tables
WHERE
table_schema = ?
ORDER BY
name ASC`,
[db.name]
)
db.tables = tables.map((t) => ({ ...t, columns: [] }))

// step 3: get columns for each table
for (let j = 0; j < db.tables.length; j++) {
const table = db.tables[j]

const columns = await conn.execute(
`
SELECT
COLUMN_NAME as col, DATA_TYPE as data_type, IS_NULLABLE as is_nullable
FROM
information_schema.columns
WHERE
table_schema = ? AND table_name = ?
ORDER BY
col ASC`,
[db.name, table.name]
)
table.columns = columns.map((c) => ({
col: c.col,
data_type: c.data_type,
nullable: c.is_nullable === 'YES'
}))
}
}
return new Response(
JSON.stringify({ code: 200, message: 'ok', data: schema }),
{
headers: {
'cache-control': 'public, s-maxage=3600'
}
}
)
}

export const config = { path: '/api/schema', cache: 'manual' }
39 changes: 39 additions & 0 deletions netlify/edge-functions/statement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { Config, Context } from '@netlify/edge-functions'
import { connect } from 'https://esm.sh/@tidbcloud/serverless'

type StatementReq = {
database: string
sql: string
}

export default async (req: Request, _context: Context) => {
const body: StatementReq = await req.json()

// url:
// mysql://[user]:[pwd]@[host]/
// database is skipped and its default value is `test`
const conn = connect({
url: Netlify.env.get('TIDBCLOUD_DATABASE_URL') + body.database
})

if (body.sql.trim().toLowerCase().startsWith('select')) {
const res = await conn.execute(body.sql, null, {
arrayMode: true,
fullResult: true
})

return new Response(JSON.stringify({ code: 200, message: 'ok', data: res }))
} else {
return new Response(
JSON.stringify({
code: 403,
message:
'forbidden, only select statement is available to run in this playground',
data: {}
}),
{ status: 403 }
)
}
}

export const config: Config = { path: '/api/statement' }
19 changes: 2 additions & 17 deletions packages/extensions/events/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tidbcloud/tisqleditor-extension-events",
"version": "1.0.0",
"version": "0.0.1",
"description": "tisqleditor extensions",
"type": "module",
"main": "dist/index.js",
Expand Down Expand Up @@ -28,29 +28,14 @@
"author": "",
"license": "MIT",
"devDependencies": {
"@codemirror/autocomplete": "^6.16.2",
"@codemirror/commands": "6.3.3",
"@codemirror/lang-sql": "^6.6.4",
"@codemirror/language": "^6.10.2",
"@codemirror/lint": "^6.8.0",
"@codemirror/search": "^6.5.6",
"@codemirror/state": "^6.4.1",
"@codemirror/view": "^6.26.3",
"@rollup/plugin-typescript": "^11.1.6",
"rollup": "^4.18.0",
"tslib": "^2.6.3",
"typescript": "^5.4.5"
},
"peerDependencies": {
"@codemirror/autocomplete": "^6.16.2",
"@codemirror/commands": "6.3.3",
"@codemirror/lang-sql": "^6.6.4",
"@codemirror/language": "^6.10.2",
"@codemirror/lint": "^6.8.0",
"@codemirror/search": "^6.5.6",
"@codemirror/state": "^6.4.1",
"@codemirror/view": "^6.26.3",
"@lezer/highlight": "^1.2.0"
"@codemirror/view": "^6.26.3"
},
"dependencies": {
"@tidbcloud/tisqleditor-extension-cur-sql": "workspace:^",
Expand Down
3 changes: 1 addition & 2 deletions packages/extensions/sql-parser/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ const statementsField = StateField.define<SqlStatement[]>({
// regex to match use statement
// examples:
// - use test;
// - use test ;
// - USE `test`;
// - use 'test';
// - use "test";
export const useStatementRegex = /^use\s+[`]?([a-zA-Z0-9_-]+)[`]?\s*;$/i
const ddlStatementRegex =
/^(create|drop|alter|truncate|rename|comment|grant|revoke)/i
Expand Down
4 changes: 4 additions & 0 deletions packages/playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
"preview": "vite preview"
},
"dependencies": {
"@codemirror/autocomplete": "^6.16.2",
"@codemirror/lang-sql": "^6.6.4",
"@codemirror/state": "^6.4.1",
"@codemirror/view": "^6.26.3",
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
Expand All @@ -20,6 +23,7 @@
"@radix-ui/react-tabs": "^1.0.4",
"@tanstack/react-query": "^5.45.1",
"@tidbcloud/tisqleditor-extension-save-helper": "workspace:^",
"@tidbcloud/tisqleditor-extension-sql-parser": "workspace:^",
"@tidbcloud/tisqleditor-extension-themes": "workspace:^",
"@tidbcloud/tisqleditor-react": "workspace:^",
"class-variance-authority": "^0.7.0",
Expand Down
22 changes: 14 additions & 8 deletions packages/playground/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,28 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

import { EditorCacheProvider } from '@tidbcloud/tisqleditor-react'

import { FilesProvider } from '@/contexts/files-context-provider'
import { Panels } from '@/components/biz/panels'
import { ThemeProvider } from '@/components/darkmode-toggle/theme-provider'
import { StatementProvider } from '@/contexts/statement-context-provider'
import { FilesProvider } from '@/contexts/files-context-provider'
import { SchemaProvider } from '@/contexts/schema-context-provider'

const queryClient = new QueryClient()

function App() {
return (
<QueryClientProvider client={queryClient}>
<FilesProvider>
<EditorCacheProvider>
<ThemeProvider>
<Panels />
</ThemeProvider>
</EditorCacheProvider>
</FilesProvider>
<EditorCacheProvider>
<ThemeProvider>
<StatementProvider>
<SchemaProvider>
<FilesProvider>
<Panels />
</FilesProvider>
</SchemaProvider>
</StatementProvider>
</ThemeProvider>
</EditorCacheProvider>
</QueryClientProvider>
)
}
Expand Down
Loading

0 comments on commit 1002b8d

Please sign in to comment.