Case vs. Object
Mercury DB® is also called a "case database". Let's try to explain what the concept of a "case" is in the interpretation of the system. A case is any object described by a type and its parameters. I wondered for a long time how to name the basic unit defining such an object. The word Object is reserved by many programming languages, hence the concept of Case, which in this case becomes its synonym. The concept of Case also has its reference to business concepts, which it represents in a number of practical applications. A case is a representation of the object of a contract, a contractor, a computer, a car and an infinite number of things that surround us, and we would like to record them in electronic form. The document contains many concepts such as "complex object", "dependent case", "parent case", "type", "type parameters", which can be interpreted differently. In the following part we will try to explain, based on a specific example, what these concepts mean from the point of view of the Mercury DB® system. We will refer to an example of a data object definition in the IBM BPM system, in which we use the concept of "Business Object" (BO).
Simple object and complex object
Definition of the sample business object TestMrcObject
An object, in the interpretation of the Mercury DB (HgDB) 3.0 system, is a set of fields with a specific name and a specific type. We can distinguish two types of objects:
- Simple object is a set of fields whose definitions are based on simple types such as:
String
,Integer
,Number
,Decimal
,Date
etc. or lists whose elements are based on simple types such as a list of elements of theString
type. - A complex object is a set of fields, among which the type definition is other "simple objects" or "complex objects"
In the given example, the TestMrcObject object is a "complex object" because the field named role
is of type TestRole
(by the way, this object is a "simple object", it contains only simple fields: name
of type String
, priv
of type String
and the field users
, which is a list of simple elements of type String
). Similarly, the field user
, whose type is another "simple object" named TestUser
.
A simple case and a complex case
Every system must have the ability to uniquely identify data. In relational databases, the way to uniquely identify a row is to define a primary key. In the Mercury DB system, the role of such a primary key is played by a field called "mrcCaseHeader" (this name is constant and unchangeable) of type MrcCaseHeader (the description of the object can be found later in this document). So, to transform a "simple object" or "complex object" into a case, you need to add a field with the mentioned name to their definition:
Definition of the sample business object TestMrcObject
We distinguish the following types of cases:
- Simple case - a case was created based on a simple object, i.e. it is a set of fields whose types are simple types such as:
String
,Integer
,Number
,Decimal
,Date
, etc. or lists whose elements are based on simple types such as a list of elements of typeString
and has a fieldmrcCaseHeader
of typeMrcCaseHeader
. - Complex case – a case was created based on a complex object, i.e. in the set of fields there are fields whose type definition is other "simple cases" or "complex cases" and has a field
mrcCaseHeader
of typeMrcCaseHeader
. "Simple cases" and "complex cases" being the field definition of another complex case will also be called "dependent cases", and the complex case itself, in relation to its components, will be called a "parent case". Let's sum up:- dependent case = simple or complex case being a component of another complex case in relation to this case
- parent case = complex case in relation to its components.
In the presented example:
- The
TestRole
object has become a simple case and can exist in the Mercury DB (HgDB) 3.0 system as an independent entity. - The
TestUser
object has become a simple case and can exist in the Mercury DB (HgDB) 3.0 system as a standalone entity. - The
TestMrcObject
object has become a complex case and at the same time theTestRole
andTestUser
cases are dependent cases in relation toTestMrcObject
, andTestMrcObject
is a superior case in relation toTestRole
andTestUser
.
It is worth emphasizing that while the definition of the complex case TestMrcObject
cannot exist without the definition of TestRole
and TestUser
, TestRole
and TestUser
can be separate and independent entities.
There are restrictions related to the naming of object fields, e.g. a field in the object represented by the case (simple or complex) cannot be called mrcCaseHeader
.
Currently, there can be a maximum of 128 fields in the object (simple or complex) represented by the case.
Case type, case parameters
We need to clarify the terms of the concepts of "type", "parameter" and their interpretation by the Mercury DB system. Although their names seem intuitive, it is necessary to spend some time on this issue.
We distinguish the following concepts related to defining the case type:
- Type code, a name grouping different versions of types, is represented by the TypeCode entity object (described later in this section)
- Type version, is represented by the TypeCase entity object (described later in this section). The version has its own name, which is most often the same as the "type code", which is why the mistake of confusing the code with the version and vice versa is made. Very often, "Type Code" and "Type Version" are defined with the same meaning "case type", which unfortunately, can often lead to misunderstandings.
- A type parameter, which is represented by the TypeParam entity object (described later). It is a link between the parameter definition and the type version. Each type parameter has a defined, predetermined position of occurrence in a given type version. Changing the definition or position implies the creation of a new type version.
- A parameter definition is a link between the field name and its type. It is represented by the ParamDefinition entity object (described later)
As mentioned earlier, "Type Code" is simply a name grouping different types of types. As an entity object, it is used to create links between case types and other entities occurring in the system (except for the entity representing the case, which is directly related to a specific type version).
Let's go back to our example and break it down into its prime factors in the context of interpreting the analyzed concepts. Recall that we defined a case called TestMrcObject
:
In this case, the "type code" will take the following values:
- For a simple case
TestRole
: value "TestRole" - For a simple case
TestUser
: value "TestUser" - For a complex case
TestMrcObject
: value "TestMrcObject"
After saving the case to the Mercury system, the following type versions will be created:
- For a simple case
TestRole
: version of the type named "TestRole" - For a simple case
TestUser
: version of the type named "TestUser" - For a complex case
TestMrcObject
: version of the type named "TestMrcObject"
Each of the created versions will contain a list of parameters, which are an ordered set of "parameter definitions" at specific positions. In our case, the following parameter definitions will be created:
- the definition named
name
, with a simple typeString
- the definition named
priv
, with a simple typeString
- the definition named
users
, as a list of elements of a simple typeString
- the definition named
id
, with a simple typeInteger
- the definition named
userName
, with a simple typeString
- the definition named
fullName
, with a simple typeString
- the definition named
isActive
, with a simple typeInteger
- the definition named
isTechnical
, with a simple typeInteger
- the definition named
locale
, with a simple typeString
- the definition named
timeZone
, with a simple typeString
- the definition named
listStr
, as a list of elements of a simple typeString
- the definition named
listInt
, as a list of elements of the simple typeInteger
- the definition named
listDec
, as a list of elements of the simple typeDecimal
- the definition named
map
, as an object of the typeLOB
(Large Object), subtype Map (all "compound objects" not recognized as "cases" - do not have the fieldmrcCaseHeader
, are treated as typeLOB
) - the definition named
indexedMap
as an object of the typeLOB
(Large Object), subtype IndexedMap (all "compound objects" not recognized ascases
- do not have the fieldmrcCaseHeader
, are treated as typeLOB
) - the definition named
listMap
as an object of the typeLOB
the definition namedlistDates
as a list of elements of the simple typeDate
- the definition named
role
, whose type is "dependent case", version of the type with codeTestRole
- definition named
user
, whose type is "dependent case", version of the type with the codeTestUser
Therefore, the individual versions of the types will have the following parameters:
- The version of the case type named TestRole will have:
- the definition named
name
in position 1 - the definition named
priv
in position 2 - the definition named
users
in position 3
- the definition named
- The version of the case type named TestUser will have:
- the definition named
id
in position 1 - the definition named
userName
in position 2 - the definition named
fullName
in position 3 - the definition named
isActive
in position 4 - the definition named
isTechnical
in position 5 - the definition named
locale
in position 6 - the definition named
timeZone
in position 7
- the definition named
- The version of the case type named TestMrcObject will have:
- the definition named
role
in position 1 - the definition named
user
in position 2 - the definition named
listStr
in position 3 - the definition named
listInt
in position 4 - the definition named
listDec
in position 5 - the definition named
map
in position 6 - the definition named
indexedMap
in position 7 - the definition named
listMap
in position 8 - the definition named
listDates
in position 9
- the definition named
To sum up: the example was intended to show how individual components of an object are interpreted by the Mercury DB (HgDB) 3.0 system and what are the differences in understanding certain terms related to object orientation. As further reading will show, the definitions of the entities TypeCode
, TypeCase
, TypeParam
and ParamDefinition
are not as simple as they are now presented, because they also provide support for other system functionalities, including mechanisms for generating forms for editing case data.
For the basic functionality of the Mercury system, which is storing data about any cases, the presented transformation of an object into a case is completely sufficient.