mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
feat: add support for table comment in MySQL (#10017)
* feat: add table comment * feat: resolve conflict * feat: del auroraMysql comment * feat: add changeTableComment method for MySQL * feat: QueryRunner subclass add changeTableComment Implementation * oracle implement changeTableComment * add test * feat: loadTables support comment * feat: rename * feat: update mysql changeTableComment * fix: fix conflict * feat: add table comment * feat: resolve conflict * feat: del auroraMysql comment * feat: add changeTableComment method for MySQL * feat: QueryRunner subclass add changeTableComment Implementation * oracle implement changeTableComment * add test * feat: loadTables support comment * feat: rename * feat: update mysql changeTableComment --------- Co-authored-by: sinkhaha <1468709606@qq.com>
This commit is contained in:
parent
15bc8876f8
commit
338df16439
@ -41,6 +41,7 @@ export function Entity(
|
||||
schema: options.schema ? options.schema : undefined,
|
||||
synchronize: options.synchronize,
|
||||
withoutRowid: options.withoutRowid,
|
||||
comment: options.comment ? options.comment : undefined,
|
||||
} as TableMetadataArgs)
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,4 +46,9 @@ export interface EntityOptions {
|
||||
* @see https://www.sqlite.org/withoutrowid.html.
|
||||
*/
|
||||
withoutRowid?: boolean
|
||||
|
||||
/**
|
||||
* Table comment. Not supported by all database types.
|
||||
*/
|
||||
comment?: string
|
||||
}
|
||||
|
||||
@ -2822,4 +2822,16 @@ export class AuroraMysqlQueryRunner
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Change table comment.
|
||||
*/
|
||||
changeTableComment(
|
||||
tableOrName: Table | string,
|
||||
comment?: string,
|
||||
): Promise<void> {
|
||||
throw new TypeORMError(
|
||||
`aurora-mysql driver does not support change table comment.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,8 @@ import { AuroraPostgresDriver } from "./AuroraPostgresDriver"
|
||||
import { PostgresQueryRunner } from "../postgres/PostgresQueryRunner"
|
||||
import { ReplicationMode } from "../types/ReplicationMode"
|
||||
import { QueryResult } from "../../query-runner/QueryResult"
|
||||
import { Table } from "../../schema-builder/table/Table"
|
||||
import { TypeORMError } from "../../error"
|
||||
|
||||
class PostgresQueryRunnerWrapper extends PostgresQueryRunner {
|
||||
driver: any
|
||||
@ -194,4 +196,16 @@ export class AuroraPostgresQueryRunner
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Change table comment.
|
||||
*/
|
||||
changeTableComment(
|
||||
tableOrName: Table | string,
|
||||
comment?: string,
|
||||
): Promise<void> {
|
||||
throw new TypeORMError(
|
||||
`aurora-postgres driver does not support change comment.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -4211,4 +4211,15 @@ export class CockroachQueryRunner
|
||||
|
||||
return c
|
||||
}
|
||||
/**
|
||||
* Change table comment.
|
||||
*/
|
||||
changeTableComment(
|
||||
tableOrName: Table | string,
|
||||
comment?: string,
|
||||
): Promise<void> {
|
||||
throw new TypeORMError(
|
||||
`cockroachdb driver does not support change table comment.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1263,4 +1263,16 @@ export class MongoQueryRunner implements QueryRunner {
|
||||
.db(this.connection.driver.database!)
|
||||
.collection(collectionName)
|
||||
}
|
||||
|
||||
/**
|
||||
* Change table comment.
|
||||
*/
|
||||
changeTableComment(
|
||||
tableOrName: Table | string,
|
||||
comment?: string,
|
||||
): Promise<void> {
|
||||
throw new TypeORMError(
|
||||
`mongodb driver does not support change table comment.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -746,6 +746,49 @@ export class MysqlQueryRunner extends BaseQueryRunner implements QueryRunner {
|
||||
this.replaceCachedTable(oldTable, newTable)
|
||||
}
|
||||
|
||||
/**
|
||||
* Change table comment.
|
||||
*/
|
||||
async changeTableComment(
|
||||
tableOrName: Table | string,
|
||||
newComment?: string,
|
||||
): Promise<void> {
|
||||
const upQueries: Query[] = []
|
||||
const downQueries: Query[] = []
|
||||
|
||||
const table = InstanceChecker.isTable(tableOrName)
|
||||
? tableOrName
|
||||
: await this.getCachedTable(tableOrName)
|
||||
|
||||
newComment = this.escapeComment(newComment)
|
||||
const comment = this.escapeComment(table.comment)
|
||||
|
||||
if (newComment === comment) {
|
||||
return
|
||||
}
|
||||
|
||||
const newTable = table.clone()
|
||||
|
||||
upQueries.push(
|
||||
new Query(
|
||||
`ALTER TABLE ${this.escapePath(
|
||||
newTable,
|
||||
)} COMMENT ${newComment}`,
|
||||
),
|
||||
)
|
||||
downQueries.push(
|
||||
new Query(
|
||||
`ALTER TABLE ${this.escapePath(table)} COMMENT ${comment}`,
|
||||
),
|
||||
)
|
||||
|
||||
await this.executeQueries(upQueries, downQueries)
|
||||
|
||||
// change table comment and replace it in cached tabled;
|
||||
table.comment = newTable.comment
|
||||
this.replaceCachedTable(table, newTable)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new column from the column in the table.
|
||||
*/
|
||||
@ -2346,11 +2389,15 @@ export class MysqlQueryRunner extends BaseQueryRunner implements QueryRunner {
|
||||
// will cause the query to not hit the optimizations & do full scans. This is why
|
||||
// a number of queries below do `UNION`s of single `WHERE` clauses.
|
||||
|
||||
const dbTables: { TABLE_SCHEMA: string; TABLE_NAME: string }[] = []
|
||||
const dbTables: {
|
||||
TABLE_SCHEMA: string
|
||||
TABLE_NAME: string
|
||||
TABLE_COMMENT: string
|
||||
}[] = []
|
||||
|
||||
if (!tableNames) {
|
||||
// Since we don't have any of this data we have to do a scan
|
||||
const tablesSql = `SELECT \`TABLE_SCHEMA\`, \`TABLE_NAME\` FROM \`INFORMATION_SCHEMA\`.\`TABLES\``
|
||||
const tablesSql = `SELECT \`TABLE_SCHEMA\`, \`TABLE_NAME\`, \`TABLE_COMMENT\` FROM \`INFORMATION_SCHEMA\`.\`TABLES\``
|
||||
|
||||
dbTables.push(...(await this.query(tablesSql)))
|
||||
} else {
|
||||
@ -2367,7 +2414,7 @@ export class MysqlQueryRunner extends BaseQueryRunner implements QueryRunner {
|
||||
database = currentDatabase
|
||||
}
|
||||
|
||||
return `SELECT \`TABLE_SCHEMA\`, \`TABLE_NAME\` FROM \`INFORMATION_SCHEMA\`.\`TABLES\` WHERE \`TABLE_SCHEMA\` = '${database}' AND \`TABLE_NAME\` = '${name}'`
|
||||
return `SELECT \`TABLE_SCHEMA\`, \`TABLE_NAME\`, \`TABLE_COMMENT\` FROM \`INFORMATION_SCHEMA\`.\`TABLES\` WHERE \`TABLE_SCHEMA\` = '${database}' AND \`TABLE_NAME\` = '${name}'`
|
||||
})
|
||||
.join(" UNION ")
|
||||
|
||||
@ -2925,6 +2972,8 @@ export class MysqlQueryRunner extends BaseQueryRunner implements QueryRunner {
|
||||
})
|
||||
})
|
||||
|
||||
table.comment = dbTable["TABLE_COMMENT"]
|
||||
|
||||
return table
|
||||
}),
|
||||
)
|
||||
@ -3058,6 +3107,10 @@ export class MysqlQueryRunner extends BaseQueryRunner implements QueryRunner {
|
||||
|
||||
sql += `) ENGINE=${table.engine || "InnoDB"}`
|
||||
|
||||
if (table.comment) {
|
||||
sql += ` COMMENT="${table.comment}"`
|
||||
}
|
||||
|
||||
return new Query(sql)
|
||||
}
|
||||
|
||||
|
||||
@ -3181,4 +3181,16 @@ export class OracleQueryRunner extends BaseQueryRunner implements QueryRunner {
|
||||
|
||||
return `"${tableName}"`
|
||||
}
|
||||
|
||||
/**
|
||||
* Change table comment.
|
||||
*/
|
||||
changeTableComment(
|
||||
tableOrName: Table | string,
|
||||
comment?: string,
|
||||
): Promise<void> {
|
||||
throw new TypeORMError(
|
||||
`oracle driver does not support change table comment.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -4717,4 +4717,16 @@ export class PostgresQueryRunner
|
||||
)
|
||||
return result.length ? true : false
|
||||
}
|
||||
|
||||
/**
|
||||
* Change table comment.
|
||||
*/
|
||||
changeTableComment(
|
||||
tableOrName: Table | string,
|
||||
comment?: string,
|
||||
): Promise<void> {
|
||||
throw new TypeORMError(
|
||||
`postgres driver does not support change table comment.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -3354,4 +3354,16 @@ export class SapQueryRunner extends BaseQueryRunner implements QueryRunner {
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
/**
|
||||
* Change table comment.
|
||||
*/
|
||||
changeTableComment(
|
||||
tableOrName: Table | string,
|
||||
comment?: string,
|
||||
): Promise<void> {
|
||||
throw new TypeORMError(
|
||||
`spa driver does not support change table comment.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2227,4 +2227,16 @@ export class SpannerQueryRunner extends BaseQueryRunner implements QueryRunner {
|
||||
query.startsWith("DELETE")
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Change table comment.
|
||||
*/
|
||||
changeTableComment(
|
||||
tableOrName: Table | string,
|
||||
comment?: string,
|
||||
): Promise<void> {
|
||||
throw new TypeORMError(
|
||||
`spanner driver does not support change table comment.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2242,4 +2242,14 @@ export abstract class AbstractSqliteQueryRunner
|
||||
.map((i) => (disableEscape ? i : `"${i}"`))
|
||||
.join(".")
|
||||
}
|
||||
|
||||
/**
|
||||
* Change table comment.
|
||||
*/
|
||||
changeTableComment(
|
||||
tableOrName: Table | string,
|
||||
comment?: string,
|
||||
): Promise<void> {
|
||||
throw new TypeORMError(`sqlit driver does not support change comment.`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -4161,4 +4161,16 @@ export class SqlServerQueryRunner
|
||||
return ISOLATION_LEVEL.READ_COMMITTED
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change table comment.
|
||||
*/
|
||||
changeTableComment(
|
||||
tableOrName: Table | string,
|
||||
comment?: string,
|
||||
): Promise<void> {
|
||||
throw new TypeORMError(
|
||||
`sqlserver driver does not support change table comment.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,4 +70,9 @@ export interface TableMetadataArgs {
|
||||
* an integer primary key column named 'rowid' on table creation.
|
||||
*/
|
||||
withoutRowid?: boolean
|
||||
|
||||
/**
|
||||
* Table comment. Not supported by all database types.
|
||||
*/
|
||||
comment?: string
|
||||
}
|
||||
|
||||
@ -516,6 +516,11 @@ export class EntityMetadata {
|
||||
*/
|
||||
propertiesMap: ObjectLiteral
|
||||
|
||||
/**
|
||||
* Table comment. Not supported by all database types.
|
||||
*/
|
||||
comment?: string
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ---------------------------------------------------------------------
|
||||
@ -1065,6 +1070,8 @@ export class EntityMetadata {
|
||||
this.tableMetadataArgs.type === "junction"
|
||||
this.isClosureJunction =
|
||||
this.tableMetadataArgs.type === "closure-junction"
|
||||
|
||||
this.comment = this.tableMetadataArgs.comment
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -320,6 +320,7 @@ export abstract class BaseQueryRunner {
|
||||
foundTable.checks = changedTable.checks
|
||||
foundTable.justCreated = changedTable.justCreated
|
||||
foundTable.engine = changedTable.engine
|
||||
foundTable.comment = changedTable.comment
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -271,6 +271,14 @@ export interface QueryRunner {
|
||||
newTableName: string,
|
||||
): Promise<void>
|
||||
|
||||
/**
|
||||
* Change table comment. Only supports MySQL and MariaDB
|
||||
*/
|
||||
changeTableComment(
|
||||
tableOrName: Table | string,
|
||||
comment?: string,
|
||||
): Promise<void>
|
||||
|
||||
/**
|
||||
* Adds a new column.
|
||||
*/
|
||||
|
||||
@ -221,6 +221,7 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {
|
||||
await this.dropCompositeUniqueConstraints()
|
||||
// await this.renameTables();
|
||||
await this.renameColumns()
|
||||
await this.changeTableComment()
|
||||
await this.createNewTables()
|
||||
await this.dropRemovedColumns()
|
||||
await this.addNewColumns()
|
||||
@ -590,6 +591,24 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change table comment
|
||||
*/
|
||||
protected async changeTableComment(): Promise<void> {
|
||||
for (const metadata of this.entityToSyncMetadatas) {
|
||||
const table = this.queryRunner.loadedTables.find(
|
||||
(table) =>
|
||||
this.getTablePath(table) === this.getTablePath(metadata),
|
||||
)
|
||||
if (!table) continue
|
||||
|
||||
if (DriverUtils.isMySQLFamily(this.connection.driver)) {
|
||||
const newComment = metadata.comment
|
||||
await this.queryRunner.changeTableComment(table, newComment)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates tables that do not exist in the database yet.
|
||||
* New tables are created without foreign and primary keys.
|
||||
|
||||
@ -74,4 +74,9 @@ export interface TableOptions {
|
||||
* Table engine.
|
||||
*/
|
||||
engine?: string
|
||||
|
||||
/**
|
||||
* Table comment. Not supported by all database types.
|
||||
*/
|
||||
comment?: string
|
||||
}
|
||||
|
||||
@ -83,6 +83,11 @@ export class Table {
|
||||
*/
|
||||
engine?: string
|
||||
|
||||
/**
|
||||
* Table comment. Not supported by all database types.
|
||||
*/
|
||||
comment?: string
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
@ -137,6 +142,8 @@ export class Table {
|
||||
if (options.withoutRowid) this.withoutRowid = options.withoutRowid
|
||||
|
||||
this.engine = options.engine
|
||||
|
||||
this.comment = options.comment
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,6 +178,7 @@ export class Table {
|
||||
justCreated: this.justCreated,
|
||||
withoutRowid: this.withoutRowid,
|
||||
engine: this.engine,
|
||||
comment: this.comment,
|
||||
})
|
||||
}
|
||||
|
||||
@ -411,6 +419,7 @@ export class Table {
|
||||
exclusions: entityMetadata.exclusions.map((exclusion) =>
|
||||
TableExclusion.create(exclusion),
|
||||
),
|
||||
comment: entityMetadata.comment,
|
||||
}
|
||||
|
||||
return new Table(options)
|
||||
|
||||
8
test/github-issues/9991/entity/ExampleEntity.ts
Normal file
8
test/github-issues/9991/entity/ExampleEntity.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { Entity } from "../../../../src/decorator/entity/Entity"
|
||||
import { PrimaryGeneratedColumn } from "../../../../src/decorator/columns/PrimaryGeneratedColumn"
|
||||
|
||||
@Entity({ name: "example", comment: "table comment" })
|
||||
export class ExampleEntity {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number
|
||||
}
|
||||
86
test/github-issues/9991/issue-9991.ts
Normal file
86
test/github-issues/9991/issue-9991.ts
Normal file
@ -0,0 +1,86 @@
|
||||
import { DataSource } from "../../../src"
|
||||
import {
|
||||
closeTestingConnections,
|
||||
createTestingConnections,
|
||||
reloadTestingDatabases,
|
||||
} from "../../utils/test-utils"
|
||||
import { ExampleEntity } from "./entity/ExampleEntity"
|
||||
import { expect } from "chai"
|
||||
|
||||
describe("github issues > #9991", () => {
|
||||
let dataSources: DataSource[]
|
||||
|
||||
before(async () => {
|
||||
dataSources = await createTestingConnections({
|
||||
entities: [ExampleEntity],
|
||||
enabledDrivers: ["mysql", "mariadb"],
|
||||
})
|
||||
})
|
||||
|
||||
beforeEach(() => reloadTestingDatabases(dataSources))
|
||||
after(() => closeTestingConnections(dataSources))
|
||||
|
||||
it("add table comment", async () => {
|
||||
await Promise.all(
|
||||
dataSources.map(async (dataSource) => {
|
||||
const sql =
|
||||
'SELECT `TABLE_COMMENT` FROM `INFORMATION_SCHEMA`.`TABLES` WHERE TABLE_NAME = "example"'
|
||||
|
||||
const result = await dataSource.manager.query(sql)
|
||||
expect(result).to.be.eql([{ TABLE_COMMENT: "table comment" }])
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it("should correctly change table comment and change", async () => {
|
||||
await Promise.all(
|
||||
dataSources.map(async (dataSource) => {
|
||||
const queryRunner = dataSource.createQueryRunner()
|
||||
let table = await queryRunner.getTable("example")
|
||||
|
||||
await queryRunner.changeTableComment(
|
||||
table!,
|
||||
"new table comment",
|
||||
)
|
||||
const sql =
|
||||
'SELECT `TABLE_COMMENT` FROM `INFORMATION_SCHEMA`.`TABLES` WHERE TABLE_NAME = "example"'
|
||||
|
||||
let result = await dataSource.manager.query(sql)
|
||||
expect(result).to.be.eql([
|
||||
{ TABLE_COMMENT: "new table comment" },
|
||||
])
|
||||
|
||||
// revert changes
|
||||
await queryRunner.executeMemoryDownSql()
|
||||
|
||||
result = await dataSource.manager.query(sql)
|
||||
expect(result).to.be.eql([{ TABLE_COMMENT: "table comment" }])
|
||||
|
||||
await queryRunner.release()
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it("should correctly synchronize when table comment change", async () => {
|
||||
await Promise.all(
|
||||
dataSources.map(async (dataSource) => {
|
||||
const queryRunner = dataSource.createQueryRunner()
|
||||
|
||||
const exampleMetadata = dataSource.getMetadata(ExampleEntity)
|
||||
exampleMetadata.comment = "change table comment"
|
||||
|
||||
await dataSource.synchronize()
|
||||
|
||||
const sql =
|
||||
'SELECT `TABLE_COMMENT` FROM `INFORMATION_SCHEMA`.`TABLES` WHERE TABLE_NAME = "example"'
|
||||
|
||||
const result = await dataSource.manager.query(sql)
|
||||
expect(result).to.be.eql([
|
||||
{ TABLE_COMMENT: "change table comment" },
|
||||
])
|
||||
|
||||
await queryRunner.release()
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
Loading…
x
Reference in New Issue
Block a user