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

View file

@ -77,20 +77,86 @@ nodeRouter.put("/", async (ctx) => {
nodeRouter.post("/query", async (ctx) => {});
nodeRouter.get("/:id", async (ctx) => {
const query = dataSource
.createQueryBuilder()
.select("node")
.from(PNode, "node")
.where("node.id = :id", { id: ctx.params.id });
nodeRouter.get("/recent", async (ctx) => {
const result = await dataSource.query<NodeHasAttribute[]>(`
SELECT
node20.id as nodeId,
hasAttr.attrName,
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();
if (node === null) {
console.log("result", result);
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.body = { error: "Not found" };
return;
}
ctx.body = { node };
});
nodeRouter.post("/:id", async (ctx) => {});