initial commit
This commit is contained in:
89
src/example-def.ts
Normal file
89
src/example-def.ts
Normal file
@ -0,0 +1,89 @@
|
||||
import { SystemDef } from './processDef';
|
||||
|
||||
let def: SystemDef = {
|
||||
storage: {
|
||||
tables: [
|
||||
{
|
||||
name: "tasks",
|
||||
relations: [
|
||||
{
|
||||
type: 'belongs-to',
|
||||
table: 'lists',
|
||||
}
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
name: "name",
|
||||
type: "string",
|
||||
nullable: false,
|
||||
},
|
||||
{
|
||||
name: "description",
|
||||
type: "string",
|
||||
nullable: true,
|
||||
},
|
||||
{
|
||||
name: "completed",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
},
|
||||
{
|
||||
name: "completed_date",
|
||||
type: "date",
|
||||
nullable: true,
|
||||
},
|
||||
{
|
||||
name: "metadata",
|
||||
type: "blob",
|
||||
nullable: true,
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "lists",
|
||||
relations: [],
|
||||
columns: [
|
||||
{
|
||||
name: "name",
|
||||
type: "string",
|
||||
unique: false,
|
||||
nullable: false,
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "users",
|
||||
relations: [],
|
||||
columns: [
|
||||
{
|
||||
name: "name",
|
||||
type: "string",
|
||||
nullable: false,
|
||||
},
|
||||
{
|
||||
name: "password",
|
||||
type: "string",
|
||||
nullable: false,
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
relations: [
|
||||
{
|
||||
left: 'lists',
|
||||
relation: 'many-to-many',
|
||||
right: 'users',
|
||||
columns: [
|
||||
{
|
||||
name: 'access',
|
||||
type: 'string',
|
||||
unique: false,
|
||||
nullable: false,
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export default def;
|
114
src/processDef.ts
Normal file
114
src/processDef.ts
Normal file
@ -0,0 +1,114 @@
|
||||
|
||||
import defs from './example-def';
|
||||
|
||||
function createDatabase(storageDef: StorageDef) {
|
||||
let tableCreationQueries: string[] = [];
|
||||
for (let i in storageDef.tables) {
|
||||
tableCreationQueries.push(getTableCreationString(storageDef.tables[i]));
|
||||
}
|
||||
for (let i in storageDef.relations) {
|
||||
tableCreationQueries.push(getTableRelationsCreationString(storageDef.relations[i]));
|
||||
}
|
||||
tableCreationQueries.map((query: string) => {
|
||||
console.log(query);
|
||||
});
|
||||
}
|
||||
|
||||
function getTableCreationString(tableDef: TableDef): string {
|
||||
let primaryKeyString: string = `${tableDef.name}_id VARCHAR(36) PRIMARY KEY`;
|
||||
let columnString: string = `${primaryKeyString}`;
|
||||
let defaultColumns: string = `created DATETIME NOT NULL DEFAULT NOW(), modified DATETIME NOT NULL DEFAULT NOW()`
|
||||
let indexString: string = ``;
|
||||
|
||||
// columns
|
||||
for (let i in tableDef.columns) {
|
||||
let column: ColumnDef = tableDef.columns[i];
|
||||
columnString = `${columnString}, ${createColumnString(column)}`;
|
||||
}
|
||||
|
||||
// relations
|
||||
for (let i in tableDef.relations) {
|
||||
let relation: BelongsToDef = tableDef.relations[i];
|
||||
columnString = `${columnString}, ${relation.table}_id VARCHAR(36)`;
|
||||
}
|
||||
|
||||
// default created & modified
|
||||
columnString = `${columnString}, ${defaultColumns}`;
|
||||
|
||||
return `CREATE TABLE IF NOT EXISTS ${tableDef.name} (${columnString}${indexString !== '' ? ', ' + indexString : ''});`;
|
||||
}
|
||||
|
||||
function createColumnString(column: ColumnDef) {
|
||||
const typeMap: {[type: string]: string} = {
|
||||
"blob": "BLOB",
|
||||
"boolean": "BOOLEAN",
|
||||
"date": "DATE",
|
||||
"dateTIME": "DATETIME",
|
||||
"number": "INT",
|
||||
"string": "VARCHAR(255)",
|
||||
};
|
||||
|
||||
return `${column.name} ${typeMap[column.type]}${column.nullable ? '' : ' NOT NULL'}${column.default ? ' DEFAULT ' + column.default : ''}${column.autoIncrement ? ' AUTO_INCREMENT' : ''}${column.unique ? ' UNIQUE' : ''}`;
|
||||
}
|
||||
|
||||
function getTableRelationsCreationString(relationsDef: ManyToManyDef): string {
|
||||
let columnString: string = `${relationsDef.left}_id VARCHAR(36) NOT NULL, ${relationsDef.right}_id VARCHAR(36) NOT NULL`;
|
||||
let indexString: string = `INDEX ${relationsDef.left}_id_index (${relationsDef.left}_id), INDEX ${relationsDef.right}_id_index (${relationsDef.right}_id)`;
|
||||
|
||||
if (relationsDef.columns && relationsDef.columns.length) {
|
||||
for (let i in relationsDef.columns) {
|
||||
let column: ColumnDef = relationsDef.columns[i];
|
||||
columnString = `${columnString}, ${createColumnString(column)}`;
|
||||
}
|
||||
}
|
||||
|
||||
return `CREATE TABLE IF NOT EXISTS ${relationsDef.left}_${relationsDef.right} (${columnString}${indexString !== '' ? ', ' + indexString : ''});`;
|
||||
}
|
||||
|
||||
|
||||
createDatabase(defs.storage);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
interface SystemDef {
|
||||
storage: StorageDef;
|
||||
// TODO: add Views, ACLs, Behaviors, UX
|
||||
}
|
||||
|
||||
interface StorageDef {
|
||||
tables: TableDef[];
|
||||
relations: ManyToManyDef[];
|
||||
}
|
||||
|
||||
interface TableDef {
|
||||
name: string;
|
||||
columns: ColumnDef[],
|
||||
relations: BelongsToDef[],
|
||||
}
|
||||
|
||||
interface ColumnDef {
|
||||
name: string;
|
||||
type: "blob" | "boolean" | "date" | "dateTIME" | "number" | "string";
|
||||
nullable: boolean;
|
||||
unique?: boolean;
|
||||
autoIncrement?: boolean;
|
||||
default?: string;
|
||||
}
|
||||
|
||||
interface BelongsToDef {
|
||||
type: 'belongs-to';
|
||||
table: string;
|
||||
}
|
||||
|
||||
interface ManyToManyDef {
|
||||
left: string;
|
||||
relation: 'many-to-many';
|
||||
right: string;
|
||||
columns?: ColumnDef[];
|
||||
}
|
||||
|
||||
export {
|
||||
SystemDef
|
||||
}
|
Reference in New Issue
Block a user