ORDA data model class functions are provided as a preview feature in 4D v18 R4: all functions you create are exposed without restrictions. Future releases will include more control over the function availability, especially from REST requests. In the next release, by default all your data model class functions will be set to private. You will have to specify individually each function that you want to be exposed.
ORDA allows you to create high-level class functions above the data model. This allows you to write business-oriented code and "publish" it just like an API. Datastore, dataclasses, entity selections, and entities are all available as class objects that can contain functions.
For example, you could create a
getNextWithHigherSalary() function in the
EmployeeEntity class to return employees with a salary higher than the selected one. It would be as simple to call as:
Developers can not only use these functions in local datastores, but also in client/server as well as remote architectures (see the full example below):
//$cityManager is the reference of a remote datastore Form.comp.city:=$cityManager.City.getCityName(Form.comp.zipcode)
Thanks to this feature, the entire business logic of your 4D application can be stored as a independent layer so that it can be easily maintained or reused:
it allows you to "hide" the overall complexity of the underlying physical structure and only expose understandable and ready-to-use functions.
if the physical structure evolves, you simply to adapt function code and client applications will continue to call them transparently.
In addition, 4D Developer automatically pre-creates the classes for each available data model object.
All ORDA data model classes are exposed as properties of the
cs class store. The following ORDA classes are available:
|Class||Example name||Instantiated by|
ORDA user classes are stored as regular class files (.4dm) in the Classes subfolder of the project (see below).
In addition, object instances from ORDA data model user classes benefit from their parent's properties and functions. For example, an Entity class object can call functions from the ORDA Entity generic class.
Note: Keep in mind that ORDA data model functions are always executed on the server. Thus, calling a function generates a request to the server.
A 4D database exposes its own DataStore class in the
cs class store.
- Extends: 4D.DataStoreImplementation
- Class name: cs.DataStore
You can create functions in the DataStore class that will be available through the
// cs.DataStore class Class extends DataStoreImplementation Function getDesc $0:="Database exposing employees and their companies"
This function can then be called:
$desc:=ds.getDesc() //"Database exposing..."
Each table exposed with ORDA offers a DataClass class in the
cs class store.
- Extends: 4D.DataClass
- Class name: cs.DataClassName (where DataClassName is the table name)
- Example name: cs.Employee
// cs.Company class Class extends DataClass // Returns companies which revenue is over the average // Returns an entity selection related to the DataClass Company Function GetBestOnes() $sel:=This.query("revenues >= :1";This.all().average("revenues")); $0:=$sel
Then, you can get an entity selection of the "best" companies by executing:
var $best : cs.CompanySelection $best:=ds.Company.GetBestOnes()
Example with a remote datastore
The following City catalog is exposed in a remote datastore (partial view):
City Class provides an API:
// cs.City class Class extends DataClass Function getCityName() var $1; $zipcode : Integer var $zip : 4D.Entity var $0 : Text $zipcode:=$1 $zip:=ds.ZipCode.get($zipcode) $0:="" If ($zip#Null) $0:=$zip.city.name End if
The client application opens a session on the remote datastore:
$cityManager:=Open datastore(New object("hostname";"127.0.0.1:8111");"CityManager")
Then a client application can use the API to get the city matching a zip code (for example) from a form:
Each table exposed with ORDA offers an EntitySelection class in the
cs class store.
- Extends: 4D.EntitySelection
- Class name: DataClassNameSelection (where DataClassName is the table name)
- Example name: cs.EmployeeSelection
// cs.EmployeeSelection class Class extends EntitySelection //Extract from this entity selection the employees with a salary greater than the average Function withSalaryGreaterThanAverage C_OBJECT($0) $0:=This.query("salary > :1";This.average("salary")).orderBy("salary")
Then, you can get employees with a salary greater than the average in any entity selection by executing:
Each table exposed with ORDA offers an Entity class in the
cs class store.
- Extends: 4D.Entity
- Class name: DataClassNameEntity (where DataClassName is the table name)
- Example name: cs.CityEntity
// cs.CityEntity class Class extends Entity Function getPopulation() $0:=This.zips.sum("population") Function isBigCity C_BOOLEAN($0) // The function getPopulation() is usable inside the class $0:=This.getPopulation()>50000
Then, you can call this code:
var $cityManager; $city : Object $cityManager:=Open datastore(New object("hostname";"127.0.0.1:8111");"CityManager") $city:=$cityManager.City.getCity("Caguas") If ($city.isBigCity()) ALERT($city.name + " is a big city") End if
When creating or editing data model classes, you must pay attention to the rules described below.
Since they are used to define automatic DataClass class names in the cs class store, 4D table names must be compliant in order to avoid any conflict in the cs namespace. In particular:
- Do not give the same name to a 4D table and to a user class name. If such a case occurs, the constructor of the user class becomes unusable (a warning is returned by the compiler).
- Do not use a reserved name for a 4D table (e.g. "DataClass").
When defining a class, make sure the
Class extendsstatement matches exactly the parent class (case sensitive) name. For example,
Class extends EntitySelectionfor an entity selection class.
You cannot instantiate a data model class object with the
new()keyword (an error is returned). You must use a regular instantiation method.
You cannot override a native ORDA class method from the
4Dclass store with a data model user class function.
Support in 4D projects
An ORDA data model user class is defined by adding, at the same location as regular class files (i.e. in the
/Sources/Classes folder of the project folder), a .4dm file with the name of the class. For example, an entity class for the
Utilities dataclass will be defined through a
4D automatically pre-creates empty classes in memory for each available data model object.
By default, empty ORDA classes are not displayed in the Explorer. You need to show them by selecting Show all data classes from the Explorer's options menu:
ORDA user classes have a different icon from regular classes. Empty classes are dimmed:
To create an ORDA class file, you just need to double-click on the corresponding predefined class in the Explorer. 4D creates the class file and add the
extends code. For example, for an Entity class:
Class extends Entity
Once a class is defined, its name is no longer dimmed in the Explorer.
To open a defined ORDA class in the 4D method editor, select or double-click on an ORDA class name and use Edit... from the contextual menu/options menu of the Explorer window (like for any class):
For ORDA classes based upon the local datastore (ds), you can directly access the class code from the 4D Structure window:
In the 4D method editor, variables typed as an ORDA class automatically benefit from autocompletion features. Example with an Entity class variable: