This repository has been archived by the owner on Dec 5, 2022. It is now read-only.
forked from cwp/bluefin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfixture.js
102 lines (90 loc) · 2.64 KB
/
fixture.js
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
import Configuration from './lib/configuration'
import Database from './lib/database'
import {migrate} from './lib/commands'
import {promisify} from 'util'
import {randomBytes} from 'crypto'
const randbytes = promisify(randomBytes)
export async function create(endpoint, confFilePath, nickname, fs) {
const [conf, dbName] = await Promise.all([
await Configuration.db(nickname, confFilePath, fs),
genName(nickname),
])
Object.assign(conf.raw, endpoint)
const sysdb = await createDatabase(conf, dbName)
conf.raw.database = dbName
try {
await build(conf)
return fixture(conf, sysdb)
} catch (e) {
try {
await destroyDatabase(conf, sysdb)
} catch (destroyError) {
console.log(destroyError)
} finally {
throw e
}
}
}
export async function rebuild(confFilePath, nickname, _options = {}, fs) {
const options = Object.assign(
{},
{rebuild: true, quiet: true, migrations: true, grants: true},
_options,
)
const conf = await migrate(nickname, confFilePath, options)
const dsn = conf.dsn()
delete dsn.application_name
return dsn
}
const genName = async base => {
const buf = await randbytes(4)
const val = buf.readUInt32BE(0)
return `fixture_${base}_${val.toString(36)}`
}
const createDatabase = async (conf, dbName) => {
try {
var sysClient = await conf.connect()
await sysClient.exec(`create database ${dbName}`)
var sysdb = await sysClient.value('select current_database()')
} finally {
if (sysClient) await sysClient.disconnect()
}
return sysdb
}
const build = async conf => {
try {
const options = {rebuild: false, migrations: true, grants: true}
const oracle = Database.stub()
const middleware = await conf.loadMiddleware()
const plan = await conf.plan(options)
await plan.initialize(options, middleware)
await plan.customize(options, oracle, middleware)
await plan.finalize(options, middleware)
var client = await conf.connect()
await plan.execute(client)
if ('grants' in conf.raw) {
const roles = Object.keys(conf.raw.grants).join(', ')
await client.exec(`grant connect on database ${conf.name} to ${roles}`)
}
} catch (e) {
console.error(e)
} finally {
if (client) await client.disconnect()
}
}
const destroyDatabase = async (conf, sysdb) => {
try {
var client = await conf.connect(sysdb)
await client.exec(`drop database if exists ${conf.name}`)
} finally {
if (client) await client.disconnect()
}
}
const fixture = (conf, sysdb) => {
const endpoint = conf.dsn()
delete endpoint.application_name
return {
endpoint,
destroy: () => destroyDatabase(conf, sysdb),
}
}