
# Schema definition

Schema definition file is imported from Config.txt by @FILE.
It should be in the same directory as Config.txt.

Schema definition file is composed of segment, entity and collection.

Segment is a unit of database made by *createdb* command.
Entity is your business entity definition represented by *table*.
And collection is an aggregation represented by *junction table*.

The segment is actually the database made by *createdb* command.
But the entity and collection is not always a representation of physical table.
You can assume this entity to be a logical definition as long as being with your stored procedure.

## Sample

```
=== Product (Product) ===

# Product (Product)
aggregate:Product/ProductProductImage
sequence:productSeq(1000)

	field*			type*		name*			search*				valid*			tags
	---------------+-----------+---------------+-------------------+---------------+-------------------------
	productID		int4		ProductID		key					notNull
	productName(*)	text		Product Name	key,like,orderby	notNull
	price			int2		Price			num,orderby			positiveValue
	depositoryID	int			DepositoryID	key					-				helper:Product/Depository
	registerDate	timestamp	Registered Date	timestamp,orderby	timestampString

	data:
	1	Apple		200		1	2013-01-01
	2	Orange		300		1	2013-02-01
	3	Banana		400		1	2013-03-01
	4	Strawberry	150		2	2013-04-01

* ProductProductImage (Product-ProductImage)

	collector/collected*					type*
	---------------------------------------+------
	Product/Product.productID				int4
	Product/ProductImage.productImageID		int4

# ProductImage (Product Image)
featuringImage:true
sequence:productImageSeq(1000)

	field*			type*		name*			search*		valid*			tags
	---------------+-----------+---------------+-----------+---------------+-------------------------
	productImageID	int4		ProductImageID	key			notNull
	productImage(i)	image		ProductImage	-			notNull			
	width			int2		Width			num			positiveValue	autoset:imageSelected
	height			int2		Height			num			positiveValue	autoset:imageSelected
	name(*)			text		Image Name		like		notNull			editor:textField
	caption			text		Caption			like		-				editor:textArea
```

## Term

| word                 | explanation                                                             |
|:---------------------|:------------------------------------------------------------------------|
| Segment              | database segment, or its representation of segment definition           |
| Entity               | table, or its representation of entity definition, almost same as Model |
| Segment/Entity       | an Entity defined in a Segment                                          |
| Segment/Entity.field | a field defined in an Entity defined in a Segment                       |
| Collection           | entity relation represented by junction table                           |

## Segment definition

The line starting with **===** represents database segment name.
This segment name should be your database name starting with an upper case character.

Trailing word noted in brackets is its human-readable name used in UI.

Whitespace character is allowed around the word.

In above sample, === at the end of the line is just a decoration.

## Entity definition

The line starting with **#** represents the start of entity definition.

Entity may have some tags defined below.

* sequence

 Option for entity defining.

 Defines sequence generator for this entity.

 The value, just after **:** is your sequence defined in this database.
 Begin number can be defined in brackets.

* aggregate

 Option for entity defining.

 Represents this entity has many-to-many relationship.
 The value, just after **:** is the collected entity defined as Segment/Entity.

 This can be an external(foreing) entity, defined in another database segment.
 In this case, search query will be generated by using dblink.
 (Therefore, in this case, the query will not be parameterized in auto generated implementation.)

* featuringImage

 Represent this entity has image field.
 The value, just after **:** is *true* if you define this keyword.

 If this keyword is defined, UI will be generated as with thumbnail in List and Editor for the field.

### Field definition

The line starting with TAB, and being in an entity definition, the line represents field definition.
The first two lines will be assumed to be a comment.
(so you can define field header in there)

Field definition contains six elements.
**field**, **type**, **name**, **search**, **valid** and **tags**.
The first four elements are must items.

Each element should be separated by TAB.
White space character will be allowed around the value.

#### field

A field of this entity.

* primary key

 The first line is for primary key.

 Rutile requires primary key for each entity and its name should be *lowercase started entity name* with *trailing ID*, 
 and its value should be generated by sequence defined by *sequence tag*. (This primary key is aka surrogate key or pseudo key.)

 For example, Product entity should have productID definition at the first element of field definition.
 And its value should be a number from starting from 1000, generated by sequence:productSeq(1000).

