Broadcast on Broadcast off
The Documentation for Project Zero has moved. Please update your bookmarks to: http://www.projectzero.org/documentation/

Table of
Contents...
Hide

Project Zero Developer’s Guide

Concepts and components
Basic concepts overview
Event processing
Writing Java handlers
Writing Groovy handlers
Firing events
Global Context
Global Context reference
Application directory layout
Virtualized directories
Assemble
PHP
Features and configuration
Configuration
Debugging
Dependencies
Packaging
Application classpath
Logging and tracing
RESTful resources
RESTful documentation
File serving
Response rendering
Validators and validation
HTTP error handling
Calling a remote resource
Using the Connection API
Sending an email using EmailConnection
Configuring destinations
Configuring protocols
Configuring connection handlers
Creating a connection handler
Creating a custom protocol transport
Simple logging connection handlers
Protocol reference
Client programming with Dojo
Runtime options
Deployment modifications
HTTP configuration
SSL configuration
Proxy configuration
Extending the CLI
Security considerations
Authentication
OpenID authentication
Extending security
Security tokens
CSRF prevention support
Extending token support
Leveraging TAI
User service
File based user service
LDAP user service
Extending user service
Security Utilities
Leveraging XOREncoder
Extensions
Atom support
RSS support
JSON support
XMLEncoder
REST to SOAP extension
URIUtils
Developer Web tools
Database setup tools
Configuring data access
Common query patterns
Advanced query patterns
Update patterns
Local database transactions
Extending data access
Configuration vendor differences
PHP data access
Resource model
Configuring ZRM
Resource model declaration
Programmatic model API
HTTP REST API
A ZRM mini tutorial
Active content filtering support
Default filters
Custom filters
Runtime management
Management commands
Zero socket opener
Other extension modules
Amazon E-commerce service
Flickr service
WeatherZero forecast service
Wikipedia service
Reference
Zero command line interface
JavaDoc - Public API
JavaDoc - Public SPI
JavaDoc - All Classes

 

Resource model declaration

A resource model is the single, definitive source of metadata about your data. It contains declarations about the essential fields and behaviors of the data in your application. Presently, each model maps to a single database table and the following list provides other basic information:

A resource model example

This example model defines a persons resource model that has first_name and birth_date fields:

// File: /app/models/persons.groovy
fields = [
    first_name: [type: 'CharField'],
    birth_date: [type: 'DateField'],
]

The first_name and birth_date fields are fields of the resource model. Each field is assigned metadata that modify its behavior at runtime (for example, validation rules) and field attribute maps to a database column.

The previous persons model would create a database table as shown in the following example:

CREATE TABLE persons (
    first_name VARCHAR(30) NOT NULL,
    birth_date DATE,
    id INTEGER PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 100, INCREMENT BY 1) NOT NULL,
    updated TIMESTAMP NOT NULL
)

Technical notes:

  • The name of the table, persons, is automatically derived from file name /app/models/persons.groovy but can be overridden. See the following Table customization section.
  • An id field is added automatically. Keys are generated by default and begin at 100, incrementing by 1.
  • An updated field is added automatically.
  • The CREATE TABLE SQL in this example is formatted using Derby syntax. At present only the Derby database is supported.

Fields

The most important part of a resource model — and the only required part — is the list of fields it declares. Fields are specified by a data structure assigned to fields as shown in the previous example.

Field name restrictions

Three restrictions exist on resource model field names:
  1. A field name cannot be a Java, Groovy, or SQL reserved word.
  2. At present, a field name cannot contain more than one underscore in a row, due to the way the query lookup syntax works.
  3. Field names with upper case characters are also prohibited in M3.

The following example shows these restrictions:

// ILLEGAL!
// 'while' and 'where' are reserved words
// 'my__field' has two underscores
// 'mixedCase' has mixed case characters
fields = [
   while: [type:'CharField'],
   where: [type:'CharField'],
   my__field: [type:'CharField'],
   mixedCase: [type:'CharField']
]

Field types

Each field in your resource model must have a specified type string. This string maps to a field class. The resource model uses the field class types to determine the following things:

  • The database column type (for example, INTEGER, VARCHAR).
  • The minimal validation requirements.

The supported datatypes for a resource declaration are:

BooleanField

A true/false field. Valid values for true are true, 't', 'true', 'True', '1', or 1 and valid values for false are false, 'f', 'false', 'False', '0', 0.

CharField

A string field, for small- to large-sized strings. For large amounts of text, use TextField.

Argument Required Description
max_length No The maximum character length is by default 50. However, CharField can take max_length as extra argument and which specifies the maximum character length of the field. The max_length is enforced at the database level and in the Resource Model validation.

In the following example, name values can have up to 50 characters and address up to 255.

fields = [
    name: [type: 'CharField'],
    address: [type: 'CharField', max_length:255],
]

DateField

A field representing a date (day, month, and year). Valid values take the form of yyyy-MM-dd.

DateTimeField

