mirror of
https://github.com/directus/directus.git
synced 2026-04-03 03:00:39 -04:00
Added supported function to geometryHelper, added geometrySupport to serverinfo (#9290)
Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
This commit is contained in:
@@ -1,34 +1,36 @@
|
||||
import { Field, RawField } from '@directus/shared/types';
|
||||
import { Knex } from 'knex';
|
||||
import { stringify as geojsonToWKT, GeoJSONGeometry } from 'wellknown';
|
||||
import { getDatabaseClient } from '..';
|
||||
import getDatabase from '..';
|
||||
|
||||
let geometryHelper: KnexSpatial | undefined;
|
||||
|
||||
export function getGeometryHelper(): KnexSpatial {
|
||||
export function getGeometryHelper(database?: Knex): KnexSpatial {
|
||||
if (!geometryHelper) {
|
||||
const db = getDatabase();
|
||||
const client = db.client.config.client as string;
|
||||
database = database ?? getDatabase();
|
||||
const client = getDatabaseClient(database);
|
||||
const constructor = {
|
||||
mysql: KnexSpatial_MySQL,
|
||||
mariadb: KnexSpatial_MySQL,
|
||||
sqlite3: KnexSpatial,
|
||||
pg: KnexSpatial_PG,
|
||||
sqlite: KnexSpatial_SQLite,
|
||||
postgres: KnexSpatial_PG,
|
||||
redshift: KnexSpatial_Redshift,
|
||||
mssql: KnexSpatial_MSSQL,
|
||||
oracledb: KnexSpatial_Oracle,
|
||||
oracle: KnexSpatial_Oracle,
|
||||
}[client];
|
||||
if (!constructor) {
|
||||
throw new Error(`Geometry helper not implemented on ${client}.`);
|
||||
}
|
||||
geometryHelper = new constructor(db);
|
||||
geometryHelper = new constructor(database);
|
||||
}
|
||||
return geometryHelper;
|
||||
return geometryHelper!;
|
||||
}
|
||||
|
||||
class KnexSpatial {
|
||||
constructor(protected knex: Knex) {}
|
||||
supported(): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
isTrue(expression: Knex.Raw) {
|
||||
return expression;
|
||||
}
|
||||
@@ -73,7 +75,17 @@ class KnexSpatial {
|
||||
}
|
||||
}
|
||||
|
||||
class KnexSpatial_SQLite extends KnexSpatial {
|
||||
async supported() {
|
||||
const res = await this.knex.select('name').from('pragma_function_list').where({ name: 'spatialite_version' });
|
||||
return res.length > 0;
|
||||
}
|
||||
}
|
||||
class KnexSpatial_PG extends KnexSpatial {
|
||||
async supported() {
|
||||
const res = await this.knex.select('oid').from('pg_proc').where({ proname: 'postgis_version' });
|
||||
return res.length > 0;
|
||||
}
|
||||
createColumn(table: Knex.CreateTableBuilder, field: RawField | Field) {
|
||||
const type = field.schema?.geometry_type ?? 'geometry';
|
||||
return table.specificType(field.field, `geometry(${type})`);
|
||||
@@ -145,7 +157,7 @@ class KnexSpatial_Oracle extends KnexSpatial {
|
||||
return table.specificType(field.field, 'sdo_geometry');
|
||||
}
|
||||
asText(table: string, column: string): Knex.Raw {
|
||||
return this.knex.raw('sdo_util.from_wktgeometry(??.??) as ??', [table, column, column]);
|
||||
return this.knex.raw('sdo_util.to_wktgeometry(??.??) as ??', [table, column, column]);
|
||||
}
|
||||
fromText(text: string): Knex.Raw {
|
||||
return this.knex.raw('sdo_geometry(?, 4326)', text);
|
||||
|
||||
@@ -9,6 +9,7 @@ import fse from 'fs-extra';
|
||||
import path from 'path';
|
||||
import { merge } from 'lodash';
|
||||
import { promisify } from 'util';
|
||||
import { getGeometryHelper } from './helpers/geometry';
|
||||
|
||||
let database: Knex | null = null;
|
||||
let inspector: ReturnType<typeof SchemaInspector> | null = null;
|
||||
@@ -152,7 +153,7 @@ export async function validateDatabaseConnection(database?: Knex): Promise<void>
|
||||
}
|
||||
}
|
||||
|
||||
export function getDatabaseClient(database?: Knex): 'mysql' | 'postgres' | 'sqlite' | 'oracle' | 'mssql' {
|
||||
export function getDatabaseClient(database?: Knex): 'mysql' | 'postgres' | 'sqlite' | 'oracle' | 'mssql' | 'redshift' {
|
||||
database = database ?? getDatabase();
|
||||
|
||||
switch (database.client.constructor.name) {
|
||||
@@ -167,6 +168,8 @@ export function getDatabaseClient(database?: Knex): 'mysql' | 'postgres' | 'sqli
|
||||
return 'oracle';
|
||||
case 'Client_MSSQL':
|
||||
return 'mssql';
|
||||
case 'Client_Redshift':
|
||||
return 'redshift';
|
||||
}
|
||||
|
||||
throw new Error(`Couldn't extract database client`);
|
||||
@@ -219,32 +222,18 @@ export async function validateMigrations(): Promise<boolean> {
|
||||
export async function validateDatabaseExtensions(): Promise<void> {
|
||||
const database = getDatabase();
|
||||
const databaseClient = getDatabaseClient(database);
|
||||
|
||||
if (databaseClient === 'postgres') {
|
||||
let available = false;
|
||||
let installed = false;
|
||||
|
||||
const exists = await database.raw(`SELECT name FROM pg_available_extensions WHERE name = 'postgis';`);
|
||||
|
||||
if (exists.rows.length > 0) {
|
||||
available = true;
|
||||
}
|
||||
|
||||
if (available) {
|
||||
try {
|
||||
await database.raw(`SELECT PostGIS_version();`);
|
||||
installed = true;
|
||||
} catch {
|
||||
installed = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (available === false) {
|
||||
logger.warn(`PostGIS isn't installed. Geometry type support will be limited.`);
|
||||
} else if (available === true && installed === false) {
|
||||
logger.warn(
|
||||
`PostGIS is installed, but hasn't been activated on this database. Geometry type support will be limited.`
|
||||
);
|
||||
const geometryHelper = getGeometryHelper(database);
|
||||
const geometrySupport = await geometryHelper.supported();
|
||||
if (!geometrySupport) {
|
||||
switch (databaseClient) {
|
||||
case 'postgres':
|
||||
logger.warn(`PostGIS isn't installed. Geometry type support will be limited.`);
|
||||
break;
|
||||
case 'sqlite':
|
||||
logger.warn(`Spatialite isn't installed. Geometry type support will be limited.`);
|
||||
break;
|
||||
default:
|
||||
logger.warn(`Geometry type not supported on ${databaseClient}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user