Related links
Sales & Asset management
Sales related services
Description of a part of the AM module - sales partFI - Finance Management
Framework Core functionality
- AyMINE Framework Server
- frmFrm – provided functionality
- System Rights
- System messaging
- AyMINE Business – Price calculation
- Strings and translations
- Export collection of objects
- AyMINE Framework management FAQ
- The AyMINE licence model
- AyMINE On-premise
- System events
- Mutli-client architecture
- Import collection of objects
- User sessions
- Default server methods
- Client-defined object attributes
- Common Libraries
Module - support for management
Libraries & Lincences
Mobile & Web Application
- Runtime debugging
- System console
- AyMINE Application
- In-line table edit support
- Object scripting API – object lang
- Application object structure
- Multilingual support
- View of a single object – detail
- Is using EVAL / feval method risky?
- Included library – String operations
- Cliplink
- Object API – object <g>
- API – Data object
- Object scripting API – object User
- Object view definition
- Framework support for Drag & Drop
- Common libraries
- Multiple-object update implementation
- fClip & fCliplist
- Offline persistent objects
- Mobile application
HR - Human Resources
System Management (part of framework)
Task, Project, Quality
Task & Task pattern
CMS - Content Management & Web API services
Object inheritance
Inheritance of the persistent objects
- About inheritance
- Object distinctions in database
- How is the object inherited
- Extending table for descendant object
About inheritance
The AyMINE objects support inheritance. The inheritance is applied for all parts of the object – attributes, view definitions as well as orchestration methods. The descendant object can even define its own attributes stored in the separate table. Object can have only single direct parent (multiple-parent inheritance is not supported).
An object that is a descendant of another object should have extension defined in the object about definition:
{
// About the file with object definition
"about":
{
"version":1,
"module":"<module>",
"name":"<descendant object name>"},
// Object definition
"data": {
// About the object
"about": {
"extends":"<parent object name>",
"name":"<object name>",
. . .
"type":"<descendant object type>",
"classID":"<descendant object short id>",
"short":"<optional shortage>",
"icon":"<descendant object icon>",
"groups":["extending parent object list of groups"],
"langModules": [ "extending parent object list of translation string resources" ]
}
},
// Object database definition
"tableSQL": {
"module":"<descendant module – could be different from parent module",
"extendingTable":"name of the table with descendant attributes"
. . .
},
}
Object distinctions in database
It is expected that an object that supports inheritance, has defined attribute systemObject:
"systemObject":{
"type":"string", // name of the object
"lenght":32, // maximal supported object name lenght
"required":true, // system object should always be defined
"default":"@fAttr.this" // default ways how to fill the object name
},
It is strongly recommended to follow this rule and always created the systemObject attribute. The application is tested only with inherited objects that follow this rule. Some of the default methods defined by persistentObject class trust on that. However, this is not required and objects can use inheritance even without that but all methods should be properly tested!
It is also stronly recommended not to use the systemObject attribute for anything else.
How is the object inherited
The complete master object definition is inherited to the descendant object. The descendant object could change definitions or add new parts in the same way as is used in other programming languages (TypeScript, C++, PHP etc.).
Attribute inheritance
Abstract master object could define attributes and descendant can complete or change its definition:
Master object
The abstract master object has attributes:
"attributes": {
// systemObject attribute that
"systemObject":{"type":"string", "required":true, "default":"@fAttr.this"},
. . .
}
Descendant object
The descendant adds its own attrbitutes:
"attributes": {
// redefine the master object attributes
"systemType":{
// Descendant uses its own counter for system type attribute
"type":"enum",
"enum":"tsk/problemSystemType",
"required":true
},
// Other field changes
"priority":{"type":"enum", "required":true, "enum":"sys/priority"}
}
Descendant iherits all master attributes and can modify their definition
Extending table for descendant object
Descendant object can define its own attributes and store them in a slave table. The slave table definition should fulfil the rules:
- Name of the slave table is not limitied. the Recommended name is
<master object table name>_<slave object name>
. Example:tskInfItem_problem
- Name of the ID field in the slave table should be the same as the ID name of the field in the master table
- Slave table name is defined by the object field definition
data->tableSQL->extendingTable
. - Records in the slave table are auto-deleted by database constraint linked with the master table
- Attributes of the slave objects are defined in the slave object with
"source":"objExtension"
- Records on the slave table are not always created. They are created only if user edits some of the additional fields. When the slave record is created it is never deleted by application, but should be deleted by database through the cascade constraint.
- Application supports only single descendant slave table. More complex inheritance is not supported. However, objects can be inherited with more than single parent:
<abstract parent> -> <specific object> -> <specific object variant>
Descendant object example
Problem is descendant of the abstract parent object AbstractInfItem. Parent object is stored in the tskInfItem table with tskInfItemID ID field
Descendant table and view definition
The descendant object is defined:
CREATE OR REPLACE TABLE tskInfItem_problem (
-- primary key has the same name as in the master table
-- slave tables never have its own id but always shares id from master table
tskInfItemID BIGINT UNSIGNED NOT NULL,
PRIMARY KEY (tskInfItemID),
-- constraint deletes slave record with master record
-- application does not do that and trust on the database
CONSTRAINT fk_tskInfItem_problem_master
FOREIGN KEY (tskInfItemID)
REFERENCES tskInfItem(tskInfItemID)
ON DELETE CASCADE,
-- fields of the descendant object
reportedByName varchar(32) comment 'user or other subject that reported the problem',
reportedByID bigint unsigned null comment 'ID for reportedBy'
) comment 'Additional fields for object tskProblem';
The descendant object also needs a database view for list and detail application views:
create or replace view tskwProblemS as select
ii.*,
-- add extended fields indcluding their definition
ip.reportedByName,
ip.reportedByID,
-- add field with description of the linked object
objDesc(ip.reportedByName,ip.reportedbyID) as reportedbyIDDesc
from
tskwInfItemDetailS ii
left outer join tskInfItem_problem ip on ip.tskInfItemID = ii.tskInfItemID;
The descendant object definition
{
"about": { . . . },
"data": {
"about": { "extends":"tskAbstractInfItem",
"name":"tskProblem",
. . .
// Adds its own list of translation string
"langModules": [ "tsk/langs/@/problem" ]
},
"attributes": {
. . .
// New attribues defined by descendant object and stored in the slave table
"reportedByName":{
"type":"string", "length":32,
"source":"objExtension" // information where attributes are stored
},
"reportedByID":{
"type":"objectPrincipal",
"source":"objExtension",
"objAllowed":["sysUser", "crmPersonSubject"]
}
}
"tableSQL": {
// Descendant object should define its module (even when is from the same module as the parent).
"module":"tsk",
// Name of the table where the descendant attributes are stored
"extendingTable":"tskInfItem_problem",
. . .
},
"views":{
// *************************** Details ****************************
"details":{
"default":{
. . .
"serverData": {
// Descendant object should have defined view that combines data from both tables
// Application does not automatically loads fields from more tables because
// all larger object needs view anyway
"selectFROM":"tskwProblemS"
}
}
},
} } }