diff --git a/README.md b/README.md index 1d247d3..0f75ca9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,55 @@ # Gina +Gina is a tool to auto-generate and run migrations based on Sequelize ORM. + +## How to use it + +### Install + +You can install this using: + +```bash +npm install gina-sequelize +``` + +You'll need to install it globally so you can you the gina-cli + +```bash +npm install -g gina-sequelize +# make sure to install ts-node too: +npm install -g ts-node +``` + +### Initialize Gina + +If this is the first time you are running Gina on your project you'll need to initialize it. + +```bash +gina-cli init +``` + +This will generate a folder `gina` to your project. +Inside this folder you will find the file `initializeModels.ts`. +You will need to modify this file so that the `initializeModels` method inside it return a valid sequelize instance object that *has all your models ALREADY loaded*. + +### Upgrade database + +Once you have the `initializeModels` configured you can upgrade your database using: + +```bash +gina-cli upgrade +``` + +### Generating new migration + +Once you have the `initializeModels` configured you can generate auto migrations. +It'll compare your loaded models with the database that you are connected. +All differences should be listed on a new migration file that will be placed inside the folder `gina/migrations`. + +```bash +gina-cli generate-migration "Creating user table" +``` + ## Development If you want to edit the cli and test it you can install it locally: diff --git a/lib/gina.ts b/lib/gina.ts index bb8481e..4c1a2bc 100644 --- a/lib/gina.ts +++ b/lib/gina.ts @@ -1,4 +1,4 @@ -import { DataTypes, ModelCtor, Model, Sequelize, ModelAttributeColumnOptions, QueryTypes } from 'sequelize'; +import { DataTypes, ModelCtor, Model, Sequelize, ModelAttributeColumnOptions, QueryTypes, ColumnDescription } from 'sequelize'; import fs from 'fs/promises'; import moment from 'moment'; import { MigrationFile } from './typings/migration'; @@ -212,6 +212,38 @@ class Migration { this.downFields = tabsToSpace(`\n\t\tawait queryInterface.removeColumn('${tableName}', '${attribute.field}');\n`) + this.downFields; } + columnAttributeProps(attribute: ColumnDescription) { + if (!this.imports.includes('DataTypes')) { + this.imports.push('DataTypes'); + } + + let attrProps = ''; + + console.log('attribute.defaultValue', attribute.defaultValue); + + attrProps += tabsToSpace(`\n${tabs(3)}type: DataTypes.${attribute.type.replace('VARCHAR(', 'STRING(')},`); + if (attribute.autoIncrement !== null) { + attrProps += tabsToSpace(`\n${tabs(3)}autoIncrement: ${this.getAutoIncrement(attribute)},`); + } + if (attribute.allowNull !== null) { + attrProps += tabsToSpace(`\n${tabs(3)}allowNull: ${this.getAllowNull(attribute)},`); + } + if (attribute.primaryKey !== null) { + attrProps += tabsToSpace(`\n${tabs(3)}primaryKey: ${this.getPrimaryKey(attribute)},`); + } + if (attribute.defaultValue !== null) { + attrProps += tabsToSpace(`\n${tabs(3)}defaultValue: ${this.getDefaultValue(attribute)},`); + } + + return attrProps; + } + + dropColumn(tableName: string, field: string, attribute: ColumnDescription) { + console.debug(`drop column ${tableName} ${field} `); + this.upFields += tabsToSpace(`\n\t\tawait queryInterface.removeColumn('${tableName}', '${field}');\n`); + this.downFields = tabsToSpace(`\n\t\tawait queryInterface.addColumn('${tableName}', '${field}', {${this.columnAttributeProps(attribute)}\n\t\t});`) + this.downFields; + } + async checkDiffs() { const models = Object.keys(this.sequelize.models); const modelTableNames: string[] = []; @@ -242,23 +274,7 @@ class Migration { for (const attr of Object.keys(attrs)) { if (!modelFields.includes(attr)) { - console.debug(`drop column ${modelTable} ${attr} `); - - this.upFields += `; - await queryInterface.removeColumn('${modelTable}', '${attr}'); - `; - - if (!this.imports.includes('DataTypes')) { - this.imports.push('DataTypes'); - } - - this.downFields = `; - await queryInterface.addColumn('${modelTable}', '${attr}', { - type: DataTypes.${attrs[attr].type.replace('VARCHAR(', 'STRING(')}, - allowNull: ${this.getAllowNull(attrs[attr])}, - defaultValue: ${attrs[attr].defaultValue}, - }); - ` + this.downFields; + this.dropColumn(modelTable, attr, attrs[attr]); } } diff --git a/package.json b/package.json index 5cd55c5..c4c517c 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "gina-cli": "./bin/index.ts" }, "types": "./dist/gina.d.ts", - "version": "0.0.9", + "version": "0.0.10", "description": "Gina is a tool to auto-generate and run migrations based on Sequelize ORM.", "scripts": { "eslint": "eslint .",