mysql-migration 1.0.5 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2023-present 𝐒𝐡𝐞𝐫𝐊𝐚𝐧
2
+
3
+ This software is protected by copyright and is provided under this license.
4
+
5
+ You are allowed to use this software only for non-commercial purposes and only in the form in which it is distributed by the author. You are not allowed to modify the source code, redistribute this software in any form, or use it for commercial purposes.
6
+
7
+ This software is provided "as is," without any warranty of any kind. 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 use or distribution of this software.
package/README.md CHANGED
@@ -4,44 +4,59 @@ A simple command-line tool for generating and running database migrations for My
4
4
 
5
5
  ## Installation
6
6
 
7
- You can install `mysql-migration` using npm:
8
- npm install -g mysql-migration
7
+ You can install `mysql-migration` using npm: `npm install mysql-migration`
9
8
 
9
+ ### Initialize the migrations table
10
10
 
11
- ## Usage
12
-
13
- ### Create a new migration
11
+ If you have not yet run any migrations, you need to initialize the migrations table by running the following command: `npx mysql-migration init`
14
12
 
15
- To create a new migration, run the following command:
16
- npx mysql-migration migration-name database-name
13
+ <br>
17
14
 
18
- This will create a new migration file in the `migrations` directory with a timestamp and the name `migration-name`.
15
+ ## Configuration
19
16
 
17
+ The configuration file `mysql-migration.config.json` should export an object with the following properties:
20
18
 
21
- ### Running migrations
19
+ - `host`: the MySQL server host
20
+ - `database`: the name of the database to migrate
21
+ - `user`: the MySQL user name
22
+ - `password`: the MySQL user password
22
23
 
23
- To run pending migrations, run the following command:
24
- npx mysql-migration run database-name (optional)
24
+ ```json
25
+ {
26
+ "databases": {
27
+ "db_name": {
28
+ "host": "db_host",
29
+ "user": "db_user",
30
+ "password": "db_password",
31
+ "database": "db_name"
32
+ }
33
+ }
34
+ }
35
+ ```
36
+
37
+ <br>
25
38
 
39
+ ## Usage
26
40
 
27
- This will run all migrations that have not yet been run.
41
+ ### Create a new migration
28
42
 
29
- ### Initialize the migrations table
43
+ To create a new migration, run the following command:\
44
+ &emsp;`npx mysql-migration create migration-name database-name`
30
45
 
31
- If you have not yet run any migrations, you need to initialize the migrations table by running the following command:
32
- npx mysql-migration init
46
+ This will create a new migration file in the `migrations` directory with a timestamp and the name `migration-name`.
33
47
 
48
+ ### Running migrations
34
49
 
35
- ### Configuration
50
+ To run pending migrations, run the following command:\
51
+ &emsp;`npx mysql-migration run database-name(optional)`
36
52
 
37
- The configuration file should export an object with the following properties:
53
+ This will run all migrations that have not yet been run.
38
54
 
39
- - `host`: the MySQL server host
40
- - `database`: the name of the database to migrate
41
- - `user`: the MySQL user name
42
- - `password`: the MySQL user password
55
+ ### Rolling back migrations
43
56
 
57
+ To roll back the last migration, run the following command:\
58
+ &emsp;`npx mysql-migration rollback database-name batch`
44
59
 
45
- ### License
60
+ This will roll back migrations to the given batch number.
46
61
 
