Fix review comments

- Combine the various exported types; the only API surface is now the
  `PluginDatabaseClientFactory` which is a free function.
- Rename to the SingleConnectionManager class.
- Refactor the PluginEnvironment type to use databaseClientFactory for
  clarity.
- Fix mergeDatabaseConfig to not override the input dictionary.
This commit is contained in:
Joel Low
2020-10-02 12:35:40 +08:00
parent e277c5dfa5
commit 8c78b4e9dd
15 changed files with 78 additions and 119 deletions
@@ -17,43 +17,39 @@
import Knex from 'knex';
import { Config } from '@backstage/config';
import { createDatabaseClient, ensureDatabaseExists } from './connection';
import {
DatabaseConfiguration,
PluginDatabaseFactory,
PluginDatabaseManager,
} from './types';
import { PluginDatabaseClientFactory } from './types';
export class SingleDatabaseConfiguration implements DatabaseConfiguration {
/**
* Implements a Database Manager which will automatically create new databases for plugins when requested. All
* requested databases are created with the credentials provided.
*/
export class SingleConnectionManager {
private readonly config: Config;
constructor(config: Config) {
this.config = config;
}
getDatabaseConfig(_pluginId: string): Config {
private getDatabaseConfig(): Config {
return this.config;
}
getAdminConfig(): Config {
private getAdminConfig(): Config {
return this.config;
}
}
export class SingleDatabaseManager implements PluginDatabaseManager {
private readonly config: DatabaseConfiguration;
constructor(config: DatabaseConfiguration) {
this.config = config;
/**
* Generates a PluginDatabaseClientFactory for consumption by plugins.
*/
getDatabaseClientFactory(pluginId: string): PluginDatabaseClientFactory {
return (database?: string): Promise<Knex> => {
return this.getDatabase(pluginId, database);
};
}
getDatabaseFactory(pluginId: string): PluginDatabaseFactory {
// eslint-disable-next-line no-use-before-define
return new SinglePluginDatabaseFactory(this, pluginId);
}
async getDatabase(pluginId: string, suffix?: string): Promise<Knex> {
const config = this.config.getDatabaseConfig(pluginId);
const overrides = SingleDatabaseManager.getDatabaseOverrides(
private async getDatabase(pluginId: string, suffix?: string): Promise<Knex> {
const config = this.getDatabaseConfig();
const overrides = SingleConnectionManager.getDatabaseOverrides(
pluginId,
suffix,
);
@@ -76,21 +72,7 @@ export class SingleDatabaseManager implements PluginDatabaseManager {
}
private async ensureDatabase(database: string) {
const config = this.config.getAdminConfig();
const config = this.getAdminConfig();
await ensureDatabaseExists(config, database);
}
}
export class SinglePluginDatabaseFactory implements PluginDatabaseFactory {
private manager: SingleDatabaseManager;
private readonly pluginId: string;
constructor(manager: SingleDatabaseManager, pluginId: string) {
this.manager = manager;
this.pluginId = pluginId;
}
getDatabase(database?: string): Promise<Knex> {
return this.manager.getDatabase(this.pluginId, database);
}
}
@@ -23,5 +23,5 @@ import { merge } from 'lodash';
* @param overrides Any additional overrides
*/
export function mergeDatabaseConfig(config: any, ...overrides: any[]) {
return merge(config, ...overrides);
return merge({}, config, ...overrides);
}
@@ -16,4 +16,4 @@
export * from './connection';
export * from './types';
export * from './SingleDatabase';
export * from './SingleConnection';
@@ -15,7 +15,6 @@
*/
import knex, { PgConnectionConfig } from 'knex';
import { cloneDeep } from 'lodash';
import { Config } from '@backstage/config';
import { mergeDatabaseConfig } from './config';
@@ -45,7 +44,7 @@ export function buildPgDatabaseConfig(
overrides?: knex.Config,
) {
return mergeDatabaseConfig(
cloneDeep(dbConfig.get()),
dbConfig.get(),
{
connection: getPgConnectionConfig(dbConfig, !!overrides),
useNullAsDefault: true,
+6 -38
View File
@@ -15,45 +15,13 @@
*/
import knex from 'knex';
import { Config } from '@backstage/config';
/**
* DatabaseConfiguration exposes the Application configuration to PluginDatabaseManager instances.
*/
export interface DatabaseConfiguration {
/**
* Returns the database configuration for the given Plugin.
*/
getDatabaseConfig(pluginId: string): Config;
/**
* Returns the database configuration for administrating the database server.
*/
getAdminConfig(): Config;
}
/**
* The PluginDatabaseManager produces PluginDatabaseFactory objects for plugins to consume and store their data.
*/
export type PluginDatabaseManager = {
/**
* getDatabaseFactory returns the database factory object for plugins to obtain database connections.
*/
getDatabaseFactory(pluginId: string): PluginDatabaseFactory;
};
/**
* The PluginDatabaseFactory is used to provide a mechanism for backend plugins to obtain database connections for
* itself.
* The PluginDatabaseClientFactory is used to provide a mechanism for backend plugins to obtain database connections
* for itself.
*
* The purpose of this factory is to allow plugins to get isolated data stores so that plugins are discouraged from database integration.
* The purpose of this factory is to allow plugins to get isolated data stores so that plugins are discouraged from
* database integration. Plugins can omit the `database` parameter to get the default plugin database, or
* provide an identifier that will be used to identify a separate database from the default.
*/
export type PluginDatabaseFactory = {
/**
* Returns a database connection. Plugins can omit the `database` parameter to get the default plugin database, or
* provide an identifier that will be used to identify a separate database from the default.
*
* Plugins completely own and manage the state of the database (including schema/migrations/data.)
*/
getDatabase(database?: String): Promise<knex>;
};
export type PluginDatabaseClientFactory = (database?: string) => Promise<knex>;