Skip to content

Commit

Permalink
refactor: generalize polygenix terminology #176
Browse files Browse the repository at this point in the history
  • Loading branch information
shah committed Dec 12, 2023
1 parent d71dbaa commit 84de411
Show file tree
Hide file tree
Showing 19 changed files with 517 additions and 296 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"deno.codeLens.implementations": false,
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": "explicit"
},
"[javascript]": {
"editor.formatOnSave": true,
Expand Down
15 changes: 8 additions & 7 deletions render/ddl/table/foreign-key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,30 +286,31 @@ export function foreignKeysFactory<
for (const key of tableShapeKeys) {
const zodTypeSD = zbSchema[key];
if (isForeignKeyDestination(zodTypeSD.sqlDomain)) {
const fks = zodTypeSD.sqlDomain.foreignKeySource;
const target = entityByName(fks.tableName);
const fkNature = zodTypeSD.sqlDomain.foreignKeyRelNature;
const fkSrc = zodTypeSD.sqlDomain.foreignKeySource;
const target = entityByName(fkSrc.tableName);
if (target) {
const attr = target.attributes.find((sd) =>
sd.identity == fks.columnName
sd.identity == fkSrc.columnName
);
if (attr) {
yield {
from: { entity, attr: zodTypeSD.sqlDomain },
to: { entity: target, attr },
nature: isBelongsToForeignKeyNature(fks)
? { isBelongsTo: true, collectionName: fks.collectionName }
nature: isBelongsToForeignKeyNature(fkNature)
? { isBelongsTo: true, collectionName: fkNature.collectionName }
: "reference",
};
} else {
reportIssue({
// deno-fmt-ignore
lintIssue: `table column '${fks.columnName}' referenced in foreignKey ${JSON.stringify(fks)} not found in graph`,
lintIssue: `table column '${fkSrc.columnName}' referenced in foreignKey ${JSON.stringify(fkSrc)} not found in graph`,
});
}
} else {
reportIssue({
// deno-fmt-ignore
lintIssue: `table '${fks.tableName}' referenced in foreignKey ${JSON.stringify(fks)} not found in graph`,
lintIssue: `table '${fkSrc.tableName}' referenced in foreignKey ${JSON.stringify(fkSrc)} not found in graph`,
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion render/ddl/table/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ export function tableDefinition<
const result: g.GraphEntityDefinition<
TableName,
Context,
Any,
string,
DomainQS,
DomainsQS
> = {
Expand Down
53 changes: 37 additions & 16 deletions render/diagram/plantuml-ie-notation.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,48 @@
import * as SQLa from "../mod.ts";

// deno-lint-ignore no-explicit-any
type Any = any;

export interface PlantUmlIeOptions<
Context extends SQLa.SqlEmitContext,
DomainQS extends SQLa.SqlDomainQS,
DomainsQS extends SQLa.SqlDomainsQS<DomainQS>,
> {
readonly diagramName: string;
readonly includeEntityAttr: (
ea: SQLa.GraphEntityAttrReference<Any, Any, Context, DomainQS, DomainsQS>,
ea: SQLa.GraphEntityAttrReference<
string,
string,
Context,
DomainQS,
DomainsQS
>,
) => boolean;
readonly elaborateEntityAttr?: (
ea: SQLa.GraphEntityAttrReference<Any, Any, Context, DomainQS, DomainsQS>,
ea: SQLa.GraphEntityAttrReference<
string,
string,
Context,
DomainQS,
DomainsQS
>,
entity: (
name: string,
) =>
| SQLa.GraphEntityDefinition<Any, Context, Any, DomainQS, DomainsQS>
| SQLa.GraphEntityDefinition<string, Context, string, DomainQS, DomainsQS>
| undefined,
ns: SQLa.SqlObjectNames,
) => string;
readonly includeEntity: (
e: SQLa.GraphEntityDefinition<Any, Context, Any, DomainQS, DomainsQS>,
e: SQLa.GraphEntityDefinition<string, Context, string, DomainQS, DomainsQS>,
) => boolean;
readonly includeRelationship: (
edge: SQLa.GraphEdge<Context, Any, Any>,
edge: SQLa.GraphEdge<Context, DomainQS, DomainsQS>,
) => boolean;
readonly relationshipIndicator: (
edge: SQLa.GraphEdge<Context, Any, Any>,
edge: SQLa.GraphEdge<Context, DomainQS, DomainsQS>,
) => string | false;
readonly includeChildren: (
ir: SQLa.EntityGraphInboundRelationship<
Any,
Any,
string,
string,
Context,
DomainQS,
DomainsQS
Expand Down Expand Up @@ -65,9 +74,9 @@ export function typicalPlantUmlIeOptions<

export function plantUmlIE<
Entity extends SQLa.GraphEntityDefinition<
Any,
string,
Context,
Any,
string,
DomainQS,
DomainsQS
>,
Expand All @@ -79,11 +88,23 @@ export function plantUmlIE<
entityDefns: (ctx: Context) => Generator<Entity>,
puieOptions: PlantUmlIeOptions<Context, DomainQS, DomainsQS>,
) {
const graph = SQLa.entitiesGraph(ctx, entityDefns);
const graph = SQLa.entitiesGraph<
SQLa.GraphEntityDefinition<string, Context, string, DomainQS, DomainsQS>,
Context,
DomainQS,
DomainsQS,
SQLa.EntitiesGraphQS<DomainQS, DomainsQS>
>(ctx, entityDefns);
const ns = ctx.sqlNamingStrategy(ctx);

const attrPuml = (
ea: SQLa.GraphEntityAttrReference<Any, Any, Context, DomainQS, DomainsQS>,
ea: SQLa.GraphEntityAttrReference<
string,
string,
Context,
DomainQS,
DomainsQS
>,
) => {
const tcName = ns.tableColumnName({
tableName: ea.entity.identity("presentation"),
Expand All @@ -103,7 +124,7 @@ export function plantUmlIE<
};

const entityPuml = (
e: SQLa.GraphEntityDefinition<Any, Context, Any, DomainQS, DomainsQS>,
e: SQLa.GraphEntityDefinition<string, Context, string, DomainQS, DomainsQS>,
) => {
const columns: string[] = [];
// we want to put all the primary keys at the top of the entity
Expand Down
2 changes: 1 addition & 1 deletion render/domain/domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export type SqlDomain<
) => tmpl.SqlTextSupplier<Context>;
readonly polygenixDataType: (
purpose: "info-model",
) => tmpl.PolygenSrcCode<Context>;
) => tmpl.PolygenCellContent<Context>;
readonly sqlDefaultValue?: (
purpose: "create table column" | "stored routine arg",
) => tmpl.SqlTextSupplier<Context>;
Expand Down
6 changes: 6 additions & 0 deletions render/emit/js.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export type JsTokenSupplier<Context extends tmpl.SqlEmitContext> = (
| "js-class-member-decl"
| "js-var-ref"
| "ts-type-decl"
| "rust-struct-member-decl"
| "rust-type-decl"
| "sql-token"
| "sql-token-quoted",
) => string;
Expand All @@ -33,8 +35,12 @@ export function jsSnakeCaseToken<Context extends tmpl.SqlEmitContext>(
return snakeToCamelCase(src);

case "ts-type-decl":
case "rust-type-decl":
return snakeToPascalCase(src);

case "rust-struct-member-decl":
return src;

case "sql-token":
return src;

Expand Down
26 changes: 13 additions & 13 deletions render/emit/polygenix-notebook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,16 @@ export function polygenNotebookFactory<
nbd,
kernel,
instance,
sourceCode: async (
polygenContent: async (
options: {
separator?: (
cell: Parameters<EventEmitter["afterCell"]>[0],
state: Parameters<EventEmitter["afterCell"]>[1],
) => pgen.PolygenSrcCodeBehaviorSupplier<Context>;
) => pgen.PolygenCellContentBehaviorSupplier<Context>;
onNotSrcCodeSupplier?: (
cell: Parameters<EventEmitter["afterCell"]>[0],
state: Parameters<EventEmitter["afterCell"]>[1],
) => pgen.PolygenSrcCodeBehaviorSupplier<Context>;
) => pgen.PolygenCellContentBehaviorSupplier<Context>;
},
...srcCodeIdentities: CellID[]
) => {
Expand All @@ -62,31 +62,31 @@ export function polygenNotebookFactory<
},
});

const sourceCode: (
| pgen.PolygenSrcCodeSupplier<Context>
| pgen.PolygenSrcCodeBehaviorSupplier<Context>
const content: (
| pgen.PolygenCellContentSupplier<Context>
| pgen.PolygenCellContentBehaviorSupplier<Context>
)[] = [];
initRunState.runState.eventEmitter.afterCell = (cell, state) => {
if (state.status == "successful") {
if (
pgen.isPolygenSrcCodeSupplier<Context>(state.execResult) ||
pgen.isPolygenSrcCodeBehaviorSupplier<Context>(state.execResult)
pgen.isPolygenCellContentSupplier<Context>(state.execResult) ||
pgen.isPolygenCellContentBehaviorSupplier<Context>(state.execResult)
) {
if (options.separator) {
sourceCode.push(options.separator(cell, state));
content.push(options.separator(cell, state));
}
const sts = state.execResult as pgen.PolygenSrcCodeSupplier<
const sts = state.execResult as pgen.PolygenCellContentSupplier<
Context
>;
sourceCode.push(sts);
content.push(sts);
} else {
const notSTS = options.onNotSrcCodeSupplier?.(cell, state);
if (notSTS) sourceCode.push(notSTS);
if (notSTS) content.push(notSTS);
}
}
};
await kernel.run(instance(), initRunState);
return sourceCode;
return content;
},
};
}
73 changes: 35 additions & 38 deletions render/emit/polygenix.ts
Original file line number Diff line number Diff line change
@@ -1,82 +1,79 @@
import * as safety from "../../lib/universal/safety.ts";
import * as sql from "./sql.ts";

export interface PolygenSrcCodeEmitOptions {
readonly tableStructName: (tableName: string) => string;
readonly tableStructFieldName: (
tc: { tableName: string; columnName: string },
) => string;
}

export type PolygenSrcCodeText =
export type PolygenCellText =
| string
| string[];

export type PolygenSrcCode<Context extends sql.SqlEmitContext> =
| PolygenSrcCodeText
| ((ctx: Context) => PolygenSrcCodeText | Promise<PolygenSrcCodeText>)
export type PolygenCellContent<Context extends sql.SqlEmitContext> =
| PolygenCellText
| ((ctx: Context) => PolygenCellText | Promise<PolygenCellText>)
| sql.SqlTextSupplier<Context>;

export type PolygenSrcCodeSync<Context extends sql.SqlEmitContext> =
| PolygenSrcCodeText
| ((ctx: Context) => PolygenSrcCodeText)
export type PolygenCellContentSync<Context extends sql.SqlEmitContext> =
| PolygenCellText
| ((ctx: Context) => PolygenCellText)
| sql.SqlTextSupplier<Context>;

export async function sourceCodeText<Context extends sql.SqlEmitContext>(
export async function polygenCellContent<Context extends sql.SqlEmitContext>(
ctx: Context,
psc: PolygenSrcCodeSupplier<Context> | PolygenSrcCode<Context>,
psc: PolygenCellContentSupplier<Context> | PolygenCellContent<Context>,
): Promise<string> {
if (isPolygenSrcCodeSupplier<Context>(psc)) {
return sourceCodeText(ctx, psc.sourceCode);
if (isPolygenCellContentSupplier<Context>(psc)) {
return polygenCellContent(ctx, psc.polygenContent);
}
if (sql.isSqlTextSupplier<Context>(psc)) return psc.SQL(ctx);

if (typeof psc === "string") {
return psc;
} else if (typeof psc === "function") {
return await sourceCodeText(ctx, await psc(ctx));
return await polygenCellContent(ctx, await psc(ctx));
} else {
if (psc.length == 0) return "";
return psc.join("\n");
}
}

export function sourceCodeTextSync<Context extends sql.SqlEmitContext>(
export function polygenCellContentSync<Context extends sql.SqlEmitContext>(
ctx: Context,
psc: PolygenSrcCodeSync<Context>,
psc: PolygenCellContentSync<Context>,
): string {
if (sql.isSqlTextSupplier<Context>(psc)) return psc.SQL(ctx);

if (typeof psc === "string") {
return psc;
} else if (typeof psc === "function") {
return sourceCodeTextSync(ctx, psc(ctx));
return polygenCellContentSync(ctx, psc(ctx));
} else {
if (psc.length == 0) return "";
return psc.join("\n");
}
}

export interface PolygenSrcCodeSupplier<Context extends sql.SqlEmitContext> {
readonly sourceCode: PolygenSrcCode<Context>;
export interface PolygenCellContentSupplier<
Context extends sql.SqlEmitContext,
> {
readonly polygenContent: PolygenCellContent<Context>;
}

export function isPolygenSrcCodeSupplier<Context extends sql.SqlEmitContext>(
export function isPolygenCellContentSupplier<
Context extends sql.SqlEmitContext,
>(
o: unknown,
): o is PolygenSrcCodeSupplier<Context> {
const isPSCS = safety.typeGuard<PolygenSrcCodeSupplier<Context>>(
"sourceCode",
): o is PolygenCellContentSupplier<Context> {
const isPCCS = safety.typeGuard<PolygenCellContentSupplier<Context>>(
"polygenContent",
);
return isPSCS(o);
return isPCCS(o);
}

export interface PolygenSrcCodeBehaviorEmitTransformer {
export interface PolygenCellContentEmitTransformer {
before: (interpolationSoFar: string, exprIdx: number) => string;
after: (nextLiteral: string, exprIdx: number) => string;
}

export const removeLineFromPolygenEmitStream:
PolygenSrcCodeBehaviorEmitTransformer = {
PolygenCellContentEmitTransformer = {
before: (isf) => {
// remove the last line in the interpolation stream
return isf.replace(/\n.*?$/, "");
Expand All @@ -87,24 +84,24 @@ export const removeLineFromPolygenEmitStream:
},
};

export interface PolygenSrcCodeBehaviorSupplier<
export interface PolygenCellContentBehaviorSupplier<
Context extends sql.SqlEmitContext,
> {
readonly executePolygenSrcCodeBehavior: (
context: Context,
) =>
| PolygenSrcCodeBehaviorEmitTransformer
| PolygenSrcCodeSupplier<Context>
| PolygenSrcCodeSupplier<Context>[];
| PolygenCellContentEmitTransformer
| PolygenCellContentSupplier<Context>
| PolygenCellContentSupplier<Context>[];
}

export function isPolygenSrcCodeBehaviorSupplier<
export function isPolygenCellContentBehaviorSupplier<
Context extends sql.SqlEmitContext,
>(
o: unknown,
): o is PolygenSrcCodeBehaviorSupplier<Context> {
): o is PolygenCellContentBehaviorSupplier<Context> {
const isPSCBS = safety.typeGuard<
PolygenSrcCodeBehaviorSupplier<Context>
PolygenCellContentBehaviorSupplier<Context>
>("executePolygenSrcCodeBehavior");
return isPSCBS(o);
}
Loading

0 comments on commit 84de411

Please sign in to comment.