First Working Version #1
4 changed files with 101 additions and 27 deletions
11
src/db.ts
11
src/db.ts
|
@ -1,5 +1,5 @@
|
|||
import mariadb from 'mariadb';
|
||||
import { checkConstraint, Constraint, Datatype, uniqueConstraint } from './dbStructure';
|
||||
import { checkConstraint, Constraint, Datatype, foreignConstraint, uniqueConstraint } from './dbStructure';
|
||||
import { Handler } from './defaultHandler';
|
||||
import { Query } from './query';
|
||||
import { attributeSettings, extendedAttributeSettings, onAction } from './types';
|
||||
|
@ -67,6 +67,15 @@ export class Attribute {
|
|||
[this]
|
||||
))
|
||||
}
|
||||
if (ops.foreginKey != null) {
|
||||
table.addConstraint(new foreignConstraint(
|
||||
table.dbLangDatabaseInstance.name + "_" + table.dbLangTableName + "_" + name + "_foreign_constraint_to_"+ops.foreginKey.link.name,
|
||||
[this],
|
||||
[ops.foreginKey.link],
|
||||
ops.foreginKey.onDelete,
|
||||
ops.foreginKey.onUpdate
|
||||
));
|
||||
}
|
||||
}
|
||||
serializeDatatype(handler: Handler) {
|
||||
return this.type.serialize(handler);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Attribute, Table } from "./db";
|
||||
import { Handler } from "./defaultHandler";
|
||||
import { QueryBuilder } from "./query";
|
||||
import { allModifierInput, primaryData, serializeReturn } from "./types";
|
||||
import { allModifierInput, onAction, primaryData, serializeReturn } from "./types";
|
||||
|
||||
export class Datatype {
|
||||
type: string;
|
||||
|
@ -101,10 +101,14 @@ export class foreignConstraint implements Constraint {
|
|||
name: string;
|
||||
fromAttrs: Attribute[];
|
||||
toAttrs: Attribute[];
|
||||
constructor(name: string, from: Attribute[], to: 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;
|
||||
}
|
||||
serialize(handler: Handler): QueryBuilder {
|
||||
throw new Error("Method not implemented.");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Attribute, DB, Table } from "./db"
|
||||
import { Aggregation, checkConstraint, Constraint, Datatype, Modifier, uniqueConstraint } from "./dbStructure"
|
||||
import { Aggregation, checkConstraint, Constraint, Datatype, foreignConstraint, Modifier, uniqueConstraint } from "./dbStructure"
|
||||
import { Query, QueryBuilder, selectQuery } from "./query"
|
||||
import { allModifierInput, primaryData, serializeReturn } from "./types"
|
||||
import { allModifierInput, onAction, primaryData, serializeReturn } from "./types"
|
||||
|
||||
export class Handler {
|
||||
async syncDB(db: DB, handler: Handler, deleteInDB: boolean = false) {
|
||||
|
@ -19,8 +19,10 @@ export class Handler {
|
|||
|
||||
let [key, constraints] = await db.query(handler.builders.query(gd));
|
||||
|
||||
//Table List
|
||||
let allTables = (await db.query(handler.builders.query(handler.querys.listTables(handler, db)))).map((d: any) => d.TABLE_NAME);
|
||||
|
||||
// gether Table Schematics
|
||||
let tableData: { [key: string]: any; } = {};
|
||||
for (let i = 0; i < db.tables.length; i++) {
|
||||
const table = db.tables[i];
|
||||
|
@ -45,7 +47,6 @@ export class Handler {
|
|||
const c = t.dbLangConstrains[i];
|
||||
if (c.name == n.toLowerCase() && c instanceof uniqueConstraint) {
|
||||
let attrs = c.attrs.map(a => a.name);
|
||||
console.log(attrs);
|
||||
let found = 0;
|
||||
for (let j = 0; j < key.length; j++) {
|
||||
if (
|
||||
|
@ -61,6 +62,35 @@ export class Handler {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkForeignIsVaild(n: string, table: string) {
|
||||
let t = db.getTable(table);
|
||||
if (t == null) return false;
|
||||
for (let i = 0; i < t.dbLangConstrains.length; i++) {
|
||||
const c = t.dbLangConstrains[i];
|
||||
if (c.name == n.toLowerCase() && c instanceof foreignConstraint) {
|
||||
let fromAttrs = c.fromAttrs.map(a => a.name);
|
||||
let toAttrs = c.toAttrs.map(a => a.name);
|
||||
let refTable = c.toAttrs[0].table.dbLangTableName;
|
||||
let found = 0;
|
||||
for (let j = 0; j < key.length; j++) {
|
||||
if (
|
||||
key[j].CONSTRAINT_NAME == n
|
||||
&& key[j].TABLE_NAME == table
|
||||
&& key[j].REFERENCED_TABLE_NAME == refTable
|
||||
) {
|
||||
let inF = fromAttrs.indexOf(key[j].COLUMN_NAME.toLowerCase());
|
||||
let inT = toAttrs.indexOf(key[j].REFERENCED_COLUMN_NAME.toLowerCase());
|
||||
if (inF != -1 && inT == inF) found++;
|
||||
else return false;
|
||||
}
|
||||
}
|
||||
return found == fromAttrs.length && found == toAttrs.length;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkUniqueExists(tabel: Table, c: uniqueConstraint) {
|
||||
let attrs = c.attrs.map(a => a.name);
|
||||
let found = 0;
|
||||
|
@ -75,6 +105,25 @@ export class Handler {
|
|||
}
|
||||
return found == attrs.length;
|
||||
}
|
||||
function checkForeignExists(tabel: Table, c: foreignConstraint) {
|
||||
let fromAttrs = c.fromAttrs.map(a => a.name);
|
||||
let toAttrs = c.toAttrs.map(a => a.name);
|
||||
let refTable = c.toAttrs[0].table.dbLangTableName;
|
||||
let found = 0;
|
||||
for (let j = 0; j < key.length; j++) {
|
||||
if (
|
||||
key[j].CONSTRAINT_NAME == c.name
|
||||
&& key[j].TABLE_NAME == tabel.dbLangTableName
|
||||
&& key[j].REFERENCED_TABLE_NAME == refTable
|
||||
) {
|
||||
let inF = fromAttrs.indexOf(key[j].COLUMN_NAME.toLowerCase());
|
||||
let inT = toAttrs.indexOf(key[j].REFERENCED_COLUMN_NAME.toLowerCase());
|
||||
if (inF != -1 && inT == inF) found++;
|
||||
else return false;
|
||||
}
|
||||
}
|
||||
return found == fromAttrs.length && found == toAttrs.length;
|
||||
}
|
||||
|
||||
//delete check and unused/false(unique, foreign) constraints
|
||||
for (let i = 0; i < constraints.length; i++) {
|
||||
|
@ -86,15 +135,17 @@ export class Handler {
|
|||
(typeof tableData[c.TABLE_NAME.toLowerCase()] == "undefined" && deleteInDB)
|
||||
|| !checkUniqueIsVaild(c.CONSTRAINT_NAME, c.TABLE_NAME)
|
||||
) del.appendEnding(handler.querys.removeUnique(handler, c.TABLE_NAME, c.CONSTRAINT_NAME));
|
||||
} else if (c.CONSTRAINT_TYPE == "FOREIGN KEY" && deleteInDB) {
|
||||
if (typeof tableData[c.TABLE_NAME.toLowerCase()] == "undefined") del.appendEnding(handler.querys.removeForeignKey(handler, c.TABLE_NAME, c.CONSTRAINT_NAME));
|
||||
} else if (c.CONSTRAINT_TYPE == "FOREIGN KEY") {
|
||||
if (
|
||||
(typeof tableData[c.TABLE_NAME.toLowerCase()] == "undefined" && deleteInDB)
|
||||
|| !checkForeignIsVaild(c.CONSTRAINT_NAME, c.TABLE_NAME)
|
||||
) del.appendEnding(handler.querys.removeForeignKey(handler, c.TABLE_NAME, c.CONSTRAINT_NAME));
|
||||
}
|
||||
}
|
||||
//delete unused Tables
|
||||
if (deleteInDB) for (let i = 0; i < allTables.length; i++) {
|
||||
if (typeof tableData[allTables[i].toLowerCase()] == "undefined") del.appendEnding(handler.querys.deleteTable(handler, allTables[i]));
|
||||
}
|
||||
// TODO: delete old constraints/tables
|
||||
|
||||
function freeForUpdate(attr: string, table: string) {
|
||||
for (let i = 0; i < key.length; i++) {
|
||||
|
@ -113,7 +164,7 @@ export class Handler {
|
|||
const table = db.tables[i];
|
||||
const tableD = tableData[table.dbLangTableName.toLowerCase()];
|
||||
//delete unused Columns
|
||||
if (deleteInDB) {
|
||||
if (deleteInDB && tableD != null) {
|
||||
let keys = Object.keys(tableD);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
if (table.dbLangTableAttributes[keys[i]] == null) {
|
||||
|
@ -141,10 +192,10 @@ export class Handler {
|
|||
(!!a.ops.notNull || !!a.ops.autoIncrement || !!a.ops.primaryKey) != (attrData.Null == "NO") ||
|
||||
(!!a.ops.autoIncrement) != (attrData.Extra == "auto_increment")
|
||||
) {
|
||||
console.log(!handler.builders.compareDatatypes(handler, a.type, attrData.Type), "|",
|
||||
/*console.log(!handler.builders.compareDatatypes(handler, a.type, attrData.Type), "|",
|
||||
a.ops.default, attrData.Default, "|",
|
||||
(!!a.ops.notNull || !!a.ops.autoIncrement || !!a.ops.primaryKey), (attrData.Null == "NO"), "|",
|
||||
(!!a.ops.autoIncrement), (attrData.Extra == "auto_increment"));
|
||||
(!!a.ops.autoIncrement), (attrData.Extra == "auto_increment"));*/
|
||||
freeForUpdate(a.name, a.table.dbLangTableName);
|
||||
create.appendEnding(handler.querys.changeColumn(handler, a));
|
||||
}
|
||||
|
@ -170,10 +221,12 @@ export class Handler {
|
|||
if (!checkUniqueExists(table, c)) {
|
||||
create.appendEnding(handler.querys.addUnique(handler, table, c));
|
||||
}
|
||||
} else if (c instanceof foreignConstraint) {
|
||||
if (!checkForeignExists(table, c)) {
|
||||
create.appendEnding(handler.querys.addForeignKey(handler, table, c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: unique, foreignkey
|
||||
}
|
||||
if (!create.isEmpty()) del.append(create);
|
||||
if (!del.isEmpty()) await db.query(handler.builders.query(del));
|
||||
|
@ -262,22 +315,29 @@ export class Handler {
|
|||
builder.addCode(handler.builders.escapeID(attr));
|
||||
return builder;
|
||||
},
|
||||
addForeignKey: (handler: Handler, attr: Attribute, target: Attribute) => {
|
||||
addForeignKey: (handler: Handler, table: Table, c: foreignConstraint) => {
|
||||
const builder = new QueryBuilder();
|
||||
builder.addCode("ALTER TABLE ");
|
||||
builder.addCode(attr.table.serialize(handler));
|
||||
builder.addCode(table.serialize(handler));
|
||||
builder.addCode(" ADD CONSTRAINT ");
|
||||
builder.addCode(handler.builders.escapeID(attr.table.dbLangDatabaseInstance.name
|
||||
+ "_" + attr.table.dbLangTableName
|
||||
+ "_" + attr.name + "_foreign_key_constraint_to_"
|
||||
+ target.table.dbLangTableName + "_" + target.name));
|
||||
builder.addCode(handler.builders.escapeID(c.name));
|
||||
builder.addCode(" FOREIGN KEY (");
|
||||
builder.addCode(attr.serialize(handler));
|
||||
builder.addCodeCommaSeperated(c.fromAttrs.map(a => a.serialize(handler)));
|
||||
builder.addCode(") REFERENCES ");
|
||||
builder.addCode(target.table.serialize(handler));
|
||||
builder.addCode(c.toAttrs[0].table.serialize(handler));
|
||||
builder.addCode("(");
|
||||
builder.addCode(target.serialize(handler));
|
||||
builder.addCodeCommaSeperated(c.toAttrs.map(a => a.serialize(handler)));
|
||||
builder.addCode(")");
|
||||
|
||||
if (c.onUpdate == onAction.cascade) builder.addCode(" ON UPDATE CASCADE");
|
||||
if (c.onUpdate == onAction.noAction) builder.addCode(" ON UPDATE NO ACTION");
|
||||
if (c.onUpdate == onAction.setDefault) builder.addCode(" ON UPDATE SET DEFUALT");
|
||||
if (c.onUpdate == onAction.setNull) builder.addCode(" ON UPDATE SET NULL");
|
||||
|
||||
if (c.onDelete == onAction.cascade) builder.addCode(" ON DELETE CASCADE");
|
||||
if (c.onDelete == onAction.noAction) builder.addCode(" ON DELETE NO ACTION");
|
||||
if (c.onDelete == onAction.setDefault) builder.addCode(" ON DELETE SET DEFUALT");
|
||||
if (c.onDelete == onAction.setNull) builder.addCode(" ON DELETE SET NULL");
|
||||
return builder;
|
||||
},
|
||||
removeForeignKey: (handler: Handler, tablenName: string, name: string) => {
|
||||
|
|
|
@ -42,6 +42,7 @@ export type extendedAttributeSettings = {
|
|||
}
|
||||
|
||||
export enum onAction {
|
||||
nothing,
|
||||
cascade,
|
||||
noAction,
|
||||
setNull,
|
||||
|
|
Loading…
Reference in a new issue