* normal field

 Other lines define normal field name.

#### type

Data type of this field.

| type      | in db     | UI                      |
|:----------|:----------|:------------------------|
| int       | int       | numeric input field     |
| int2      | int2      | numeric input field     |
| int4      | int4      | numeric input field     |
| text      | text      | text field or text area |
| date      | date      | date picker             |
| timestamp | timestamp | timestamp picker        |
| image     | text      | image picker            |
| geography | point     | Ti.Map                  |

* **image**

 If you define image type, the field will be represented by image in generated UI.
 In database, that is stored as MIME encoded text.

* **geography**

 This value should be a text representing postgis geography type defined by point, POINT(lon lat).

#### name

Human-readable name for this field. Used in generated UI.

#### search

Defines how to generate server and client function to search this field.

| search    | generated search constraint                       |
|:----------|:--------------------------------------------------|
| key       | match full                                        |
| num       | range, less than, greater than                    |
| like      | match partial                                     |
| date      | range, less than, greater than                    |
| timestamp | range, less than, greater than                    |
| nearby    | geo point within a distance from a point          |
| area      | geo point included in a area                      |
| orderby   | orderby for this field, desc and asc              |
| join      | for foreign key, search by foreign entity's field | 

**join** should be with **helper** tag.

According to this definition, Rutile generates server side search module and client side UI search form.

You can define multiple search properties separated by ','.

#### valid

Defines how to generate server side data check for this field.
This is optional definition, you can skip this definition but have to set **-**.

| valid           | required value                         |
|:----------------|:---------------------------------------|
| -               | don't generate validation              |
| notNull         | don't allow null                       |
| positiveValue   | positive value                         |
| negativeValue   | negative value                         | 
| timestampString | string representing timestamp          |
| dateString      | string representing date               |
| emailString     | string represent email address         |
| escapedHtmlTag  | escaped html tag in the source value   | 
| geographyPoint  | string representing geographical point | 

The *valid* property does not affect on client side.
So you can input any invalid value into your generated form.
When the server receives invalid value for a field, it returns exception message for your request.

#### tags

Optional generator controls.
You can define multiple tags separated by ','.

* **helper**

 Defines foreign entity.

 Its value after the trailing **:** is formatted as Segment/Entity.
 This tag should be with **join** keyword in search section.

 If you define this tag, search logic, both server side and client side, will be generated to search its joined field.
 For example, defining helper for the field of Product/Product.productClassID makes it possible to search Product/Product.productID by Product/ProductClass.productClassName.

 Additionally, with helper tag, field editor will be generated as a selector for the foreign entity.

* **editor**

 Whether to use TextField or TextArea for this text editor.

 **textField** and **textArea** can be defined.

* **autoset**

 Injecting cross edit form interaction.

 Generated form UI emits an event when some value has been selected.
 Field type *image* will generate image picker for the UI.
 After selecting a image for the field, **imageSelected** event will be emitted.

 Injected code should be defined in Inject/Autosetter.js.
 And it should be an CommonJS module returns a hash object to get injecting code for appropriate event.

 To set a field, Product/ProductImage.width, by an event *imageSelected* that is fired by selecting an image of Product/ProductImage.image,
 Autosetter.js should have { imageSelected:{'Product/ProductImage.width':CODE} }.
 The CODE should be some text value defining your injection.

 *entitySelected* event also can be used.

## Collection definition

The line starting * represent the start of collection definition.
After the line, also should be appear lines starting TAB.

Collection should have two field style definitions, collector and collected.
It means the former owns the latter.
Both lines should be a primary key expression represented by Segment/Entity.primaryKey.

## Predefined data

You can append predefined data entry for yor Entity and Collection.

Data definition should be after your field definition, starting with **data:**.
Each value should be separated by tab.

See the Sample and [rutile_kickstart/README.md](https://github.com/RayKitajima/rutile_kickstart/tree/master/1st_step/en)

