@@ -326,7 +326,7 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
326
326
async createDatabase ( database : string , ifNotExist ?: boolean ) : Promise < void > {
327
327
if ( ifNotExist ) {
328
328
const databaseAlreadyExists = await this . hasDatabase ( database ) ;
329
-
329
+
330
330
if ( databaseAlreadyExists )
331
331
return Promise . resolve ( ) ;
332
332
}
@@ -1401,16 +1401,27 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
1401
1401
1402
1402
await this . startTransaction ( ) ;
1403
1403
try {
1404
+ // drop views
1404
1405
const selectViewDropsQuery = `SELECT 'DROP VIEW IF EXISTS "' || schemaname || '"."' || viewname || '" CASCADE;' as "query" ` +
1405
1406
`FROM "pg_views" WHERE "schemaname" IN (${ schemaNamesString } ) AND "viewname" NOT IN ('geography_columns', 'geometry_columns', 'raster_columns', 'raster_overviews')` ;
1406
1407
const dropViewQueries : ObjectLiteral [ ] = await this . query ( selectViewDropsQuery ) ;
1407
1408
await Promise . all ( dropViewQueries . map ( q => this . query ( q [ "query" ] ) ) ) ;
1408
1409
1410
+ // drop materialized views
1411
+ const selectMatViewDropsQuery = `SELECT 'DROP MATERIALIZED VIEW IF EXISTS "' || schemaname || '"."' || matviewname || '" CASCADE;' as "query" ` +
1412
+ `FROM "pg_matviews" WHERE "schemaname" IN (${ schemaNamesString } )` ;
1413
+ const dropMatViewQueries : ObjectLiteral [ ] = await this . query ( selectMatViewDropsQuery ) ;
1414
+ await Promise . all ( dropMatViewQueries . map ( q => this . query ( q [ "query" ] ) ) ) ;
1415
+
1409
1416
// ignore spatial_ref_sys; it's a special table supporting PostGIS
1410
1417
// TODO generalize this as this.driver.ignoreTables
1418
+
1419
+ // drop tables
1411
1420
const selectTableDropsQuery = `SELECT 'DROP TABLE IF EXISTS "' || schemaname || '"."' || tablename || '" CASCADE;' as "query" FROM "pg_tables" WHERE "schemaname" IN (${ schemaNamesString } ) AND "tablename" NOT IN ('spatial_ref_sys')` ;
1412
1421
const dropTableQueries : ObjectLiteral [ ] = await this . query ( selectTableDropsQuery ) ;
1413
1422
await Promise . all ( dropTableQueries . map ( q => this . query ( q [ "query" ] ) ) ) ;
1423
+
1424
+ // drop enum types
1414
1425
await this . dropEnumTypes ( schemaNamesString ) ;
1415
1426
1416
1427
await this . commitTransaction ( ) ;
@@ -1442,14 +1453,18 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
1442
1453
return `("t"."schema" = '${ schema } ' AND "t"."name" = '${ name } ')` ;
1443
1454
} ) . join ( " OR " ) ;
1444
1455
1445
- const query = `SELECT "t".*, "v"."check_option" FROM ${ this . escapePath ( this . getTypeormMetadataTableName ( ) ) } "t" ` +
1446
- `INNER JOIN "information_schema"."views" "v" ON "v"."table_schema" = "t"."schema" AND "v"."table_name" = "t"."name" WHERE "t"."type" = 'VIEW' ${ viewsCondition ? `AND (${ viewsCondition } )` : "" } ` ;
1456
+ const query = `SELECT "t".* FROM ${ this . escapePath ( this . getTypeormMetadataTableName ( ) ) } "t" ` +
1457
+ `INNER JOIN "pg_catalog"."pg_class" "c" ON "c"."relname" = "t"."name" ` +
1458
+ `INNER JOIN "pg_namespace" "n" ON "n"."oid" = "c"."relnamespace" AND "n"."nspname" = "t"."schema" ` +
1459
+ `WHERE "t"."type" IN ('VIEW', 'MATERIALIZED_VIEW') ${ viewsCondition ? `AND (${ viewsCondition } )` : "" } ` ;
1460
+
1447
1461
const dbViews = await this . query ( query ) ;
1448
1462
return dbViews . map ( ( dbView : any ) => {
1449
1463
const view = new View ( ) ;
1450
1464
const schema = dbView [ "schema" ] === currentSchema && ! this . driver . options . schema ? undefined : dbView [ "schema" ] ;
1451
1465
view . name = this . driver . buildTableName ( dbView [ "name" ] , schema ) ;
1452
1466
view . expression = dbView [ "value" ] ;
1467
+ view . materialized = dbView [ "type" ] === "MATERIALIZED_VIEW" ;
1453
1468
return view ;
1454
1469
} ) ;
1455
1470
}
@@ -1463,8 +1478,7 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
1463
1478
if ( ! tableNames || ! tableNames . length )
1464
1479
return [ ] ;
1465
1480
1466
- const currentSchemaQuery = await this . query ( `SELECT * FROM current_schema()` ) ;
1467
- const currentSchema : string = currentSchemaQuery [ 0 ] [ "current_schema" ] ;
1481
+ const currentSchema = await this . getCurrentSchema ( )
1468
1482
1469
1483
const tablesCondition = tableNames . map ( tableName => {
1470
1484
let [ schema , name ] = tableName . split ( "." ) ;
@@ -1918,8 +1932,7 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
1918
1932
}
1919
1933
1920
1934
protected async insertViewDefinitionSql ( view : View ) : Promise < Query > {
1921
- const currentSchemaQuery = await this . query ( `SELECT * FROM current_schema()` ) ;
1922
- const currentSchema = currentSchemaQuery [ 0 ] [ "current_schema" ] ;
1935
+ const currentSchema = await this . getCurrentSchema ( )
1923
1936
const splittedName = view . name . split ( "." ) ;
1924
1937
let schema = this . driver . options . schema || currentSchema ;
1925
1938
let name = view . name ;
@@ -1928,11 +1941,12 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
1928
1941
name = splittedName [ 1 ] ;
1929
1942
}
1930
1943
1944
+ const type = view . materialized ? "MATERIALIZED_VIEW" : "VIEW"
1931
1945
const expression = typeof view . expression === "string" ? view . expression . trim ( ) : view . expression ( this . connection ) . getQuery ( ) ;
1932
1946
const [ query , parameters ] = this . connection . createQueryBuilder ( )
1933
1947
. insert ( )
1934
1948
. into ( this . getTypeormMetadataTableName ( ) )
1935
- . values ( { type : "VIEW" , schema : schema , name : name , value : expression } )
1949
+ . values ( { type : type , schema : schema , name : name , value : expression } )
1936
1950
. getQueryAndParameters ( ) ;
1937
1951
1938
1952
return new Query ( query , parameters ) ;
@@ -1941,29 +1955,29 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
1941
1955
/**
1942
1956
* Builds drop view sql.
1943
1957
*/
1944
- protected dropViewSql ( viewOrPath : View | string ) : Query {
1945
- return new Query ( `DROP VIEW ${ this . escapePath ( viewOrPath ) } ` ) ;
1958
+ protected dropViewSql ( view : View ) : Query {
1959
+ const materializedClause = view . materialized ? "MATERIALIZED " : "" ;
1960
+ return new Query ( `DROP ${ materializedClause } VIEW ${ this . escapePath ( view ) } ` ) ;
1946
1961
}
1947
1962
1948
1963
/**
1949
1964
* Builds remove view sql.
1950
1965
*/
1951
- protected async deleteViewDefinitionSql ( viewOrPath : View | string ) : Promise < Query > {
1952
- const currentSchemaQuery = await this . query ( `SELECT * FROM current_schema()` ) ;
1953
- const currentSchema = currentSchemaQuery [ 0 ] [ "current_schema" ] ;
1954
- const viewName = viewOrPath instanceof View ? viewOrPath . name : viewOrPath ;
1955
- const splittedName = viewName . split ( "." ) ;
1966
+ protected async deleteViewDefinitionSql ( view : View ) : Promise < Query > {
1967
+ const currentSchema = await this . getCurrentSchema ( )
1968
+ const splittedName = view . name . split ( "." ) ;
1956
1969
let schema = this . driver . options . schema || currentSchema ;
1957
- let name = viewName ;
1970
+ let name = view . name ;
1958
1971
if ( splittedName . length === 2 ) {
1959
1972
schema = splittedName [ 0 ] ;
1960
1973
name = splittedName [ 1 ] ;
1961
1974
}
1962
1975
1976
+ const type = view . materialized ? "MATERIALIZED_VIEW" : "VIEW"
1963
1977
const qb = this . connection . createQueryBuilder ( ) ;
1964
1978
const [ query , parameters ] = qb . delete ( )
1965
1979
. from ( this . getTypeormMetadataTableName ( ) )
1966
- . where ( `${ qb . escape ( "type" ) } = 'VIEW'` )
1980
+ . where ( `${ qb . escape ( "type" ) } = :type` , { type } )
1967
1981
. andWhere ( `${ qb . escape ( "schema" ) } = :schema` , { schema } )
1968
1982
. andWhere ( `${ qb . escape ( "name" ) } = :name` , { name } )
1969
1983
. getQueryAndParameters ( ) ;
0 commit comments