Skip to content

Commit 43cf40e

Browse files
add initSQLFilePath option functionality
1 parent 929437e commit 43cf40e

File tree

4 files changed

+47
-6
lines changed

4 files changed

+47
-6
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ Description: A string with SQL queries to run before the database starts to acce
186186

187187
Default: ""
188188

189-
Description: A path to a .sql file with SQL queries to run before the database starts to accept connections. This option can be used for things like importing an exported MySQL database. Check the [Init SQL file order of operations](#init-sql-file-order-of-operations) to learn more about what SQL queries are ran and in what order before the database starts accepting connections. If a filepath is defined and reading the file fails (like if the path does not exist), then the database creation will fail.
189+
Description: A path to a UTF-8 .sql file with SQL queries to run before the database starts to accept connections. This option can be used for things like importing an exported MySQL database. Check the [Init SQL file order of operations](#init-sql-file-order-of-operations) to learn more about what SQL queries are ran and in what order before the database starts accepting connections. If a filepath is defined and reading the file fails (like if the path does not exist), then the database creation will fail.
190190

191191
- `arch: "arm64" | "x64"`
192192

src/constants.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { InternalServerOptions, OptionTypeChecks } from "../types";
22
import {normalize as normalizePath} from 'path'
33
import { tmpdir } from "os";
44
import { valid as validSemver, coerce as coerceSemver } from "semver";
5+
import { existsSync } from "fs";
56

67
export const DEFAULT_OPTIONS: InternalServerOptions = {
78
version: undefined,
@@ -18,7 +19,8 @@ export const DEFAULT_OPTIONS: InternalServerOptions = {
1819
downloadRetries: 10,
1920
initSQLString: '',
2021
arch: process.arch,
21-
xEnabled: 'FORCE'
22+
xEnabled: 'FORCE',
23+
initSQLFilePath: ''
2224
} as const;
2325

2426
export const DEFAULT_OPTIONS_KEYS = Object.freeze(Object.keys(DEFAULT_OPTIONS))
@@ -115,7 +117,12 @@ export const OPTION_TYPE_CHECKS: OptionTypeChecks = {
115117
check: (opt: any) => opt === undefined || pluginActivationStates.includes(opt),
116118
errorMessage: `xEnabled must be either undefined or one of the following: ${pluginActivationStates.join(', ')}`,
117119
definedType: 'boolean'
118-
}
120+
},
121+
initSQLFilePath: {
122+
check: (opt: any) => opt === undefined || (typeof opt === 'string' && existsSync(opt)),
123+
errorMessage: 'Option initSQLFilePath must be either undefined or a filepath string that points to a file that exists.',
124+
definedType: 'string'
125+
},
119126
} as const;
120127

121128
export const MIN_SUPPORTED_MYSQL = '5.7.19';

src/libraries/Executor.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,29 @@ class Executor {
358358
})
359359
}
360360

361+
#streamAppendToFile(readPath: string, writePath: string): Promise<void> {
362+
return new Promise((resolve, reject) => {
363+
const rs = fs.createReadStream(readPath, {encoding: 'utf-8'})
364+
const ws = fs.createWriteStream(writePath, {flags: 'a', encoding: 'utf-8'})
365+
366+
rs.on('error', (e) => {
367+
ws.end();
368+
this.logger.error('Received error from streamAppendToFile read stream:', e)
369+
reject(e)
370+
})
371+
372+
ws.on('error', (e) => {
373+
rs.close();
374+
this.logger.error('Received error from streamAppendToFile write stream:', e)
375+
reject(e)
376+
})
377+
378+
rs.pipe(ws)
379+
380+
ws.on('finish', () => resolve)
381+
})
382+
}
383+
361384
async #setupDataDirectories(options: InternalServerOptions, binary: DownloadedMySQLVersion, datadir: string, retry: boolean): Promise<void> {
362385
const binaryFilepath = binary.path
363386
this.logger.log('Created data directory for database at:', datadir)
@@ -499,9 +522,18 @@ class Executor {
499522

500523
this.logger.log('Writing init file')
501524

502-
await fsPromises.writeFile(`${this.databasePath}/init.sql`, initText, {encoding: 'utf8'})
525+
const initFilePath = `${this.databasePath}/init.sql`
526+
await fsPromises.writeFile(initFilePath, initText, {encoding: 'utf8'})
503527

504528
this.logger.log('Finished writing init file')
529+
530+
if (options.initSQLFilePath) {
531+
this.logger.log('Appending init.sql file with the contents of the file at path provided by options.initSQLFilePath.')
532+
533+
await this.#streamAppendToFile(options.initSQLFilePath, initFilePath)
534+
535+
this.logger.log('Successfully appended init.sql file with the contents of the file at path provided by options.initSQLFilePath.')
536+
}
505537
}
506538

507539
async startMySQL(options: InternalServerOptions, installedMySQLBinary: DownloadedMySQLVersion): Promise<MySQLDB> {

types/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ export type ServerOptions = {
1919
downloadRetries?: number | undefined,
2020
initSQLString?: string | undefined,
2121
arch?: "arm64" | "x64" | undefined,
22-
xEnabled?: PluginActivationState | undefined
22+
xEnabled?: PluginActivationState | undefined,
23+
initSQLFilePath?: string | undefined
2324
}
2425

2526
export type InternalServerOptions = {
@@ -37,7 +38,8 @@ export type InternalServerOptions = {
3738
downloadRetries: number,
3839
initSQLString: string,
3940
arch: string,
40-
xEnabled: PluginActivationState
41+
xEnabled: PluginActivationState,
42+
initSQLFilePath: string
4143
}
4244

4345
export type ExecuteFileReturn = {

0 commit comments

Comments
 (0)