Skip to content

Commit 744f649

Browse files
Merge pull request #55 from Sebastian-Webster/add-informative-mysql-out-of-date-error
Add informative MySQL out of date error
2 parents 7e1c7a0 + 8f69c62 commit 744f649

File tree

7 files changed

+49
-9
lines changed

7 files changed

+49
-9
lines changed

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,13 @@ Default: undefined
7676

7777
Description: Version of MySQL to use for the database. Uses semver for getting the version, so valid semver versions are allowed. For example, `8.x` is a valid version and will use the latest 8.x MySQL version.
7878

79-
If left undefined and the system has MySQL already installed, the system installed version of MySQL will be used. If left undefined and the system does not have MySQL installed, the latest version of MySQL in the `versions.json` file in this package will be downloaded. If defined and the system has that version of MySQL installed, the system installed version will be used. If defined and the system does not have that version of MySQL installed, that version will be downloaded as long as it is found in the `versions.json` file in this package.
79+
If left undefined:
80+
- If the system has MySQL installed, the system-installed version will be used. If the installed version is not supported by this package (currently <8.0.20), an error will be thrown unless `ignoreUnsupportedSystemVersion` is set to `true`.
81+
- If the system does not have MySQL installed, the latest version of MySQL in the `versions.json` file in this package will be downloaded.
82+
83+
If defined:
84+
- If the version is 8.0.19 or older, an error will be thrown as this package does not currently support those versions of MySQL.
85+
- If MySQL is installed on the system, the installed version will be used. Otherwise the selected version will be downloaded from the MySQL CDN as long as it can be found in the `versions.json` file. If it cannot be found in that file, an error will be thrown.
8086

8187
- `dbName: string`
8288

@@ -136,6 +142,14 @@ Default: root
136142

137143
Description: The username of the user that is used to login to the database.
138144

145+
- `ignoreUnsupportedSystemVersion: boolean`
146+
147+
Required: No
148+
149+
Default: false
150+
151+
Description: This option only applies if the system-installed MySQL version is lower than the oldest supported MySQL version for this package (8.0.20). If set to `true`, this package will use the latest version of MySQL instead of the system-installed version. If `false`, the package will throw an error.
152+
139153
- `deleteDBAfterStopped: boolean`
140154

141155
Required: No

src/constants.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const CONSTANTS = {
2+
MIN_SUPPORTED_MYSQL: '8.0.20'
3+
}
4+
5+
export default CONSTANTS

src/index.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import Logger from './libraries/Logger'
22
import * as os from 'node:os'
33
import Executor from "./libraries/Executor"
4-
import { satisfies } from "semver"
4+
import { satisfies, lt } from "semver"
55
import DBDestroySignal from "./libraries/AbortSignal"
66
import { BinaryInfo, InternalServerOptions, ServerOptions } from '../types'
77
import getBinaryURL from './libraries/Version'
88
import MySQLVersions from './versions.json'
99
import { downloadBinary } from './libraries/Downloader'
1010
import { randomUUID } from "crypto";
1111
import {normalize as normalizePath} from 'path'
12+
import CONSTANTS from './constants'
1213

