Skip to content

Commit

Permalink
Merge pull request #77 from Software-Developers-IRL/f/lastlink3
Browse files Browse the repository at this point in the history
F/lastlink3 ala cart docs 0.0.9
  • Loading branch information
lastlink authored Oct 11, 2022
2 parents 7f05542 + a21c2eb commit bfa53f4
Show file tree
Hide file tree
Showing 10 changed files with 314 additions and 16 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@funktechno/little-mermaid-2-the-sql",
"version": "0.0.8",
"version": "0.0.9",
"description": "",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
Expand Down
125 changes: 125 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,131 @@
## Generating Mermaid erDiagram
* see [samples](./samples/readme.md) for more information

## Ala Cart
1. `npm install --save @funktechno/little-mermaid-2-the-sql`
1. Example
* from markdown content
```typescript
import { GenerateSqlFromMermaid } from "@funktechno/little-mermaid-2-the-sql/lib/src/Library";
import { MarkdownContentResponseI } from "@funktechno/little-mermaid-2-the-sql/lib/src/types";


const markdownContent:MarkdownContentResponseI ={
settings: {
database: "postgres",
outputName: "result",
isRaw: false,
src: ""
},
content:`
#Test
\`\`\`mermaid
erDiagram
%% comment 1
Persons {
int PersonID PK "NOT NULL"
varchar255 LastName
varchar255 FirstName
varchar255 Address
varchar255 City
}
%% comment 2
Orders {
int OrderID PK "NOT NULL"
int PersonID FK "NOT NULL"
}
Persons ||--o{ Orders : "[Persons.PersonId] to [Orders.PersonId]"
\`\`\`
`
};

