#3358 Adding db calls from node statements

This commit is contained in:
Knut Sveidqvist
2023-08-28 12:51:49 +02:00
parent b9531d56c4
commit 5fc99f1982
6 changed files with 128 additions and 47 deletions

View File

@@ -58,13 +58,8 @@
</head> </head>
<body> <body>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid">
stateDiagram-v2 block-beta
[*] --> Still id</pre
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*] </pre
> >
<pre id="diagram" class="mermaid2"> <pre id="diagram" class="mermaid2">
flowchart RL flowchart RL

View File

@@ -1,6 +1,6 @@
// import type { BlockDB } from './blockTypes.js'; // import type { BlockDB } from './blockTypes.js';
import type { DiagramDB } from '../../diagram-api/types.js'; import type { DiagramDB } from '../../diagram-api/types.js';
import { BlockConfig } from './blockTypes.js'; import { BlockConfig, BlockType, Block, Link } from './blockTypes.js';
import * as configApi from '../../config.js'; import * as configApi from '../../config.js';
// import common from '../common/common.js'; // import common from '../common/common.js';
@@ -13,47 +13,78 @@ import {
// getDiagramTitle, // getDiagramTitle,
clear as commonClear, clear as commonClear,
} from '../../commonDb.js'; } from '../../commonDb.js';
import { log } from '../../logger.js';
// export type TBlockColumnsDefaultValue = 'H'; // Do we support something else, like 'auto' | 0? // export type TBlockColumnsDefaultValue = 'H'; // Do we support something else, like 'auto' | 0?
// Initialize the node database for simple lookups
let nodeDatabase: Record<string, Node> = {};
const blockDatabase: Record<string, Block> = {};
// Function to get a node by its ID
export const getNodeById = (id: string): Node | undefined => {
return nodeDatabase[id];
};
// TODO: Convert to generic TreeNode type? Convert to class? // TODO: Convert to generic TreeNode type? Convert to class?
export interface Block {
ID: string;
label?: string;
parent?: Block;
children?: Block[];
columns?: number; // | TBlockColumnsDefaultValue;
}
export interface Link { let rootBlock = { ID: 'root', children: [] as Block[], columns: -1 };
source: Block;
target: Block;
}
let rootBlocks: Block[] = [];
let blocks: Block[] = []; let blocks: Block[] = [];
const links: Link[] = []; const links: Link[] = [];
let rootBlock = { ID: 'root', children: [], columns: -1 } as Block; // let rootBlock = { ID: 'root', children: [], columns: -1 } as Block;
let currentBlock: Block | undefined; let currentBlock = rootBlock;
const clear = (): void => { const clear = (): void => {
rootBlocks = []; log.info('Clear called');
blocks = []; // rootBlocks = [];
blocks = [] as Block[];
commonClear(); commonClear();
rootBlock = { ID: 'root', children: [], columns: -1 }; rootBlock = { ID: 'root', children: [], columns: -1 };
currentBlock = rootBlock; currentBlock = rootBlock;
nodeDatabase = {};
blockDatabase[rootBlock.ID] = rootBlock;
}; };
type IAddBlock = (block: Block) => Block; // type IAddBlock = (block: Block) => Block;
const addBlock: IAddBlock = (block: Block, parent?: Block): Block => { // const addBlock: IAddBlock = (block: Block, parent?: Block): Block => {
if (parent) { // log.info('addBlock', block, parent);
parent.children ??= []; // if (parent) {
parent.children.push(block); // parent.children ??= [];
} else { // parent.children.push(block);
rootBlocks.push(block); // } else {
// rootBlock.children.push(block);
// }
// blocks.push(block);
// return block;
// };
type ITypeStr2Type = (typeStr: string) => BlockType;
export function typeStr2Type(typeStr: string) {
// TODO: add all types
switch (typeStr) {
case '[]':
return 'square';
case '()':
return 'round';
default:
return 'square';
} }
blocks.push(block); }
return block;
type IAddBlock = (id: string, label: string, type: BlockType) => Block;
// Function to add a node to the database
export const addBlock = (id: string, _label?: string, type?: BlockType) => {
log.info('addNode called:', id, _label, type);
const label = _label || id;
const node: Block = {
ID: id,
label,
type: type || 'square',
};
blockDatabase[node.ID] = node;
currentBlock.children ??= [];
currentBlock.children.push(node);
return node;
}; };
type IAddLink = (link: Link) => Link; type IAddLink = (link: Link) => Link;
@@ -84,16 +115,21 @@ const getBlock = (id: string, blocks: Block[]): Block | undefined => {
type IGetColumns = (blockID: string) => number; type IGetColumns = (blockID: string) => number;
const getColumns = (blockID: string): number => { const getColumns = (blockID: string): number => {
const blocks = [rootBlock]; const block = blockDatabase[blockID];
const block = getBlock(blockID, blocks);
if (!block) { if (!block) {
return -1; return -1;
} }
return block.columns || -1; if (block.columns) {
return block.columns;
}
if (!block.children) {
return -1;
}
return block.children.length;
}; };
type IGetBlocks = () => Block[]; type IGetBlocks = () => Block[];
const getBlocks: IGetBlocks = () => blocks; const getBlocks: IGetBlocks = () => rootBlock.children || [];
type IGetLinks = () => Link[]; type IGetLinks = () => Link[];
const getLinks: IGetLinks = () => links; const getLinks: IGetLinks = () => links;
@@ -111,12 +147,14 @@ export interface BlockDB extends DiagramDB {
getLinks: IGetLinks; getLinks: IGetLinks;
setColumns: ISetColumns; setColumns: ISetColumns;
getColumns: IGetColumns; getColumns: IGetColumns;
typeStr2Type: ITypeStr2Type;
} }
const db: BlockDB = { const db: BlockDB = {
getConfig: () => configApi.getConfig().block, getConfig: () => configApi.getConfig().block,
addBlock: addBlock, addBlock: addBlock,
addLink: addLink, addLink: addLink,
typeStr2Type: typeStr2Type,
getLogger, // TODO: remove getLogger, // TODO: remove
getBlocks, getBlocks,
getLinks, getLinks,

View File

@@ -3,3 +3,36 @@ import type { BaseDiagramConfig } from '../../config.type.js';
export interface BlockConfig extends BaseDiagramConfig { export interface BlockConfig extends BaseDiagramConfig {
padding?: number; padding?: number;
} }
export type BlockType =
| 'round'
| 'square'
| 'diamond'
| 'hexagon'
| 'odd'
| 'lean_right'
| 'lean_left'
| 'trapezoid'
| 'inv_trapezoid'
| 'odd_right'
| 'circle'
| 'ellipse'
| 'stadium'
| 'subroutine'
| 'cylinder'
| 'group'
| 'doublecircle';
export interface Block {
ID: string;
label?: string;
parent?: Block;
type?: BlockType;
children?: Block[];
columns?: number; // | TBlockColumnsDefaultValue;
}
export interface Link {
source: Block;
target: Block;
}

View File

@@ -177,8 +177,8 @@ statement
; ;
nodeStatement nodeStatement
: nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) ');} : nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) '); yy.addBlock($1.id);}
| node { yy.getLogger().info('Rule: nodeStatement (node) ', $1);} | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1); yy.addBlock($1.id, $1.label, yy.typeStr2Type($1)); }
; ;
columnsStatement columnsStatement
@@ -192,16 +192,16 @@ blockStatement
node node
: NODE_ID : NODE_ID
{ yy.getLogger().info("Rule: node (NODE_ID seperator): ", $1); } { yy.getLogger().info("Rule: node (NODE_ID seperator): ", $1); $$ = { id: $1 }; }
|NODE_ID nodeShapeNLabel |NODE_ID nodeShapeNLabel
{ yy.getLogger().info("Rule: node (NODE_ID nodeShapeNLabel seperator): ", $1, $2); } { yy.getLogger().info("Rule: node (NODE_ID nodeShapeNLabel seperator): ", $1, $2); $$ = { id: $1, label: $2.label, typeStr: $2.typeStr };}
// |nodeShapeNLabel seperator // |nodeShapeNLabel seperator
// { yy.getLogger().info("Rule: node (nodeShapeNLabel seperator): ", $1, $2, $3); } // { yy.getLogger().info("Rule: node (nodeShapeNLabel seperator): ", $1, $2, $3); }
; ;
nodeShapeNLabel nodeShapeNLabel
: NODE_DSTART STR NODE_DEND : NODE_DSTART STR NODE_DEND
{ yy.getLogger().info("Rule: nodeShapeNLabel: ", $1, $2, $3); $$ = { type: $1 + $3, descr: $2 }; } { yy.getLogger().info("Rule: nodeShapeNLabel: ", $1, $2, $3); $$ = { typeStr: $1 + $3, label: $2 }; }
; ;
%% %%

