From 70ecba06ca2a5ec66ea0925e7265330507fbc9ff Mon Sep 17 00:00:00 2001 From: Daniel Lockyer Date: Tue, 18 Jan 2022 09:03:21 +0000 Subject: [PATCH] Added `@trghost/database-info` package refs https://github.com/TryGhost/Toolbox/issues/175 - this library is a small utility around `knex` that returns info on the database used - particularly, the version used - this will initially be used within Ghost but it can be extended to other databases and projects if needed --- ghost/database-info/.eslintrc.js | 6 ++ ghost/database-info/LICENSE | 21 +++++ ghost/database-info/README.md | 43 +++++++++ ghost/database-info/index.js | 1 + ghost/database-info/lib/database-info.js | 96 ++++++++++++++++++++ ghost/database-info/package.json | 28 ++++++ ghost/database-info/test/.eslintrc.js | 6 ++ ghost/database-info/test/hello.test.js | 10 ++ ghost/database-info/test/utils/assertions.js | 11 +++ ghost/database-info/test/utils/index.js | 11 +++ ghost/database-info/test/utils/overrides.js | 10 ++ 11 files changed, 243 insertions(+) create mode 100644 ghost/database-info/.eslintrc.js create mode 100644 ghost/database-info/LICENSE create mode 100644 ghost/database-info/README.md create mode 100644 ghost/database-info/index.js create mode 100644 ghost/database-info/lib/database-info.js create mode 100644 ghost/database-info/package.json create mode 100644 ghost/database-info/test/.eslintrc.js create mode 100644 ghost/database-info/test/hello.test.js create mode 100644 ghost/database-info/test/utils/assertions.js create mode 100644 ghost/database-info/test/utils/index.js create mode 100644 ghost/database-info/test/utils/overrides.js diff --git a/ghost/database-info/.eslintrc.js b/ghost/database-info/.eslintrc.js new file mode 100644 index 0000000000..c9c1bcb522 --- /dev/null +++ b/ghost/database-info/.eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: ['ghost'], + extends: [ + 'plugin:ghost/node' + ] +}; diff --git a/ghost/database-info/LICENSE b/ghost/database-info/LICENSE new file mode 100644 index 0000000000..19bcb01bef --- /dev/null +++ b/ghost/database-info/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013-2022 Ghost Foundation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ghost/database-info/README.md b/ghost/database-info/README.md new file mode 100644 index 0000000000..a24b3d7744 --- /dev/null +++ b/ghost/database-info/README.md @@ -0,0 +1,43 @@ +# Database Info + +`@tryghost/database-info` is a small utility for `knex` that returns information on the underlying DB connection. + +It currently works with SQLite, MySQL 5 & 8, and MariaDB. + +## Install + +`npm install @tryghost/database-info --save` + +or + +`yarn add @tryghost/database-info` + + +## Usage + + +## Develop + +This is a mono repository, managed with [lerna](https://lernajs.io/). + +Follow the instructions for the top-level repo. +1. `git clone` this repo & `cd` into it as usual +2. Run `yarn` to install top-level dependencies. + + +## Run + +- `yarn dev` + + +## Test + +- `yarn lint` run just eslint +- `yarn test` run lint and tests + + + + +# Copyright & License + +Copyright (c) 2013-2022 Ghost Foundation - Released under the [MIT license](LICENSE). \ No newline at end of file diff --git a/ghost/database-info/index.js b/ghost/database-info/index.js new file mode 100644 index 0000000000..8d4bceda52 --- /dev/null +++ b/ghost/database-info/index.js @@ -0,0 +1 @@ +module.exports = require('./lib/database-info'); diff --git a/ghost/database-info/lib/database-info.js b/ghost/database-info/lib/database-info.js new file mode 100644 index 0000000000..a8d3119cc6 --- /dev/null +++ b/ghost/database-info/lib/database-info.js @@ -0,0 +1,96 @@ +module.exports = class DatabaseInfo { + /** + * @param {import('knex')} knex + */ + constructor(knex) { + this.knex = knex; + this.client = this.knex.client; + this.driver = this.client.config.client; + + this.databaseDetails = { + // The underlying driver that `knex` uses + // ie. `sqlite3`, `mysql` or `mysql2` + driver: this.driver, + + // A capitalized version of the specific database used + database: 'unknown', + + // A slugified version of the `database` + engine: 'unknown', + + // The version of the database used + version: 'unknown' + }; + } + + async init() { + switch (this.driver) { + case 'sqlite3': + this.databaseDetails.database = 'SQLite'; + this.databaseDetails.engine = 'sqlite3'; + this.databaseDetails.version = this.client.driver.VERSION; + break; + case 'mysql': + case 'mysql2': + try { + const version = await this.knex.raw('SELECT version() as version;'); + const mysqlVersion = version[0][0].version; + + if (mysqlVersion.includes('MariaDB')) { + this.databaseDetails.database = 'MariaDB'; + this.databaseDetails.engine = 'mariadb'; + this.databaseDetails.version = mysqlVersion.split('-')[0]; + } else { + this.databaseDetails.database = 'MySQL'; + + if (mysqlVersion.startsWith('5')) { + this.databaseDetails.engine = 'mysql5'; + } else if (mysqlVersion.startsWith('8')) { + this.databaseDetails.engine = 'mysql8'; + } else { + this.databaseDetails.engine = 'mysql'; + } + + this.databaseDetails.version = mysqlVersion; + } + } catch (err) { + return this.databaseDetails; + } + break; + default: + // This driver isn't supported so we should just leave the return + // object alone with the "unknown" strings + break; + } + + return this.databaseDetails; + } + + getDriver() { + return this.databaseDetails.driver; + } + + getDatabase() { + return this.databaseDetails.database; + } + + getEngine() { + return this.databaseDetails.engine; + } + + getVersion() { + return this.databaseDetails.version; + } + + isSqlite() { + return this.databaseDetails.database === 'SQLite'; + } + + isMysql() { + return this.databaseDetails.database === 'MySQL'; + } + + isMariadb() { + return this.databaseDetails.database === 'MariaDB'; + } +}; diff --git a/ghost/database-info/package.json b/ghost/database-info/package.json new file mode 100644 index 0000000000..84f39e60da --- /dev/null +++ b/ghost/database-info/package.json @@ -0,0 +1,28 @@ +{ + "name": "@tryghost/database-info", + "version": "0.0.0", + "repository": "https://github.com/TryGhost/Utils/tree/main/packages/database-info", + "author": "Ghost Foundation", + "license": "MIT", + "main": "index.js", + "scripts": { + "dev": "echo \"Implement me!\"", + "test": "NODE_ENV=testing c8 --check-coverage mocha './test/**/*.test.js'", + "lint": "eslint . --ext .js --cache", + "posttest": "yarn lint" + }, + "files": [ + "index.js", + "lib" + ], + "publishConfig": { + "access": "public" + }, + "devDependencies": { + "c8": "7.11.0", + "mocha": "9.1.4", + "should": "13.2.3", + "sinon": "12.0.1" + }, + "dependencies": {} +} diff --git a/ghost/database-info/test/.eslintrc.js b/ghost/database-info/test/.eslintrc.js new file mode 100644 index 0000000000..829b601eb0 --- /dev/null +++ b/ghost/database-info/test/.eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: ['ghost'], + extends: [ + 'plugin:ghost/test' + ] +}; diff --git a/ghost/database-info/test/hello.test.js b/ghost/database-info/test/hello.test.js new file mode 100644 index 0000000000..85d69d1e08 --- /dev/null +++ b/ghost/database-info/test/hello.test.js @@ -0,0 +1,10 @@ +// Switch these lines once there are useful utils +// const testUtils = require('./utils'); +require('./utils'); + +describe('Hello world', function () { + it('Runs a test', function () { + // TODO: Write me! + 'hello'.should.eql('hello'); + }); +}); diff --git a/ghost/database-info/test/utils/assertions.js b/ghost/database-info/test/utils/assertions.js new file mode 100644 index 0000000000..7364ee8aa1 --- /dev/null +++ b/ghost/database-info/test/utils/assertions.js @@ -0,0 +1,11 @@ +/** + * Custom Should Assertions + * + * Add any custom assertions to this file. + */ + +// Example Assertion +// should.Assertion.add('ExampleAssertion', function () { +// this.params = {operator: 'to be a valid Example Assertion'}; +// this.obj.should.be.an.Object; +// }); diff --git a/ghost/database-info/test/utils/index.js b/ghost/database-info/test/utils/index.js new file mode 100644 index 0000000000..0d67d86ff8 --- /dev/null +++ b/ghost/database-info/test/utils/index.js @@ -0,0 +1,11 @@ +/** + * Test Utilities + * + * Shared utils for writing tests + */ + +// Require overrides - these add globals for tests +require('./overrides'); + +// Require assertions - adds custom should assertions +require('./assertions'); diff --git a/ghost/database-info/test/utils/overrides.js b/ghost/database-info/test/utils/overrides.js new file mode 100644 index 0000000000..90203424ee --- /dev/null +++ b/ghost/database-info/test/utils/overrides.js @@ -0,0 +1,10 @@ +// This file is required before any test is run + +// Taken from the should wiki, this is how to make should global +// Should is a global in our eslint test config +global.should = require('should').noConflict(); +should.extend(); + +// Sinon is a simple case +// Sinon is a global in our eslint test config +global.sinon = require('sinon');