const sqlOutputs = GenerateSqlFromMermaid(markdownContent);
```

* manual mermaid db model
```typescript
import { DbParser } from "@funktechno/little-mermaid-2-the-sql/lib/src/generate-sql-ddl";
import erDb from "@funktechno/little-mermaid-2-the-sql/lib/src/mermaid/src/diagrams/er/erDb";
const db = erDb;
let entityName = "Persons";
// load mermaid db with entities
db.addEntity(entityName);
let attributes:DbEntityAttributesDefinition[] = [
{
attributeName: "PersonID",
attributeKeyType: "PK",
attributeType: "int",
attributeComment: "NOT NULL"
},
{
attributeName: "LastName",
attributeType: "varchar255"
},
{
attributeName: "FirstName",
attributeType: "varchar255"
},
{
attributeName: "Address",
attributeType: "varchar255"
},
{
attributeName: "City",
attributeType: "varchar255"
}
];
db.addAttributes(entityName,attributes);
entityName = "Orders";
db.addEntity(entityName);
attributes = [
{
attributeName: "OrderID",
attributeKeyType: "PK",
attributeType: "int",
attributeComment: "NOT NULL"
},
{
attributeName: "PersonID",
attributeKeyType: "FK",
attributeType: "int",
attributeComment: "NOT NULL"
}
];
db.addAttributes(entityName,attributes);
const relSpec:DbRelSpec= {
cardA: "ZERO_OR_MORE",
cardB: "ONLY_ONE",
relType: "IDENTIFYING"
};
db.addRelationship("Persons", `[Persons.PersonId] to [${entityName}.PersonId]`, entityName, relSpec);
const ddlSyntax = new DbParser('sqlite', db).getSQLDataDefinition();
```
* sql output
```sql
CREATE TABLE "Persons" (
"City" varchar(255),
"Address" varchar(255),
"FirstName" varchar(255),
"LastName" varchar(255),
"PersonID" int NOT NULL,
PRIMARY KEY("PersonID")
);
CREATE TABLE "Orders" (
"PersonID" int NOT NULL,
"OrderID" int NOT NULL,
PRIMARY KEY("OrderID"),
FOREIGN KEY ("PersonId") REFERENCES "Persons"("PersonId")
);
```

## Development

1. git clone repo
Expand Down
3 changes: 2 additions & 1 deletion src/mermaid/src/diagrams/er/erDb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
DbEntityAttributesDefinition,
DbEntityDefinition,
DbRelationshipDefinition,
DbRelSpec,
} from "../../../../types";
// import mermaidAPI from '../../mermaidAPI';
// import * as configApi from '../../../../../deps/mermaid/src/config'
Expand Down Expand Up @@ -69,7 +70,7 @@ const addRelationship = function (
entA: string,
rolA: string,
entB: string,
rSpec: string
rSpec: DbRelSpec
) {
const rel: DbRelationshipDefinition = {
entityA: entA,
Expand Down
14 changes: 10 additions & 4 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,38 @@ export interface DiagramDefinition {
export interface DbEntityAttributesDefinition {
attributeType?: string;
attributeName?: string;
attributeKeyType?: string;
attributeKeyType?: "PK" | "FK";
attributeComment?: string;
}

export interface DbEntityDefinition {
attributes: DbEntityAttributesDefinition[];
}

export interface DbRelSpec {
cardA: string;
cardB: string;
relType: string;
}

export interface DbRelationshipDefinition {
entityA: string;
roleA: string;
entityB: string;
relSpec: string;
relSpec: DbRelSpec;
}

export interface DbDefinition {
Cardinality: Record<string, string>;
Identification: Record<string, string>;
addEntity: (name: string) => void;
addAttributes: (entityName: string, attribs: any[]) => void;
addAttributes: (entityName: string, attribs: DbEntityAttributesDefinition[]) => void;
getEntities: () => Record<string, DbEntityDefinition>;
addRelationship: (
entA: string,
rolA: string,
entB: string,
rSpec: string
rSpec: DbRelSpec
) => void;
getRelationships: () => DbRelationshipDefinition[];
clear: () => void;
Expand Down
1 change: 1 addition & 0 deletions tests/data/results/GenerateSqlFromMermaid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
3 changes: 3 additions & 0 deletions tests/data/results/getSQLDataDefinition.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"Generate DDL examples Should generate create table SQL syntax": "CREATE TABLE \"Persons\" (\n\t\"City\" varchar(255),\n\t\"Address\" varchar(255),\n\t\"FirstName\" varchar(255),\n\t\"LastName\" varchar(255),\n\t\"PersonID\" int NOT NULL,\n\tPRIMARY KEY(\"PersonID\")\n);\n\nCREATE TABLE \"Orders\" (\n\t\"PersonID\" int NOT NULL,\n\t\"OrderID\" int NOT NULL,\n\tPRIMARY KEY(\"OrderID\"),\n\tFOREIGN KEY (\"PersonId\") REFERENCES \"Persons\"(\"PersonId\")\n);\n\n"
}
10 changes: 0 additions & 10 deletions tests/generate-sql-ddl.spec.ts

This file was deleted.

53 changes: 53 additions & 0 deletions tests/src/Library.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { getExpected, updateExpected } from "../utils/helper";
import { GenerateSqlFromMermaid } from "../../src/Library";
import { MarkdownContentResponseI } from "../../src/types";

const dataSource = "GenerateSqlFromMermaid";

describe("Generate DDL examples from markdown", () => {
it("Create DLL", async () => {
const markdownContent:MarkdownContentResponseI ={
settings: {
database: "postgres",
outputName: "result",
isRaw: false,
src: ""
},
content:`
#Test
\`\`\`mermaid
erDiagram
%% comment 1
Persons {
int PersonID PK "NOT NULL"
varchar255 LastName
varchar255 FirstName
varchar255 Address
varchar255 City
}
%% comment 2
Orders {
int OrderID PK "NOT NULL"
int PersonID FK "NOT NULL"
}
Persons ||--o{ Orders : "[Persons.PersonId] to [Orders.PersonId]"
\`\`\`
`
};
// junit compile error for require parser.js export
// const sqlOutputs = GenerateSqlFromMermaid(markdownContent);

// const dataKey = expect.getState().currentTestName || "unknown";