47
- This package is licensed under the MIT License.
62
+ > **Copyright (c) 2023-present [𝐒𝐡𝐞𝐫𝐊𝐚𝐧](https://github.com/SherKan-n). All Rights Reserved.**
package/index.js CHANGED
@@ -1,10 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  const program = require('commander');
3
3
  //---------------------------------------
4
- program
5
- .version('1.0.0')
6
- .description('Migration for mysql database');
7
- //---------------------------------------
8
4
  program
9
5
  .command('init')
10
6
  .description('Initialize migration')
@@ -15,6 +11,11 @@ program
15
11
  .description('Run migration')
16
12
  .action((dbName) => require('./src/commands/run')(dbName));
17
13
  //---------------------------------------
14
+ program
15
+ .command('rollback <dbName> <batch>')
16
+ .description('Rollback migration')
17
+ .action((dbName, batch) => require('./src/commands/back')(dbName, batch));
18
+ //---------------------------------------
18
19
  program
19
20
  .command('create <migrationName> <dbName>')
20
21
  .description('Create a new migration')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mysql-migration",
3
- "version": "1.0.5",
3
+ "version": "1.1.1",
4
4
  "description": "Migration for mysql database",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -21,5 +21,5 @@
21
21
  "commander": "^2.20.0"
22
22
  },
23
23
  "author": "SherKan",
24
- "license": "MIT"
24
+ "license": "SEE LICENSE IN LICENSE.md"
25
25
  }
@@ -0,0 +1,65 @@
1
+ 'use strict';
2
+ //==============================================================================
3
+ const fs = require('fs');
4
+ const mysql = require('mysql');
5
+ //---------------------------------------
6
+ const currentPath = process.cwd();
7
+ const config = require(`${currentPath}/migrations/mysql-migration.config.json`);
8
+ const { checkTableMigrations, createTableMigrations, getAllMigrations, getCurrentBatch, deleteMigration } = require("../utils/functions");
9
+ //==============================================================================
10
+ async function back_migration(dbName, batch) {
11
+ const connection = {};
12
+ const databases = config.databases;
13
+ //---------------------------------------
14
+ if (dbName) {
15
+ const batchNumber = parseInt(batch);
16
+ if (isNaN(batchNumber)) {
17
+ console.error('\x1b[31m%s\x1b[0m', `Error: Invalid batch number.`);
18
+ process.exit(1);
19
+ }
20
+ //---------------------------------------
21
+ if (!databases[dbName]) {
22
+ console.error('\x1b[31m%s\x1b[0m', `Error: Invalid database name "${dbName}".`);
23
+ process.exit(1);
24
+ }
25
+ //---------------------------------------
26
+ connection[dbName] = mysql.createConnection(databases[dbName]);
27
+ connection[dbName].connect((err) => {
28
+ if (err) {
29
+ console.error('\x1b[31m%s\x1b[0m', `Error: Unable to connect to database "${dbName}".\n${err}`);
30
+ process.exit(1);
31
+ }
32
+ });
33
+ //---------------------------------------
34
+ const tableMigrations = await checkTableMigrations(connection[dbName]);
35
+ if (!tableMigrations) await createTableMigrations(connection[dbName]);
36
+ //---------------------------------------
37
+ const currentBatch = await getCurrentBatch(connection[dbName]);
38
+ if (batchNumber >= currentBatch) {
39
+ console.error('\x1b[31m%s\x1b[0m', `Error: Invalid batch number, the current batch is "${currentBatch}".`);
40
+ process.exit(1);
41
+ }
42
+ const migrations = await getAllMigrations(connection[dbName], batchNumber);
43
+ //---------------------------------------
44
+ for (let file of migrations) {
45
+ if (!fs.existsSync(`${currentPath}/migrations/${dbName}_db/${file.migration}.js`)) {
46
+ console.warn('\x1b[33m%s\x1b[0m', `Warning: Migration "${file.migration}" not found.`);
47
+ }
48
+ else {
49
+ const migration = require(`${currentPath}/migrations/${dbName}_db/${file.migration}`);
50
+ try {
51
+ await migration.down(connection[dbName]);
52
+ await deleteMigration(connection[dbName], file.migration, batchNumber);
53
+ console.log('\x1b[32m%s\x1b[0m', `Migration "${file.migration}" has been successfully rolled back.`);
54
+ }
55
+ catch (err) {
56
+ console.warn('\x1b[33m%s\x1b[0m', `Warning: "${err}" in migration "${file.migration}".`);
57
+ }
58
+ }
59
+ }
60
+ connection[dbName].end();
61
+ }
62
+ else console.error('\x1b[31m%s\x1b[0m', `Error: Database name is empty !`);
63
+ }
64
+ //==============================================================================
65
+ module.exports = back_migration;
@@ -4,7 +4,7 @@ const fs = require('fs');
4
4
  const moment = require('moment');
