Ufront DB Objects

This is the base class for models in Ufront's "Model, View, Controller" pattern.

Each model extends ufront.db.Object, and uses simple fields to describe what kind of data each of these objects will contain, and how that is saved to the database. The type of each variable matches the type used in the database.

On the server, this class extends sys.db.Object and adds:

  • a default unique this.id field (SUId, unsigned auto-incrementing integer)
  • a this.created timestamp (SDateTime)
  • a this.modified timestamps (SDateTime)
  • modified this.insert() and this.update() methods that check validation and updates this.created and this.modified timestamps
  • a this.save() method that performs either this.insert() or this.update()
  • a this.validate() method that checks if the object is valid. This method is filled out with validation rules by a build macro.
  • a this.validationErrors property to check which errors were found in validation.
  • macro powered this.hxSerialize() and this.hxUnserialize() methods to ensure these objects serialize and unserialize nicely.
  • a default this.toString() method that provides "${modelName}#${id}" eg "Person#23"
  • a save signal

On the client, this does not longer extends sys.db.Object, so you can interact with your models even on targets that don't have access to the sys.db APIs - for example, Javascript in the browser.

This means that:

  • Client side code can create, edit, and validate the objects.
  • You can send objects back and forward using Haxe remoting, for example saving an object to the server, or retrieving a list from the server.
  • When you unpack the object on the client it is fully typed, and you get full code re-use between client and server.
  • They just can't save them back to the database, because you can't connect to (for example) MySQL directly.
  • There is the experimental ClientDS library which allows you to save back to the server asynchronously using a remoting API.

You should use -D server or -D client defines in your hxml build file to help ufront know whether we're compiling for the server or client.

Build macro effects:

  • Process BelongsTo<T>, HasMany<T>, HasOne<T> and ManyToMany<A,B> relationships and create the appropriate getters and setters.
  • Add the appropriate validation checks to our this.validate() method.
  • Save appropriate metadata for being able to serialize and unserialize correctly.
  • On the server, create a public static var manager:Manager<T> = new Manager(T) property for each class.
  • On the client, if using ClientDS, create a public static var clientDS:ClientDS<T> property for each class.

Constructor

new ()

Fields

created:SDateTime

The time this record was first created.

id:SId

A default ID. Auto-incrementing 32-bit Int.

modified:SDateTime

The time this record was last modified.

read only saved:Signal<Noise>

A signal that is triggered after a successful save.

validationErrors:ValidationErrors

If a call to validate() fails, it will populate this map with a list of errors. The key should be the name of the field that failed validation, and the values should be a description of any errors.

Methods

delete ():Void

Available on js-client

insert ():Void

Inserts a new record to the database. Will throw an error if this.validate() fails. Updates the "created" and "modified" timestamps before saving.

refresh ():Void

Refresh the relations on this object. Currently this does not refresh the object itself, it merely empties the cached related objects so they will be fetched again. In future we might get this to refresh the object itself from the database.

save ():Void

Save a record (either inserting or updating) to the database. If id is null, then it needs to be inserted. If id already exists, try to update first. If that throws an error, it means that it is not inserted yet, so then insert it. Updates the "created" and "modified" timestamps as required.

update ():Void

Updates an existing record in the database. Will throw an error if this.validate() fails. Updates the "modified" timestamp before saving.

validate ():Bool

A function to validate the current model.

By default, this checks that no values are null unless they are Null / SNull, or if it the unique ID that will be automatically generated. If any are null when they shouldn't be, the model fails to validate.

It also looks for "validate_{fieldName}" functions, and if they match, it executes the function. If the function throws an error or returns false, then validation will fail.

If you override this method to add more custom validation, then we recommend starting with super.validate() and ending with return validationErrors.isValid;