// const expectedResult = await getExpected(dataSource, dataKey);

// if (sqlOutputs != expectedResult) {
// await updateExpected(dataSource, dataKey, sqlOutputs);
// }

// expect(sqlOutputs).toStrictEqual(expectedResult);
});
});

84 changes: 84 additions & 0 deletions tests/src/generate-sql-ddl.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { DbParser } from "../../src/generate-sql-ddl";
import erDb from "../../src/mermaid/src/diagrams/er/erDb";
import { DbEntityAttributesDefinition, DbRelSpec } from "../../src/types";
import { getExpected, updateExpected } from "../utils/helper";
import * as fs from "fs";

const dataSource = "getSQLDataDefinition";
describe("Generate DDL examples", () => {
it("Should generate create table SQL syntax", async () => {
const db = erDb;
let entityName = "Persons";
db.addEntity(entityName);
let attributes:DbEntityAttributesDefinition[] = [
{
attributeName: "PersonID",
attributeKeyType: "PK",
attributeType: "int",
attributeComment: "NOT NULL"
},
{
attributeName: "LastName",
attributeType: "varchar255"
},
{
attributeName: "FirstName",
attributeType: "varchar255"
},
{
attributeName: "Address",
attributeType: "varchar255"
},
{
attributeName: "City",
attributeType: "varchar255"
}
];
db.addAttributes(entityName,attributes);

entityName = "Orders";
db.addEntity(entityName);
attributes = [
{
attributeName: "OrderID",
attributeKeyType: "PK",
attributeType: "int",
attributeComment: "NOT NULL"
},
{
attributeName: "PersonID",
attributeKeyType: "FK",
attributeType: "int",
attributeComment: "NOT NULL"
}
];
db.addAttributes(entityName,attributes);

const relSpec:DbRelSpec= {
cardA: "ZERO_OR_MORE",
cardB: "ONLY_ONE",
relType: "IDENTIFYING"
};

db.addRelationship("Persons", `[Persons.PersonId] to [${entityName}.PersonId]`,entityName, relSpec);
// `erDiagram artists { }`;
const ddlSyntax = new DbParser("sqlite", db).getSQLDataDefinition();

const dataKey = expect.getState().currentTestName || "unknown";

const expectedResult = await getExpected(dataSource, dataKey);

if (ddlSyntax != expectedResult) {
await updateExpected(dataSource, dataKey, ddlSyntax);
}

// console.log(result);
expect(ddlSyntax).toStrictEqual(expectedResult);
// expect(ddlSyntax).toBe('CREATE TABLE artists');

// await fs.writeFileSync(
// "output-sqlite.sql",
// ddlSyntax
// );
});
});
35 changes: 35 additions & 0 deletions tests/utils/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* eslint-disable @typescript-eslint/no-var-requires */
// import {fs} from "fs";
import * as fs from "fs";
// const fs = require("fs");
const path = require("path");
const base_DIR = path.join(__dirname, "../data/results");

export async function getExpectedDict<T>(testData: string): Promise<Record<string, T | null>> {
const filePath = path.join(base_DIR, testData + ".json");
console.log(filePath);
if (await fs.existsSync(filePath)) {
const expectedResults: Record<string, T> = await JSON.parse(fs.readFileSync(filePath, "utf8"));
return expectedResults;
} else
return {};
}

export async function getExpected<T>(testData: string, key: string): Promise<T | null> {
const expectedResults = await getExpectedDict<T>(testData);
if (expectedResults[key]) {
return expectedResults[key];
} else {
return null;
}
}

export async function updateExpected<T>(testData: string, key: string, result: T | null) {
const expectedResults = await getExpectedDict<T>(testData);

expectedResults[key] = result;

const filePath = path.join(base_DIR, testData + ".json");
const stringResults = JSON.stringify(expectedResults, null, 4);
await fs.writeFileSync(filePath, stringResults);
}

0 comments on commit bfa53f4

Please sign in to comment.