Skip to content

Commit

Permalink
feat: add table comment for postgres (#10613)
Browse files Browse the repository at this point in the history
  • Loading branch information
kazu728 committed Jan 26, 2024
1 parent 8ebe769 commit 4493db4
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 9 deletions.
57 changes: 49 additions & 8 deletions src/driver/postgres/PostgresQueryRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,11 @@ export class PostgresQueryRunner
downQueries.push(this.dropIndexSql(table, index))
})
}

if (table.comment) {
upQueries.push(new Query("COMMENT ON TABLE " + this.escapePath(table) + " IS '" + table.comment + "'"));
downQueries.push(new Query("COMMENT ON TABLE " + this.escapePath(table) + " IS NULL"));
}

await this.executeQueries(upQueries, downQueries)
}
Expand Down Expand Up @@ -3276,10 +3281,14 @@ export class PostgresQueryRunner
const currentSchema = await this.getCurrentSchema()
const currentDatabase = await this.getCurrentDatabase()

const dbTables: { table_schema: string; table_name: string }[] = []
const dbTables: {
table_schema: string
table_name: string
table_comment: string
}[] = []

if (!tableNames) {
const tablesSql = `SELECT "table_schema", "table_name" FROM "information_schema"."tables"`
const tablesSql = `SELECT "table_schema", "table_name", obj_description(('"' || "table_schema" || '"."' || "table_name" || '"')::regclass, 'pg_class') AS table_comment FROM "information_schema"."tables"`
dbTables.push(...(await this.query(tablesSql)))
} else {
const tablesCondition = tableNames
Expand All @@ -3292,7 +3301,7 @@ export class PostgresQueryRunner
.join(" OR ")

const tablesSql =
`SELECT "table_schema", "table_name" FROM "information_schema"."tables" WHERE ` +
`SELECT "table_schema", "table_name", obj_description(('"' || "table_schema" || '"."' || "table_name" || '"')::regclass, 'pg_class') AS table_comment FROM "information_schema"."tables" WHERE ` +
tablesCondition
dbTables.push(...(await this.query(tablesSql)))
}
Expand Down Expand Up @@ -3416,6 +3425,7 @@ export class PostgresQueryRunner
const schema = getSchemaFromKey(dbTable, "table_schema")
table.database = currentDatabase
table.schema = dbTable["table_schema"]
table.comment = dbTable["table_comment"]
table.name = this.driver.buildTableName(
dbTable["table_name"],
schema,
Expand Down Expand Up @@ -4318,7 +4328,7 @@ export class PostgresQueryRunner
table: Table | View,
indexOrName: TableIndex | string,
): Query {
let indexName = InstanceChecker.isTableIndex(indexOrName)
const indexName = InstanceChecker.isTableIndex(indexOrName)
? indexOrName.name
: indexOrName
const concurrent = InstanceChecker.isTableIndex(indexOrName)
Expand Down Expand Up @@ -4721,12 +4731,43 @@ export class PostgresQueryRunner
/**
* Change table comment.
*/
changeTableComment(
async changeTableComment(
tableOrName: Table | string,
comment?: string,
newComment?: string,
): Promise<void> {
throw new TypeORMError(
`postgres driver does not support change table comment.`,
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(
`COMMENT ON TABLE ${this.escapePath(
newTable,
)} IS ${newComment}`,
),
)

downQueries.push(
new Query(
`COMMENT ON TABLE ${this.escapePath(table)} IS ${comment}`,
),
)

await this.executeQueries(upQueries, downQueries)

table.comment = newTable.comment
this.replaceCachedTable(table, newTable)
}
}
5 changes: 4 additions & 1 deletion src/schema-builder/RdbmsSchemaBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,10 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {
)
if (!table) continue

if (DriverUtils.isMySQLFamily(this.connection.driver)) {
if (
DriverUtils.isMySQLFamily(this.connection.driver) ||
this.connection.driver.options.type === 'postgres'
) {
const newComment = metadata.comment
await this.queryRunner.changeTableComment(table, newComment)
}
Expand Down
8 changes: 8 additions & 0 deletions test/github-issues/10612/entity/ExampleEntity.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 86 additions & 0 deletions test/github-issues/10612/issue-10612.ts
Original file line number Diff line number Diff line change
@@ -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 > #10612", () => {
let dataSources: DataSource[]

before(async () => {
dataSources = await createTestingConnections({
entities: [ExampleEntity],
enabledDrivers: ["postgres"],
})
})

beforeEach(() => reloadTestingDatabases(dataSources))
after(() => closeTestingConnections(dataSources))

it("add table comment", async () => {
await Promise.all(
dataSources.map(async (dataSource) => {
const sql =
"SELECT obj_description('example'::regclass::oid, 'pg_class') AS table_comment"

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()
const table = await queryRunner.getTable("example")

await queryRunner.changeTableComment(
table!,
"new table comment",
)
const sql =
"SELECT obj_description('example'::regclass::oid, 'pg_class') AS table_comment"

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 obj_description('example'::regclass::oid, 'pg_class') AS table_comment"

const result = await dataSource.manager.query(sql)
expect(result).to.be.eql([
{ table_comment: "change table comment" },
])

await queryRunner.release()
}),
)
})
})

0 comments on commit 4493db4

Please sign in to comment.