1314
process.on('exit', () => {
1415
DBDestroySignal.abort('Process is exiting')
@@ -25,7 +26,8 @@ export async function createDB(opts?: ServerOptions) {
2526
username: 'root',
2627
deleteDBAfterStopped: true,
2728
//mysqlmsn = MySQL Memory Server Node.js
28-
dbPath: normalizePath(`${os.tmpdir()}/mysqlmsn/dbs/${randomUUID().replace(/-/g, '')}`)
29+
dbPath: normalizePath(`${os.tmpdir()}/mysqlmsn/dbs/${randomUUID().replace(/-/g, '')}`),
30+
ignoreUnsupportedSystemVersion: false
2931
}
3032

3133
const options: InternalServerOptions = {...defaultOptions, ...opts}
@@ -35,8 +37,23 @@ export async function createDB(opts?: ServerOptions) {
3537
const executor = new Executor(logger)
3638

3739
const version = await executor.getMySQLVersion(options.version)
40+
41+
const unsupportedMySQLIsInstalled = version && lt(version.version, CONSTANTS.MIN_SUPPORTED_MYSQL)
42+
43+
const throwUnsupportedError = unsupportedMySQLIsInstalled && !options.ignoreUnsupportedSystemVersion && !options.version
44+
45+
if (throwUnsupportedError) {
46+
throw `A version of MySQL is installed on your system that is not supported by this package. If you want to download a MySQL binary instead of getting this error, please set the option "ignoreUnsupportedSystemVersion" to true.`
47+
}
48+
49+
if (options.version && lt(options.version, CONSTANTS.MIN_SUPPORTED_MYSQL)) {
50+
//The difference between the throw here and the throw above is this throw is because the selected "version" is not supported.
51+
//The throw above is because the system-installed MySQL is out of date and "ignoreUnsupportedSystemVersion" is not set to true.
52+
throw `The selected version of MySQL (${options.version}) is not currently supported by this package. Please choose a different version to use.`
53+
}
54+
3855
logger.log('Version currently installed:', version)
39-
if (version === null || (options.version && !satisfies(version.version, options.version))) {
56+
if (version === null || (options.version && !satisfies(version.version, options.version)) || unsupportedMySQLIsInstalled) {
4057
let binaryInfo: BinaryInfo;
4158
let binaryFilepath: string;
4259
try {

stress-tests/stress.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ for (let i = 0; i < 100; i++) {
1515
const options: ServerOptions = {
1616
username: 'dbuser',
1717
logLevel: 'LOG',
18-
deleteDBAfterStopped: !process.env.useCIDBPath
18+
deleteDBAfterStopped: !process.env.useCIDBPath,
19+
ignoreUnsupportedSystemVersion: true
1920
}
2021

2122
if (process.env.useCIDBPath) {

tests/sql.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ beforeEach(async () => {
1515
const options: ServerOptions = {
1616
username: 'root',
1717
logLevel: 'LOG',
18-
deleteDBAfterStopped: !process.env.useCIDBPath
18+
deleteDBAfterStopped: !process.env.useCIDBPath,
19+
ignoreUnsupportedSystemVersion: true
1920
}
2021

2122
if (process.env.useCIDBPath) {

tests/versions.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jest.setTimeout(500_000);
1414
for (const version of versions) {
1515
test(`running on version ${version}`, async () => {
1616
Error.stackTraceLimit = Infinity
17-
const options: ServerOptions = {version, dbName: 'testingdata', username: 'root', logLevel: 'LOG', deleteDBAfterStopped: !process.env.useCIDBPath}
17+
const options: ServerOptions = {version, dbName: 'testingdata', username: 'root', logLevel: 'LOG', deleteDBAfterStopped: !process.env.useCIDBPath, ignoreUnsupportedSystemVersion: true}
1818

1919
if (process.env.useCIDBPath) {
2020
options.dbPath = `${dbPathPrefix}/${randomUUID()}`

types/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ export type ServerOptions = {
1212
lockRetryWait?: number,
1313
username?: string,
1414
deleteDBAfterStopped?: boolean,
15-
dbPath?: string
15+
dbPath?: string,
16+
ignoreUnsupportedSystemVersion?: boolean
1617
}
1718

1819
export type InternalServerOptions = {
@@ -25,7 +26,8 @@ export type InternalServerOptions = {
2526
lockRetryWait: number,
2627
username: string,
2728
deleteDBAfterStopped: boolean,
28-
dbPath: string
29+
dbPath: string,
30+
ignoreUnsupportedSystemVersion: boolean
2931
}
3032

3133
export type ExecutorOptions = {

0 commit comments

Comments
 (0)