postgres implementation
This commit is contained in:
parent
9c546dfdef
commit
6d4a97d39a
@ -11,6 +11,10 @@ import IndexColumnInfo from "../oldModels/IndexColumnInfo";
|
||||
import RelationTempInfo from "../oldModels/RelationTempInfo";
|
||||
import IConnectionOptions from "../IConnectionOptions";
|
||||
import { Entity } from "../models/Entity";
|
||||
import { Column } from "../models/Column";
|
||||
import { Index } from "../models/Index";
|
||||
import IGenerationOptions from "../IGenerationOptions";
|
||||
import { RelationInternal } from "../models/RelationInternal";
|
||||
|
||||
export default class PostgresDriver extends AbstractDriver {
|
||||
public defaultValues: DataTypeDefaults = new TypeormDriver.PostgresDriver({
|
||||
@ -40,125 +44,131 @@ export default class PostgresDriver extends AbstractDriver {
|
||||
entities: Entity[],
|
||||
schema: string
|
||||
): Promise<Entity[]> {
|
||||
throw new Error();
|
||||
// TODO: Remove
|
||||
// const response: {
|
||||
// table_name: string;
|
||||
// column_name: string;
|
||||
// udt_name: string;
|
||||
// column_default: string;
|
||||
// is_nullable: string;
|
||||
// data_type: string;
|
||||
// character_maximum_length: number;
|
||||
// numeric_precision: number;
|
||||
// numeric_scale: number;
|
||||
// isidentity: string;
|
||||
// isunique: string;
|
||||
// enumvalues: string | null;
|
||||
// }[] = (await this.Connection
|
||||
// .query(`SELECT table_name,column_name,udt_name,column_default,is_nullable,
|
||||
// data_type,character_maximum_length,numeric_precision,numeric_scale,
|
||||
// case when column_default LIKE 'nextval%' then 'YES' else 'NO' end isidentity,
|
||||
// (SELECT count(*)
|
||||
// FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
|
||||
// inner join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cu
|
||||
// on cu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
|
||||
// where
|
||||
// tc.CONSTRAINT_TYPE = 'UNIQUE'
|
||||
// and tc.TABLE_NAME = c.TABLE_NAME
|
||||
// and cu.COLUMN_NAME = c.COLUMN_NAME
|
||||
// and tc.TABLE_SCHEMA=c.TABLE_SCHEMA) IsUnique,
|
||||
// (SELECT
|
||||
// string_agg(enumlabel, ',')
|
||||
// FROM "pg_enum" "e"
|
||||
// INNER JOIN "pg_type" "t" ON "t"."oid" = "e"."enumtypid"
|
||||
// INNER JOIN "pg_namespace" "n" ON "n"."oid" = "t"."typnamespace"
|
||||
// WHERE "n"."nspname" = table_schema AND "t"."typname"=udt_name
|
||||
// ) enumValues
|
||||
// FROM INFORMATION_SCHEMA.COLUMNS c
|
||||
// where table_schema in (${schema})
|
||||
// order by ordinal_position`)).rows;
|
||||
// entities.forEach(ent => {
|
||||
// response
|
||||
// .filter(filterVal => filterVal.table_name === ent.tsEntityName)
|
||||
// .forEach(resp => {
|
||||
// const colInfo: ColumnInfo = new ColumnInfo();
|
||||
// colInfo.tsName = resp.column_name;
|
||||
// colInfo.options.name = resp.column_name;
|
||||
// colInfo.options.nullable = resp.is_nullable === "YES";
|
||||
// colInfo.options.generated = resp.isidentity === "YES";
|
||||
// colInfo.options.unique = resp.isunique === "1";
|
||||
// colInfo.options.default = colInfo.options.generated
|
||||
// ? null
|
||||
// : PostgresDriver.ReturnDefaultValueFunction(
|
||||
// resp.column_default
|
||||
// );
|
||||
const response: {
|
||||
table_name: string;
|
||||
column_name: string;
|
||||
udt_name: string;
|
||||
column_default: string;
|
||||
is_nullable: string;
|
||||
data_type: string;
|
||||
character_maximum_length: number;
|
||||
numeric_precision: number;
|
||||
numeric_scale: number;
|
||||
isidentity: string;
|
||||
isunique: string;
|
||||
enumvalues: string | null;
|
||||
}[] = (await this.Connection
|
||||
.query(`SELECT table_name,column_name,udt_name,column_default,is_nullable,
|
||||
data_type,character_maximum_length,numeric_precision,numeric_scale,
|
||||
case when column_default LIKE 'nextval%' then 'YES' else 'NO' end isidentity,
|
||||
(SELECT count(*)
|
||||
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
|
||||
inner join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cu
|
||||
on cu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
|
||||
where
|
||||
tc.CONSTRAINT_TYPE = 'UNIQUE'
|
||||
and tc.TABLE_NAME = c.TABLE_NAME
|
||||
and cu.COLUMN_NAME = c.COLUMN_NAME
|
||||
and tc.TABLE_SCHEMA=c.TABLE_SCHEMA) IsUnique,
|
||||
(SELECT
|
||||
string_agg(enumlabel, ',')
|
||||
FROM "pg_enum" "e"
|
||||
INNER JOIN "pg_type" "t" ON "t"."oid" = "e"."enumtypid"
|
||||
INNER JOIN "pg_namespace" "n" ON "n"."oid" = "t"."typnamespace"
|
||||
WHERE "n"."nspname" = table_schema AND "t"."typname"=udt_name
|
||||
) enumValues
|
||||
FROM INFORMATION_SCHEMA.COLUMNS c
|
||||
where table_schema in (${schema})
|
||||
order by ordinal_position`)).rows;
|
||||
entities.forEach(ent => {
|
||||
response
|
||||
.filter(filterVal => filterVal.table_name === ent.tscName)
|
||||
.forEach(resp => {
|
||||
const tscName = resp.column_name;
|
||||
const options: Partial<Column["options"]> = {};
|
||||
options.name = resp.column_name;
|
||||
if (resp.is_nullable === "YES") options.nullable = true;
|
||||
if (resp.isunique === "1") options.unique = true;
|
||||
|
||||
// const columnTypes = this.MatchColumnTypes(
|
||||
// resp.data_type,
|
||||
// resp.udt_name,
|
||||
// resp.enumvalues
|
||||
// );
|
||||
// if (!columnTypes.sqlType || !columnTypes.tsType) {
|
||||
// if (
|
||||
// resp.data_type === "USER-DEFINED" ||
|
||||
// resp.data_type === "ARRAY"
|
||||
// ) {
|
||||
// TomgUtils.LogError(
|
||||
// `Unknown ${resp.data_type} column type: ${resp.udt_name} table name: ${resp.table_name} column name: ${resp.column_name}`
|
||||
// );
|
||||
// } else {
|
||||
// TomgUtils.LogError(
|
||||
// `Unknown column type: ${resp.data_type} table name: ${resp.table_name} column name: ${resp.column_name}`
|
||||
// );
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
// colInfo.options.type = columnTypes.sqlType as any;
|
||||
// colInfo.tsType = columnTypes.tsType;
|
||||
// colInfo.options.array = columnTypes.isArray;
|
||||
// colInfo.options.enum = columnTypes.enumValues;
|
||||
// if (colInfo.options.array) {
|
||||
// colInfo.tsType = colInfo.tsType
|
||||
// .split("|")
|
||||
// .map(x => `${x.replace("|", "").trim()}[]`)
|
||||
// .join(" | ") as any;
|
||||
// }
|
||||
const generated =
|
||||
resp.isidentity === "YES" ? true : undefined;
|
||||
const defaultValue = generated
|
||||
? undefined
|
||||
: PostgresDriver.ReturnDefaultValueFunction(
|
||||
resp.column_default
|
||||
);
|
||||
|
||||
// if (
|
||||
// this.ColumnTypesWithPrecision.some(
|
||||
// v => v === colInfo.options.type
|
||||
// )
|
||||
// ) {
|
||||
// colInfo.options.precision = resp.numeric_precision;
|
||||
// colInfo.options.scale = resp.numeric_scale;
|
||||
// }
|
||||
// if (
|
||||
// this.ColumnTypesWithLength.some(
|
||||
// v => v === colInfo.options.type
|
||||
// )
|
||||
// ) {
|
||||
// colInfo.options.length =
|
||||
// resp.character_maximum_length > 0
|
||||
// ? resp.character_maximum_length
|
||||
// : undefined;
|
||||
// }
|
||||
// if (
|
||||
// this.ColumnTypesWithWidth.some(
|
||||
// v => v === colInfo.options.type
|
||||
// )
|
||||
// ) {
|
||||
// colInfo.options.width =
|
||||
// resp.character_maximum_length > 0
|
||||
// ? resp.character_maximum_length
|
||||
// : undefined;
|
||||
// }
|
||||
// if (colInfo.options.type && colInfo.tsType) {
|
||||
// ent.Columns.push(colInfo);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// return entities;
|
||||
const columnTypes = this.MatchColumnTypes(
|
||||
resp.data_type,
|
||||
resp.udt_name,
|
||||
resp.enumvalues
|
||||
);
|
||||
if (!columnTypes.sqlType || !columnTypes.tsType) {
|
||||
if (
|
||||
resp.data_type === "USER-DEFINED" ||
|
||||
resp.data_type === "ARRAY"
|
||||
) {
|
||||
TomgUtils.LogError(
|
||||
`Unknown ${resp.data_type} column type: ${resp.udt_name} table name: ${resp.table_name} column name: ${resp.column_name}`
|
||||
);
|
||||
} else {
|
||||
TomgUtils.LogError(
|
||||
`Unknown column type: ${resp.data_type} table name: ${resp.table_name} column name: ${resp.column_name}`
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const columnType = columnTypes.sqlType as any;
|
||||
let tscType = columnTypes.tsType;
|
||||
if (columnTypes.isArray) options.array = true;
|
||||
if (columnTypes.enumValues.length > 0)
|
||||
options.enum = columnTypes.enumValues;
|
||||
if (options.array) {
|
||||
tscType = tscType
|
||||
.split("|")
|
||||
.map(x => `${x.replace("|", "").trim()}[]`)
|
||||
.join(" | ") as any;
|
||||
}
|
||||
|
||||
if (
|
||||
this.ColumnTypesWithPrecision.some(
|
||||
v => v === columnType
|
||||
)
|
||||
) {
|
||||
if (resp.numeric_precision !== null) {
|
||||
options.precision = resp.numeric_precision;
|
||||
}
|
||||
if (resp.numeric_scale !== null) {
|
||||
options.scale = resp.numeric_scale;
|
||||
}
|
||||
}
|
||||
if (
|
||||
this.ColumnTypesWithLength.some(v => v === columnType)
|
||||
) {
|
||||
options.length =
|
||||
resp.character_maximum_length > 0
|
||||
? resp.character_maximum_length
|
||||
: undefined;
|
||||
}
|
||||
if (this.ColumnTypesWithWidth.some(v => v === columnType)) {
|
||||
options.width =
|
||||
resp.character_maximum_length > 0
|
||||
? resp.character_maximum_length
|
||||
: undefined;
|
||||
}
|
||||
if (columnType && tscType) {
|
||||
ent.columns.push({
|
||||
generated,
|
||||
type: columnType,
|
||||
default: defaultValue,
|
||||
options: { name: "", ...options }, // TODO: Change
|
||||
tscName,
|
||||
tscType
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
return entities;
|
||||
}
|
||||
|
||||
public MatchColumnTypes(
|
||||
@ -167,7 +177,7 @@ export default class PostgresDriver extends AbstractDriver {
|
||||
enumValues: string | null
|
||||
) {
|
||||
let ret: {
|
||||
tsType?: ColumnInfo["tsType"];
|
||||
tsType?: Column["tscType"];
|
||||
sqlType: string | null;
|
||||
isArray: boolean;
|
||||
enumValues: string[];
|
||||
@ -382,9 +392,7 @@ export default class PostgresDriver extends AbstractDriver {
|
||||
.split(",")
|
||||
.join('" | "')}"` as never) as string;
|
||||
ret.sqlType = "enum";
|
||||
ret.enumValues = (`"${enumValues
|
||||
.split(",")
|
||||
.join('","')}"` as never) as string[];
|
||||
ret.enumValues = enumValues.split(",");
|
||||
} else {
|
||||
ret.tsType = undefined;
|
||||
ret.sqlType = null;
|
||||
@ -404,152 +412,162 @@ export default class PostgresDriver extends AbstractDriver {
|
||||
entities: Entity[],
|
||||
schema: string
|
||||
): Promise<Entity[]> {
|
||||
throw new Error();
|
||||
// TODO: Remove
|
||||
// const response: {
|
||||
// tablename: string;
|
||||
// indexname: string;
|
||||
// columnname: string;
|
||||
// is_unique: number;
|
||||
// is_primary_key: number;
|
||||
// }[] = (await this.Connection.query(`SELECT
|
||||
// c.relname AS tablename,
|
||||
// i.relname as indexname,
|
||||
// f.attname AS columnname,
|
||||
// CASE
|
||||
// WHEN ix.indisunique = true THEN 1
|
||||
// ELSE 0
|
||||
// END AS is_unique,
|
||||
// CASE
|
||||
// WHEN ix.indisprimary='true' THEN 1
|
||||
// ELSE 0
|
||||
// END AS is_primary_key
|
||||
// FROM pg_attribute f
|
||||
// JOIN pg_class c ON c.oid = f.attrelid
|
||||
// JOIN pg_type t ON t.oid = f.atttypid
|
||||
// LEFT JOIN pg_attrdef d ON d.adrelid = c.oid AND d.adnum = f.attnum
|
||||
// LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
|
||||
// LEFT JOIN pg_index AS ix ON f.attnum = ANY(ix.indkey) and c.oid = f.attrelid and c.oid = ix.indrelid
|
||||
// LEFT JOIN pg_class AS i ON ix.indexrelid = i.oid
|
||||
// WHERE c.relkind = 'r'::char
|
||||
// AND n.nspname in (${schema})
|
||||
// AND f.attnum > 0
|
||||
// AND i.oid<>0
|
||||
// ORDER BY c.relname,f.attname;`)).rows;
|
||||
// entities.forEach(ent => {
|
||||
// response
|
||||
// .filter(filterVal => filterVal.tablename === ent.tsEntityName)
|
||||
// .forEach(resp => {
|
||||
// let indexInfo: IndexInfo = {} as IndexInfo;
|
||||
// const indexColumnInfo: IndexColumnInfo = {} as IndexColumnInfo;
|
||||
// if (
|
||||
// ent.Indexes.filter(
|
||||
// filterVal => filterVal.name === resp.indexname
|
||||
// ).length > 0
|
||||
// ) {
|
||||
// indexInfo = ent.Indexes.find(
|
||||
// filterVal => filterVal.name === resp.indexname
|
||||
// )!;
|
||||
// } else {
|
||||
// indexInfo.columns = [] as IndexColumnInfo[];
|
||||
// indexInfo.name = resp.indexname;
|
||||
// indexInfo.isUnique = resp.is_unique === 1;
|
||||
// indexInfo.isPrimaryKey = resp.is_primary_key === 1;
|
||||
// ent.Indexes.push(indexInfo);
|
||||
// }
|
||||
// indexColumnInfo.name = resp.columnname;
|
||||
// if (resp.is_primary_key === 0) {
|
||||
// indexInfo.isPrimaryKey = false;
|
||||
// }
|
||||
// indexInfo.columns.push(indexColumnInfo);
|
||||
// });
|
||||
// });
|
||||
const response: {
|
||||
tablename: string;
|
||||
indexname: string;
|
||||
columnname: string;
|
||||
is_unique: number;
|
||||
is_primary_key: number;
|
||||
}[] = (await this.Connection.query(`SELECT
|
||||
c.relname AS tablename,
|
||||
i.relname as indexname,
|
||||
f.attname AS columnname,
|
||||
CASE
|
||||
WHEN ix.indisunique = true THEN 1
|
||||
ELSE 0
|
||||
END AS is_unique,
|
||||
CASE
|
||||
WHEN ix.indisprimary='true' THEN 1
|
||||
ELSE 0
|
||||
END AS is_primary_key
|
||||
FROM pg_attribute f
|
||||
JOIN pg_class c ON c.oid = f.attrelid
|
||||
JOIN pg_type t ON t.oid = f.atttypid
|
||||
LEFT JOIN pg_attrdef d ON d.adrelid = c.oid AND d.adnum = f.attnum
|
||||
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
|
||||
LEFT JOIN pg_index AS ix ON f.attnum = ANY(ix.indkey) and c.oid = f.attrelid and c.oid = ix.indrelid
|
||||
LEFT JOIN pg_class AS i ON ix.indexrelid = i.oid
|
||||
WHERE c.relkind = 'r'::char
|
||||
AND n.nspname in (${schema})
|
||||
AND f.attnum > 0
|
||||
AND i.oid<>0
|
||||
ORDER BY c.relname,f.attname;`)).rows;
|
||||
entities.forEach(ent => {
|
||||
const entityIndices = response.filter(
|
||||
filterVal => filterVal.tablename === ent.tscName
|
||||
);
|
||||
const indexNames = new Set(entityIndices.map(v => v.indexname));
|
||||
indexNames.forEach(indexName => {
|
||||
const records = entityIndices.filter(
|
||||
v => v.indexname === indexName
|
||||
);
|
||||
const indexInfo: Index = {
|
||||
columns: [],
|
||||
options: {},
|
||||
name: records[0].indexname
|
||||
};
|
||||
if (records[0].is_primary_key === 1) indexInfo.primary = true;
|
||||
if (records[0].is_unique === 1) indexInfo.options.unique = true;
|
||||
records.forEach(record => {
|
||||
indexInfo.columns.push(record.columnname);
|
||||
});
|
||||
ent.indices.push(indexInfo);
|
||||
});
|
||||
});
|
||||
|
||||
// return entities;
|
||||
return entities;
|
||||
}
|
||||
|
||||
public async GetRelations(
|
||||
entities: Entity[],
|
||||
schema: string
|
||||
schema: string,
|
||||
dbNames: string,
|
||||
generationOptions: IGenerationOptions
|
||||
): Promise<Entity[]> {
|
||||
throw new Error();
|
||||
// TODO: Remove
|
||||
// const response: {
|
||||
// tablewithforeignkey: string;
|
||||
// fk_partno: number;
|
||||
// foreignkeycolumn: string;
|
||||
// tablereferenced: string;
|
||||
// foreignkeycolumnreferenced: string;
|
||||
// ondelete: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION";
|
||||
// onupdate: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION";
|
||||
// object_id: string;
|
||||
// // Distinct because of note in https://www.postgresql.org/docs/9.1/information-schema.html
|
||||
// }[] = (await this.Connection.query(`SELECT DISTINCT
|
||||
// con.relname AS tablewithforeignkey,
|
||||
// att.attnum as fk_partno,
|
||||
// att2.attname AS foreignkeycolumn,
|
||||
// cl.relname AS tablereferenced,
|
||||
// att.attname AS foreignkeycolumnreferenced,
|
||||
// delete_rule as ondelete,
|
||||
// update_rule as onupdate,
|
||||
// concat(con.conname,con.conrelid,con.confrelid) as object_id
|
||||
// FROM (
|
||||
// SELECT
|
||||
// unnest(con1.conkey) AS parent,
|
||||
// unnest(con1.confkey) AS child,
|
||||
// con1.confrelid,
|
||||
// con1.conrelid,
|
||||
// cl_1.relname,
|
||||
// con1.conname,
|
||||
// nspname
|
||||
// FROM
|
||||
// pg_class cl_1,
|
||||
// pg_namespace ns,
|
||||
// pg_constraint con1
|
||||
// WHERE
|
||||
// con1.contype = 'f'::"char"
|
||||
// AND cl_1.relnamespace = ns.oid
|
||||
// AND con1.conrelid = cl_1.oid
|
||||
// and nspname in (${schema})
|
||||
// ) con,
|
||||
// pg_attribute att,
|
||||
// pg_class cl,
|
||||
// pg_attribute att2,
|
||||
// information_schema.referential_constraints rc
|
||||
// WHERE
|
||||
// att.attrelid = con.confrelid
|
||||
// AND att.attnum = con.child
|
||||
// AND cl.oid = con.confrelid
|
||||
// AND att2.attrelid = con.conrelid
|
||||
// AND att2.attnum = con.parent
|
||||
// AND rc.constraint_name= con.conname AND constraint_catalog=current_database() AND rc.constraint_schema=nspname
|
||||
// `)).rows;
|
||||
// const relationsTemp: RelationTempInfo[] = [] as RelationTempInfo[];
|
||||
// response.forEach(resp => {
|
||||
// let rels = relationsTemp.find(
|
||||
// val => val.objectId === resp.object_id
|
||||
// );
|
||||
// if (rels === undefined) {
|
||||
// rels = {} as RelationTempInfo;
|
||||
// rels.ownerColumnsNames = [];
|
||||
// rels.referencedColumnsNames = [];
|
||||
// rels.actionOnDelete =
|
||||
// resp.ondelete === "NO ACTION" ? null : resp.ondelete;
|
||||
// rels.actionOnUpdate =
|
||||
// resp.onupdate === "NO ACTION" ? null : resp.onupdate;
|
||||
// rels.objectId = resp.object_id;
|
||||
// rels.ownerTable = resp.tablewithforeignkey;
|
||||
// rels.referencedTable = resp.tablereferenced;
|
||||
// relationsTemp.push(rels);
|
||||
// }
|
||||
// rels.ownerColumnsNames.push(resp.foreignkeycolumn);
|
||||
// rels.referencedColumnsNames.push(resp.foreignkeycolumnreferenced);
|
||||
// });
|
||||
// const retVal = PostgresDriver.GetRelationsFromRelationTempInfo(
|
||||
// relationsTemp,
|
||||
// entities
|
||||
// );
|
||||
// return retVal;
|
||||
const response: {
|
||||
tablewithforeignkey: string;
|
||||
fk_partno: number;
|
||||
foreignkeycolumn: string;
|
||||
tablereferenced: string;
|
||||
foreignkeycolumnreferenced: string;
|
||||
ondelete: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION";
|
||||
onupdate: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION";
|
||||
object_id: string;
|
||||
// Distinct because of note in https://www.postgresql.org/docs/9.1/information-schema.html
|
||||
}[] = (await this.Connection.query(`SELECT DISTINCT
|
||||
con.relname AS tablewithforeignkey,
|
||||
att.attnum as fk_partno,
|
||||
att2.attname AS foreignkeycolumn,
|
||||
cl.relname AS tablereferenced,
|
||||
att.attname AS foreignkeycolumnreferenced,
|
||||
delete_rule as ondelete,
|
||||
update_rule as onupdate,
|
||||
concat(con.conname,con.conrelid,con.confrelid) as object_id
|
||||
FROM (
|
||||
SELECT
|
||||
unnest(con1.conkey) AS parent,
|
||||
unnest(con1.confkey) AS child,
|
||||
con1.confrelid,
|
||||
con1.conrelid,
|
||||
cl_1.relname,
|
||||
con1.conname,
|
||||
nspname
|
||||
FROM
|
||||
pg_class cl_1,
|
||||
pg_namespace ns,
|
||||
pg_constraint con1
|
||||
WHERE
|
||||
con1.contype = 'f'::"char"
|
||||
AND cl_1.relnamespace = ns.oid
|
||||
AND con1.conrelid = cl_1.oid
|
||||
and nspname in (${schema})
|
||||
) con,
|
||||
pg_attribute att,
|
||||
pg_class cl,
|
||||
pg_attribute att2,
|
||||
information_schema.referential_constraints rc
|
||||
WHERE
|
||||
att.attrelid = con.confrelid
|
||||
AND att.attnum = con.child
|
||||
AND cl.oid = con.confrelid
|
||||
AND att2.attrelid = con.conrelid
|
||||
AND att2.attnum = con.parent
|
||||
AND rc.constraint_name= con.conname AND constraint_catalog=current_database() AND rc.constraint_schema=nspname
|
||||
`)).rows;
|
||||
|
||||
const relationsTemp: RelationInternal[] = [] as RelationInternal[];
|
||||
const relationKeys = new Set(response.map(v => v.object_id));
|
||||
|
||||
relationKeys.forEach(relationId => {
|
||||
const rows = response.filter(v => v.object_id === relationId);
|
||||
const ownerTable = entities.find(
|
||||
v => v.sqlName === rows[0].tablewithforeignkey
|
||||
);
|
||||
const relatedTable = entities.find(
|
||||
v => v.sqlName === rows[0].tablereferenced
|
||||
);
|
||||
if (!ownerTable || !relatedTable) {
|
||||
TomgUtils.LogError(
|
||||
`Relation between tables ${rows[0].tablewithforeignkey} and ${rows[0].tablereferenced} wasn't found in entity model.`,
|
||||
true
|
||||
);
|
||||
return;
|
||||
}
|
||||
const internal: RelationInternal = {
|
||||
ownerColumns: [],
|
||||
relatedColumns: [],
|
||||
ownerTable,
|
||||
relatedTable
|
||||
};
|
||||
if (rows[0].ondelete !== "NO ACTION") {
|
||||
internal.onDelete = rows[0].ondelete;
|
||||
}
|
||||
if (rows[0].onupdate !== "NO ACTION") {
|
||||
internal.onUpdate = rows[0].onupdate;
|
||||
}
|
||||
rows.forEach(row => {
|
||||
internal.ownerColumns.push(row.foreignkeycolumn);
|
||||
internal.relatedColumns.push(row.foreignkeycolumnreferenced);
|
||||
});
|
||||
relationsTemp.push(internal);
|
||||
});
|
||||
|
||||
const retVal = PostgresDriver.GetRelationsFromRelationTempInfo(
|
||||
relationsTemp,
|
||||
entities,
|
||||
generationOptions
|
||||
);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public async DisconnectFromServer() {
|
||||
@ -623,10 +641,10 @@ export default class PostgresDriver extends AbstractDriver {
|
||||
|
||||
private static ReturnDefaultValueFunction(
|
||||
defVal: string | null
|
||||
): string | null {
|
||||
): string | undefined {
|
||||
let defaultValue = defVal;
|
||||
if (!defaultValue) {
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
defaultValue = defaultValue.replace(/'::[\w ]*/, "'");
|
||||
if (defaultValue.startsWith(`'`)) {
|
||||
|
@ -81,7 +81,7 @@ export class Post {
|
||||
varbit: string;
|
||||
|
||||
@Column("bit varying")
|
||||
bit_varying: string;
|
||||
bitVarying: string;
|
||||
|
||||
@Column("timetz")
|
||||
timetz: string;
|
||||
@ -93,10 +93,10 @@ export class Post {
|
||||
timestamp: Date;
|
||||
|
||||
@Column("timestamp without time zone")
|
||||
timestamp_without_time_zone: Date;
|
||||
timestampWithoutTimeZone: Date;
|
||||
|
||||
@Column("timestamp with time zone")
|
||||
timestamp_with_time_zone: Date;
|
||||
timestampWithTimeZone: Date;
|
||||
|
||||
@Column("date")
|
||||
date: string;
|
||||
@ -104,10 +104,10 @@ export class Post {
|
||||
@Column("time")
|
||||
time: string;
|
||||
@Column("time without time zone")
|
||||
time_without_time_zone: string;
|
||||
timeWithoutTimeZone: string;
|
||||
|
||||
@Column("time with time zone")
|
||||
time_with_time_zone: string;
|
||||
timeWithTimeZone: string;
|
||||
|
||||
@Column("interval")
|
||||
interval: any;
|
||||
|
@ -2,7 +2,6 @@ import { Entity, PrimaryColumn, Column } from "typeorm";
|
||||
|
||||
@Entity("PostArrays")
|
||||
export class PostArrays {
|
||||
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@ -82,7 +81,7 @@ export class PostArrays {
|
||||
varbit: string[];
|
||||
|
||||
@Column("bit varying", { array: true })
|
||||
bit_varying: string[];
|
||||
bitVarying: string[];
|
||||
|
||||
@Column("timetz", { array: true })
|
||||
timetz: string[];
|
||||
@ -97,7 +96,7 @@ export class PostArrays {
|
||||
// timestamp_without_time_zone: Date[];
|
||||
|
||||
@Column("timestamp with time zone", { array: true })
|
||||
timestamp_with_time_zone: Date[];
|
||||
timestampWithTimeZone: Date[];
|
||||
|
||||
@Column("date", { array: true })
|
||||
date: string[];
|
||||
@ -105,10 +104,10 @@ export class PostArrays {
|
||||
@Column("time", { array: true })
|
||||
time: string[];
|
||||
@Column("time without time zone", { array: true })
|
||||
time_without_time_zone: string[];
|
||||
timeWithoutTimeZone: string[];
|
||||
|
||||
@Column("time with time zone", { array: true })
|
||||
time_with_time_zone: string[];
|
||||
timeWithTimeZone: string[];
|
||||
|
||||
@Column("interval", { array: true })
|
||||
interval: any[];
|
||||
@ -187,5 +186,4 @@ export class PostArrays {
|
||||
|
||||
@Column("daterange", { array: true })
|
||||
daterange: string[];
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user