-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathsql.ts
119 lines (109 loc) · 3.06 KB
/
sql.ts
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 * as core from '@actions/core'
import { ConnectionString } from 'connection-string'
import { createWriteStream, readFileSync, writeFileSync } from 'fs'
import { createConnection, DatabaseType } from 'typeorm'
import { SQLConfig } from '../config'
import * as path from 'path'
import stringify from 'csv-stringify'
// TODO: wish there was a dynamic way to import this for runtime usage from the DatabaseType type
const TYPEORM_PROTOCOLS = [
'mysql',
'postgres',
'cockroachdb',
'sap',
'mariadb',
'sqlite',
'cordova',
'react-native',
'nativescript',
'sqljs',
'oracle',
'mssql',
'mongodb',
'aurora-data-api',
'aurora-data-api-pg',
'expo',
'better-sqlite3',
]
function isValidDatabaseType(protocol: string): protocol is DatabaseType {
return TYPEORM_PROTOCOLS.includes(protocol)
}
export default async function fetchSQL(config: SQLConfig): Promise<string> {
core.info('Fetching: SQL')
let connection
let query
core.debug('Reading query file')
try {
core.debug(`SQL Query file path: ${config.sql_queryfile}`)
query = readFileSync(config.sql_queryfile, { encoding: 'utf8' })
} catch (error) {
core.setFailed(
`Unable to read queryfile ${config.sql_queryfile}: ${error.message}`
)
throw error
}
core.debug('Connecting to database')
const parsed = new ConnectionString(config.sql_connstring)
try {
const protocol = parsed.protocol
if (!protocol) {
throw new Error(
'Unable to determine the database protocol from the connection string'
)
}
if (!isValidDatabaseType(protocol)) {
throw new Error(
`The '${protocol}' protocol is not supported. Please choose one of: ${TYPEORM_PROTOCOLS.join(
', '
)}`
)
}
// @ts-ignore
connection = await createConnection({
type: protocol,
url: config.sql_connstring,
})
} catch (error) {
core.setFailed(`Unable to connect to database: ${error.message}`)
throw error
}
core.info('Querying database')
let result
try {
result = await connection.query(query)
} catch (error) {
core.setFailed(`Unable to query database: ${error.message}`)
throw error
}
core.info('Closing database')
try {
await connection.close();
} catch (error) {
core.setFailed(`Unable to close database: ${error.message}`)
throw error
}
const outfile = `${config.downloaded_filename}`
const sqlFormat = outfile.split('.').pop() // should be csv or json
try {
switch (sqlFormat) {
case 'csv':
core.info('Writing CSV')
const writer = createWriteStream(outfile, { encoding: 'utf8' })
stringify(result, {
header: true,
}).pipe(writer)
await new Promise((resolve, reject) => {
writer.on('finish', resolve)
writer.on('error', reject)
})
break
default:
core.info('Writing JSON')
await writeFileSync(outfile, JSON.stringify(result))
}
return outfile
} catch (error) {
core.setFailed(`Unable to write results to ${outfile}: ${error.message}`)
throw error
}
}