Skip to content

Commit 595d3e8

Browse files
add option xEnabled to set plugin activiation state for X
1 parent ecdbc75 commit 595d3e8

File tree

3 files changed

+44
-31
lines changed

3 files changed

+44
-31
lines changed

src/constants.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ export const DEFAULT_OPTIONS: InternalServerOptions = {
1717
xPort: 0,
1818
downloadRetries: 10,
1919
initSQLString: '',
20-
arch: process.arch
20+
arch: process.arch,
21+
xEnabled: 'FORCE'
2122
} as const;
2223

2324
export const DEFAULT_OPTIONS_KEYS = Object.freeze(Object.keys(DEFAULT_OPTIONS))
@@ -41,6 +42,7 @@ export function getInternalEnvVariable(envVar: keyof typeof internalOptions): st
4142
}
4243

4344
const allowedArches = ['x64', 'arm64']
45+
const pluginActivationStates = ['OFF', 'ON', 'FORCE', 'FORCE_PLUS_PERMANENT']
4446
export const OPTION_TYPE_CHECKS: OptionTypeChecks = {
4547
version: {
4648
check: (opt: any) => opt === undefined || typeof opt === 'string' && validSemver(coerceSemver(opt)) !== null,
@@ -111,6 +113,11 @@ export const OPTION_TYPE_CHECKS: OptionTypeChecks = {
111113
check: (opt: any) => opt === undefined || allowedArches.includes(opt),
112114
errorMessage: `Option arch must be either of the following: ${allowedArches.join(', ')}`,
113115
definedType: 'string'
116+
},
117+
xEnabled: {
118+
check: (opt: any) => opt === undefined || pluginActivationStates.includes(opt),
119+
errorMessage: `xEnabled must be either undefined or one of the following: ${pluginActivationStates.join(', ')}`,
120+
definedType: 'boolean'
114121
}
115122
} as const;
116123

src/libraries/Executor.ts

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,14 @@ class Executor {
6363
return null
6464
}
6565

66-
#startMySQLProcess(options: InternalServerOptions, port: number, mySQLXPort: number, datadir: string, dbPath: string, binaryFilepath: string): Promise<MySQLDB> {
66+
#startMySQLProcess(options: InternalServerOptions, datadir: string, dbPath: string, binaryFilepath: string): Promise<MySQLDB> {
6767
const errors: string[] = []
6868
const logFile = `${dbPath}/log.log`
6969
const errorLogFile = `${datadir}/errorlog.err`
7070

71+
const port = options.port || GenerateRandomPort()
72+
const mySQLXPort = options.xPort || GenerateRandomPort();
73+
7174
return new Promise(async (resolve, reject) => {
7275
await fsPromises.rm(logFile, {force: true})
7376

@@ -76,11 +79,8 @@ class Executor {
7679

7780
const mysqlArguments = [
7881
'--no-defaults',
79-
'--mysqlx=FORCE',
8082
`--port=${port}`,
8183
`--datadir=${datadir}`,
82-
`--mysqlx-port=${mySQLXPort}`,
83-
`--mysqlx-socket=${xSocket}`,
8484
`--socket=${socket}`,
8585
`--general-log-file=${logFile}`,
8686
'--general-log=1',
@@ -91,23 +91,29 @@ class Executor {
9191
`--user=${os.userInfo().username}`
9292
]
9393

94-
//<8.0.11 does not have MySQL X turned on by default so we will be installing the X Plugin in this if statement.
95-
//MySQL 5.7.12 introduced the X plugin, but according to https://dev.mysql.com/doc/refman/5.7/en/document-store-setting-up.html, the database needs to be initialised with version 5.7.19.
96-
//If the MySQL version is >=5.7.19 & <8.0.11 then install the X Plugin
97-
if (lt(this.version, '8.0.11') && gte(this.version, '5.7.19')) {
98-
const pluginExtension = os.platform() === 'win32' ? 'dll' : 'so';
99-
let pluginPath: string;
100-
const firstPath = resolvePath(`${binaryFilepath}/../../lib/plugin`)
101-
const secondPath = '/usr/lib/mysql/plugin'
102-
103-
if (fs.existsSync(`${firstPath}/mysqlx.${pluginExtension}`)) {
104-
pluginPath = firstPath
105-
} else if (os.platform() === 'linux' && fs.existsSync(`${secondPath}/mysqlx.so`)) {
106-
pluginPath = secondPath
107-
} else {
108-
throw 'Could not install MySQL X as the path to the plugin cannot be found.'
94+
if (options.xEnabled !== 'OFF') {
95+
mysqlArguments.push(`--mysqlx=${options.xEnabled}`)
96+
mysqlArguments.push(`--mysqlx-port=${mySQLXPort}`)
97+
mysqlArguments.push(`--mysqlx-socket=${xSocket}`)
98+
99+
//<8.0.11 does not have MySQL X turned on by default so we will be installing the X Plugin in this if statement.
100+
//MySQL 5.7.12 introduced the X plugin, but according to https://dev.mysql.com/doc/refman/5.7/en/document-store-setting-up.html, the database needs to be initialised with version 5.7.19.
101+
//If the MySQL version is >=5.7.19 & <8.0.11 then install the X Plugin
102+
if (lt(this.version, '8.0.11') && gte(this.version, '5.7.19')) {
103+
const pluginExtension = os.platform() === 'win32' ? 'dll' : 'so';
104+
let pluginPath: string;
105+
const firstPath = resolvePath(`${binaryFilepath}/../../lib/plugin`)
106+
const secondPath = '/usr/lib/mysql/plugin'
107+
108+
if (fs.existsSync(`${firstPath}/mysqlx.${pluginExtension}`)) {
109+
pluginPath = firstPath
110+
} else if (os.platform() === 'linux' && fs.existsSync(`${secondPath}/mysqlx.so`)) {
111+
pluginPath = secondPath
112+
} else {
113+
throw 'Could not install MySQL X as the path to the plugin cannot be found.'
114+
}
115+
mysqlArguments.splice(1, 0, `--plugin-dir=${pluginPath}`, `--early-plugin-load=mysqlx=mysqlx.${pluginExtension};`)
109116
}
110-
mysqlArguments.splice(1, 0, `--plugin-dir=${pluginPath}`, `--early-plugin-load=mysqlx=mysqlx.${pluginExtension};`)
111117
}
112118

113119
const process = spawn(binaryFilepath, mysqlArguments, {signal: this.DBDestroySignal.signal, killSignal: 'SIGKILL'})
@@ -504,13 +510,9 @@ class Executor {
504510
await this.#setupDataDirectories(options, installedMySQLBinary, datadir, true);
505511
this.logger.log('Setting up directories was successful')
506512

507-
const port = options.port || GenerateRandomPort()
508-
const mySQLXPort = options.xPort || GenerateRandomPort();
509-
this.logger.log('Using port:', port, 'and MySQLX port:', mySQLXPort, 'on retry:', retries)
510-
511513
try {
512514
this.logger.log('Starting MySQL process')
513-
const resolved = await this.#startMySQLProcess(options, port, mySQLXPort, datadir, this.databasePath, installedMySQLBinary.path)
515+
const resolved = await this.#startMySQLProcess(options, datadir, this.databasePath, installedMySQLBinary.path)
514516
this.logger.log('Starting process was successful')
515517
return resolved
516518
} catch (e) {
@@ -521,7 +523,7 @@ class Executor {
521523
}
522524
retries++
523525
if (retries <= options.portRetries) {
524-
this.logger.warn(`One or both of these ports are already in use: ${port} or ${mySQLXPort}. Now retrying... ${retries}/${options.portRetries} possible retries.`)
526+
this.logger.warn(`Tried a port that is already in use. Now retrying... ${retries}/${options.portRetries} possible retries.`)
525527
} else {
526528
throw `The port has been retried ${options.portRetries} times and a free port could not be found.\nEither try again, or if this is a common issue, increase options.portRetries.`
527529
}

types/index.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { ExecFileException } from "child_process"
22

33
export type LOG_LEVEL = 'LOG' | 'WARN' | 'ERROR'
44

5+
export type PluginActivationState = 'OFF' | 'ON' | 'FORCE' | 'FORCE_PLUS_PERMANENT'
6+
57
export type ServerOptions = {
68
version?: string | undefined,
79
dbName?: string | undefined,
@@ -16,7 +18,8 @@ export type ServerOptions = {
1618
xPort?: number | undefined,
1719
downloadRetries?: number | undefined,
1820
initSQLString?: string | undefined,
19-
arch?: "arm64" | "x64" | undefined
21+
arch?: "arm64" | "x64" | undefined,
22+
xEnabled?: PluginActivationState | undefined
2023
}
2124

2225
export type InternalServerOptions = {
@@ -33,7 +36,8 @@ export type InternalServerOptions = {
3336
xPort: number,
3437
downloadRetries: number,
3538
initSQLString: string,
36-
arch: string
39+
arch: string,
40+
xEnabled: PluginActivationState
3741
}
3842

3943
export type ExecuteFileReturn = {
@@ -44,9 +48,9 @@ export type ExecuteFileReturn = {
4448

4549
export type MySQLDB = {
4650
port: number,
47-
xPort: number,
51+
xPort: number | undefined,
4852
socket: string,
49-
xSocket: string,
53+
xSocket: string | undefined,
5054
dbName: string,
5155
username: string,
5256
mysql: {

0 commit comments

Comments
 (0)