-
-
Notifications
You must be signed in to change notification settings - Fork 108
Expand file tree
/
Copy pathindex.ts
More file actions
119 lines (99 loc) · 3.08 KB
/
Copy pathindex.ts
File metadata and controls
119 lines (99 loc) · 3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import type { CompiledQuery, Dialect, Driver, QueryResult } from 'kysely'
import type { connections } from '~/drizzle'
import { type } from 'arktype'
import { DummyDriver, MysqlQueryCompiler } from 'kysely'
import { logSql } from '../../sql'
function escapeSqlString(v: string) {
return v.replace(/[\\']/g, '\\$&')
}
const dateStringType = type('string.date')
function prepareQuery(compiledQuery: CompiledQuery) {
let i = 0
const compiledSql = compiledQuery.sql.replace(/\?/g, () => {
const param = compiledQuery.parameters[i++]
if (param === null || param === undefined) {
return 'NULL'
}
if (typeof param === 'number') {
return `${param}`
}
if (param instanceof Date) {
return `parseDateTime64BestEffort('${escapeSqlString(param.toISOString())}')`
}
if (typeof param !== 'string') {
return `'${escapeSqlString(JSON.stringify(param))}'`
}
if (dateStringType.allows(param)) {
return `parseDateTime64BestEffort('${escapeSqlString(param)}')`
}
return `'${escapeSqlString(param)}'`
})
return compiledSql.replace(
/^update ((`\w+`\.)*`\w+`) set/i,
'alter table $1 update',
)
}
function execute(connection: typeof connections.$inferSelect, compiledQuery: CompiledQuery) {
if (!window.electron) {
throw new Error('Electron is not available')
}
const preparedQuery = prepareQuery(compiledQuery)
const promise = window.electron.query.clickhouse({
connectionString: connection.connectionString,
sql: preparedQuery,
})
logSql(connection, promise, { sql: preparedQuery })
return promise
}
function createDriver(connection: typeof connections.$inferSelect) {
return {
async init() {},
async acquireConnection() {
return {
executeQuery: async <R>(compiledQuery: CompiledQuery): Promise<QueryResult<R>> => {
const { result } = await execute(connection, compiledQuery)
return {
rows: result as R[],
}
},
streamQuery() {
throw new Error('Not implemented')
},
}
},
async beginTransaction() {},
async commitTransaction() {},
async rollbackTransaction() {},
async releaseConnection() {},
async destroy() {},
} satisfies Driver
}
function clickhouseAdapter() {
return {
supportsCreateIfNotExists: false,
supportsTransactionalDdl: false,
supportsReturning: false,
acquireMigrationLock: async () => {},
releaseMigrationLock: async () => {},
}
}
export function clickhouseDialect(connection: typeof connections.$inferSelect) {
return {
createAdapter: clickhouseAdapter,
createDriver: () => createDriver(connection),
createQueryCompiler: () => new MysqlQueryCompiler(),
createIntrospector: () => {
throw new Error('Not implemented')
},
} satisfies Dialect
}
export function clickhouseColdDialect() {
return {
createAdapter: clickhouseAdapter,
createDriver: () => new DummyDriver(),
createQueryCompiler: () => new MysqlQueryCompiler(),
createIntrospector: () => {
throw new Error('Not implemented')
},
} satisfies Dialect
}