Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create index bug fix #16

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,18 @@ module.exports = {

then you can apply this `npx sequelize db:migrate --to 00000001-noname.js`

## Possible Usage Scenario
Make sure to have writeMigration in your System under development and that sequelize is all set up

If you change a model and re-run the backend there should be a new file under `db/migrations`, but the database
won't update automatically. There are easy but important steps:
1) Rename the file's name as well as the content (Info: name), so that everyone knows what this migration is about
2) Migrate your database `sequelize db:migrate`
3) Re-Serve the backend. You Should see 'No changes found'.
4) Test the automatically created file's down function `sequelize db:migrate:undo`
5) If there are any troubles, fix the auto-generated file (ordering!)
6) Run `sequelize db:migrate:undo` and continue your amazing work

## Documentation

not ready yet.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 9 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sequelize-typescript-migration",
"version": "0.0.1-beta.3",
"name": "sequelize-typescript-migration-v2",
"version": "0.0.2-beta.4",
"description": "migration tool for sequelize & typescript users",
"keywords": [
"sequelize",
Expand All @@ -9,24 +9,25 @@
"migration",
"makemigration"
],
"homepage": "https://github.com/kimjbstar/sequelize-typescript-migration",
"homepage": "https://github.com/syon-development/sequelize-typescript-migration",
"bugs": {
"url": "https://github.com/kimjbstar/sequelize-typescript-migration/issues",
"email": "[email protected]"
"url": "https://github.com/syon-development/sequelize-typescript-migration/issues",
"email": "[email protected]"
},
"main": "dist/index.js",
"scripts": {
"build": "tsc",
"prepare": "tsc",
"start": "node dist/index.js"
},
"bin": "./dist/index.js",
"repository": {
"type": "git",
"url": "git://github.com/kimjbstar/sequelize-typescript-migration.git"
"url": "git://github.com/syon-development/sequelize-typescript-migration"
},
"author": {
"name": "kimjbstar",
"email": "[email protected]"
"name": "Thomas Kugi",
"email": "[email protected]"
},
"license": "MIT",
"dependencies": {
Expand Down
253 changes: 126 additions & 127 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Sequelize } from "sequelize-typescript";
import {Sequelize} from "sequelize-typescript";
import * as beautify from "js-beautify";
import * as fs from "fs";
import { IMigrationState } from "./constants";
import { ModelCtor, Model, QueryInterface } from "sequelize/types";
import {IMigrationState} from "./constants";
import {Model, ModelCtor, QueryInterface} from "sequelize/types";
import getTablesFromModels from "./utils/getTablesFromModels";
import getDiffActionsFromTables from "./utils/getDiffActionsFromTables";
import getMigration from "./utils/getMigration";
Expand All @@ -11,134 +11,133 @@ import getLastMigrationState from "./utils/getLastMigrationState";
import writeMigration from "./utils/writeMigration";

export interface IMigrationOptions {
/**
* directory where migration file saved. We recommend that you specify this path to sequelize migration path.
*/
outDir: string;
/**
* if true, it doesn't generate files but just prints result action.
*/
preview?: boolean;
/**
* migration file name, default is "noname"
*/
migrationName?: string;
/**
* comment of migration.
*/
comment?: string;
debug?: boolean;
/**
* directory where migration file saved. We recommend that you specify this path to sequelize migration path.
*/
outDir: string;
/**
* if true, it doesn't generate files but just prints result action.
*/
preview?: boolean;
/**
* migration file name, default is "noname"
*/
migrationName?: string;
/**
* comment of migration.
*/
comment?: string;
debug?: boolean;
}

