1 // ==========================================================================
2 // Project: xTuple Postbooks - Business Management System Framework
3 // Copyright: ©2011 OpenMFG LLC, d/b/a xTuple
4 // ==========================================================================
9 An ORM is an Object Relational Mapping that defines the relationship between object oriented type
10 definitions and relational tables or views in a database. This implementation is currently designed
11 to apply specifically to a PostgreSQL database, but theoretically could be applied to any database
12 for which an ORM API is defined to process these definitions.
14 In the xTuple PostgreSQL implmentation the installation of ORM files triggers views to be created
15 whose structures and rules conform to the definition of the ORM. The ORMs use camel and class case
16 conventions when referencing object attributes and snake case conventions when referencing database
17 attributes. Because ORMs generates views, these views can in turn be referenced by other ORMs to manage
18 a class hierachy. To determine the name of a view created by an ORM simply convert the name space
19 qualified type of the object to a snake case schema and view name like so:
21 Object Name Datbase Name
22 -------------- ----------------
25 XM.ToDoComment xm.to_do_comment
27 ORMs are specifically designed to be extensible so that a database table can be virtually expanded
28 without changing the original table definition, while presenting the new data through the ORM API
29 as though it were all one unit. This effectively ensures that "core" database definitions
30 and custom or 3rd party data extensions are effectively encapuslated from one another. In addition
31 ORMs can be activated and deactivated in the xt.orm table so extensions can be "turned off" at
34 The initial ORM is referred to as the "base" ORM. Additional ORMs can be defined against the
35 original base using the same name space and type but giving them a different context name and
36 setting the isExtension flag to true. Typically the table on an ORM extension should reside in a
37 different database schema where you would create a table with colums that contain data you want to
38 "add" to a table in the original schema. The new table should contain a column relation to associate
39 with the original (which may also be the primary key for it as well.) When you create an ORM
40 extension the new table will be left joined on the original. Any inserts, updates or delete
41 actions will propagate results to both the original and the new table automatically.
43 Extensions can be created as both completely independent ORM definitions or added to an
44 extension array on a base or extension ORM.
49 A container identifier that correlates with an object name space.
59 A specific type name that correlates with an object type.
65 "type": "ProjectTask",
68 Context is a sub container for name space that allows extending the same
69 name space and type in different contexts. The name space, type and context
70 must be unique. When you extend an ORM outside the original definition, you
71 should create a new context for each extension.
80 The source table or view from which you are drawing data. Schema qualifications
81 should be included when referencing views created by other ORMs. Only one table
82 may be defined per root ORM. Use extensions to relate additional tables.
91 Table name that specifies which table controls the versioning information
92 for records. If not specified, `table` will be the versioned table.
93 Useful if the `table` property actually references a view that can not, by
94 definition, be version controlled.
100 "lockTable": "prjtask",
103 Indicates this ORM is an extension to another ORM. A join will be created between
104 the two tables to represent them as one in the corresponding view.
109 "isExtension": false,
112 This value only applies to extensions and indicates the query should perform a join
113 instead of a left join to improve performance. It should only be used in cases where
114 a related record on the extension's table is always guaranteed to exist.
122 The table sequence to use when generating the next unique record id. Necessary
123 for any objects for which new records can be created.
127 "idSequenceName": "prjtask_prjtask_id_seq",
130 Text describing the purpose of the ORM which will be appended to the associated
135 "comment": "Project Task Map",
138 Designates that data for this type can only be accessed in the context of a parent. Any attempts
139 by a client to query or update this record directly, regardless of privilege settings, will fail.
144 "isNestedOnly": false,
147 Used to describe document access. If absent no access will be granted to this type.
155 Describes privileges that allow a user to have access to all records of this
156 object type. The same privilege can be set to control multiple or all of the create, read,
157 update and delete (aka. crud) access methods. Privilege settings can be a boolean that indicates
158 universal access or lack thereof, or a string that refereces a specific privilege name that
159 allows access if the user has been granted the privilege.
167 The create privilege for this object.
171 "create": "MaintainAllProjects",
174 The read privilege for this object.
178 "read": "ViewAllProjects",
181 The update privilege for this object. This
182 privilege also implicitly enables read access if
183 the privilege for read is not explicitly granted.
188 "update": "MaintainAllProjects",
190 /** The delete privilege for this object.
194 "delete": "MaintainAllProjects"
198 Describes privileges that allow a user to have access only to specific records
199 of this object type as defined by a specific relationship between the user and the
200 record as determined by matching logged in user account name to the value of the
201 fields listed in the "properties" array.
207 The personal create privilege for this object.
211 "create": "MaintainPersonalProjects",
214 The personal read privilege for this object.
218 "read": "ViewPersonalProjects",
221 The personal update privilege for this object. This privilege also implicitly
222 enables read access if the privilege for read is not explicitly granted.
226 "update": "MaintainPersonalProjects",
229 The personal delete privilege for this object.
233 "delete": "MaintainPersonalProjects",
236 An array properties on the object on which to compare the logged in user
237 account name to determine access.
249 Attribute level privileges. Each attribute that has privilege control should be listed
250 as a key/value pair where the key is a properties attribute name and the value is an object
251 that contains one or both of its own key/value pairs whose keys would be `view` or `create`, or `update`.
252 The value in these pairs is a string with one or more space separated privilege listings.
258 "create": "editOwner",
259 "update": "editOwner"
262 "view": "viewCosts maintainCosts"
267 The array of client object properties that maps to table columns. Each hash listed
268 should have one and only one of the following properties: attr, toOne or toMany,
269 the purposes of which are described below.
287 Indicates this property is an attribute that maps directly to table column.
293 The expected type of the property. Should be any of the following:
313 The mapped database column associated with this property.
315 There is support for a special case where if the column name is `obj_uuid` and
316 it is not found to exist on the table, the ORM generator will add the column
317 with type `uuid` that generates it's own default value. This is usefull for adding
318 a naturalKey to a table that is normally a child table and doesn't have one good
319 attribute to serve as the natural key.
323 "column": "prjtask_id",
326 * Parity bit that is set when we intend for this field to be derived
327 * from a method invocation or some other source. If `method` is to be
328 * used, `derived` must equal `true`. `dervied` and `column` are
329 * mutually exclusive.
336 * Method which determines the value of this derived field. The result
337 * is used in SELECT queries, and is not required for INSERT or UPDATE
338 * since it is a vitual column.
342 "method": "xt.count_project_tasks(prjtask_id)",
345 Indicates this column is the relation to be used qualifying updates and deletions
348 The current implementation requires one and only one property to be defined as
349 the primary key per map.
354 "isPrimaryKey": true,
357 Indicates this column is the relation to be used qualifying updates and deletions
358 externally. This key will appear as the value on non-nested toOne relations.
363 "isNaturalKey": true,
366 Use to indicate a mandatory property.
371 Indicates a fixed value on which to filter all table reads and set as default on
372 new inserts. It can not be updated.
374 Useful for tables that store data of mixed types where one column holds
375 a source code string that designates the type as part of compound key. It forces
376 queries to return and affect only records with values that match the one
385 Flags whether the proprety should be visible on query results or not.
387 Useful when used in conjunction with "value" where there is no need to see the
388 fixed value in a result set.
396 Flags whether the property must be encrypted. When true, the data source must pass
397 an encryption key in with the payload to encrypte the data. If one is not found
398 the commit will fail.
407 Indicates this property will return the entire row to which this column is related.
414 The non-name space qualified type name of the object to which this property is
415 related. This ORM will be dependent on the definition of this object already existing
416 and will not install unless it does.
420 "type": "UserAccountInfo",
423 If true the returned value will contain the complete row for each matching record, otherwise
424 the value will return exactly like a regular attribute.
432 The table column to map to. It should be a foreign key relation to the corresponding type.
438 "column": "prjtask_username",
441 The property relation of the type on which to join. Will accept camel case or snake case
442 mappings, but camel case is recommended.
449 "inverse": "username",
452 If true a join will be performed on the table instead of a left join to improve performance.
453 This should only be done if this property is required and is always guaranteed to have
462 A value to substitute if the client returns a null value.
471 Indicates this property will return an array of all records to which it is related.
478 The type name of the objects to be included. Type name should be class case and not include
479 a name space qualification.
481 Note that the toMany relationship will be dependent on an ORM of this type in a matching
482 name space already existing. If it does not installation will fail.
488 "type": "ProjectTaskComment",
491 The table column to map to. If not specified all rows for the type will be returned.
495 "column": "prjtask_id",
498 The key that is the relation to the column. Ignored if no column specified.
502 "inverse": "project_task",
505 If true the returned array will contain the complete row for each matching record, otherwise
506 the array will contain only primary keys for matching records.
508 Nested records will be automatically deleted when the parent is deleted so long as their edit
509 rules allow it. See deleteDelegate for situations where the rules are in conflict.
521 The extensions array allows you to define addtional tables on which to join to the table
522 of this ORM. The following keys apply to extensions in the exact same manner as the root
530 Note that the name space should not be included in extension arrays. It will be assumed
531 to be the root name space. The isExension property will automatically be true on values
532 listed in the extensions array.
538 Indicates the ORM has been created as part of an extension package. Helps to differentiate
539 standard from custom ORMs created by users for local implementations.
547 Dictates the sequence that extensions are processed in. Higher sequences will add columns to the
548 furthermost right of the ORM views.