Skip to content

Commit d9992f9

Browse files
committed
feat: add data editor capability for various SQL data sources and update dependencies
1 parent 2889fb3 commit d9992f9

118 files changed

Lines changed: 8112 additions & 246 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,28 @@ Status:
3333

3434
Datasource types:
3535
- `mysql`
36+
- `mariadb`
3637
- `postgres`
38+
- `cockroachdb`
3739
- `sqlite` (local only)
40+
- `duckdb` (local only)
41+
- `mssql`
42+
- `clickhouse`
43+
- `oracle`
44+
- `cassandra`
45+
- `mongodb`
46+
- `redis`
3847
- `elasticsearch`
3948
- `s3`
4049
- `minio`
4150

51+
Frontend export formats:
52+
- `csv`
53+
- `json`
54+
- `sql inserts`
55+
- `xml`
56+
- `html table`
57+
4258
Runtime targets:
4359
- Electron desktop app with a built-in local backend
4460
- Hosted backend + Vite frontend for browser usage

packages/backend/package.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,28 @@
1818
"author": "",
1919
"license": "ISC",
2020
"dependencies": {
21+
"@clickhouse/client": "^1.18.2",
22+
"@duckdb/node-api": "1.5.1-r.1",
2123
"@elastic/elasticsearch": "^9.3.4",
2224
"@types/body-parser": "^1.19.5",
2325
"@types/express": "^5.0.2",
2426
"@types/express-ws": "^3.0.5",
25-
"body-parser": "^2.2.0",
2627
"better-sqlite3": "^12.8.0",
28+
"body-parser": "^2.2.0",
29+
"cassandra-driver": "^4.8.0",
2730
"cors": "^2.8.5",
2831
"drizzle-orm": "^0.45.1",
2932
"express": "^5.0.2",
3033
"express-ws": "^5.0.2",
3134
"minio": "^8.0.7",
35+
"mongodb": "^7.1.1",
36+
"mssql": "^12.2.1",
3237
"mysql2": "^3.14.1",
3338
"nodemon": "^3.1.10",
3439
"openid-client": "^6.8.2",
40+
"oracledb": "^6.10.0",
3541
"pg": "^8.20.0",
42+
"redis": "^5.11.0",
3643
"ts-node": "^10.9.2",
3744
"tsx": "^4.21.0",
3845
"ws": "^8.18.2"
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { createRequire } from 'node:module'
2+
import type { Client } from 'cassandra-driver'
3+
import type * as CassandraNamespace from 'cassandra-driver'
4+
import type { QueryResult } from '../../adapters/database/sql/default-sql-adapter/DefaultSQLAdapter.ts'
5+
import { createSelectResultFromRows, QueryOnlySqlAdapter } from '../shared-sql/query-only-adapter.ts'
6+
7+
type CassandraConfig = {
8+
host: string
9+
port: number
10+
user?: string
11+
password?: string
12+
database?: string
13+
ssl?: boolean
14+
}
15+
16+
type CassandraModule = typeof CassandraNamespace
17+
18+
export class CassandraSqlAdapter extends QueryOnlySqlAdapter {
19+
private static readonly require = createRequire(import.meta.url)
20+
private client!: Client
21+
22+
constructor(private readonly config: CassandraConfig) {
23+
super()
24+
}
25+
26+
private loadCassandraModule() {
27+
return CassandraSqlAdapter.require('cassandra-driver') as CassandraModule
28+
}
29+
30+
async connect() {
31+
const { Client } = this.loadCassandraModule()
32+
this.client = new Client({
33+
contactPoints: [this.config.host],
34+
localDataCenter: 'datacenter1',
35+
protocolOptions: {
36+
port: this.config.port,
37+
},
38+
keyspace: this.config.database,
39+
credentials:
40+
this.config.user
41+
? {
42+
username: this.config.user,
43+
password: this.config.password ?? '',
44+
}
45+
: undefined,
46+
sslOptions: this.config.ssl ? {} : undefined,
47+
})
48+
49+
await this.client.connect()
50+
}
51+
52+
async close() {
53+
await this.client?.shutdown()
54+
}
55+
56+
async execute(sqlText: string): Promise<QueryResult> {
57+
const result = await this.client.execute(sqlText)
58+
const rows = result.rows.map((row) => ({ ...row }))
59+
60+
if (rows.length || result.columns?.length) {
61+
return createSelectResultFromRows(rows as Record<string, unknown>[])
62+
}
63+
64+
return {
65+
type: 'RESULT',
66+
result: {
67+
command: 'CQL',
68+
},
69+
}
70+
}
71+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { normalizeNetworkSqlConfig } from '../shared-sql/network-config.ts'
2+
import type { DataSourceModule } from '../shared/module.ts'
3+
import { CassandraSqlAdapter } from './adapter.ts'
4+
5+
export const cassandraDataSourceModule = {
6+
definition: {
7+
type: 'cassandra',
8+
kind: 'sql',
9+
label: 'Cassandra',
10+
icon: 'database',
11+
capabilities: {
12+
sqlQuery: true,
13+
tableBrowser: false,
14+
dataEditor: false,
15+
schemaEditor: false,
16+
resourceBrowser: false,
17+
},
18+
},
19+
secretFields: ['password'],
20+
normalizeConfig(config) {
21+
return normalizeNetworkSqlConfig(config, {
22+
defaultPort: 9042,
23+
requireUser: false,
24+
requirePassword: false,
25+
requireDatabase: false,
26+
includeSsl: true,
27+
})
28+
},
29+
createSqlAdapter(config) {
30+
return new CassandraSqlAdapter(
31+
config as {
32+
host: string
33+
port: number
34+
user?: string
35+
password?: string
36+
database?: string
37+
ssl?: boolean
38+
},
39+
)
40+
},
41+
} satisfies DataSourceModule

0 commit comments

Comments
 (0)