feat(cli): check database version before installation (#572)

* feat(cli): check database version before installation

* fix: log

* fix: fix bugs

* fix: postgres

* fix: run beforeInstall
This commit is contained in:
chenos 2022-07-04 13:41:07 +08:00 committed by GitHub
parent 4e9384bce2
commit ec7bc2bc8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 66 additions and 4 deletions

View File

@ -76,7 +76,7 @@ yarn dev
Production
```bash
yarn start
yarn start # Does not support running on win platform
```
Note: For production, if the code has been modified, you need to execute `yarn build` and restart NocoBase.

View File

@ -56,7 +56,7 @@ Production
# Compile
yarn build
# Start
yarn start
yarn start # Does not support running on win platform
```
## 7. Log in to NocoBase

View File

@ -83,7 +83,7 @@ yarn dev
生产环境
```bash
yarn start
yarn start # 暂不支持在 win 平台下运行
```
注:生产环境,如果代码有修改,需要执行 `yarn build`,再重新启动 NocoBase。

View File

@ -58,7 +58,7 @@ yarn dev
# 编译
yarn build
# 启动
yarn start
yarn start # 暂不支持在 win 平台下运行
```
## 7. 登录 NocoBase

View File

@ -19,6 +19,12 @@ module.exports = (cli) => {
if (opts.port) {
process.env.APP_PORT = opts.port;
}
if (process.platform === 'win32') {
console.log(
chalk.yellow(`It is not supported on win platform, please use \`${chalk.green('yarn dev')}\` instead`),
);
return;
}
if (process.argv.includes('-h') || process.argv.includes('--help')) {
promptForTs();
run('ts-node', [

View File

@ -18,6 +18,7 @@
"flat": "^5.0.2",
"glob": "^7.1.6",
"mathjs": "^10.6.1",
"semver": "^7.3.7",
"sequelize": "^6.9.0",
"umzug": "^3.1.1"
},

View File

@ -4,6 +4,7 @@ import { EventEmitter } from 'events';
import glob from 'glob';
import lodash from 'lodash';
import { basename, isAbsolute, resolve } from 'path';
import semver from 'semver';
import {
ModelCtor,
Op,
@ -65,6 +66,46 @@ export type AddMigrationsOptions = {
type OperatorFunc = (value: any, ctx?: RegisterOperatorsContext) => any;
class DatabaseVersion {
db: Database;
constructor(db: Database) {
this.db = db;
}
async satisfies(versions) {
const dialects = {
sqlite: {
sql: 'select sqlite_version() as version',
get: (v) => v,
},
mysql: {
sql: 'select version() as version',
get: (v) => v,
},
postgres: {
sql: 'select version() as version',
get: (v) => {
const keys = v.split(' ');
keys.shift();
return semver.minVersion(keys.shift()).version;
},
},
};
for (const dialect of Object.keys(dialects)) {
if (this.db.inDialect(dialect)) {
if (!versions?.[dialect]) {
return false;
}
const [result] = (await this.db.sequelize.query(dialects[dialect].sql)) as any;
console.log(`db version: ${dialects[dialect].get(result?.[0]?.version)}`);
return semver.satisfies(dialects[dialect].get(result?.[0]?.version), versions[dialect]);
}
}
return false;
}
}
export class Database extends EventEmitter implements AsyncEmitter {
sequelize: Sequelize;
migrator: Umzug;
@ -79,12 +120,15 @@ export class Database extends EventEmitter implements AsyncEmitter {
modelCollection = new Map<ModelCtor<any>, Collection>();
modelHook: ModelHook;
version: DatabaseVersion;
delayCollectionExtend = new Map<string, { collectionOptions: CollectionOptions; mergeOptions?: any }[]>();
constructor(options: DatabaseOptions) {
super();
this.version = new DatabaseVersion(this);
const opts = {
sync: {
alter: {

View File

@ -323,6 +323,17 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
async install(options: InstallOptions = {}) {
await this.emitAsync('beforeInstall', this, options);
const r = await this.db.version.satisfies({
mysql: '8.x',
sqlite: '3.x',
postgres: '>=10',
});
if (!r) {
console.log('The database only supports MySQL 8.x, SQLite 3.x and PostgreSQL 10+');
return;
}
if (options?.clean) {
await this.db.clean(isBoolean(options.clean) ? { drop: options.clean } : options.clean);
}