View File

@@ -3,8 +3,7 @@ import block from './block.jison';
import db from '../blockDB.js'; import db from '../blockDB.js';
import { cleanupComments } from '../../../diagram-api/comments.js'; import { cleanupComments } from '../../../diagram-api/comments.js';
import { prepareTextForParsing } from '../blockUtils.js'; import { prepareTextForParsing } from '../blockUtils.js';
import * as fs from 'fs'; import { setConfig } from '../../../config.js';
import * as path from 'path';
describe('Block diagram', function () { describe('Block diagram', function () {
describe('when parsing an block diagram graph it should handle > ', function () { describe('when parsing an block diagram graph it should handle > ', function () {
@@ -20,6 +19,22 @@ describe('Block diagram', function () {
`; `;
block.parse(str); block.parse(str);
const blocks = db.getBlocks();
expect(blocks.length).toBe(1);
expect(blocks[0].ID).toBe('id');
expect(blocks[0].label).toBe('id');
});
it('a node with a square shape and a label', async () => {
const str = `block-beta
id["A label"]
`;
block.parse(str);
const blocks = db.getBlocks();
expect(blocks.length).toBe(1);
expect(blocks[0].ID).toBe('id');
expect(blocks[0].label).toBe('A label');
expect(blocks[0].type).toBe('square');
}); });
it('a diagram with multiple nodes', async () => { it('a diagram with multiple nodes', async () => {
const str = `block-beta const str = `block-beta

View File

@@ -1,7 +1,7 @@
import flowDb from '../flowDb.js'; import flowDb from '../flowDb.js';
import flow from './flow.jison'; import flow from './flow.jison';
import { setConfig } from '../../../config.js';
import { cleanupComments } from '../../../diagram-api/comments.js'; import { cleanupComments } from '../../../diagram-api/comments.js';
import { setConfig } from '../../../config.js';
setConfig({ setConfig({
securityLevel: 'strict', securityLevel: 'strict',