properly select

This commit is contained in:
Michael Zhang 2024-07-10 04:19:18 -05:00
parent f5b9494d26
commit ba7b14937e
2 changed files with 119 additions and 18 deletions

View file

@ -2,6 +2,7 @@ import {
Column, Column,
Entity, Entity,
Index, Index,
JoinColumn,
ManyToOne, ManyToOne,
OneToMany, OneToMany,
PrimaryColumn, PrimaryColumn,
@ -18,7 +19,7 @@ export class PNode {
@OneToMany( @OneToMany(
() => NodeHasAttribute, () => NodeHasAttribute,
(hasAttr) => hasAttr.nodeId, (hasAttr) => hasAttr.node,
) )
attributes!: NodeHasAttribute[]; attributes!: NodeHasAttribute[];
} }
@ -29,22 +30,25 @@ export class App {
id!: string; id!: string;
@Column() @Column()
@Index({})
name!: string; name!: string;
@OneToMany( @OneToMany(
() => Attribute, () => Attribute,
(attr) => attr.appId, (attr) => attr.app,
) )
attributes!: Attribute[]; attributes!: Attribute[];
@OneToMany(
() => NodeHasAttribute,
(attr) => attr.app,
)
attributeInstances!: NodeHasAttribute[];
} }
@Entity() @Entity()
export class Attribute { export class Attribute {
@PrimaryColumn() @PrimaryColumn()
@ManyToOne(
() => App,
(app) => app.id,
)
appId!: string; appId!: string;
@PrimaryColumn() @PrimaryColumn()
@ -53,20 +57,51 @@ export class Attribute {
@Column() @Column()
@Index({}) @Index({})
type!: string; type!: string;
@ManyToOne(
() => App,
(app) => app.attributes,
)
@JoinColumn({ name: "appId", referencedColumnName: "id" })
app!: App;
@OneToMany(
() => NodeHasAttribute,
(attr) => attr.attr,
)
instances!: NodeHasAttribute[];
} }
@Entity() @Entity()
export class NodeHasAttribute { export class NodeHasAttribute {
@PrimaryColumn()
@ManyToOne( @ManyToOne(
() => PNode, () => PNode,
(node) => node.id, (node) => node.attributes,
) )
@JoinColumn({ name: "nodeId" })
node!: PNode;
@PrimaryColumn()
nodeId!: string; nodeId!: string;
@ManyToOne(
() => App,
(app) => app.attributeInstances,
)
@JoinColumn({ name: "appId", referencedColumnName: "id" })
app!: App;
@PrimaryColumn() @PrimaryColumn()
appId!: string; appId!: string;
@ManyToOne(
() => Attribute,
(attr) => attr.instances,
)
@JoinColumn({ name: "appId", referencedColumnName: "appId" })
@JoinColumn({ name: "attrName", referencedColumnName: "name" })
attr!: Attribute;
@PrimaryColumn() @PrimaryColumn()
attrName!: string; attrName!: string;

View file

@ -77,20 +77,86 @@ nodeRouter.put("/", async (ctx) => {
nodeRouter.post("/query", async (ctx) => {}); nodeRouter.post("/query", async (ctx) => {});
nodeRouter.get("/:id", async (ctx) => { nodeRouter.get("/recent", async (ctx) => {
const query = dataSource const result = await dataSource.query<NodeHasAttribute[]>(`
.createQueryBuilder() SELECT
.select("node") node20.id as nodeId,
.from(PNode, "node") hasAttr.attrName,
.where("node.id = :id", { id: ctx.params.id }); app.name AS appName,
attr.type AS attrType,
hasAttr.nodeRef,
hasAttr.number,
hasAttr.string,
hasAttr.boolean,
hasAttr.instant
FROM node_has_attribute hasAttr
INNER JOIN (SELECT * FROM node ORDER BY lastUpdated DESC LIMIT 20) node20 ON node20.id = hasAttr.nodeId
INNER JOIN app ON app.id = hasAttr.appId
INNER JOIN attribute attr ON attr.appId = hasAttr.appId AND attr.name = hasAttr.attrName
`);
const node = await query.getOne(); console.log("result", result);
if (node === null) {
const convertValue = (type: string, row: Partial<NodeHasAttribute>): any => {
switch (type) {
case "string":
return row.string;
case "datetime":
return new Date(row.instant);
default:
console.error(`unknown type ${type}`);
return "";
}
};
const idAttrs = new Map<string, Map<string, any>>();
for (const hasAttr of result) {
if (!idAttrs.has(hasAttr.nodeId)) idAttrs.set(hasAttr.nodeId, new Map());
idAttrs
.get(hasAttr.nodeId)!
.set(
`${hasAttr.appName}::${hasAttr.attrName}`,
convertValue(hasAttr.attrType, hasAttr),
);
}
const result2 = [...idAttrs.entries()].map(([id, attrs]) => ({
id,
attributes: Object.fromEntries(attrs.entries()),
}));
// result = result.map((v) => ({
// id: v.id,
// attributes: new Map(
// v.attr.map((attr) => [
// `${attr.app.name}::${attr.attrName}`,
// convertValue(attr.attr.type, attr),
// ]),
// ),
// }));
ctx.body = result2;
});
nodeRouter.get("/:id", async (ctx) => {
const result: false | undefined = await dataSource.transaction(async (em) => {
const query = dataSource
.createQueryBuilder()
.select("node")
.from(PNode, "node")
.where("node.id = :id", { id: ctx.params.id });
const node = await query.getOne();
if (node === null) return false;
ctx.body = { node };
});
if (result === false) {
ctx.status = 404; ctx.status = 404;
ctx.body = { error: "Not found" }; ctx.body = { error: "Not found" };
return;
} }
ctx.body = { node };
}); });
nodeRouter.post("/:id", async (ctx) => {}); nodeRouter.post("/:id", async (ctx) => {});