export class SequelizeTypescriptMigration {
/**
* generates migration file including up, down code
* after this, run 'npx sequelize-cli db:migrate'.
* @param sequelize sequelize-typescript instance
* @param options options
*/
public static makeMigration = async (
sequelize: Sequelize,
options: IMigrationOptions
) => {
options.preview = options.preview || false;
if (fs.existsSync(options.outDir) === false) {
return Promise.reject({
msg: `${options.outDir} not exists. check path and if you did 'npx sequelize init' you must use path used in sequelize migration path`,
});
}
await sequelize.authenticate();

const models: {
[key: string]: ModelCtor<Model>;
} = sequelize.models;

const queryInterface: QueryInterface = sequelize.getQueryInterface();

await createMigrationTable(sequelize);
const lastMigrationState = await getLastMigrationState(sequelize);

const previousState: IMigrationState = {
revision:
lastMigrationState !== undefined ? lastMigrationState["revision"] : 0,
version:
lastMigrationState !== undefined ? lastMigrationState["version"] : 1,
tables:
lastMigrationState !== undefined ? lastMigrationState["tables"] : {},
};
const currentState: IMigrationState = {
revision: previousState.revision + 1,
tables: getTablesFromModels(sequelize, models),
};

const upActions = getDiffActionsFromTables(
previousState.tables,
currentState.tables
);
const downActions = getDiffActionsFromTables(
currentState.tables,
previousState.tables
);

const migration = getMigration(upActions);
const tmp = getMigration(downActions);

migration.commandsDown = tmp.commandsUp;

if (migration.commandsUp.length === 0) {
console.log("No changes found");
process.exit(0);
}

// log
migration.consoleOut.forEach(v => {
console.log(`[Actions] ${v}`);
});
if (options.preview) {
console.log("Migration result:");
console.log(beautify(`[ \n${migration.commandsUp.join(", \n")} \n];\n`));
console.log("Undo commands:");
console.log(
beautify(`[ \n${migration.commandsDown.join(", \n")} \n];\n`)
);
return Promise.resolve({ msg: "success without save" });
}

const info = await writeMigration(
currentState.revision,
migration,
options
);

console.log(
`New migration to revision ${currentState.revision} has been saved to file '${info.filename}'`
);

// save current state, Ugly hack, see https://github.com/sequelize/sequelize/issues/8310
const rows = [
{
revision: currentState.revision,
name: info.info.name,
state: JSON.stringify(currentState),
},
];

try {
await queryInterface.bulkDelete("SequelizeMetaMigrations", {
revision: currentState.revision,
});
await queryInterface.bulkInsert("SequelizeMetaMigrations", rows);

console.log(`Use sequelize CLI:
/**
* generates migration file including up, down code
* after this, run 'npx sequelize-cli db:migrate'.
* @param sequelize sequelize-typescript instance
* @param options options
*/
public static makeMigration = async (
sequelize: Sequelize,
options: IMigrationOptions
) => {
options.preview = options.preview || false;
if (fs.existsSync(options.outDir) === false) {
return Promise.reject({
msg: `${options.outDir} not exists. check path and if you did 'npx sequelize init' you must use path used in sequelize migration path`,
});
}
await sequelize.authenticate();

const models: {
[key: string]: ModelCtor<Model>;
} = sequelize.models;

const queryInterface: QueryInterface = sequelize.getQueryInterface();

await createMigrationTable(sequelize);
const lastMigrationState = await getLastMigrationState(sequelize);

const previousState: IMigrationState = {
revision:
lastMigrationState !== undefined ? lastMigrationState["revision"] : 0,
version:
lastMigrationState !== undefined ? lastMigrationState["version"] : 1,
tables:
lastMigrationState !== undefined ? lastMigrationState["tables"] : {},
};
const currentState: IMigrationState = {
revision: previousState.revision + 1,
tables: getTablesFromModels(sequelize, models),
};

const upActions = getDiffActionsFromTables(
previousState.tables,
currentState.tables
);
const downActions = getDiffActionsFromTables(
currentState.tables,
previousState.tables
);

const migration = getMigration(upActions);
const tmp = getMigration(downActions);

migration.commandsDown = tmp.commandsUp;

if (migration.commandsUp.length === 0) {
return Promise.resolve({msg: "success: no changes found"});
}

// log
migration.consoleOut.forEach(v => {
console.log(`[Actions] ${v}`);
});
if (options.preview) {
console.log("Migration result:");
console.log(beautify(`[ \n${migration.commandsUp.join(", \n")} \n];\n`));
console.log("Undo commands:");
console.log(
beautify(`[ \n${migration.commandsDown.join(", \n")} \n];\n`)
);
return Promise.resolve({msg: "success without save"});
}

const info = await writeMigration(
currentState,
migration,
options
);

console.log(
`New migration to revision ${currentState.revision} has been saved to file '${info.filename}'`
);

// save current state, Ugly hack, see https://github.com/sequelize/sequelize/issues/8310
const rows = [
{
revision: currentState.revision,
name: info.info.name,
state: JSON.stringify(currentState),
},
];

try {
await queryInterface.bulkDelete("SequelizeMetaMigrations", {
revision: currentState.revision,
});
await queryInterface.bulkInsert("SequelizeMetaMigrations", rows);

console.log(`Use sequelize CLI:
npx sequelize db:migrate --to ${info.revisionNumber}-${
info.info.name
}.js ${`--migrations-path=${options.outDir}`} `);
info.info.name
}.js ${`--migrations-path=${options.outDir}`} `);

return Promise.resolve({ msg: "success" });
} catch (err) {
if (options.debug) console.error(err);
}
return Promise.resolve({msg: "success"});
} catch (err) {
if (options.debug) console.error(err);
}

return Promise.resolve({ msg: "success anyway.." });
};
return Promise.resolve({msg: "success anyway.."});
};
}
4 changes: 2 additions & 2 deletions src/utils/getDiffActionsFromTables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export default function getDiffActionsFromTables(
}

// new index
if (df.path[1] === "indexes") {
if (df.path[1] === "indexes" && df.rhs) {
const tableName = df.path[0];
const copied = df.rhs
? JSON.parse(JSON.stringify(df.rhs))
Expand Down Expand Up @@ -189,7 +189,7 @@ export default function getDiffActionsFromTables(
}
}

if (df.path[1] === "indexes") {
if (df.path[1] === "indexes" && df.lhs) {
actions.push({
actionType: "removeIndex",
tableName,
Expand Down
2 changes: 1 addition & 1 deletion src/utils/getLastMigrationState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default async function getLastMigrationState(sequelize: Sequelize) {

const lastRevision: number =
lastExecutedMigration !== undefined
? lastExecutedMigration["name"].split("-")[0]
? parseInt(lastExecutedMigration["name"].split("-")[0])
: -1;

const [
Expand Down
2 changes: 1 addition & 1 deletion src/utils/getTablesFromModels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export default function reverseModels(
"references",
"onUpdate",
"onDelete",
"validate",
//"validate",
].forEach(key => {
if (attribute[key] !== undefined) {
rowAttribute[key] = attribute[key];
Expand Down
2 changes: 1 addition & 1 deletion src/utils/parseIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function parseIndex(idx: IndexesOptions) {

// @todo: UNIQUE|FULLTEXT|SPATIAL
if (idx.unique) {
options["indicesType"] = "UNIQUE";
options["type"] = "UNIQUE";
}

// Set a type for the index, e.g. BTREE. See the documentation of the used dialect
Expand Down
Loading