mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
added schema sync log and migrations basic generation commands
This commit is contained in:
parent
b82b2f31a8
commit
6dacbc4e5e
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "typeorm",
|
||||
"private": true,
|
||||
"version": "0.1.0-alpha.12",
|
||||
"version": "0.1.0-alpha.13",
|
||||
"description": "Data-Mapper ORM for TypeScript, ES7, ES6, ES5. Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, WebSQL, MongoDB databases.",
|
||||
"license": "MIT",
|
||||
"readmeFilename": "README.md",
|
||||
|
||||
16
src/cli.ts
16
src/cli.ts
@ -8,21 +8,19 @@ import {MigrationCreateCommand} from "./commands/MigrationCreateCommand";
|
||||
import {MigrationRunCommand} from "./commands/MigrationRunCommand";
|
||||
import {MigrationRevertCommand} from "./commands/MigrationRevertCommand";
|
||||
import {SubscriberCreateCommand} from "./commands/SubscriberCreateCommand";
|
||||
|
||||
require("yargonaut")
|
||||
.style("blue")
|
||||
.style("yellow", "required")
|
||||
.helpStyle("green")
|
||||
.errorsStyle("red");
|
||||
import {SchemaSyncLogCommand} from "./commands/SchemaSyncLogCommand";
|
||||
import {MigrationGenerateCommand} from "./commands/MigrationGenerateCommand";
|
||||
|
||||
require("yargs")
|
||||
.usage("Usage: $0 <command> [options]")
|
||||
.command(new SchemaSyncCommand())
|
||||
.command(new SchemaSyncLogCommand())
|
||||
.command(new SchemaDropCommand())
|
||||
.command(new QueryCommand())
|
||||
.command(new EntityCreateCommand())
|
||||
.command(new SubscriberCreateCommand())
|
||||
.command(new MigrationCreateCommand())
|
||||
.command(new MigrationGenerateCommand())
|
||||
.command(new MigrationRunCommand())
|
||||
.command(new MigrationRevertCommand())
|
||||
.demand(1)
|
||||
@ -31,3 +29,9 @@ require("yargs")
|
||||
.help("h")
|
||||
.alias("h", "help")
|
||||
.argv;
|
||||
|
||||
require("yargonaut")
|
||||
.style("blue")
|
||||
.style("yellow", "required")
|
||||
.helpStyle("green")
|
||||
.errorsStyle("red");
|
||||
|
||||
98
src/commands/MigrationGenerateCommand.ts
Normal file
98
src/commands/MigrationGenerateCommand.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import {ConnectionOptionsReader} from "../connection/ConnectionOptionsReader";
|
||||
import {CommandUtils} from "./CommandUtils";
|
||||
import {Connection} from "../connection/Connection";
|
||||
import {createConnection} from "../index";
|
||||
const mkdirp = require("mkdirp");
|
||||
|
||||
/**
|
||||
* Generates a new migration file with sql needs to be executed to update schema.
|
||||
*/
|
||||
export class MigrationGenerateCommand {
|
||||
|
||||
command = "migrations:generate";
|
||||
describe = "Generates a new migration file with sql needs to be executed to update schema.";
|
||||
|
||||
builder(yargs: any) {
|
||||
return yargs
|
||||
.option("c", {
|
||||
alias: "connection",
|
||||
default: "default",
|
||||
describe: "Name of the connection on which run a query."
|
||||
})
|
||||
.option("n", {
|
||||
alias: "name",
|
||||
describe: "Name of the migration class.",
|
||||
demand: true
|
||||
})
|
||||
.option("d", {
|
||||
alias: "dir",
|
||||
describe: "Directory where migration should be created."
|
||||
})
|
||||
.option("cf", {
|
||||
alias: "config",
|
||||
default: "ormconfig",
|
||||
describe: "Name of the file with connection configuration."
|
||||
});
|
||||
}
|
||||
|
||||
async handler(argv: any) {
|
||||
const timestamp = new Date().getTime();
|
||||
const filename = timestamp + "-" + argv.name + ".ts";
|
||||
let directory = argv.dir;
|
||||
|
||||
// if directory is not set then try to open tsconfig and find default path there
|
||||
if (!directory) {
|
||||
try {
|
||||
const connectionOptionsReader = new ConnectionOptionsReader({ root: process.cwd(), configName: argv.config });
|
||||
const connectionOptions = await connectionOptionsReader.get(argv.connection);
|
||||
directory = connectionOptions.cli ? connectionOptions.cli.migrationsDir : undefined;
|
||||
} catch (err) { }
|
||||
}
|
||||
|
||||
let connection: Connection|undefined = undefined;
|
||||
try {
|
||||
process.env.LOGGER_CLI_SCHEMA_SYNC = true;
|
||||
process.env.SKIP_SCHEMA_CREATION = true;
|
||||
|
||||
const connectionOptionsReader = new ConnectionOptionsReader({ root: process.cwd(), configName: argv.config });
|
||||
const connectionOptions = await connectionOptionsReader.get(argv.connection);
|
||||
connection = await createConnection(connectionOptions);
|
||||
const sqls = await connection.logSyncSchema();
|
||||
const fileContent = MigrationGenerateCommand.getTemplate(argv.name, timestamp, sqls);
|
||||
await CommandUtils.createFile(process.cwd() + "/" + (directory ? (directory + "/") : "") + filename, fileContent);
|
||||
|
||||
} catch (err) {
|
||||
if (connection)
|
||||
(connection as Connection).logger.log("error", err);
|
||||
throw err;
|
||||
|
||||
} finally {
|
||||
if (connection)
|
||||
await connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Static Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets contents of the migration file.
|
||||
*/
|
||||
protected static getTemplate(name: string, timestamp: number, sqlQueries: string[]): string {
|
||||
return `import {Connection, EntityManager, MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class ${name}${timestamp} implements MigrationInterface {
|
||||
|
||||
public async up(queryRunner: QueryRunner, connection: Connection, entityManager?: EntityManager): Promise<any> {
|
||||
${sqlQueries.map(query => "queryRunner.query(" + query + ")\r\n")}
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner, connection: Connection, entityManager?: EntityManager): Promise<any> {
|
||||
}
|
||||
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
}
|
||||
50
src/commands/SchemaSyncLogCommand.ts
Normal file
50
src/commands/SchemaSyncLogCommand.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import {createConnections, createConnection} from "../index";
|
||||
import {Connection} from "../connection/Connection";
|
||||
import {ConnectionOptionsReader} from "../connection/ConnectionOptionsReader";
|
||||
|
||||
/**
|
||||
* Shows sql to be executed by schema:sync command.
|
||||
*/
|
||||
export class SchemaSyncLogCommand {
|
||||
command = "schema:sync";
|
||||
describe = "Shows sql to be executed by schema:sync command. It shows schema:sync log only for your default connection. " +
|
||||
"To run update queries on a concrete connection use -c option.";
|
||||
|
||||
builder(yargs: any) {
|
||||
return yargs
|
||||
.option("c", {
|
||||
alias: "connection",
|
||||
default: "default",
|
||||
describe: "Name of the connection of which schema sync log should be shown."
|
||||
})
|
||||
.option("cf", {
|
||||
alias: "config",
|
||||
default: "ormconfig",
|
||||
describe: "Name of the file with connection configuration."
|
||||
});
|
||||
}
|
||||
|
||||
async handler(argv: any) {
|
||||
|
||||
let connection: Connection|undefined = undefined;
|
||||
try {
|
||||
process.env.LOGGER_CLI_SCHEMA_SYNC = true;
|
||||
process.env.SKIP_SCHEMA_CREATION = true;
|
||||
|
||||
const connectionOptionsReader = new ConnectionOptionsReader({ root: process.cwd(), configName: argv.config });
|
||||
const connectionOptions = await connectionOptionsReader.get(argv.connection);
|
||||
connection = await createConnection(connectionOptions);
|
||||
const sqls = await connection.logSyncSchema();
|
||||
sqls.forEach(sql => console.log(sql));
|
||||
|
||||
} catch (err) {
|
||||
if (connection)
|
||||
(connection as Connection).logger.log("error", err);
|
||||
throw err;
|
||||
|
||||
} finally {
|
||||
if (connection)
|
||||
await connection.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -200,6 +200,17 @@ export class Connection {
|
||||
await schemaBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns sql queries generated by schema builder.
|
||||
*/
|
||||
async logSyncSchema(): Promise<string[]> {
|
||||
if (!this.isConnected)
|
||||
throw new CannotExecuteNotConnectedError(this.name);
|
||||
|
||||
const schemaBuilder = this.driver.createSchemaBuilder();
|
||||
return schemaBuilder.log();
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the database and all its data.
|
||||
* Be careful with this method on production since this method will erase all your database tables and their data.
|
||||
|
||||
@ -560,6 +560,32 @@ export class MongoQueryRunner implements QueryRunner {
|
||||
.dropCollection(collectionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables special query runner mode in which sql queries won't be executed,
|
||||
* instead they will be memorized into a special variable inside query runner.
|
||||
* You can get memorized sql using getMemorySql() method.
|
||||
*/
|
||||
enableSqlMemory(): void {
|
||||
throw new Error(`This operation is not supported by MongoDB driver.`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables special query runner mode in which sql queries won't be executed
|
||||
* started by calling enableSqlMemory() method.
|
||||
*
|
||||
* Previously memorized sql will be flushed.
|
||||
*/
|
||||
disableSqlMemory(): void {
|
||||
throw new Error(`This operation is not supported by MongoDB driver.`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets sql stored in the memory. Parameters in the sql are already replaced.
|
||||
*/
|
||||
getMemorySql(): string[] {
|
||||
throw new Error(`This operation is not supported by MongoDB driver.`);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -45,6 +45,16 @@ export class MysqlQueryRunner implements QueryRunner {
|
||||
*/
|
||||
protected databaseConnectionPromise: Promise<any>;
|
||||
|
||||
/**
|
||||
* Indicates if special query runner mode in which sql queries won't be executed is enabled.
|
||||
*/
|
||||
protected sqlMemoryMode: boolean = false;
|
||||
|
||||
/**
|
||||
* Sql-s stored if "sql in memory" mode is enabled.
|
||||
*/
|
||||
protected sqlsInMemory: string[] = [];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
@ -130,6 +140,12 @@ export class MysqlQueryRunner implements QueryRunner {
|
||||
if (this.isReleased)
|
||||
throw new QueryRunnerAlreadyReleasedError();
|
||||
|
||||
// if sql-in-memory mode is enabled then simply store sql in memory and return
|
||||
if (this.sqlMemoryMode === true) {
|
||||
this.sqlsInMemory.push(query);
|
||||
return Promise.resolve() as Promise<any>;
|
||||
}
|
||||
|
||||
return new Promise(async (ok, fail) => {
|
||||
this.driver.connection.logger.logQuery(query, parameters);
|
||||
const databaseConnection = await this.connect();
|
||||
@ -549,6 +565,33 @@ export class MysqlQueryRunner implements QueryRunner {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables special query runner mode in which sql queries won't be executed,
|
||||
* instead they will be memorized into a special variable inside query runner.
|
||||
* You can get memorized sql using getMemorySql() method.
|
||||
*/
|
||||
enableSqlMemory(): void {
|
||||
this.sqlMemoryMode = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables special query runner mode in which sql queries won't be executed
|
||||
* started by calling enableSqlMemory() method.
|
||||
*
|
||||
* Previously memorized sql will be flushed.
|
||||
*/
|
||||
disableSqlMemory(): void {
|
||||
this.sqlsInMemory = [];
|
||||
this.sqlMemoryMode = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets sql stored in the memory. Parameters in the sql are already replaced.
|
||||
*/
|
||||
getMemorySql(): string[] {
|
||||
return this.sqlsInMemory;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -47,6 +47,16 @@ export class OracleQueryRunner implements QueryRunner {
|
||||
*/
|
||||
protected databaseConnectionPromise: Promise<any>;
|
||||
|
||||
/**
|
||||
* Indicates if special query runner mode in which sql queries won't be executed is enabled.
|
||||
*/
|
||||
protected sqlMemoryMode: boolean = false;
|
||||
|
||||
/**
|
||||
* Sql-s stored if "sql in memory" mode is enabled.
|
||||
*/
|
||||
protected sqlsInMemory: string[] = [];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
@ -615,6 +625,33 @@ AND cons.constraint_name = cols.constraint_name AND cons.owner = cols.owner ORDE
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables special query runner mode in which sql queries won't be executed,
|
||||
* instead they will be memorized into a special variable inside query runner.
|
||||
* You can get memorized sql using getMemorySql() method.
|
||||
*/
|
||||
enableSqlMemory(): void {
|
||||
this.sqlMemoryMode = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables special query runner mode in which sql queries won't be executed
|
||||
* started by calling enableSqlMemory() method.
|
||||
*
|
||||
* Previously memorized sql will be flushed.
|
||||
*/
|
||||
disableSqlMemory(): void {
|
||||
this.sqlsInMemory = [];
|
||||
this.sqlMemoryMode = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets sql stored in the memory. Parameters in the sql are already replaced.
|
||||
*/
|
||||
getMemorySql(): string[] {
|
||||
return this.sqlsInMemory;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -50,6 +50,16 @@ export class PostgresQueryRunner implements QueryRunner {
|
||||
*/
|
||||
protected releaseCallback: Function;
|
||||
|
||||
/**
|
||||
* Indicates if special query runner mode in which sql queries won't be executed is enabled.
|
||||
*/
|
||||
protected sqlMemoryMode: boolean = false;
|
||||
|
||||
/**
|
||||
* Sql-s stored if "sql in memory" mode is enabled.
|
||||
*/
|
||||
protected sqlsInMemory: string[] = [];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
@ -641,6 +651,33 @@ where constraint_type = 'PRIMARY KEY' AND c.table_schema = '${this.schemaName}'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables special query runner mode in which sql queries won't be executed,
|
||||
* instead they will be memorized into a special variable inside query runner.
|
||||
* You can get memorized sql using getMemorySql() method.
|
||||
*/
|
||||
enableSqlMemory(): void {
|
||||
this.sqlMemoryMode = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables special query runner mode in which sql queries won't be executed
|
||||
* started by calling enableSqlMemory() method.
|
||||
*
|
||||
* Previously memorized sql will be flushed.
|
||||
*/
|
||||
disableSqlMemory(): void {
|
||||
this.sqlsInMemory = [];
|
||||
this.sqlMemoryMode = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets sql stored in the memory. Parameters in the sql are already replaced.
|
||||
*/
|
||||
getMemorySql(): string[] {
|
||||
return this.sqlsInMemory;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -35,6 +35,20 @@ export class SqliteQueryRunner implements QueryRunner {
|
||||
*/
|
||||
isTransactionActive = false;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Indicates if special query runner mode in which sql queries won't be executed is enabled.
|
||||
*/
|
||||
protected sqlMemoryMode: boolean = false;
|
||||
|
||||
/**
|
||||
* Sql-s stored if "sql in memory" mode is enabled.
|
||||
*/
|
||||
protected sqlsInMemory: string[] = [];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
@ -557,6 +571,33 @@ export class SqliteQueryRunner implements QueryRunner {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables special query runner mode in which sql queries won't be executed,
|
||||
* instead they will be memorized into a special variable inside query runner.
|
||||
* You can get memorized sql using getMemorySql() method.
|
||||
*/
|
||||
enableSqlMemory(): void {
|
||||
this.sqlMemoryMode = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables special query runner mode in which sql queries won't be executed
|
||||
* started by calling enableSqlMemory() method.
|
||||
*
|
||||
* Previously memorized sql will be flushed.
|
||||
*/
|
||||
disableSqlMemory(): void {
|
||||
this.sqlsInMemory = [];
|
||||
this.sqlMemoryMode = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets sql stored in the memory. Parameters in the sql are already replaced.
|
||||
*/
|
||||
getMemorySql(): string[] {
|
||||
return this.sqlsInMemory;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -49,6 +49,16 @@ export class SqlServerQueryRunner implements QueryRunner {
|
||||
*/
|
||||
protected queryResponsibilityChain: Promise<any>[] = [];
|
||||
|
||||
/**
|
||||
* Indicates if special query runner mode in which sql queries won't be executed is enabled.
|
||||
*/
|
||||
protected sqlMemoryMode: boolean = false;
|
||||
|
||||
/**
|
||||
* Sql-s stored if "sql in memory" mode is enabled.
|
||||
*/
|
||||
protected sqlsInMemory: string[] = [];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
@ -666,6 +676,33 @@ WHERE columnUsages.TABLE_CATALOG = '${this.dbName}' AND tableConstraints.TABLE_C
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables special query runner mode in which sql queries won't be executed,
|
||||
* instead they will be memorized into a special variable inside query runner.
|
||||
* You can get memorized sql using getMemorySql() method.
|
||||
*/
|
||||
enableSqlMemory(): void {
|
||||
this.sqlMemoryMode = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables special query runner mode in which sql queries won't be executed
|
||||
* started by calling enableSqlMemory() method.
|
||||
*
|
||||
* Previously memorized sql will be flushed.
|
||||
*/
|
||||
disableSqlMemory(): void {
|
||||
this.sqlsInMemory = [];
|
||||
this.sqlMemoryMode = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets sql stored in the memory. Parameters in the sql are already replaced.
|
||||
*/
|
||||
getMemorySql(): string[] {
|
||||
return this.sqlsInMemory;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -49,6 +49,16 @@ export class WebsqlQueryRunner implements QueryRunner {
|
||||
*/
|
||||
protected databaseConnectionPromise: Promise<any>;
|
||||
|
||||
/**
|
||||
* Indicates if special query runner mode in which sql queries won't be executed is enabled.
|
||||
*/
|
||||
protected sqlMemoryMode: boolean = false;
|
||||
|
||||
/**
|
||||
* Sql-s stored if "sql in memory" mode is enabled.
|
||||
*/
|
||||
protected sqlsInMemory: string[] = [];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
@ -608,6 +618,33 @@ export class WebsqlQueryRunner implements QueryRunner {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables special query runner mode in which sql queries won't be executed,
|
||||
* instead they will be memorized into a special variable inside query runner.
|
||||
* You can get memorized sql using getMemorySql() method.
|
||||
*/
|
||||
enableSqlMemory(): void {
|
||||
this.sqlMemoryMode = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables special query runner mode in which sql queries won't be executed
|
||||
* started by calling enableSqlMemory() method.
|
||||
*
|
||||
* Previously memorized sql will be flushed.
|
||||
*/
|
||||
disableSqlMemory(): void {
|
||||
this.sqlsInMemory = [];
|
||||
this.sqlMemoryMode = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets sql stored in the memory. Parameters in the sql are already replaced.
|
||||
*/
|
||||
getMemorySql(): string[] {
|
||||
return this.sqlsInMemory;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -3,8 +3,6 @@ import {ColumnMetadata} from "../metadata/ColumnMetadata";
|
||||
import {TableSchema} from "../schema-builder/schema/TableSchema";
|
||||
import {ForeignKeySchema} from "../schema-builder/schema/ForeignKeySchema";
|
||||
import {IndexSchema} from "../schema-builder/schema/IndexSchema";
|
||||
import {ColumnType} from "../driver/types/ColumnTypes";
|
||||
import {ColumnOptions} from "../decorator/options/ColumnOptions";
|
||||
|
||||
/**
|
||||
* Runs queries on a single database connection.
|
||||
@ -233,4 +231,24 @@ export interface QueryRunner {
|
||||
*/
|
||||
truncate(tableName: string): Promise<void>;
|
||||
|
||||
/**
|
||||
* Enables special query runner mode in which sql queries won't be executed,
|
||||
* instead they will be memorized into a special variable inside query runner.
|
||||
* You can get memorized sql using getMemorySql() method.
|
||||
*/
|
||||
enableSqlMemory(): void;
|
||||
|
||||
/**
|
||||
* Disables special query runner mode in which sql queries won't be executed
|
||||
* started by calling enableSqlMemory() method.
|
||||
*
|
||||
* Previously memorized sql will be flushed.
|
||||
*/
|
||||
disableSqlMemory(): void;
|
||||
|
||||
/**
|
||||
* Gets sql stored in the memory. Parameters in the sql are already replaced.
|
||||
*/
|
||||
getMemorySql(): string[];
|
||||
|
||||
}
|
||||
@ -45,4 +45,11 @@ export class MongoSchemaBuilder implements SchemaBuilder {
|
||||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns query to be executed by schema builder.
|
||||
*/
|
||||
log(): Promise<string[]> {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
}
|
||||
@ -62,15 +62,7 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {
|
||||
|
||||
await this.queryRunner.startTransaction();
|
||||
try {
|
||||
await this.dropOldForeignKeys();
|
||||
// await this.dropOldPrimaryKeys(); // todo: need to drop primary column because column updates are not possible
|
||||
await this.createNewTables();
|
||||
await this.dropRemovedColumns();
|
||||
await this.addNewColumns();
|
||||
await this.updateExistColumns();
|
||||
await this.updatePrimaryKeys();
|
||||
await this.createIndices(); // we need to create indices before foreign keys because foreign keys rely on unique indices
|
||||
await this.createForeignKeys();
|
||||
await this.executeSchemaSyncOperationsInProperOrder();
|
||||
await this.queryRunner.commitTransaction();
|
||||
|
||||
} catch (error) {
|
||||
@ -85,14 +77,30 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns sql queries to be executed by schema builder.
|
||||
*/
|
||||
async log(): Promise<string[]> {
|
||||
this.queryRunner = await this.connection.createQueryRunner();
|
||||
try {
|
||||
this.tableSchemas = await this.loadTableSchemas();
|
||||
this.queryRunner.enableSqlMemory();
|
||||
await this.executeSchemaSyncOperationsInProperOrder();
|
||||
return this.queryRunner.getMemorySql();
|
||||
|
||||
} finally {
|
||||
// its important to disable this mode despite the fact we are release query builder
|
||||
// because there exist drivers which reuse same query runner. Also its important to disable
|
||||
// sql memory after call of getMemorySql() method because last one flushes sql memory.
|
||||
this.queryRunner.disableSqlMemory();
|
||||
await this.queryRunner.release();
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
protected get entityToSyncMetadatas(): EntityMetadata[] {
|
||||
return this.connection.entityMetadatas.filter(metadata => !metadata.skipSync && metadata.tableType !== "single-table-child");
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all table schemas from the database.
|
||||
*/
|
||||
@ -101,6 +109,29 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {
|
||||
return this.queryRunner.loadTableSchemas(tableNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns only entities that should be synced in the database.
|
||||
*/
|
||||
protected get entityToSyncMetadatas(): EntityMetadata[] {
|
||||
return this.connection.entityMetadatas.filter(metadata => !metadata.skipSync && metadata.tableType !== "single-table-child");
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes schema sync operations in a proper order.
|
||||
* Order of operations matter here.
|
||||
*/
|
||||
protected async executeSchemaSyncOperationsInProperOrder(): Promise<void> {
|
||||
await this.dropOldForeignKeys();
|
||||
// await this.dropOldPrimaryKeys(); // todo: need to drop primary column because column updates are not possible
|
||||
await this.createNewTables();
|
||||
await this.dropRemovedColumns();
|
||||
await this.addNewColumns();
|
||||
await this.updateExistColumns();
|
||||
await this.updatePrimaryKeys();
|
||||
await this.createIndices(); // we need to create indices before foreign keys because foreign keys rely on unique indices
|
||||
await this.createForeignKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops all (old) foreign keys that exist in the table schemas, but do not exist in the entity metadata.
|
||||
*/
|
||||
|
||||
@ -8,4 +8,9 @@ export interface SchemaBuilder {
|
||||
*/
|
||||
build(): Promise<void>;
|
||||
|
||||
/**
|
||||
* Returns queries to be executed by schema builder.
|
||||
*/
|
||||
log(): Promise<string[]>;
|
||||
|
||||
}
|
||||
@ -9,20 +9,13 @@ import {View} from "./entity/View";
|
||||
import {Category} from "./entity/Category";
|
||||
import {closeTestingConnections, createTestingConnections, setupSingleTestingConnection} from "../../utils/test-utils";
|
||||
import {Connection} from "../../../src/connection/Connection";
|
||||
import {PostgresDriver} from "../../../src/driver/postgres/PostgresDriver";
|
||||
import {Repository} from "../../../src/repository/Repository";
|
||||
import {TreeRepository} from "../../../src/repository/TreeRepository";
|
||||
import {getConnectionManager} from "../../../src/index";
|
||||
import {NoConnectionForRepositoryError} from "../../../src/connection/error/NoConnectionForRepositoryError";
|
||||
import {FirstCustomNamingStrategy} from "./naming-strategy/FirstCustomNamingStrategy";
|
||||
import {SecondCustomNamingStrategy} from "./naming-strategy/SecondCustomNamingStrategy";
|
||||
import {EntityManager} from "../../../src/entity-manager/EntityManager";
|
||||
import {CannotGetEntityManagerNotConnectedError} from "../../../src/connection/error/CannotGetEntityManagerNotConnectedError";
|
||||
import {Blog} from "./modules/blog/entity/Blog";
|
||||
import {Question} from "./modules/question/entity/Question";
|
||||
import {Video} from "./modules/video/entity/Video";
|
||||
import {ConnectionOptions} from "../../../src/connection/ConnectionOptions";
|
||||
import {DefaultNamingStrategy} from "../../../src/naming-strategy/DefaultNamingStrategy";
|
||||
import {PostgresConnectionOptions} from "../../../src/driver/postgres/PostgresConnectionOptions";
|
||||
|
||||
describe("Connection", () => {
|
||||
@ -194,6 +187,21 @@ describe("Connection", () => {
|
||||
|
||||
});
|
||||
|
||||
describe.only("log a schema when connection.logSyncSchema is called", function() {
|
||||
|
||||
let connections: Connection[];
|
||||
before(async () => connections = await createTestingConnections({
|
||||
entities: [Post]
|
||||
}));
|
||||
after(() => closeTestingConnections(connections));
|
||||
|
||||
it("should return sql log properly", () => Promise.all(connections.map(async connection => {
|
||||
const sql = await connection.logSyncSchema();
|
||||
console.log(sql);
|
||||
})));
|
||||
|
||||
});
|
||||
|
||||
describe("after connection is closed successfully", function() {
|
||||
|
||||
// open a close connections
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user