import { Attribute, Table } from "./db"; import { Handler } from "./defaultHandler"; import { QueryBuilder } from "./query"; import { allModifierInput, joinElements, joinType, onAction, primaryData, serializeReturn } from "./types"; export class Datatype { type: string; args: primaryData[]; constructor(type: string, args: primaryData[]) { this.type = type; this.args = args; } serialize(handler: Handler): QueryBuilder { return handler.datatypes[this.type as keyof typeof handler.datatypes](this.args); } } export abstract class Modifier { t: string; a: Array; constructor(type: string, args: (allModifierInput)[]) { this.t = type; this.a = args; } serialize(handler: Handler): QueryBuilder { return handler.modifiers[this.t as keyof typeof handler.modifiers](handler, this.a); } } export class BooleanModifier extends Modifier { } export class NumberModifier extends Modifier { } export class StringModifier extends Modifier { } export class Aggregation { t: string; a: Attribute; constructor(type: string, args: Attribute) { this.t = type; this.a = args; } serialize(handler: Handler): QueryBuilder { return handler.aggregations[this.t as keyof typeof handler.aggregations](handler, this.a); } } export interface Joins { serialize(handler: Handler): QueryBuilder } export class joinNatural implements Joins{ tables: joinElements[]; type: joinType; constructor(tables:joinElements[], type: joinType){ this.tables = tables; this.type = type; } serialize(handler: Handler): QueryBuilder { return handler.joins.natural(handler,this); } } export class onJoin implements Joins{ tableA: joinElements; tableB: joinElements; type: joinType; on: BooleanModifier; constructor(tableA: joinElements, tableB: joinElements, type: joinType, on: BooleanModifier){ this.tableA = tableA; this.tableB = tableB; this.type = type; this.on = on; } serialize(handler: Handler): QueryBuilder { return handler.joins.on(handler,this); } } export class usingJoin implements Joins{ tableA: joinElements; tableB: joinElements; type: joinType; using: Attribute[]; constructor(tableA: joinElements, tableB: joinElements, type: joinType, using: Attribute[]){ this.tableA = tableA; this.tableB = tableB; this.type = type; this.using = using; } serialize(handler: Handler): QueryBuilder { return handler.joins.using(handler,this); } } export class joinCross implements Joins{ tables: joinElements[]; constructor(tables:joinElements[]){ this.tables = tables; } serialize(handler: Handler): QueryBuilder { return handler.joins.cross(handler,this); } } export interface Constraint { name: string; uses(attr: Attribute): boolean; check(table: Table): boolean | string; } export class checkConstraint implements Constraint { checkQuery: BooleanModifier; name: string; constructor(name: string, check: BooleanModifier) { this.name = name.toLowerCase(); this.checkQuery = check; } check(attr: Table): boolean { return true; } uses(attr: Attribute): boolean { throw new Error("Method not implemented."); } } export class uniqueConstraint implements Constraint { name: string; attrs: Attribute[]; constructor(name: string, attrs: Attribute[]) { this.name = name.toLowerCase(); this.attrs = attrs; } check(table: Table): boolean | string { for (let i = 0; i < this.attrs.length; i++) { if (this.attrs[i].ops.primaryKey) return "Can not combine unique Constraint and primary key"; if (this.attrs[i].table != table) return "Referencing Attributes must be in host Table."; } return false; } uses(attr: Attribute): boolean { return this.attrs.includes(attr); } } export class foreignConstraint implements Constraint { name: string; fromAttrs: Attribute[]; toAttrs: Attribute[]; onUpdate: onAction; onDelete: onAction; constructor(name: string, from: Attribute[], to: Attribute[], onDelete: onAction = onAction.nothing, onUpdate: onAction = onAction.nothing) { this.name = name.toLowerCase(); this.fromAttrs = from; this.toAttrs = to; this.onUpdate = onUpdate; this.onDelete = onDelete; } uses(attr: Attribute): boolean { throw new Error("Method not implemented."); } check(t: Table): string | boolean { let table = this.toAttrs[0].table; for (let i = 0; i < this.toAttrs.length; i++) { if (table != this.toAttrs[i].table) return "Referenced Attributes must be in one Table."; if (this.toAttrs[i].ops.primaryKey) return "Can not reference non primary keys."; } for (let i = 0; i < this.fromAttrs.length; i++) { if (this.fromAttrs[i].table != t) return "Referencing Attributes must be in host Table."; } return false; } }