mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-02 00:54:00 +00:00
mongo perspective stuff - basic skeleton works
This commit is contained in:
@@ -39,6 +39,7 @@ import { FilterType } from 'dbgate-filterparser/lib/types';
|
|||||||
import { Condition, Expression, Select } from 'dbgate-sqltree';
|
import { Condition, Expression, Select } from 'dbgate-sqltree';
|
||||||
// import { getPerspectiveDefaultColumns } from './getPerspectiveDefaultColumns';
|
// import { getPerspectiveDefaultColumns } from './getPerspectiveDefaultColumns';
|
||||||
import uuidv1 from 'uuid/v1';
|
import uuidv1 from 'uuid/v1';
|
||||||
|
import { PerspectiveDataPatternColumn } from './PerspectiveDataPattern';
|
||||||
|
|
||||||
export interface PerspectiveDataLoadPropsWithNode {
|
export interface PerspectiveDataLoadPropsWithNode {
|
||||||
props: PerspectiveDataLoadProps;
|
props: PerspectiveDataLoadProps;
|
||||||
@@ -699,6 +700,173 @@ export class PerspectiveTableColumnNode extends PerspectiveTreeNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class PerspectivePatternColumnNode extends PerspectiveTreeNode {
|
||||||
|
foreignKey: ForeignKeyInfo;
|
||||||
|
refTable: TableInfo;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public column: PerspectiveDataPatternColumn,
|
||||||
|
dbs: MultipleDatabaseInfo,
|
||||||
|
config: PerspectiveConfig,
|
||||||
|
setConfig: ChangePerspectiveConfigFunc,
|
||||||
|
dataProvider: PerspectiveDataProvider,
|
||||||
|
databaseConfig: PerspectiveDatabaseConfig,
|
||||||
|
parentNode: PerspectiveTreeNode,
|
||||||
|
designerId: string
|
||||||
|
) {
|
||||||
|
super(dbs, config, setConfig, parentNode, dataProvider, databaseConfig, designerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// matchChildRow(parentRow: any, childRow: any): boolean {
|
||||||
|
// if (!this.foreignKey) return false;
|
||||||
|
// return parentRow[this.foreignKey.columns[0].columnName] == childRow[this.foreignKey.columns[0].refColumnName];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// getChildMatchColumns() {
|
||||||
|
// if (!this.foreignKey) return [];
|
||||||
|
// return [this.foreignKey.columns[0].columnName];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// getParentMatchColumns() {
|
||||||
|
// if (!this.foreignKey) return [];
|
||||||
|
// return [this.foreignKey.columns[0].refColumnName];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// getParentJoinCondition(alias: string, parentAlias: string): Condition[] {
|
||||||
|
// if (!this.foreignKey) return [];
|
||||||
|
// return this.foreignKey.columns.map(column => {
|
||||||
|
// const res: Condition = {
|
||||||
|
// conditionType: 'binary',
|
||||||
|
// operator: '=',
|
||||||
|
// left: {
|
||||||
|
// exprType: 'column',
|
||||||
|
// columnName: column.columnName,
|
||||||
|
// source: { alias: parentAlias },
|
||||||
|
// },
|
||||||
|
// right: {
|
||||||
|
// exprType: 'column',
|
||||||
|
// columnName: column.refColumnName,
|
||||||
|
// source: { alias },
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
// return res;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// createReferenceConfigColumns(): PerspectiveReferenceConfig['columns'] {
|
||||||
|
// return this.foreignKey?.columns?.map(col => ({
|
||||||
|
// source: col.columnName,
|
||||||
|
// target: col.refColumnName,
|
||||||
|
// }));
|
||||||
|
// }
|
||||||
|
|
||||||
|
getNodeLoadProps(parentRows: any[]): PerspectiveDataLoadProps {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get icon() {
|
||||||
|
return 'img column';
|
||||||
|
}
|
||||||
|
|
||||||
|
get codeName() {
|
||||||
|
return this.column.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
get columnName() {
|
||||||
|
return this.column.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
get fieldName() {
|
||||||
|
return this.codeName + 'Ref';
|
||||||
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return this.column.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isExpandable() {
|
||||||
|
return !!this.foreignKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isSortable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
get filterType(): FilterType {
|
||||||
|
return 'mongo';
|
||||||
|
}
|
||||||
|
|
||||||
|
generateChildNodes(): PerspectiveTreeNode[] {
|
||||||
|
return [];
|
||||||
|
// if (!this.foreignKey) return [];
|
||||||
|
// const tbl = this?.db?.tables?.find(
|
||||||
|
// x => x.pureName == this.foreignKey?.refTableName && x.schemaName == this.foreignKey?.refSchemaName
|
||||||
|
// );
|
||||||
|
|
||||||
|
// return getTableChildPerspectiveNodes(
|
||||||
|
// tbl,
|
||||||
|
// this.dbs,
|
||||||
|
// this.config,
|
||||||
|
// this.setConfig,
|
||||||
|
// this.dataProvider,
|
||||||
|
// this.databaseConfig,
|
||||||
|
// this
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
|
||||||
|
// get filterInfo(): PerspectiveFilterColumnInfo {
|
||||||
|
// return {
|
||||||
|
// columnName: this.columnName,
|
||||||
|
// filterType: this.filterType,
|
||||||
|
// pureName: this.column.pureName,
|
||||||
|
// schemaName: this.column.schemaName,
|
||||||
|
// foreignKey: this.foreignKey,
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// parseFilterCondition(source = null): Condition {
|
||||||
|
// const filter = this.getFilter();
|
||||||
|
// if (!filter) return null;
|
||||||
|
// const condition = parseFilter(filter, this.filterType);
|
||||||
|
// if (!condition) return null;
|
||||||
|
// return _cloneDeepWith(condition, (expr: Expression) => {
|
||||||
|
// if (expr.exprType == 'placeholder') {
|
||||||
|
// return {
|
||||||
|
// exprType: 'column',
|
||||||
|
// columnName: this.column.columnName,
|
||||||
|
// source,
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// get headerTableAttributes() {
|
||||||
|
// if (this.foreignKey) {
|
||||||
|
// return {
|
||||||
|
// schemaName: this.foreignKey.refSchemaName,
|
||||||
|
// pureName: this.foreignKey.refTableName,
|
||||||
|
// conid: this.databaseConfig.conid,
|
||||||
|
// database: this.databaseConfig.database,
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// get tableCode() {
|
||||||
|
// return `${this.collection.schemaName}|${this.table.pureName}`;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// get namedObject(): NamedObjectInfo {
|
||||||
|
// if (this.foreignKey) {
|
||||||
|
// return {
|
||||||
|
// schemaName: this.foreignKey.refSchemaName,
|
||||||
|
// pureName: this.foreignKey.refTableName,
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
export class PerspectiveTableNode extends PerspectiveTreeNode {
|
export class PerspectiveTableNode extends PerspectiveTreeNode {
|
||||||
constructor(
|
constructor(
|
||||||
public table: TableInfo | ViewInfo,
|
public table: TableInfo | ViewInfo,
|
||||||
@@ -819,16 +987,16 @@ export class PerspectiveCollectionNode extends PerspectiveTreeNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
generateChildNodes(): PerspectiveTreeNode[] {
|
generateChildNodes(): PerspectiveTreeNode[] {
|
||||||
return [];
|
return getCollectionChildPerspectiveNodes(
|
||||||
// return getTableChildPerspectiveNodes(
|
this.designerId,
|
||||||
// this.table,
|
this.collection,
|
||||||
// this.dbs,
|
this.dbs,
|
||||||
// this.config,
|
this.config,
|
||||||
// this.setConfig,
|
this.setConfig,
|
||||||
// this.dataProvider,
|
this.dataProvider,
|
||||||
// this.databaseConfig,
|
this.databaseConfig,
|
||||||
// this
|
this
|
||||||
// );
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get icon() {
|
get icon() {
|
||||||
@@ -1172,6 +1340,43 @@ function findDesignerIdForNode<T extends PerspectiveTreeNode>(
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getCollectionChildPerspectiveNodes(
|
||||||
|
designerId: string,
|
||||||
|
collection: CollectionInfo,
|
||||||
|
dbs: MultipleDatabaseInfo,
|
||||||
|
config: PerspectiveConfig,
|
||||||
|
setConfig: ChangePerspectiveConfigFunc,
|
||||||
|
dataProvider: PerspectiveDataProvider,
|
||||||
|
databaseConfig: PerspectiveDatabaseConfig,
|
||||||
|
parentNode: PerspectiveTreeNode
|
||||||
|
) {
|
||||||
|
if (!collection) return [];
|
||||||
|
const db = parentNode.db;
|
||||||
|
|
||||||
|
const pattern = dataProvider.dataPatterns[designerId];
|
||||||
|
if (!pattern) return [];
|
||||||
|
|
||||||
|
const columnNodes = pattern.columns.map(col =>
|
||||||
|
findDesignerIdForNode(
|
||||||
|
config,
|
||||||
|
parentNode,
|
||||||
|
designerId =>
|
||||||
|
new PerspectivePatternColumnNode(
|
||||||
|
col,
|
||||||
|
dbs,
|
||||||
|
config,
|
||||||
|
setConfig,
|
||||||
|
dataProvider,
|
||||||
|
databaseConfig,
|
||||||
|
parentNode,
|
||||||
|
designerId
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return columnNodes;
|
||||||
|
}
|
||||||
|
|
||||||
export function getTableChildPerspectiveNodes(
|
export function getTableChildPerspectiveNodes(
|
||||||
table: TableInfo | ViewInfo,
|
table: TableInfo | ViewInfo,
|
||||||
dbs: MultipleDatabaseInfo,
|
dbs: MultipleDatabaseInfo,
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
import { findForeignKeyForColumn } from 'dbgate-tools';
|
import { findForeignKeyForColumn } from 'dbgate-tools';
|
||||||
import { DatabaseInfo, TableInfo, ViewInfo } from 'dbgate-types';
|
import { DatabaseInfo, TableInfo, ViewInfo } from 'dbgate-types';
|
||||||
import { createPerspectiveNodeConfig, MultipleDatabaseInfo, PerspectiveConfig } from './PerspectiveConfig';
|
import { createPerspectiveNodeConfig, MultipleDatabaseInfo, PerspectiveConfig } from './PerspectiveConfig';
|
||||||
import { PerspectiveDataPatternDict } from './PerspectiveDataPattern';
|
import { PerspectiveDataPattern, PerspectiveDataPatternDict } from './PerspectiveDataPattern';
|
||||||
import { PerspectiveTableNode } from './PerspectiveTreeNode';
|
import { PerspectiveTableNode } from './PerspectiveTreeNode';
|
||||||
|
|
||||||
|
const namePredicates = [
|
||||||
|
x => x.toLowerCase() == 'name',
|
||||||
|
x => x.toLowerCase() == 'title',
|
||||||
|
x => x.toLowerCase().includes('name'),
|
||||||
|
x => x.toLowerCase().includes('title'),
|
||||||
|
x => x.toLowerCase().includes('subject'),
|
||||||
|
];
|
||||||
|
|
||||||
function getPerspectiveDefaultColumns(
|
function getPerspectiveDefaultColumns(
|
||||||
table: TableInfo | ViewInfo,
|
table: TableInfo | ViewInfo,
|
||||||
db: DatabaseInfo,
|
db: DatabaseInfo,
|
||||||
@@ -11,13 +19,7 @@ function getPerspectiveDefaultColumns(
|
|||||||
): [string[], string[]] {
|
): [string[], string[]] {
|
||||||
const columns = table.columns.map(x => x.columnName);
|
const columns = table.columns.map(x => x.columnName);
|
||||||
const predicates = [
|
const predicates = [
|
||||||
x => x.toLowerCase() == 'name',
|
...namePredicates,
|
||||||
x => x.toLowerCase() == 'title',
|
|
||||||
x => x.toLowerCase().includes('name'),
|
|
||||||
x => x.toLowerCase().includes('title'),
|
|
||||||
x => x.toLowerCase().includes('subject'),
|
|
||||||
// x => x.toLowerCase().includes('text'),
|
|
||||||
// x => x.toLowerCase().includes('desc'),
|
|
||||||
x =>
|
x =>
|
||||||
table.columns
|
table.columns
|
||||||
.find(y => y.columnName == x)
|
.find(y => y.columnName == x)
|
||||||
@@ -45,6 +47,16 @@ function getPerspectiveDefaultColumns(
|
|||||||
return [[columns[0]], null];
|
return [[columns[0]], null];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPerspectiveDefaultCollectionColumns(pattern: PerspectiveDataPattern): string[] {
|
||||||
|
const columns = pattern.columns.map(x => x.name);
|
||||||
|
const predicates = [...namePredicates, x => pattern.columns.find(y => y.name == x)?.types?.includes('string')];
|
||||||
|
|
||||||
|
for (const predicate of predicates) {
|
||||||
|
const col = columns.find(predicate);
|
||||||
|
if (col) return [col];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function perspectiveNodesHaveStructure(
|
export function perspectiveNodesHaveStructure(
|
||||||
config: PerspectiveConfig,
|
config: PerspectiveConfig,
|
||||||
dbInfos: MultipleDatabaseInfo,
|
dbInfos: MultipleDatabaseInfo,
|
||||||
@@ -83,6 +95,7 @@ export function shouldProcessPerspectiveDefaultColunns(
|
|||||||
function processPerspectiveDefaultColunnsStep(
|
function processPerspectiveDefaultColunnsStep(
|
||||||
config: PerspectiveConfig,
|
config: PerspectiveConfig,
|
||||||
dbInfos: MultipleDatabaseInfo,
|
dbInfos: MultipleDatabaseInfo,
|
||||||
|
dataPatterns: PerspectiveDataPatternDict,
|
||||||
conid: string,
|
conid: string,
|
||||||
database: string
|
database: string
|
||||||
) {
|
) {
|
||||||
@@ -112,6 +125,7 @@ function processPerspectiveDefaultColunnsStep(
|
|||||||
|
|
||||||
const table = db.tables.find(x => x.pureName == node.pureName && x.schemaName == node.schemaName);
|
const table = db.tables.find(x => x.pureName == node.pureName && x.schemaName == node.schemaName);
|
||||||
const view = db.views.find(x => x.pureName == node.pureName && x.schemaName == node.schemaName);
|
const view = db.views.find(x => x.pureName == node.pureName && x.schemaName == node.schemaName);
|
||||||
|
const collection = db.collections.find(x => x.pureName == node.pureName && x.schemaName == node.schemaName);
|
||||||
|
|
||||||
if (table || view) {
|
if (table || view) {
|
||||||
const treeNode = root.findNodeByDesignerId(node.designerId);
|
const treeNode = root.findNodeByDesignerId(node.designerId);
|
||||||
@@ -186,6 +200,22 @@ function processPerspectiveDefaultColunnsStep(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (collection) {
|
||||||
|
const defaultColumns = getPerspectiveDefaultCollectionColumns(dataPatterns?.[node.designerId]);
|
||||||
|
return {
|
||||||
|
...config,
|
||||||
|
nodes: config.nodes.map(n =>
|
||||||
|
n.designerId == node.designerId
|
||||||
|
? {
|
||||||
|
...n,
|
||||||
|
defaultColumnsProcessed: true,
|
||||||
|
checkedColumns: defaultColumns,
|
||||||
|
}
|
||||||
|
: n
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -204,11 +234,12 @@ function markAllProcessed(config: PerspectiveConfig): PerspectiveConfig {
|
|||||||
export function processPerspectiveDefaultColunns(
|
export function processPerspectiveDefaultColunns(
|
||||||
config: PerspectiveConfig,
|
config: PerspectiveConfig,
|
||||||
dbInfos: MultipleDatabaseInfo,
|
dbInfos: MultipleDatabaseInfo,
|
||||||
|
dataPatterns: PerspectiveDataPatternDict,
|
||||||
conid: string,
|
conid: string,
|
||||||
database: string
|
database: string
|
||||||
): PerspectiveConfig {
|
): PerspectiveConfig {
|
||||||
while (config.nodes.filter(x => !x.defaultColumnsProcessed).length > 0) {
|
while (config.nodes.filter(x => !x.defaultColumnsProcessed).length > 0) {
|
||||||
const newConfig = processPerspectiveDefaultColunnsStep(config, dbInfos, conid, database);
|
const newConfig = processPerspectiveDefaultColunnsStep(config, dbInfos, dataPatterns, conid, database);
|
||||||
if (!newConfig) {
|
if (!newConfig) {
|
||||||
return markAllProcessed(config);
|
return markAllProcessed(config);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ test('test flat view', () => {
|
|||||||
const configColumns = processPerspectiveDefaultColunns(
|
const configColumns = processPerspectiveDefaultColunns(
|
||||||
createPerspectiveConfig({ pureName: 'Artist' }),
|
createPerspectiveConfig({ pureName: 'Artist' }),
|
||||||
{ conid: { db: chinookDbInfo } },
|
{ conid: { db: chinookDbInfo } },
|
||||||
|
null,
|
||||||
'conid',
|
'conid',
|
||||||
'db'
|
'db'
|
||||||
);
|
);
|
||||||
@@ -47,7 +48,7 @@ test('test one level nesting', () => {
|
|||||||
columns: [{ source: 'ArtistId', target: 'ArtistId' }],
|
columns: [{ source: 'ArtistId', target: 'ArtistId' }],
|
||||||
});
|
});
|
||||||
|
|
||||||
const configColumns = processPerspectiveDefaultColunns(config, { conid: { db: chinookDbInfo } }, 'conid', 'db');
|
const configColumns = processPerspectiveDefaultColunns(config, { conid: { db: chinookDbInfo } }, null, 'conid', 'db');
|
||||||
|
|
||||||
// const config = createPerspectiveConfig({ pureName: 'Artist' });
|
// const config = createPerspectiveConfig({ pureName: 'Artist' });
|
||||||
// config.nodes[0].checkedColumns = ['Album'];
|
// config.nodes[0].checkedColumns = ['Album'];
|
||||||
@@ -107,7 +108,7 @@ test('test two level nesting', () => {
|
|||||||
designerId: '2',
|
designerId: '2',
|
||||||
columns: [{ source: 'AlbumId', target: 'AlbumId' }],
|
columns: [{ source: 'AlbumId', target: 'AlbumId' }],
|
||||||
});
|
});
|
||||||
const configColumns = processPerspectiveDefaultColunns(config, { conid: { db: chinookDbInfo } }, 'conid', 'db');
|
const configColumns = processPerspectiveDefaultColunns(config, { conid: { db: chinookDbInfo } }, null, 'conid', 'db');
|
||||||
|
|
||||||
const root = new PerspectiveTableNode(
|
const root = new PerspectiveTableNode(
|
||||||
artistTable,
|
artistTable,
|
||||||
|
|||||||
@@ -169,7 +169,7 @@
|
|||||||
|
|
||||||
$: {
|
$: {
|
||||||
if (shouldProcessPerspectiveDefaultColunns(config, $dbInfos, $dataPatterns, conid, database)) {
|
if (shouldProcessPerspectiveDefaultColunns(config, $dbInfos, $dataPatterns, conid, database)) {
|
||||||
setConfig(cfg => processPerspectiveDefaultColunns(cfg, $dbInfos, conid, database));
|
setConfig(cfg => processPerspectiveDefaultColunns(cfg, $dbInfos, $dataPatterns, conid, database));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user