-
Notifications
You must be signed in to change notification settings - Fork 0
Serialization
A Serialization is attached to a model and permit to serialize/deserialize (save/load) objects in/from a specific output/input. For example you have defined a manifest Person and you want to serialize persons in sql database. To do so, you have to define table name and database connection by building serialization manifest file.
When it's done, you're able to serialize/deserialize objects. for more details see Object serialization chapter.
Serialization manifest is a file that describe how to serialize/deserialize objects. In this file you have to specify the serialization manifest version to determine witch parser will be used to parse the document. There is currently only one version allowed 2.0.
Serializations manifests may be defined in XML or JSON format (depends on manifest format defined in Configuration file). For each example we will illustrate XML and JSON format.
<manifest version="2.0">
<serialization/>
<properties/>
</manifest>{
"version": "2.0",
"serialization" : {},
"properties" : []
}-
serializationnode that describe your serialization settings -
propertiesnode that describe some needed properties informations for serialization
Serialization settings are described by their own manifest and are instanciated as Comhon Objets. Now we will describe and explain all availables serializations settings.
File serialization permit to store objects in files. It is attached to model Comhon\File that is described by manifest here. In fact, File is not usable to serialize an object (consider it like an abstract class), but there are serializations that extends from this one : JSON and XML.
This serialization permit to store objects in JSON files. It is attached to model Comhon\JsonFile that is described by manifest here.
This serialization permit to store objects in XML files. It is attached to model Comhon\XmlFile that is described by manifest here.
As said before, JSON and XML extends from File manifest. In fact they are exactly the same, they have two properties inherited from File :
-
saticPaththat define the folder where files will be stored -
staticNamethat define the names of files that will store all serialized objects
Each object will be serialized in intermediate folder identified by the object id.
You have an XML file serialization settings :
{
"saticPath": "/asolute/path/to/a/folder",
"staticName": "file_name.json"
}and you want to serialize an object with id an_id, file will be saved at :
/asolute/path/to/a/folder/an_id/file_name.json
This serialization permit to store objects in SQL database. It is attached to model Comhon\SqlTable that is described by manifest here.
Model Comhon\SqlTable has two properties :
-
namethat define the table name (specify schemamy_schema.my_tableif you use a postgreql database) -
databasethat define the database that own the table.
Let's explain database property :
It is attached to model Comhon\SqlDatabase that is described by manifest here.
It is a foreign property so it contain only an id that refer to a database object serialized elsewhere.
In SqlDatabase manifest you can see a property DBMS, it permit to identify your database management system. Comhon! currently manage followings DBMS :
- mysql
- pgsql
Comhon\SqlTable and Comhon\SqlDatabase have their own serialization. Actually they use JSON file serialization so you will have to store you tables and database(s) in JSON files and in two different folders. take a look at Configuration page to see how to configure those two folders.
- Sql tables must be saved in files named
table.jsonin intermediate folder named with table id (id property is the table name) - Sql databases must be saved in files named
database.jsonin intermediate folder named with database id
A right sql serialization setting looks like :
- A table file
/var/data/table/my_table_name/table.json
{
"name": "my_table_name",
"database": "my_db"
}- A database file
/var/data/database/my_db/database.json
{
"id": "my_db",
"DBMS": "mysql",
"host": "localhost",
"name": "database",
"user": "my_user",
"password": "my_passord",
"options": {
"charset": "utf8",
"timezone": "UTC"
}
}Comhon! is optimized to load only one time serializations. For example if you have two tables that refer the same database, and if you use them in a single script execution, tables will share the same instance of database.
serialization node describe your serialization settings. More exactly there are three informations to identify.
- the type of serialization (see previous section to known allowed serializations)
- the settings description, or an id that reference a serialized serialization settings. Description and id cannot coexist, you have to choose one of them. Here are the two differents ways :
1. describe directly your serialization settings in value node (see corresponding manifest to know how to describe your serialization)
<manifest version="2.0">
<serialization type="Comhon\JsonFile">
<value saticPath="/asolute/path/to/a/folder" staticName="a_file_name.json"/>
</serialization>
<properties/>
</manifest>{
"version": "2.0",
"serialization": {
"type": "Comhon\\JsonFile",
"value": {
"saticPath": "/asolute/path/to/a/folder",
"staticName": "a_file_name.json"
}
}
}2. reference an id of a serialization (obviously reference a serialization that has been serialized)
<manifest version="2.0">
<serialization type="Comhon\SqlTable" id="a_table_id"/>
<properties/>
</manifest>{
"version": "2.0",
"serialization": {
"type": "Comhon\\SqlTable",
"id": "a_table_id"
}
}- the inheritance key (optional)
this information is used if you have several models that have the same serialization. It permit to bind model with deserialized object.
For example you have a table person with a column sex that permit to differentiate men and women, and you have defined manifests of Woman and Man that extends Person. You have to define inheritance key as sex to bind Namespace\Woman or Namespace\Man model to deserialized object.
<manifest version="2.0">
<serialization type="Comhon\SqlTable" inheritanceKey="sex" id="person"/>
<properties/>
</manifest>{
"version": "2.0",
"serialization": {
"type": "Comhon\\SqlTable",
"inheritanceKey": "sex",
"id": "person"
}
}Note that value in inheritanceKey must be an existing model name.
/----------------------------------------------\
| firstname | lastname | age | sex |
|----------------------------------------------|
| jane | doe | 24 | Namespace\Woman |
| john | doe | 12 | Namespace\Man |
\----------------------------------------------/
properties node is a list of properties. Each property node refer to a property in corresponding Model.
For the following explanations we will build a serialization Person like example.
some serialization doesn't manage certain characters so you can replace a property name when you serialize your Object. For example pgsql doesn't manage columns names with uppercase, so if you have a property name APropertyName you can define a serialization name a_property_name that will match with your column name.
<manifest version="2.0">
<serialization type="Comhon\SqlTable" id="person"/>
<properties/>
<firstName serializationName="first_name"/>
</properties>
</manifest>{
"version": "2.0",
"serialization": {
"type": "Comhon\\SqlTable",
"id": "person"
},
"properties": {
"firstName": {
"serializationName": "first_name"
}
}
}serializationName can't coexist with serializationNames.
Serialization names is available only for foreign properties that have a model with several id properties. It might be used when object is serialized in database table that contain composite foreign key(s) (foreign key with several columns).
<manifest version="2.0">
<serialization type="Comhon\SqlTable" id="my_table"/>
<properties/>
<my_foreign_property_with_several_id>
<serializationNames>
<id1>my_column_foreign_id_one</id1>
<id2>my_column_foreign_id_two</id2>
</serializationNames>
</my_foreign_property_with_several_id>
</properties>
</manifest>{
"version": "2.0",
"serialization": {
"type": "Comhon\\SqlTable",
"id": "my_table"
},
"properties": {
"my_foreign_property_with_several_id": {
"serializationNames": {
"id1": "my_column_foreign_id_one",
"id2": "my_column_foreign_id_one_two"
}
}
}
}serializationNames can't coexist with serializationName.
Aggregation is a way to associate a model to others models by matching properties. This information is used only for slqTable serialization, actually it permit to make automatic join between sql tables when it's needed (typically during request). For example model Person has a foreign property homes (see Manifest example), model home has it own serialization and would have a property owner (serialized in a column like owner_id or person_id), so aggregation would refer owner and look like :
<manifest version="2.0">
<serialization type="Comhon\SqlTable" id="person"/>
<properties>
<homes>
<aggregations>
<aggregation>owner</aggregation>
</aggregations>
</homes>
</properties>
</manifest>{
"version": "2.0",
"serialization": {
"type": "Comhon\\SqlTable",
"id": "person"
},
"properties": {
"homes": {
"aggregations": [
"owner"
]
}
}
}A property can refer to several aggregations :
<manifest version="2.0">
<serialization type="Comhon\SqlTable" id="person"/>
<properties>
<children>
<aggregations>
<aggregation>mother</aggregation>
<aggregation>father</aggregation>
</aggregations>
</children>
</properties>
</manifest>{
"version": "2.0",
"serialization": {
"type": "Comhon\\SqlTable",
"id": "person"
},
"properties": {
"children": {
"aggregations": [
"mother",
"father"
]
}
}
}If a model inherit from another, it will inherit it serialization too. So if you want to keep same serialization you don't have to create a serialization manifest for inherited model. If you want a different serialization for inherited model you just have to create a serialization manifest and define serialization settings for this model, it will overwrite parent serialization.
As manifests, serializations manifests are autoloaded. All serializations manifests files must be named serialization.json or serialization.xml (depends on manifest format defined in Configuration file).
Important !!! A serialization manifest is loaded only if corresponding manifest has attribute is_serializable set to true (see Manifest page).
By default Comhon! will search serialization manifest file in same folder than manifest file.
For example if manifest is at :
/my/directory/manifests/Person/manifest.json
Comhon! will search serialization manifest at :
/my/directory/manifests/Person/serialization.json
If you want to store serializations manifests in a different directory than manifest you can do so by specifying a directory for serializations manifests in Configuration file.
For example :
"autoload": {
"manifest":{
"Test":"../manifests/manifest"
},
"serialization":{
"Test":"../manifests/serialization"
}
}
manifests in namespace Test are stored in directory :
../manifests/manifest
serializations manifests in namespace Test are stored in directory :
../manifests/serialization
If serialization manifest file is found, A serialization instance will be attached to model instance. And you will be able to serialize/deserialize objets.
<manifest version="2.0">
<serialization type="Comhon\SqlTable" inheritanceKey="sex" id="person"/>
<properties>
<firstName serializationName="first_name"/>
<birthPlace serializationName="birth_place"/>
<father serializationName="father_id"/>
<mother serializationName="mother_id"/>
<children>
<aggregations>
<aggregation>mother</aggregation>
<aggregation>father</aggregation>
</aggregations>
</children>
<homes>
<aggregations>
<aggregation>owner</aggregation>
</aggregations>
</homes>
</properties>
</manifest>{
"version": "2.0",
"serialization": {
"type": "Comhon\\SqlTable",
"inheritanceKey": "sex",
"id": "person"
},
"properties": {
"firstName": {
"serializationName": "first_name"
},
"birthPlace": {
"serializationName": "birth_place"
},
"father": {
"serializationName": "father_id"
},
"mother": {
"serializationName": "mother_id"
},
"children": {
"aggregations": [
"mother",
"father"
]
},
"homes": {
"aggregations": [
"owner"
]
}
}
}