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 mariadb from 'mariadb';
|
||||||
import { checkConstraint, Constraint, Datatype, uniqueConstraint } from './dbStructure';
|
import { checkConstraint, Constraint, Datatype, foreignConstraint, uniqueConstraint } from './dbStructure';
|
||||||
import { Handler } from './defaultHandler';
|
import { Handler } from './defaultHandler';
|
||||||
import { Query } from './query';
|
import { Query } from './query';
|
||||||
import { attributeSettings, extendedAttributeSettings, onAction } from './types';
|
import { attributeSettings, extendedAttributeSettings, onAction } from './types';
|
||||||
|
@ -67,6 +67,15 @@ export class Attribute {
|
||||||
[this]
|
[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) {
|
serializeDatatype(handler: Handler) {
|
||||||
return this.type.serialize(handler);
|
return this.type.serialize(handler);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Attribute, Table } from "./db";
|
import { Attribute, Table } from "./db";
|
||||||
import { Handler } from "./defaultHandler";
|
import { Handler } from "./defaultHandler";
|
||||||
import { QueryBuilder } from "./query";
|
import { QueryBuilder } from "./query";
|
||||||
import { allModifierInput, primaryData, serializeReturn } from "./types";
|
import { allModifierInput, onAction, primaryData, serializeReturn } from "./types";
|
||||||
|
|
||||||
export class Datatype {
|
export class Datatype {
|
||||||
type: string;
|
type: string;
|
||||||
|
@ -101,10 +101,14 @@ export class foreignConstraint implements Constraint {
|
||||||
name: string;
|
name: string;
|
||||||
fromAttrs: Attribute[];
|
fromAttrs: Attribute[];
|
||||||
toAttrs: 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.name = name.toLowerCase();
|
||||||
this.fromAttrs = from;
|
this.fromAttrs = from;
|
||||||
this.toAttrs = to;
|
this.toAttrs = to;
|
||||||
|
this.onUpdate = onUpdate;
|
||||||
|
this.onDelete = onDelete;
|
||||||
}
|
}
|
||||||
serialize(handler: Handler): QueryBuilder {
|
serialize(handler: Handler): QueryBuilder {
|
||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Attribute, DB, Table } from "./db"
|
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 { Query, QueryBuilder, selectQuery } from "./query"
|
||||||
import { allModifierInput, primaryData, serializeReturn } from "./types"
|
import { allModifierInput, onAction, primaryData, serializeReturn } from "./types"
|
||||||
|
|
||||||
export class Handler {
|
export class Handler {
|
||||||
async syncDB(db: DB, handler: Handler, deleteInDB: boolean = false) {
|
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));
|
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);
|
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; } = {};
|
let tableData: { [key: string]: any; } = {};
|
||||||
for (let i = 0; i < db.tables.length; i++) {
|
for (let i = 0; i < db.tables.length; i++) {
|
||||||
const table = db.tables[i];
|
const table = db.tables[i];
|
||||||
|
@ -45,7 +47,6 @@ export class Handler {
|
||||||
const c = t.dbLangConstrains[i];
|
const c = t.dbLangConstrains[i];
|
||||||
if (c.name == n.toLowerCase() && c instanceof uniqueConstraint) {
|
if (c.name == n.toLowerCase() && c instanceof uniqueConstraint) {
|
||||||
let attrs = c.attrs.map(a => a.name);
|
let attrs = c.attrs.map(a => a.name);
|
||||||
console.log(attrs);
|
|
||||||
let found = 0;
|
let found = 0;
|
||||||
for (let j = 0; j < key.length; j++) {
|
for (let j = 0; j < key.length; j++) {
|
||||||
if (
|
if (
|
||||||
|
@ -61,6 +62,35 @@ export class Handler {
|
||||||
}
|
}
|
||||||
return false;
|
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) {
|
function checkUniqueExists(tabel: Table, c: uniqueConstraint) {
|
||||||
let attrs = c.attrs.map(a => a.name);
|
let attrs = c.attrs.map(a => a.name);
|
||||||
let found = 0;
|
let found = 0;
|
||||||
|
@ -75,6 +105,25 @@ export class Handler {
|
||||||
}
|
}
|
||||||
return found == attrs.length;
|
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
|
//delete check and unused/false(unique, foreign) constraints
|
||||||
for (let i = 0; i < constraints.length; i++) {
|
for (let i = 0; i < constraints.length; i++) {
|
||||||
|
@ -86,15 +135,17 @@ export class Handler {
|
||||||
(typeof tableData[c.TABLE_NAME.toLowerCase()] == "undefined" && deleteInDB)
|
(typeof tableData[c.TABLE_NAME.toLowerCase()] == "undefined" && deleteInDB)
|
||||||
|| !checkUniqueIsVaild(c.CONSTRAINT_NAME, c.TABLE_NAME)
|
|| !checkUniqueIsVaild(c.CONSTRAINT_NAME, c.TABLE_NAME)
|
||||||
) del.appendEnding(handler.querys.removeUnique(handler, c.TABLE_NAME, c.CONSTRAINT_NAME));
|
) del.appendEnding(handler.querys.removeUnique(handler, c.TABLE_NAME, c.CONSTRAINT_NAME));
|
||||||
} else if (c.CONSTRAINT_TYPE == "FOREIGN KEY" && deleteInDB) {
|
} else if (c.CONSTRAINT_TYPE == "FOREIGN KEY") {
|
||||||
if (typeof tableData[c.TABLE_NAME.toLowerCase()] == "undefined") del.appendEnding(handler.querys.removeForeignKey(handler, c.TABLE_NAME, c.CONSTRAINT_NAME));
|
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
|
//delete unused Tables
|
||||||
if (deleteInDB) for (let i = 0; i < allTables.length; i++) {
|
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]));
|
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) {
|
function freeForUpdate(attr: string, table: string) {
|
||||||
for (let i = 0; i < key.length; i++) {
|
for (let i = 0; i < key.length; i++) {
|
||||||
|
@ -113,7 +164,7 @@ export class Handler {
|
||||||
const table = db.tables[i];
|
const table = db.tables[i];
|
||||||
const tableD = tableData[table.dbLangTableName.toLowerCase()];
|
const tableD = tableData[table.dbLangTableName.toLowerCase()];
|
||||||
//delete unused Columns
|
//delete unused Columns
|
||||||
if (deleteInDB) {
|
if (deleteInDB && tableD != null) {
|
||||||
let keys = Object.keys(tableD);
|
let keys = Object.keys(tableD);
|
||||||
for (let i = 0; i < keys.length; i++) {
|
for (let i = 0; i < keys.length; i++) {
|
||||||
if (table.dbLangTableAttributes[keys[i]] == null) {
|
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.notNull || !!a.ops.autoIncrement || !!a.ops.primaryKey) != (attrData.Null == "NO") ||
|
||||||
(!!a.ops.autoIncrement) != (attrData.Extra == "auto_increment")
|
(!!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.default, attrData.Default, "|",
|
||||||
(!!a.ops.notNull || !!a.ops.autoIncrement || !!a.ops.primaryKey), (attrData.Null == "NO"), "|",
|
(!!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);
|
freeForUpdate(a.name, a.table.dbLangTableName);
|
||||||
create.appendEnding(handler.querys.changeColumn(handler, a));
|
create.appendEnding(handler.querys.changeColumn(handler, a));
|
||||||
}
|
}
|
||||||
|
@ -170,10 +221,12 @@ export class Handler {
|
||||||
if (!checkUniqueExists(table, c)) {
|
if (!checkUniqueExists(table, c)) {
|
||||||
create.appendEnding(handler.querys.addUnique(handler, 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 (!create.isEmpty()) del.append(create);
|
||||||
if (!del.isEmpty()) await db.query(handler.builders.query(del));
|
if (!del.isEmpty()) await db.query(handler.builders.query(del));
|
||||||
|
@ -262,22 +315,29 @@ export class Handler {
|
||||||
builder.addCode(handler.builders.escapeID(attr));
|
builder.addCode(handler.builders.escapeID(attr));
|
||||||
return builder;
|
return builder;
|
||||||
},
|
},
|
||||||
addForeignKey: (handler: Handler, attr: Attribute, target: Attribute) => {
|
addForeignKey: (handler: Handler, table: Table, c: foreignConstraint) => {
|
||||||
const builder = new QueryBuilder();
|
const builder = new QueryBuilder();
|
||||||
builder.addCode("ALTER TABLE ");
|
builder.addCode("ALTER TABLE ");
|
||||||
builder.addCode(attr.table.serialize(handler));
|
builder.addCode(table.serialize(handler));
|
||||||
builder.addCode(" ADD CONSTRAINT ");
|
builder.addCode(" ADD CONSTRAINT ");
|
||||||
builder.addCode(handler.builders.escapeID(attr.table.dbLangDatabaseInstance.name
|
builder.addCode(handler.builders.escapeID(c.name));
|
||||||
+ "_" + attr.table.dbLangTableName
|
|
||||||
+ "_" + attr.name + "_foreign_key_constraint_to_"
|
|
||||||
+ target.table.dbLangTableName + "_" + target.name));
|
|
||||||
builder.addCode(" FOREIGN KEY (");
|
builder.addCode(" FOREIGN KEY (");
|
||||||
builder.addCode(attr.serialize(handler));
|
builder.addCodeCommaSeperated(c.fromAttrs.map(a => a.serialize(handler)));
|
||||||
builder.addCode(") REFERENCES ");
|
builder.addCode(") REFERENCES ");
|
||||||
builder.addCode(target.table.serialize(handler));
|
builder.addCode(c.toAttrs[0].table.serialize(handler));
|
||||||
builder.addCode("(");
|
builder.addCode("(");
|
||||||
builder.addCode(target.serialize(handler));
|
builder.addCodeCommaSeperated(c.toAttrs.map(a => a.serialize(handler)));
|
||||||
builder.addCode(")");
|
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;
|
return builder;
|
||||||
},
|
},
|
||||||
removeForeignKey: (handler: Handler, tablenName: string, name: string) => {
|
removeForeignKey: (handler: Handler, tablenName: string, name: string) => {
|
||||||
|
|
|
@ -42,6 +42,7 @@ export type extendedAttributeSettings = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum onAction {
|
export enum onAction {
|
||||||
|
nothing,
|
||||||
cascade,
|
cascade,
|
||||||
noAction,
|
noAction,
|
||||||
setNull,
|
setNull,
|
||||||
|
|
Loading…
Reference in a new issue