Skip to content

Commit

Permalink
Added 'postValidation' function to schema and items so that hooks can…
Browse files Browse the repository at this point in the history
… be made after successful insert or update
  • Loading branch information
MKHenson committed May 20, 2016
1 parent be155f8 commit 0d21231
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 18 deletions.
80 changes: 64 additions & 16 deletions server/src/models/schema-items/schema-foreign-key.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {SchemaItem} from "./schema-item";
import {ISchemaOptions} from "modepress-api";
import {Model} from "../model";
import {Model, ModelInstance} from "../model";
import {ObjectID} from "mongodb";
import {Utils} from "../../utils"

Expand All @@ -15,6 +15,8 @@ export class SchemaForeignKey extends SchemaItem<ObjectID | string | Modepress.I
public targetCollection : string;
public optionalKey : boolean;

private _targetDoc : ModelInstance<Modepress.IModelEntry>;

/**
* Creates a new schema item
* @param {string} name The name of this item
Expand Down Expand Up @@ -50,36 +52,82 @@ export class SchemaForeignKey extends SchemaItem<ObjectID | string | Modepress.I
{
var transformedValue = this.value;

// If they key is required then it must exist
var model = Model.getByName(this.targetCollection);

if (!model)
throw new Error(`${this.name} references a foreign key '${this.targetCollection}' which doesn't seem to exist`);

if (typeof this.value == "string")
{
if (Utils.isValidObjectID(<string>this.value))
transformedValue = this.value = new ObjectID(<string>this.value);
else if ((<string>this.value).trim() != "")
return Promise.reject<Error>( new Error( `Please use a valid ID for '${this.name}'`));
throw new Error( `Please use a valid ID for '${this.name}'`);
else
transformedValue = null;
}

if (!transformedValue)
{
this.value = null;
return Promise.resolve(true);

if (!this.optionalKey && !this.value)
throw new Error(`${this.name} does not exist`);

// We can assume the value is object id by this point
var result = await model.findOne<Modepress.IModelEntry>( { _id : <ObjectID>this.value } );

if (!this.optionalKey && !result)
throw new Error(`${this.name} does not exist`);

this._targetDoc = result;

return true;
}

/**
* Called once a schema has been validated and inserted into the database. Useful for
* doing any post update/insert operations
* @param {ModelInstance<T extends Modepress.IModelEntry>} instance The model instance that was inserted or updated
* @param {string} collection The DB collection that the model was inserted into
*/
public async postValidation<T extends Modepress.IModelEntry>( instance: ModelInstance<T>, collection : string ): Promise<void>
{
if (!this._targetDoc)
return;

// If they key is required then it must exist
var model = Model.getByName(this.targetCollection);

var optionalDeps = this._targetDoc.dbEntry._optionalDependencies;
var requiredDeps = this._targetDoc.dbEntry._requiredDependencies;

// Now we need to register the schemas source with the target model
if (this.optionalKey)
{
if ( !optionalDeps )
optionalDeps = [];

optionalDeps.push( { _id : instance.dbEntry._id, collection: collection, propertyName: this.name } );
}
else if (!this.optionalKey)
else
{
// If they key is required then it must exist
var model = Model.getByName(this.targetCollection);
if (model)
{
var result = await model.findOne<Modepress.IModelEntry>( { _id : <ObjectID>this.value } );
if (!result)
throw new Error(`${this.name} does not exist`);
}
else
throw new Error(`${this.name} references a foreign key '${this.targetCollection}' which doesn't seem to exist`);
if ( !requiredDeps )
requiredDeps = [];

requiredDeps.push( { _id : instance.dbEntry._id, collection: collection } )
}

return true;
await model.collection.updateOne( <Modepress.IModelEntry>{ _id : this._targetDoc.dbEntry._id }, {
$set : <Modepress.IModelEntry>{
_optionalDependencies : optionalDeps,
_requiredDependencies : requiredDeps
}
});

// Nullify the target doc cache
this._targetDoc = null;
return;
}

/**
Expand Down
12 changes: 12 additions & 0 deletions server/src/models/schema-items/schema-item.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {ISchemaOptions} from "modepress-api";
import {ModelInstance} from "../model";

/**
* A definition of each item in the model
Expand Down Expand Up @@ -146,6 +147,17 @@ export class SchemaItem<T>
return Promise.resolve(true);
}

/**
* Called once a schema has been validated and inserted into the database. Useful for
* doing any post update/insert operations
* @param {ModelInstance<T extends Modepress.IModelEntry>} instance The model instance that was inserted or updated
* @param {string} collection The DB collection that the model was inserted into
*/
public async postValidation<T extends Modepress.IModelEntry>( instance: ModelInstance<T>, collection : string ): Promise<void>
{
return Promise.resolve();
}

/**
* Gets the value of this item in a database safe format
* @returns {T}
Expand Down
21 changes: 19 additions & 2 deletions server/src/models/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,11 @@ export class Schema
/**
* Checks the values stored in the items to see if they are correct
* @param {boolean} checkForRequiredFields If true, then required fields must be present otherwise an error is flagged
* @returns {Promise<bool>} Returns true if successful
* @returns {Promise<Schema>} Returns true if successful
*/
public async validate( checkForRequiredFields: boolean ): Promise<Schema>
{
var items = this._items;
var error = "";
var promises : Array<Promise<any>> = [];

for (var i = 0, l = items.length; i < l; i++)
Expand All @@ -145,6 +144,24 @@ export class Schema
return this;
}

/**
* Called once a schema has been validated and inserted into the database. Useful for
* doing any post update/insert operations
* @param {ModelInstance<T>} instance The model instance that was inserted or updated
* @param {string} collection The DB collection that the model was inserted into
*/
public async postValidation<T extends Modepress.IModelEntry>( instance: ModelInstance<T>, collection : string ): Promise<Schema>
{
var items = this._items;
var promises : Array<Promise<any>> = [];

for (var i = 0, l = items.length; i < l; i++)
promises.push(items[i].postValidation(instance, collection));

var validations = await Promise.all(promises);
return this;
}

/**
* Gets a schema item from this schema by name
* @param {string} val The name of the item
Expand Down

0 comments on commit 0d21231

Please sign in to comment.