mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
Show a warning if PostGIS is missing (#7759)
* Show a warning if PostGIS is missing * Remove sqlite-extensions flag * Remove unused import
This commit is contained in:
@@ -24,7 +24,7 @@ import settingsRouter from './controllers/settings';
|
||||
import usersRouter from './controllers/users';
|
||||
import utilsRouter from './controllers/utils';
|
||||
import webhooksRouter from './controllers/webhooks';
|
||||
import { isInstalled, validateDBConnection, validateMigrations } from './database';
|
||||
import { isInstalled, validateDatabaseConnection, validateDatabaseExtensions, validateMigrations } from './database';
|
||||
import { emitAsyncSafe } from './emitter';
|
||||
import env from './env';
|
||||
import { InvalidPayloadException } from './exceptions';
|
||||
@@ -56,7 +56,8 @@ export default async function createApp(): Promise<express.Application> {
|
||||
|
||||
await validateStorage();
|
||||
|
||||
await validateDBConnection();
|
||||
await validateDatabaseConnection();
|
||||
await validateDatabaseExtensions();
|
||||
|
||||
if ((await isInstalled()) === false) {
|
||||
logger.error(`Database doesn't have Directus tables installed.`);
|
||||
|
||||
@@ -6,7 +6,7 @@ import env from '../../../env';
|
||||
import logger from '../../../logger';
|
||||
import { getSchema } from '../../../utils/get-schema';
|
||||
import { RolesService, UsersService, SettingsService } from '../../../services';
|
||||
import getDatabase, { isInstalled, validateDBConnection, hasDatabaseConnection } from '../../../database';
|
||||
import getDatabase, { isInstalled, validateDatabaseConnection, hasDatabaseConnection } from '../../../database';
|
||||
import { SchemaOverview } from '../../../types';
|
||||
|
||||
export default async function bootstrap({ skipAdminInit }: { skipAdminInit?: boolean }): Promise<void> {
|
||||
@@ -59,7 +59,7 @@ async function waitForDatabase(database: Knex) {
|
||||
}
|
||||
|
||||
// This will throw and exit the process if the database is not available
|
||||
await validateDBConnection(database);
|
||||
await validateDatabaseConnection(database);
|
||||
}
|
||||
|
||||
async function createDefaultAdmin(schema: SchemaOverview) {
|
||||
|
||||
@@ -71,8 +71,22 @@ export default function getDatabase(): Knex {
|
||||
|
||||
if (env.DB_CLIENT === 'sqlite3') {
|
||||
knexConfig.useNullAsDefault = true;
|
||||
poolConfig.afterCreate = (conn: any, cb: any) => {
|
||||
conn.run('PRAGMA foreign_keys = ON', cb);
|
||||
|
||||
poolConfig.afterCreate = async (conn: any, callback: any) => {
|
||||
logger.trace('Enabling SQLite Foreign Keys support...');
|
||||
|
||||
await run('PRAGMA foreign_keys = ON');
|
||||
|
||||
callback(null, conn);
|
||||
|
||||
async function run(sql: string): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
conn.run(sql, (err: Error | null, result: any) => {
|
||||
if (err) return reject(err);
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -116,7 +130,7 @@ export async function hasDatabaseConnection(database?: Knex): Promise<boolean> {
|
||||
database = database ?? getDatabase();
|
||||
|
||||
try {
|
||||
if (env.DB_CLIENT === 'oracledb') {
|
||||
if (getDatabaseClient(database) === 'oracle') {
|
||||
await database.raw('select 1 from DUAL');
|
||||
} else {
|
||||
await database.raw('SELECT 1');
|
||||
@@ -128,11 +142,11 @@ export async function hasDatabaseConnection(database?: Knex): Promise<boolean> {
|
||||
}
|
||||
}
|
||||
|
||||
export async function validateDBConnection(database?: Knex): Promise<void> {
|
||||
export async function validateDatabaseConnection(database?: Knex): Promise<void> {
|
||||
database = database ?? getDatabase();
|
||||
|
||||
try {
|
||||
if (env.DB_CLIENT === 'oracledb') {
|
||||
if (getDatabaseClient(database) === 'oracle') {
|
||||
await database.raw('select 1 from DUAL');
|
||||
} else {
|
||||
await database.raw('SELECT 1');
|
||||
@@ -144,12 +158,32 @@ export async function validateDBConnection(database?: Knex): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
export function getDatabaseClient(database?: Knex): 'mysql' | 'postgres' | 'sqlite' | 'oracle' | 'mssql' {
|
||||
database = database ?? getDatabase();
|
||||
|
||||
switch (database.client.constructor.name) {
|
||||
case 'Client_MySQL':
|
||||
return 'mysql';
|
||||
case 'Client_PG':
|
||||
return 'postgres';
|
||||
case 'Client_SQLite3':
|
||||
return 'sqlite';
|
||||
case 'Client_Oracledb':
|
||||
case 'Client_Oracle':
|
||||
return 'oracle';
|
||||
case 'Client_MSSQL':
|
||||
return 'mssql';
|
||||
}
|
||||
|
||||
throw new Error(`Couldn't extract database client`);
|
||||
}
|
||||
|
||||
export async function isInstalled(): Promise<boolean> {
|
||||
const inspector = getSchemaInspector();
|
||||
|
||||
// The existence of a directus_collections table alone isn't a "proper" check to see if everything
|
||||
// is installed correctly of course, but it's safe enough to assume that this collection only
|
||||
// exists when using the installer CLI.
|
||||
// exists when Directus is properly installed.
|
||||
return await inspector.hasTable('directus_collections');
|
||||
}
|
||||
|
||||
@@ -184,3 +218,39 @@ export async function validateMigrations(): Promise<boolean> {
|
||||
throw process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* These database extensions should be optional, so we don't throw or return any problem states when they don't
|
||||
*/
|
||||
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.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.`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user