Skip to content

Commit

Permalink
add support for pg_dump command arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
James committed Jan 2, 2020
1 parent ae4b5e3 commit 2cf12ab
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 11 deletions.
1 change: 1 addition & 0 deletions lib/config.js
@@ -1,5 +1,6 @@
const path = require('path')

// default config that is overridden by the Lambda event
module.exports = {
S3_REGION: 'eu-west-1',
PGDUMP_PATH: path.join(__dirname, '../bin/postgres-11.6'),
Expand Down
2 changes: 1 addition & 1 deletion lib/handler.js
Expand Up @@ -39,7 +39,7 @@ async function handler(event) {
}
catch (error) {
// log the error and rethrow for Lambda
if (process.env.NODE_ENV !== "test") {
if (process.env.NODE_ENV !== 'test') {
console.error(error)
}
throw error
Expand Down
29 changes: 23 additions & 6 deletions lib/pgdump.js
Expand Up @@ -3,30 +3,47 @@ const through2 = require('through2')
const path = require('path')
const fs = require('fs')

function spawnPgDump(config) {
function spawnPgDump(pgdumpDir, args, env) {
const pgDumpPath = path.join(
config.PGDUMP_PATH,
pgdumpDir,
'pg_dump'
)
if (!fs.existsSync(pgDumpPath)) {
throw new Error('pg_dump not found at ' + pgDumpPath)
}
const env = { ...config, LD_LIBRARY_PATH: config.PGDUMP_PATH }
return spawn(pgDumpPath, ['-Fc', '-Z 1'], {

return spawn(pgDumpPath, args, {
env
})
}

function buildArgs(config) {
let args = ['-Fc', '-Z1']
const extraArgs = config.PGDUMP_ARGS

if (typeof extraArgs === 'string') {
const splitArgs = extraArgs.split(' ')
args = args.concat(splitArgs)
}
else if (Array.isArray(extraArgs)) {
args = args.concat(extraArgs)
}

return args
}

function pgdump(config, pgDumpSpawnFn = spawnPgDump) {
return new Promise((resolve, reject) => {
let headerChecked = false
let stderr = ''

// spawn pg_dump process
const process = pgDumpSpawnFn(config)
const args = buildArgs(config)
const env = { ...config, LD_LIBRARY_PATH: config.PGDUMP_PATH }
const process = pgDumpSpawnFn(config.PGDUMP_PATH, args, env)

// hook into the process
process.stderr.on('data', (data) => {
process.stderr.on('data', data => {
stderr += data.toString('utf8')
})

Expand Down
62 changes: 58 additions & 4 deletions test/pgdump.js
Expand Up @@ -3,6 +3,7 @@ const fs = require('fs')
const mockSpawn = require('mock-spawn')
const chai = require('chai')
const chaiAsPromised = require('chai-as-promised')
const sinon = require('sinon')

chai.use(chaiAsPromised)
const { expect } = chai
Expand All @@ -27,14 +28,67 @@ describe('pgdump', () => {
)
})

it('should call pg_dump with some default args', async () => {
const pgdumpProcess = mockSpawn()()
const pgDumpFn = sinon.fake.returns(pgdumpProcess)
const config = {}
const p = pgdump(config, pgDumpFn)
pgdumpProcess.stdout.write('PGDMP - data - data')
pgdumpProcess.emit('close', 0)
await p

expect(pgDumpFn.calledOnce).to.be.true
const pgDumpArgs = pgDumpFn.getCall(0).args[1]
expect(pgDumpArgs).to.deep.equal(['-Fc', '-Z1'])
})

it('should call pg_dump with provided extra arguments as array', async () => {
const pgdumpProcess = mockSpawn()()
const pgDumpFn = sinon.fake.returns(pgdumpProcess)
const config = {
PGDUMP_ARGS: ['--exclude-table=ignored-table', '-N', 'public']
}
const p = pgdump(config, pgDumpFn)
pgdumpProcess.stdout.write('PGDMP - data - data')
pgdumpProcess.emit('close', 0)
await p

expect(pgDumpFn.calledOnce).to.be.true
const pgDumpArgs = pgDumpFn.getCall(0).args[1]

expect(
pgDumpArgs
).to.deep.equal(['-Fc', '-Z1', '--exclude-table=ignored-table', '-N', 'public'])
})

it('should call pg_dump with provided extra arguments as string', async () => {
const pgdumpProcess = mockSpawn()()
const pgDumpFn = sinon.fake.returns(pgdumpProcess)
const config = {
PGDUMP_ARGS: '--exclude-table=ignored-table -N public'
}

const p = pgdump(config, pgDumpFn)
pgdumpProcess.stdout.write('PGDMP - data - data')
pgdumpProcess.emit('close', 0)
await p

expect(pgDumpFn.calledOnce).to.be.true
const pgDumpArgs = pgDumpFn.getCall(0).args[1]

expect(
pgDumpArgs
).to.deep.equal(['-Fc', '-Z1', '--exclude-table=ignored-table', '-N', 'public'])
})

it('should stream correctly', async () => {
const mySpawn = mockSpawn()()
const pgdumpProcess = mockSpawn()()

const pgDumpFn = () => mySpawn
const pgDumpFn = () => pgdumpProcess
const config = {}
const p = pgdump(config, pgDumpFn)
mySpawn.stdout.write('PGDMP - data - data')
mySpawn.emit('close', 0)
pgdumpProcess.stdout.write('PGDMP - data - data')
pgdumpProcess.emit('close', 0)

const buffer = await p

Expand Down

0 comments on commit 2cf12ab

Please sign in to comment.