2023-10-09 21:53:44 +02:00
|
|
|
import type { Address } from "./types";
|
|
|
|
import { isAddress } from "./types";
|
|
|
|
|
2023-11-11 10:59:52 +01:00
|
|
|
export const Any = "?";
|
2023-11-11 11:17:43 +01:00
|
|
|
class Var {
|
|
|
|
constructor(public readonly name: string) {}
|
|
|
|
}
|
|
|
|
export function Variable(name: string): Var {
|
|
|
|
return new Var(name);
|
|
|
|
}
|
|
|
|
type QueryPart<T> = T | T[] | typeof Any | Var;
|
2023-10-09 21:53:44 +02:00
|
|
|
|
|
|
|
export class Query {
|
|
|
|
private _query: string | undefined;
|
|
|
|
|
2023-11-11 10:59:52 +01:00
|
|
|
public static matches(
|
|
|
|
entity: QueryPart<string>,
|
|
|
|
attribute: QueryPart<string>,
|
|
|
|
value: QueryPart<string | number | Address>
|
2023-10-09 21:53:44 +02:00
|
|
|
): Query {
|
|
|
|
const query = new Query();
|
|
|
|
|
|
|
|
let entityStr;
|
2023-11-11 10:59:52 +01:00
|
|
|
if (entity === Any) {
|
2023-10-09 21:53:44 +02:00
|
|
|
entityStr = "?";
|
2023-11-11 11:17:43 +01:00
|
|
|
} else if (entity instanceof Var) {
|
|
|
|
entityStr = `?${entity.name}`;
|
2023-10-09 21:53:44 +02:00
|
|
|
} else {
|
|
|
|
entityStr = Array.isArray(entity) ? `(in ${entity.join(" ")})` : entity;
|
|
|
|
}
|
|
|
|
|
|
|
|
let attributeStr;
|
2023-11-11 10:59:52 +01:00
|
|
|
if (attribute === Any) {
|
2023-10-09 21:53:44 +02:00
|
|
|
attributeStr = "?";
|
2023-11-11 11:17:43 +01:00
|
|
|
} else if (attribute instanceof Var) {
|
|
|
|
attributeStr = `?${attribute.name}`;
|
2023-10-09 21:53:44 +02:00
|
|
|
} else {
|
|
|
|
attributeStr = Array.isArray(attribute)
|
|
|
|
? `(in ${attribute.map((a) => `"${a}"`).join(" ")})`
|
|
|
|
: `"${attribute}"`;
|
|
|
|
}
|
|
|
|
|
|
|
|
let valueStr;
|
2023-11-11 10:59:52 +01:00
|
|
|
if (value === Any) {
|
2023-10-09 21:53:44 +02:00
|
|
|
valueStr = "?";
|
2023-11-11 11:17:43 +01:00
|
|
|
} else if (value instanceof Var) {
|
|
|
|
valueStr = `?${value.name}`;
|
2023-10-09 21:53:44 +02:00
|
|
|
} else {
|
|
|
|
valueStr = (Array.isArray(value) ? value : [value])
|
|
|
|
.map((v) => {
|
|
|
|
if (typeof v === "number") return v;
|
|
|
|
if (isAddress(v)) return v;
|
|
|
|
if (typeof v === "string") return `"${v}"`;
|
|
|
|
})
|
|
|
|
.join(" ");
|
|
|
|
valueStr = Array.isArray(value) ? `(in ${valueStr})` : valueStr;
|
|
|
|
}
|
|
|
|
|
|
|
|
query._query = `(matches ${entityStr} ${attributeStr} ${valueStr})`;
|
|
|
|
return query;
|
|
|
|
}
|
|
|
|
|
|
|
|
public toString(): string {
|
|
|
|
if (!this._query) throw new Error("Query is not defined");
|
|
|
|
return this._query;
|
|
|
|
}
|
|
|
|
}
|