postgis - analyse geo columns, show in map

This commit is contained in:
Jan Prochazka
2022-06-11 22:21:09 +02:00
parent 34496ced0e
commit 2944d0fa39
5 changed files with 78 additions and 12 deletions

View File

@@ -11,21 +11,36 @@ function normalizeTypeName(dataType) {
return dataType; return dataType;
} }
function getColumnInfo({ function getColumnInfo(
is_nullable, { is_nullable, column_name, data_type, char_max_length, numeric_precision, numeric_ccale, default_value },
column_name, table = undefined,
data_type, geometryColumns = undefined,
char_max_length, geographyColumns = undefined
numeric_precision, ) {
numeric_ccale,
default_value,
}) {
const normDataType = normalizeTypeName(data_type); const normDataType = normalizeTypeName(data_type);
let fullDataType = normDataType; let fullDataType = normDataType;
if (char_max_length && isTypeString(normDataType)) fullDataType = `${normDataType}(${char_max_length})`; if (char_max_length && isTypeString(normDataType)) fullDataType = `${normDataType}(${char_max_length})`;
if (numeric_precision && numeric_ccale && isTypeNumeric(normDataType)) if (numeric_precision && numeric_ccale && isTypeNumeric(normDataType))
fullDataType = `${normDataType}(${numeric_precision},${numeric_ccale})`; fullDataType = `${normDataType}(${numeric_precision},${numeric_ccale})`;
const autoIncrement = !!(default_value && default_value.startsWith('nextval(')); const autoIncrement = !!(default_value && default_value.startsWith('nextval('));
if (
table &&
geometryColumns &&
geometryColumns.rows.find(
x => x.schema_name == table.schemaName && x.pure_name == table.pureName && x.column_name == column_name
)
) {
fullDataType = 'geometry';
}
if (
table &&
geographyColumns &&
geographyColumns.rows.find(
x => x.schema_name == table.schemaName && x.pure_name == table.pureName && x.column_name == column_name
)
) {
fullDataType = 'geography';
}
return { return {
columnName: column_name, columnName: column_name,
dataType: fullDataType, dataType: fullDataType,
@@ -145,6 +160,18 @@ class Analyser extends DatabaseAnalyser {
: await this.driver.query(this.pool, this.createQuery('indexcols', ['tables'])); : await this.driver.query(this.pool, this.createQuery('indexcols', ['tables']));
this.feedback({ analysingMessage: 'Loading unique names' }); this.feedback({ analysingMessage: 'Loading unique names' });
const uniqueNames = await this.driver.query(this.pool, this.createQuery('uniqueNames', ['tables'])); const uniqueNames = await this.driver.query(this.pool, this.createQuery('uniqueNames', ['tables']));
let geometryColumns = { rows: [] };
if (views.rows.find(x => (x.pure_name = 'geometry_columns' && x.schema_name == 'public'))) {
this.feedback({ analysingMessage: 'Loading geometry columns' });
geometryColumns = await this.driver.query(this.pool, this.createQuery('geometryColumns', ['tables']));
}
let geographyColumns = { rows: [] };
if (views.rows.find(x => (x.pure_name = 'geography_columns' && x.schema_name == 'public'))) {
this.feedback({ analysingMessage: 'Loading geography columns' });
geographyColumns = await this.driver.query(this.pool, this.createQuery('geographyColumns', ['tables']));
}
this.feedback({ analysingMessage: 'Finalizing DB structure' }); this.feedback({ analysingMessage: 'Finalizing DB structure' });
const columnColumnsMapped = fkColumns.rows.map(x => ({ const columnColumnsMapped = fkColumns.rows.map(x => ({
@@ -179,7 +206,7 @@ class Analyser extends DatabaseAnalyser {
...newTable, ...newTable,
columns: columns.rows columns: columns.rows
.filter(col => col.pure_name == table.pure_name && col.schema_name == table.schema_name) .filter(col => col.pure_name == table.pure_name && col.schema_name == table.schema_name)
.map(getColumnInfo), .map(col => getColumnInfo(col, newTable, geometryColumns, geographyColumns)),
primaryKey: DatabaseAnalyser.extractPrimaryKeys(newTable, pkColumnsMapped), primaryKey: DatabaseAnalyser.extractPrimaryKeys(newTable, pkColumnsMapped),
foreignKeys: DatabaseAnalyser.extractForeignKeys(newTable, columnColumnsMapped), foreignKeys: DatabaseAnalyser.extractForeignKeys(newTable, columnColumnsMapped),
indexes: indexes.rows indexes: indexes.rows
@@ -231,7 +258,7 @@ class Analyser extends DatabaseAnalyser {
createSql: `CREATE VIEW "${view.schema_name}"."${view.pure_name}"\nAS\n${view.create_sql}`, createSql: `CREATE VIEW "${view.schema_name}"."${view.pure_name}"\nAS\n${view.create_sql}`,
columns: columns.rows columns: columns.rows
.filter(col => col.pure_name == view.pure_name && col.schema_name == view.schema_name) .filter(col => col.pure_name == view.pure_name && col.schema_name == view.schema_name)
.map(getColumnInfo), .map(col => getColumnInfo(col)),
})), })),
matviews: matviews matviews: matviews
? matviews.rows.map(matview => ({ ? matviews.rows.map(matview => ({
@@ -242,7 +269,7 @@ class Analyser extends DatabaseAnalyser {
createSql: `CREATE MATERIALIZED VIEW "${matview.schema_name}"."${matview.pure_name}"\nAS\n${matview.definition}`, createSql: `CREATE MATERIALIZED VIEW "${matview.schema_name}"."${matview.pure_name}"\nAS\n${matview.definition}`,
columns: matviewColumns.rows columns: matviewColumns.rows
.filter(col => col.pure_name == matview.pure_name && col.schema_name == matview.schema_name) .filter(col => col.pure_name == matview.pure_name && col.schema_name == matview.schema_name)
.map(getColumnInfo), .map(col => getColumnInfo(col)),
})) }))
: undefined, : undefined,
procedures: routines.rows procedures: routines.rows

View File

@@ -0,0 +1,8 @@
module.exports = `
select
f_table_schema as "schema_name",
f_table_name as "pure_name",
f_geography_column as "column_name"
from public.geography_columns
where ('tables:' || f_table_schema || '.' || f_table_name) =OBJECT_ID_CONDITION
`;

View File

@@ -0,0 +1,8 @@
module.exports = `
select
f_table_schema as "schema_name",
f_table_name as "pure_name",
f_geometry_column as "column_name"
from public.geometry_columns
where ('tables:' || f_table_schema || '.' || f_table_name) =OBJECT_ID_CONDITION
`;

View File

@@ -13,6 +13,8 @@ const matviewColumns = require('./matviewColumns');
const indexes = require('./indexes'); const indexes = require('./indexes');
const indexcols = require('./indexcols'); const indexcols = require('./indexcols');
const uniqueNames = require('./uniqueNames'); const uniqueNames = require('./uniqueNames');
const geometryColumns = require('./geometryColumns');
const geographyColumns = require('./geographyColumns');
const fk_keyColumnUsage = require('./fk_key_column_usage'); const fk_keyColumnUsage = require('./fk_key_column_usage');
const fk_referentialConstraints = require('./fk_referential_constraints'); const fk_referentialConstraints = require('./fk_referential_constraints');
@@ -37,4 +39,6 @@ module.exports = {
indexes, indexes,
indexcols, indexcols,
uniqueNames, uniqueNames,
geometryColumns,
geographyColumns,
}; };

View File

@@ -2,6 +2,8 @@ const { driverBase } = global.DBGATE_TOOLS;
const Dumper = require('./Dumper'); const Dumper = require('./Dumper');
const { postgreSplitterOptions } = require('dbgate-query-splitter/lib/options'); const { postgreSplitterOptions } = require('dbgate-query-splitter/lib/options');
const spatialTypes = ['GEOGRAPHY'];
/** @type {import('dbgate-types').SqlDialect} */ /** @type {import('dbgate-types').SqlDialect} */
const dialect = { const dialect = {
rangeSelect: true, rangeSelect: true,
@@ -78,6 +80,23 @@ const dialect = {
'uuid', 'uuid',
'xml', 'xml',
], ],
createColumnViewExpression(columnName, dataType, source, alias) {
if (dataType && spatialTypes.includes(dataType.toUpperCase())) {
return {
exprType: 'call',
func: 'ST_AsText',
alias: alias || columnName,
args: [
{
exprType: 'column',
columnName,
source,
},
],
};
}
},
}; };
const postgresDriverBase = { const postgresDriverBase = {