Model definition in JayData

Author: Hajnalka Battancs August 7th, 2013

JayData provides a quick and easy way of defining data structures, which you might have seen previously in the tutorials. One of our main goals was to represent the data model as a strongly typed Javascript-native object model, so defining the model is essentially type definition.

This is how a model definition section looks:

As you can see it consists of two main parts. First we define the entity classes, then we define the context which is analogous with the database structure.

Entity description

Entities are the objects that make up your data. Entities are analogous to records in a relational database. In the entity description, you can define the fields (columns) that will make up each entity type.

Defining an entity is basically a class definition, for which we provide an extensive toolset. There are two ways to do this, with the $data.Class.define or the {type}.extend methods, the second is basically a user-friendly shortcut, so here I will use this, but if you see the other method used in example code, it does the exact same thing, with slightly different syntax and more functionality (that we do not use in defining the data model).

This is the generic form of an entity definition:

The parameters are as follows:

  • Type name: The fully qualified type name of the entity. According to our best practices, you should give a name to your context (eg. $org for the simplistic HR database in the above example), and define all types under its types collection.
  • Field name: The name of the data field described.
    eg. FirstName or LastModifiedDate/
  • Field type: The field data type. Valid values for this can vary across providers. See below for a description of the most common types. You can also define reference fields, as shown above. Here the data type is an entity type you define here, eg.
  • Key: A Boolean setting whether the field is a key field. False by default.
  • Computed: A boolean setting whether the field is computed (read-only). False by default.

Reference and backreference fields define connections between entities, in a similar way to foreign keys in relational databases. For a reference to be valid, it must be marked in both directions, as a reference and a backreference field.

Backreference fields are more a technical information to help JayData determine the correct schema, and have limited use in filtering or in retrieving data. 

The parameters in reference definitions are the following:

  • (Back)Reference field name: The name of the field, according to our best practices, it is singular on the reference side and plural on the backreference side, and as all fields, should reflect the type of connection the fields represent.
    eg. Department / Employees, Author / AuthoredArticles, State / Cities, etc.
  • Entity type: The entity type on the other side of the reference.
    eg. Department / Employee, User / Article, State / City, etc.
  • Inverse property: The field name of the other side of the reference. This is vital, as this is where the system makes the connection between the fields, and creates the abstract representation of the relationship.

Ie. it is the backreference field name on the reference, and the reference field name on the backreference.

The most common data types are as follows:

  • int / integer: An integer number. Range may vary across providers.
  • number: A decimal number. Range and precision may vary across providers.
  • datetime / date: Date type, locally represented by the JavaScript Date object. Range may vary across providers.
  • text / string: A string. Maximum length may vary across providers.
  • bool / boolean: A boolean value.
  • blob: A binary object. Availability may vary across providers.
  • Array: An array of values. It is used most frequently in backreference fields (see above). Support for non-reference array fields may vary across providers.
  • Complex type: A custom value object type you defined on your context, but without creating an entity set for it. This way you can represent complex objects in your schema such as mail addresses, phone numbers, etc. Complex type fields are not references, but regular fields.
    Support for complex types may vary across providers.
    eg. $org.types.MailAddress

Validators are specific to data types:

  • All data types (including complex types):
  • required (boolean): The field must always be set.
  • customValidator (function): Allows you to enter a custom Javascript function with a boolean return value to check validity.
  • Integer, Number and Date:
  • minValue (integer): Minimum numeric value.
  • maxValue (integer): Maximum numeric value.
  • String:
  • minLength (integer): Minimum string length.
  • maxLength (integer): Maximum string length.
  • length (integer): The string must be exactly this length to be valid.
  • regex (string): A regular expression to check validity.
  • Array:
  • length (integer): The array must be exactly this length to be valid.

As an additional example, here is an entity definition with all sorts of validators in it:

Context description

Once you have your entities defined, you need to set up the database structure, which is done by the context description block. Here you can set which entities will be represented in individually queryable entity sets.

You should not create entity sets for value object types, only for true entities. As a rule of thumb, entities are types that have a key, and represent some sort of entity in the business domain, while value objects are just complex values without identity.

Entities would be articles, employees, cities, bank transactions, currencies, cars, etc. Value objects include mail addresses, phone numbers, mathematical constructs such as vectors, matrices, graphs and complex numbers, etc.

This is the generic form of the context description:

The parameters are as follows:

  • Type name: The type name of your context. According to our best practices, this should also be defined under the types collection of the context root.
    eg. $org.types.OrgContext
  • Entityset name: The name of the entityset (ie. table) described. Note that with remote services such as OData, this will be used as the name of the set, so must conform to the names in the service. (Which is the resaon why it’s not pluralized in the example.)
    eg. Employees or Employee
  • Entity type: The above defined entity type that will make up the set.
    eg. $org.types.Employee

Context creation

While not strictly part of the model definition, for JayData to work, you need to instantiate the context, using a storage provider. Here is an example with the WebSQL provider:

Or, with the OData provider:

This is where the context comes alive, and in the case of code-first providers like WebSQL and SQLite, the database is generated on the first run. The generic syntax of context creation is as follows:

The parameters are as follows:

  • Context object: The object name for the context. According to our best practices, it should be the context field under your context root.
    eg. $org.context
  • Context type: The context type you have previously defined.
    eg. $org.types.OrgContext
  • Storage provider name: The storage provider you wish to use (see comparison chart of storage providers).
  • Storage provider options: Specific options for the storage provider. See storage provider descriptions.