5
5
  //---------------------------------------
6
6
  const currentPath = process.cwd();
7
- const config = require(`${currentPath}/migrations/config.json`);
7
+ const config = require(`${currentPath}/migrations/mysql-migration.config.json`);
8
8
  //---------------------------------------
9
9
  function create_migration(migrationName, dbName) {
10
10
  if (!migrationName) {
@@ -5,7 +5,7 @@ const fs = require('fs');
5
5
  const currentPath = process.cwd();
6
6
  //---------------------------------------
7
7
  if (!fs.existsSync(`${currentPath}/migrations`)) fs.mkdirSync(`${currentPath}/migrations`);
8
- if (!fs.existsSync(`${currentPath}/migrations/config.json`)) fs.writeFileSync(`${currentPath}/migrations/config.json`, JSON.stringify({
8
+ if (!fs.existsSync(`${currentPath}/migrations/mysql-migration.config.json`)) fs.writeFileSync(`${currentPath}/migrations/mysql-migration.config.json`, JSON.stringify({
9
9
  "databases": {
10
10
  "db_name": {
11
11
  "host": "db_host",
@@ -15,4 +15,4 @@ if (!fs.existsSync(`${currentPath}/migrations/config.json`)) fs.writeFileSync(`$
15
15
  }
16
16
  }
17
17
  }, null, 3));
18
- console.log('\x1b[32m%s\x1b[0m', `Created migration config file: "config.json" in the "migrations" directory.`);
18
+ console.log('\x1b[32m%s\x1b[0m', `Created migration config file: "mysql-migration.config.json" in the "migrations" directory.`);
@@ -4,7 +4,7 @@ const fs = require('fs');
4
4
  const mysql = require('mysql');
5
5
  //---------------------------------------
6
6
  const currentPath = process.cwd();
7
- const config = require(`${currentPath}/migrations/config.json`);
7
+ const config = require(`${currentPath}/migrations/mysql-migration.config.json`);
8
8
  const { checkTableMigrations, createTableMigrations, getAllMigrations, getCurrentBatch, insertMigration } = require("../utils/functions");
9
9
  //==============================================================================
10
10
  async function run_migration(dbName) {
@@ -22,9 +22,11 @@ function createTableMigrations(connection) {
22
22
  });
23
23
  }
24
24
  //---------------------------------------
25
- function getAllMigrations(connection) {
25
+ function getAllMigrations(connection, batch = null) {
26
26
  return new Promise((resolve) => {
27
- connection.query("SELECT `migration` FROM `migrations`;", (error, results) => {
27
+ let query = "SELECT `migration` FROM `migrations`";
28
+ if (batch) query += " WHERE `batch` > ?;";
29
+ connection.query(query, [batch], (error, results) => {
28
30
  if (error) throw error;
29
31
  if (results?.length > 0) resolve(results);
30
32
  else resolve([]);
@@ -52,6 +54,16 @@ function insertMigration(connection, migration, batch) {
52
54
  });
53
55
  }
54
56
  //---------------------------------------
57
+ function deleteMigration(connection, migration, batch) {
58
+ return new Promise((resolve) => {
59
+ const query = `DELETE FROM \`migrations\` WHERE \`migration\` = '${migration}' AND \`batch\` > '${batch}';`
60
+ connection.query(query, (error) => {
61
+ if (error) throw error;
62
+ resolve(true);
63
+ });
64
+ });
65
+ }
66
+ //---------------------------------------
55
67
  module.exports = {
56
- checkTableMigrations, createTableMigrations, getAllMigrations, getCurrentBatch, insertMigration
68
+ checkTableMigrations, createTableMigrations, getAllMigrations, getCurrentBatch, insertMigration, deleteMigration
57
69
  }