A field representing an instance or timestamp (second, minute, hour, day, month, and year). Valid values take the form of any of yyyy-MM-dd, yyyy-MM-dd HH:mm, or yyyy-MM-dd HH:mm:ss.

DecimalField

A decimal number represented in Java by a java.math.BigDecimal.

Argument Required Description
max_digits Yes The maximum number of digits allowed in the number.
decimal_places Yes The number of decimal places to store with the number (the decimal number's scale)

EmailField

A CharField that checks that the value is a valid e-mail address using a regular expression.

FloatField

A floating-point number represented in Java by a float.

IntegerField

An integer.

TextField

A large text field.

TimeField

A field representing a time independent of a date (second, minute, and hour). Valid values take the form of HH:mm and HH:mm:ss.

USStateField

A CharField that checks that the value is a two letter state abbreviation.

USPhoneField

A CharField that checks that the value is a valid phone number using a regular expression.

Using fields

A resource declaration using the types described in the previous sections looks like the following example:

// File: /app/models/employees.groovy
fields = [
    name: [type: 'CharField', max_length:50],
    birth_date: [type: 'DateField'],
    age: [type: 'IntegerField'],
    salary: [type: 'DecimalField', max_digits: 9, decimal_places: 2],
    takes_lunch_at: [type: 'TimeField'],
    favorite_moment: [type: 'DateTimeField'],
    favorite_number: [type: 'FloatField'],
    biography: [type: 'TextField'],
    address :[type :'CharField', max_length: 60],
    city: [type: 'CharField', max_length: 45],
    state: [type: 'USStateField'],
    phone: [type: 'USPhoneField'],
    email: [type :'EmailField'],
]

Field options

The following optional arguments are available to all field types:

required

Default is false, which means all fields by default are not required to have a value. If true, the field is required. This constraint is enforced during:
  • create() and update() on a Collection
  • validate() on a Member instance
  • POST and PUT on the HTTP resource

Note: Empty string-based values are stored as empty strings, not as null.

Example:

fields = [
    first_name: [type: 'CharField', max_length: 25], // optional by default
    last_name: [type: 'CharField', max_length: 35, required: true]
    email: [type: 'EmailField', required: false] // permissible to explicitly declare false
]

Named collections

Resources are accessed using collection-like constructs. A filter can be applied to such collection to create a new collection that is a subset of the original. A filter condition can be applied either programmatically or using HTTP at runtime. Filters can also be specified in the model declaration by defining a named collection:
// File: /app/models/persons.groovy
fields = [
    first_name: [type: 'CharField', max_length: 30],
    birth_date: [type: 'DateField'],
    is_child: [type: 'BooleanField'],
]

collections = [
    children: [member_filters: [is_child: true]],
    christmas_birthdays: [member_filters: [birth_date__day: '25', birth_date__month: '12']],
]

Database generation

ZRM generates a database table for each resource using a top down mapping scheme. By default, the name of the model file maps to the name of the database table and the field names map to column names. Each table also has a special field, id, that is the unique identifier for that resource.

The tables are created at the application startup. For each resource, ZRM checks to determine whether the corresponding table exists. If the table exists then ZRM leaves it intact, otherwise a new table is created. If you modify a model file and want the table be recreated, you must manually drop the table and restart the application.

Loading initial data fixtures

In addition to creating the database tables at application initialization, ZRM searches for initial_data.json files across all dependencies in /app/models/fixtures directories and loads its data into the database. Note: The virtualized directory concepts are ignored in this case.

If the database has already been initialized, the data is not loaded until the database is deleted or the table is manually dropped. The JSON format of initial_data.json is specific but easy to reproduce.

Given the following resource model declaration, the subsequent initial_data.json file would load two persons instances into the backing database table:

fields = [
    first_name:[type:'CharField'],
    birth_date:[type:'DateField'],
    is_child:[type: 'BooleanField'],
]
Valid initial_data.json:
[
    {
        "type": "persons",
        "fields": {
            "id"            :   "1",
            "first_name"    :   "Tom",
            "birth_date"    :   "2005-12-12",
            "is_child"      :   "0",
            "updated"       :   "2007-09-24 03:23:34.234"
        }
    },
    {
        "type": "persons",
        "fields": {
        "id"                :   "2",
            "first_name"    :   "Bill",
            "birth_date"    :   "2001-03-1",
            "is_child"      :   "1",
            "updated"       :   "2007-09-23 03:23:34.234"
        }
    }
]

Your initial_data.json file can contain populate multiple resource model types from the same file. Just ensure that the appropriate type value is included.

Table customization

You can customize the table name against which ZRM generates and maps your resource declaration. For example, if your application sets the resource type name to be articles but needs the database table name to be magazine_editorials, then you can specify the following in your resource model file:

// /app/models/articles.groovy
fields = [ ... ]
db_table = 'magazine_editorials'

r15 - 09 Feb 2008 - 18:08:21 - paynel
Syndicate this site RSS ATOM
Copyright 2007 © IBM Corporation | Privacy | Terms of Use | About this site