Skip to content
Greenbaum Institute edited this page Apr 16, 2018 · 9 revisions

Overview

In TotalJS, schemas define CRUD interfaces for interaction with client devices such as web browser or mobile phone app.

Don't confuse them with database schemas!

Defining a schema

Schemas can be defined anywhere, but ideally should be put in your models - the .js files located in the /models folder. Multiple schemas can be defined in the same file.

For example, you might use /models/user.js to define several schemas (CRUD interfaces) associated with users of your site.

The basic syntax is as follows:

NEWSCHEMA( 'SchemaName' ).make( function( schema ) {

  // define properties

  // property defaults

  // property validators

  // define CRUD methods

  // define additional workflow methods

}

The 'SchemaName' should be a unique name of your choosing, for example NEWSCHEMA('UserSettings').

It is convention to use PascalCase for schema names, and to prefix the schema name with the model name - this makes it easier to determine which script a schema is from when that schema is referenced in another script. For example, if your script is /models/clients.js (Client model) then schemas in that file would have names like Client, ClientSettings, etc.

Properties

Usually, your schema methods will expect one or more properties (or 'fields') to be passed in to them. To help with data validation and error checking, your schema should define which properties it's methods are expecting.

Example:

NEWSCHEMA( 'SchemaName' ).make( function( schema ) {

  // define properties
  schema.define('ip', 'String(80)');
  schema.define('name', 'String(50)', true);
  schema.define('email', 'String(200)');
  schema.define('isblocked', Boolean);
  schema.define('datecreated', Date);
  schema.define('dateupdated', Date);

  // ...

}

The .define() method accepts up to 4 parameters:

schema.define( name, type, [required[, filters]] )

name:

The name parameter can be either a string, or an array of strings. In the example above, we defined both dates separately, but because they have the same settings we could choose to define them both in a single call:

 schema.define(['datecreated','dateupdated'], Date);

 // is equivalent to:

 schema.define('datecreated', Date);
 schema.define('dateupdated', Date);

type:

The type parameter specifies the property's data type. The following types are currently supported (note: any strings are converted to lowercase so, for example, 'Number' would become 'number')...

Strings:

  • String or 'string' - variable length string
  • 'string(n)', 'varchar(n)', 'nvarchar(n)', 'text(n)' - fixed length string of n characters
  • Example: 'string(80)' would be 80 chars
  • 'capitalize', 'capitalcase' or 'capital' - converts string to Capital Case (like in CSS) (v2.0+)
  • Can also specify length, eg. 'camelize(80)'
  • 'lowerize', 'lowercase' or 'lower' - converts string to lowercase (v2.0+)
  • Can also specify length, eg. 'lowerize(80)'
  • 'upperize', 'uppercase' or 'upper' - converts string to uppercase (v2.0+)
  • Can also specify length, eg. 'upperize(80)'
  • 'uid' - a unique identifier string, max length 20 chars (v2.0+)
  • 'email' - an email address string, max length 120 chars (v2.0+)
  • 'URL' - a URL string, max length 500 chars (v2.0+)
  • 'zip' - a zip (postal) code string, max length 10 chars (v2.0+)
  • 'phone' - a phone number string, max length 20 chars (v2.0+)

Numbers:

  • Number, 'number', 'float', 'double' or 'decimal' - a floating point number
  • Int or Byte - an integer number

Other:

  • Array, 'array' or '[]'- an array of any object type
  • '[type]' - an array of a specific type
  • Example: '[date]' would be an array of dates
  • Example: '[lower(10)]' would be an array of lowercase strings of max 10 chars (eg. for tags field)
  • Boolean, 'Boolean' or 'Bool' - a boolean
  • Date, 'Date' or 'Time' - a date
  • Object or 'object' - an object
  • Note: An instance of an object will be treated as an unknown type
  • 'SchemaName' - a schema referenced by its name, eg. 'UserSettings'

required:

The optional required parameter will force the schema to check that a field is defined in any interactions with the schema methods - if not, an error will be generated.

Also, required fields will invoke additional validation if applicable to the field type. For example, to check that the data provided is the correct type, length, format or schema. Again, an error will be generated if the data fails to validate.

Format validation occurs for 'uid', 'email', 'url' and 'phone' types, using the String prototype methods .isUID(), .isEmail(), .isURL() and .isPhone() respectively.

filters:

The optional filters parameter allows you to add tags to a field, and then later you can quickly filter a list of fields to specific tags, or even filter object properties to a specific set of fields using the tags.

Example:

  schema.define('id', Number, 'read');
  schema.define('name', String, true, 'read|create|update');
  schema.define('email', String, true, 'read|create');

  // some time later...

  console.log(schema.filter('*read'));
  // Properties including tag 'read'
  // Output: [ 'id', 'name', 'email' ]

  console.log(schema.filter('read'));
  // Properties with only tag 'read'
  // Output: [ 'id' ]

  console.log(schema.filter('*update'));
  // Properties including tag 'update'
  // Output: [ 'name' ]

  console.log(schema.filter('*update', true));
  // Properties excluding tag 'update'
  // Output: [ 'id', 'email' ]

  console.log(schema.filter('*update', { name: 'Peter', id: 1 }));
  // Filter to properties including tag 'update'
  // Output: { name: 'Peter' }

  console.log(schema.filter('*create', { name: 'Peter', email: 'petersirka@gmail.com', id: 5 }));
  // Filter to properties including tag 'create'
  // Output: { name: 'Peter', email: 'petersirka@gmail.com' }

  console.log(schema.filter('*create', { name: 'Peter', email: 'petersirka@gmail.com', id: 5 }, true));
  // Filter to properties excluding tag 'create'
  // Output: { id: 5 }

Property defaults

TO DO

Property validators

TO DO

CRUD methods

TO DO

Workflow methods

TO DO

Method chaining

TO DO

Controller routing

TO DO

See also