diff --git a/src/database/database.js b/src/database/database.js index f11c83f..e0d1ec3 100644 --- a/src/database/database.js +++ b/src/database/database.js @@ -47,6 +47,10 @@ class Database { return this.connection; } + async ORMReady() { + await this.ORM.syncModels(); + } + get getORM() { return this.ORM; } diff --git a/src/database/psql-entity-framework/entity-relationships.js b/src/database/psql-entity-framework/entity-relationships.js index a253385..c107ad1 100644 --- a/src/database/psql-entity-framework/entity-relationships.js +++ b/src/database/psql-entity-framework/entity-relationships.js @@ -1,7 +1,7 @@ const Logger = require('../../logger.js'); const DataTypes = require('./types.js'); const Model = require('./model.js'); - +const { DataConstraints } = require('../database.js'); /** * In order to keep the models dynamic and flexible, we need to be able to add @@ -22,27 +22,96 @@ class PSQLObjectRelation { Logger.Database('ORM Loading...'); this.connection = psqlConnection;; this.models = []; + // dummyModels are for models that have requested a model that doesn't exist + // the model that doesn't exist will be added here, and once it is added, the + // dummy dependancy will be resolved + this.dummyModels = []; } + /** + * @function model + * @description Gets a model from the database stash + * @param {string} modelName - The name of the target model + */ model(modelName) { - return { } + // TODO: Resolve the dependancy if it dosen't exist and make a note of it + if (!this.models[modelName]) { + Logger.Database(`Model ${modelName} does not exist, adding to dummyModels`); + const dummy = new Model(modelName, {}, true); + this.dummyModels.push(dummy); + return dummy; + } + return this.models[modelName]; } - addModel(name, model, constraints) { + /** + * @function addModel + * @description Adds a model to the database stash + * @param {string} name + * @param {object} model + */ + addModel(name, model) { Logger.Database(`ORM Adding ${name}`); - const keys = Object.keys(model); - this.models[name] = new Model; + if (this.models[name]) { + Logger.Error(`Redefinition of model ${name}, ignoring.`); + return; + } + const keys = Object.keys(model); + + /** + * Make sure that every property has a type and a conatraints array + * If not, add it + * The structure should always look like: + * property: { + * type: DataTypes.VARCHAR(50), + * constraints: [ DataConstraints.PRIMARY_KEY, DataConstraints.NOT_NULL ] + * } + */ + keys.forEach(key => { + if (typeof model[key] != 'object') { + const type = model[key]; + model[key] = { + type: type, + constraints: [] + }; + } + if (!model[key].constraints) { + model[key].constraints = []; + } + }); + + this.models[name] = new Model(name, model); } + /** + * @function resolveDependants + * @description Resolves all the dependancies for the models that have been added where properties weren't available when they were added + */ resolveDepends() { - + console.log(this.models) + for (const model in this.models) { + console.log(model) + + // for (const property of model.properties) { + + // for (const constraint of property.constraints) { + // if (typeof constraint === 'object') { + // console.log('') + // if (constraint.fk.ref === DataTypes.INHERET) + // Logger.Debug(`Model ${model.name} has a dependancy on ${property.inherit}`); + // } + // } + + // } + } } // ONLY run this after all models are properly added async syncModels() { Logger.Database('ORM Syncing...'); + this.resolveDepends(); } } diff --git a/src/database/psql-entity-framework/model.js b/src/database/psql-entity-framework/model.js index b1791a8..76d4bab 100644 --- a/src/database/psql-entity-framework/model.js +++ b/src/database/psql-entity-framework/model.js @@ -1,13 +1,37 @@ +const Logger = require('../../logger.js'); +const DataTypes = require('./types.js'); /** * @class Model * @classdesc The Model class is used to create a model instance. + * @param {string} name - The name of the model + * @param {object} properties - The properties of the model + * @param {boolean} dummy - Whether or not the model is a dummy model */ class Model { + constructor(name, properties, dummy = false) { + this.name = name; + this.properties = properties; + this.dummy = dummy; - constructor() { + if (dummy) + Logger.Database(`Model ${name} is dummy: ${dummy}`); + + Logger.Database(`Model ${name} created, with properties: ${JSON.stringify(properties)}`); } + property(name) { + if (this.dummy) + { + this.properties[name] = { + type: DataTypes.INHERET, + constraints: [], + dummy: true + } + return "UNRESOVLED PROPERTY"; + } + return this.property[name]; + } } module.exports = Model; diff --git a/src/database/psql-entity-framework/relationships_constraints.js b/src/database/psql-entity-framework/relationships_constraints.js index c914d05..3152821 100644 --- a/src/database/psql-entity-framework/relationships_constraints.js +++ b/src/database/psql-entity-framework/relationships_constraints.js @@ -1,5 +1,5 @@ class RelationshipTypes { - static PRIMARY_KEY() { + static get PRIMARY_KEY() { return "PRIMARY KEY"; } diff --git a/src/database/psql-entity-framework/types.js b/src/database/psql-entity-framework/types.js index 2cf084b..8667249 100644 --- a/src/database/psql-entity-framework/types.js +++ b/src/database/psql-entity-framework/types.js @@ -1,4 +1,8 @@ class DataTypes { + static get INHERET() { + return 'INHERET'; + } + static VARCHAR(length) { return `VARCHAR(${length})`; } diff --git a/src/index.js b/src/index.js index f4b3d55..e0a4772 100644 --- a/src/index.js +++ b/src/index.js @@ -14,6 +14,7 @@ async function main() { await Database.connect(); ModelManager.Init(Database); + await Database.ORMReady(); Server.Listen(process.env.PORT); } diff --git a/src/models/catagory.js b/src/models/catagory.js new file mode 100644 index 0000000..2704022 --- /dev/null +++ b/src/models/catagory.js @@ -0,0 +1,17 @@ +const Models = require('./model-manager.js'); +const { DataTypes, DataConstraints } = require('../database/database.js'); +const { ORM } = Models.Database; + +async function init() { + ORM.addModel('catagory', { + id: { + type: DataTypes.INTEGER, + constraints: [ DataConstraints.PRIMARY_KEY, DataConstraints.NOT_NULL ] + }, + name: DataTypes.VARCHAR(100) + }); +} + +module.exports = { + Init: init +} diff --git a/src/models/lego-brick.js b/src/models/lego-brick.js index a0093c9..6f2377d 100644 --- a/src/models/lego-brick.js +++ b/src/models/lego-brick.js @@ -10,7 +10,7 @@ async function init() { }, catagory: { type: DataTypes.INTEGER, - // constraints: [ DataConstraints.FOREIGN_KEY_REF(ORM.model('catagory').property('id')) ] + constraints: [ DataConstraints.FOREIGN_KEY_REF(ORM.model('catagory').property('id')) ] }, date_released: DataTypes.DATE, dimenions_x: DataTypes.DECIMAL, diff --git a/src/models/model-manager.js b/src/models/model-manager.js index e3fb9a7..ee3545c 100644 --- a/src/models/model-manager.js +++ b/src/models/model-manager.js @@ -4,7 +4,7 @@ function init(databaseInstance) { module.exports.Database = databaseInstance; module.exports.Models = {}; - let files = fs.readdirSync(__dirname); + let files = fs.readdirSync(__dirname).reverse(); files.forEach(file => { if (file !== 'model-manager.js') { const model = require(`./${file}`); @@ -15,5 +15,5 @@ function init(databaseInstance) { } module.exports = { - Init: init + Init: init, }