Skip to content
This repository has been archived by the owner on Jul 14, 2021. It is now read-only.

Commit

Permalink
feat: support compressFile option (#69)
Browse files Browse the repository at this point in the history
* allows to `gzip` compress the output file
* since the internal architecture does not allow to pass the output directly through an compressing output stream:
  * the result is written in an uncompressed manner as before,
  * the file is renamed by appending `.temp` to it,
  * and then stream processed with a pipeline of `read stream` -> `gzip stream` -> `write stream` into the final output file

implements issue #13 with a streaming approach not risking to blow up the memory
  • Loading branch information
Kosta-Github authored and bradzacher committed Jul 19, 2019
1 parent d0bdd6a commit 06b7cb8
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 5 deletions.
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ mysqldump({
dumpToFile: './dump.sql',
});

// dump the result straight to a compressed file
mysqldump({
connection: {
host: 'localhost',
user: 'root',
password: '123456',
database: 'my_database',
},
dumpToFile: './dump.sql.gz',
compressFile: true,
});

// return the dump from the function and not to a file
const result = await mysqldump({
connection: {
Expand Down Expand Up @@ -276,6 +288,11 @@ export interface Options {
* Exclude to just return the string.
*/
dumpToFile?: string;
/**
* Should the output file be compressed (gzip)?
* Defaults to false.
*/
compressFile?: boolean;
}
export interface ColumnList {
/**
Expand Down Expand Up @@ -358,11 +375,11 @@ The MIT [License](./LICENSE.md)

## Contributing

### Installation
### Local Installation

Make sure to first install all the required development dependencies:

```
```shell
yarn
// or
npm install .
Expand Down
46 changes: 46 additions & 0 deletions src/compressFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as fs from 'fs';
import * as zlib from 'zlib';

function compressFile(filename: string): Promise<void> {
const tempFilename = `${filename}.temp`;

fs.renameSync(filename, tempFilename);

const deleteFile = (file: string): void => {
try {
fs.unlinkSync(file);
} catch (_err) {
/* istanbul ignore next */
}
};

try {
const read = fs.createReadStream(tempFilename);
const zip = zlib.createGzip();
const write = fs.createWriteStream(filename);
read.pipe(zip).pipe(write);

return new Promise((resolve, reject) => {
write.on(
'error',
/* istanbul ignore next */ err => {
// close the write stream and propagate the error
write.end();
reject(err);
},
);
write.on('finish', () => {
resolve();
});
});
} catch (err) /* istanbul ignore next */ {
// in case of an error: remove the output file and propagate the error
deleteFile(filename);
throw err;
} finally {
// in any case: remove the temp file
deleteFile(tempFilename);
}
}

export { compressFile };
6 changes: 6 additions & 0 deletions src/interfaces/Options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,11 @@ interface Options {
* Exclude to just return the string.
*/
dumpToFile?: string | null;
/**
* Should the output file be compressed (gzip)?
* Defaults to false.
*/
compressFile?: boolean;
}

// Recursively requires all properties on an object
Expand All @@ -267,6 +272,7 @@ interface CompletedOptions {
connection: Required<ConnectionOptions>;
dump: RequiredRecursive<DumpOptions>;
dumpToFile: string | null;
compressFile: boolean | null;
}

export {
Expand Down
6 changes: 6 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { getTables } from './getTables';
import { getSchemaDump } from './getSchemaDump';
import { getTriggerDump } from './getTriggerDump';
import { getDataDump } from './getDataDump';
import { compressFile } from './compressFile';
import { DB } from './DB';
import { ERRORS } from './Errors';
import { HEADER_VARIABLES, FOOTER_VARIABLES } from './sessionVariables';
Expand Down Expand Up @@ -201,6 +202,11 @@ export default async function main(inputOptions: Options): Promise<DumpReturn> {
fs.appendFileSync(options.dumpToFile, FOOTER_VARIABLES);
}

// compress output file
if (options.dumpToFile && options.compressFile) {
await compressFile(options.dumpToFile);
}

return res;
} finally {
DB.cleanup();
Expand Down
8 changes: 6 additions & 2 deletions test/e2e/fileDump.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ describe('mysqldump.e2e', () => {
describe('dump to file', () => {
it('should dump a file if configured', dumpTest({}));
it(
'should not dump schema to a file if configured',
'should not dump data to a file if configured',
dumpTest({
data: false,
}),
);
it(
'should not dump data to a file if configured',
'should not dump schema to a file if configured',
dumpTest({
schema: false,
}),
Expand All @@ -22,5 +22,9 @@ describe('mysqldump.e2e', () => {
trigger: false,
}),
);
it(
'should dump a file in compressed format if configured',
dumpTest({}, undefined, /* compressFile */ true),
);
});
});
12 changes: 11 additions & 1 deletion test/e2e/lib.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as fs from 'fs';
import * as tmp from 'tmp';
import * as zlib from 'zlib';

import { DumpOptions, SchemaDumpOptions } from '../../src/interfaces/Options';
import { config } from '../testConfig';
Expand Down Expand Up @@ -72,6 +73,7 @@ function dumpFlagTest<T>(
function dumpTest(
opts: DumpOptions,
extraAssertion?: (file: string) => void,
compressFile?: boolean,
): () => void {
return async () => {
// ASSEMBLE
Expand All @@ -90,9 +92,17 @@ function dumpTest(
const res = await mysqldump({
connection: config,
dumpToFile: filename,
compressFile,
dump: opts,
});
const file = fs.readFileSync(filename, 'utf8');

let file: string;
if (compressFile) {
const f = fs.readFileSync(filename);
file = zlib.gunzipSync(f).toString('utf8');
} else {
file = fs.readFileSync(filename, 'utf8');
}

// remove the file
fs.unlinkSync(filename);
Expand Down

0 comments on commit 06b7cb8

Please sign in to comment.