properly select
This commit is contained in:
parent
f5b9494d26
commit
ba7b14937e
2 changed files with 119 additions and 18 deletions
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,71 @@ nodeRouter.put("/", async (ctx) => {
|
||||||
|
|
||||||
nodeRouter.post("/query", async (ctx) => {});
|
nodeRouter.post("/query", async (ctx) => {});
|
||||||
|
|
||||||
|
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
|
||||||
|
`);
|
||||||
|
|
||||||
|
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) => {
|
nodeRouter.get("/:id", async (ctx) => {
|
||||||
|
const result: false | undefined = await dataSource.transaction(async (em) => {
|
||||||
const query = dataSource
|
const query = dataSource
|
||||||
.createQueryBuilder()
|
.createQueryBuilder()
|
||||||
.select("node")
|
.select("node")
|
||||||
|
@ -85,12 +149,14 @@ nodeRouter.get("/:id", async (ctx) => {
|
||||||
.where("node.id = :id", { id: ctx.params.id });
|
.where("node.id = :id", { id: ctx.params.id });
|
||||||
|
|
||||||
const node = await query.getOne();
|
const node = await query.getOne();
|
||||||
if (node === null) {
|
if (node === null) return false;
|
||||||
ctx.status = 404;
|
|
||||||
ctx.body = { error: "Not found" };
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ctx.body = { node };
|
ctx.body = { node };
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (result === false) {
|
||||||
|
ctx.status = 404;
|
||||||
|
ctx.body = { error: "Not found" };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
nodeRouter.post("/:id", async (ctx) => {});
|
nodeRouter.post("/:id", async (ctx) => {});
|
||||||
|
|
Loading…
Reference in a new issue