Adding Custom Entities to the Data Model
Adding new entities to the data model involves multiple steps:
Create a New Building Block
To create a new building block, complete the following steps:
1. Create a new project. Use a unique prefix for your project, such as your company name. The PTC prefix is reserved for entities delivered by PTC. For this example, create a project named MyCompany.MyBuildingBlock. For each new Thing Template, Thing, or other entity that you create for this building block, add your new project as the Project value on the General Information page for the entity.
2. Create an entry point Thing Template in your project. For this example, name the new Thing Template MyCompany.MyBuildingBlock.EntryPoint_TT. The Base Thing Template to use depends on the type of your new building block:
◦ If your building block is extending from a PTC building block, use the entry point Thing Template from the PTC building block.
3. Create an entry point Thing in your project which uses the Thing Template that you created in step 2 as its Base Thing Template. For this example, name the new Thing MyCompany.MyBuildingBlock.EntryPoint.
4. Create a manger Thing for your building block.
◦ If your building block is extending from a PTC building block, complete the following steps:
a. Create a Thing Template in your project that uses the manager Thing Template from the PTC building block as its Base Thing Template.
b. Create a Thing in your project which uses the Thing Template that you created in step a as its Base Thing Template. For this example, name the new Thing MyCompany.MyBuildingBlock.Manager.
◦ If your building block is not extending from a PTC building block, complete the following steps:
a. Create a Thing Shape in your project to hold the service definitions for managing your new entity. For this example, name the new Thing Shape MyCompany.MyBuildingBlock.Management_TS.
b. Create a Thing Template in your project that uses PTC.Base.CommonManager_TT as its Base Thing Template. For this example, name the new Thing Template MyCompany.MyBuildingBlock.Manager_TT.
c. Add the Thing Shape that you created in step a to the Implemented Shapes field on the Thing Template that you created in step b.
d. Create a Thing in your project which uses the Thing Template that you created in step b as its Base Thing Template. For this example, name the new Thing MyCompany.MyBuildingBlock.Manager and use MyCompany.MyBuildingBlock.Manager_TT as its Base Thing Template.
5. If your building block is extending from a PTC building block, add any configurations from the manager Thing for the original building block to the manager Thing for your new building block.
a. Navigate to the manager Thing that you created in step 4, in this example MyCompany.MyBuildingBlock.Manager.
b. Under Configuration, add the same configurations that are found on the Configuration page of the manager Thing for the original building block.
6. Register the manager Thing for your building block. .
a. Navigate to the PTC.Base.Manager Thing.
b. Under Configuration, click Add for the DefaultGlobalManagerConfiguration configuration table.
▪ For Name, enter a name for the custom manager, for example, MyCompany.MyBuildingBlock.Manager.
▪ For Value, search for and select the custom manager Thing that you created in step 4.
c. Click Add to add the custom manager to the configuration table.
d. Click Save to save the updates to the manager Thing.
Create a Data Shape for the New Entity
To create a Data Shape for the new entity, complete the following steps:
1. In ThingWorx Composer, create a new Data Shape. Add the Data Shape to the project for your new building block. For this example, name the Data Shape MyObject.
2. Under Field Definitions, click Add and specify new field definitions for each property to be included on the Data Shape.
a. Designate one field as the primary key by selecting the Is Primary Key checkbox for that field.
b. Set the Base Type of the primary key field to LONG. If the primary key field is a LONG data type, then the values for this field are autogenerated, and the logic for incrementing the value is handled by the database. If a different Base Type is selected, then you must handle the logic for primary key uniqueness.
To align with the building block data model, add a UID field, with a Base Type of LONG, and select the Is Primary Key checkbox.
3. Click Save to save the new Data Shape.
|
When the database table is created for the Data Shape, the database table name is the Data Shape name, minus any prefix, in all lower case. For example, if the Data Shape is named ABC.MyObject, then the database table name is myobject. Because prefixes are not included in the database table names, multiple Data Shape names that would result in the same database table names, such as ABC.MyObject and PTC.JobOrder.MyObject, are not supported.
Similarly, the column names in the database table are the field names from the Data Shape in lowercase. For example, a field named MyPrimaryLocation results in a column named myprimarylocation. As a result, field names with the same letters but different capitalization, such as MyName, myName, and myname, are not supported on the same Data Shape.
|
Update the Database Information to Include the New Data Shape
Update the database information to include your new Data Shape. You can accomplish this by adding the database information for your entity to the GetDBInfo service on the manager Thing for your new building block (MyCompany.MyBuildingBlock.Manager).
To add the database information for the new Data Shape to an existing GetDBInfo service:
1. Navigate to the manager Thing for your new building block (MyCompany.MyBuildingBlock.Manager).
2. Under Services, navigate to and override the GetDBInfo service.
3. In the script editor, add an entry for your new Data Shape as an array, similar to the existing Data Shape entries. Include the database information for your Data Shape:
◦ dataShapeName—Name of the Data Shape for which the new database table is being added.
◦ indexedFields—Columns to be indexed. Indexing assists with faster searches and sorting. Multiple indexed fields can be defined in an array. Each element in the array can contain the following properties:
▪ name—Name of the column. Required.
▪ unique—Specify if the column must have a unique value.
▪ fieldNames—Array containing the names of the columns. If only one column is specified, a single index is created. If multiple columns are specified, a composite index is created.
|
A single index can be created by specifying name with a single value that is the name of the column, instead of specifying a single value for fieldnames. If both name and fieldnames are specified, name is ignored and the index is created using the fieldnames values.
|
▪ identifier—The name of the entity in the database. If not specified, then the system automatically generates the value in the format <table_name>_<column_name>_idx. If specified, then the value must be unique for both specified values and any automatically generated values. The maximum length for the value is the maximum length allowed by the database for identifiers.
◦ fields—Any column for which some additional specification is needed. Multiple fields can be defined in an array. Each element in the array can contain the following properties:
▪ name—Name of the column. Required.
▪ notNull—Specify if the column must not be null.
▪ defaultValue—The default value for the property.
|
If a column must have a unique value, specify this using unique in the indexedFields array, rather than in the fields array.
|
◦ foreignKeys—Any
foreign key column definitions for the new database table. Multiple foreign keys can be defined in an array. Each element in the array must contain the following properties:
▪ name—Name of the column on the current Data Shape to be a foreign key.
▪ referenceDataShapeName—The Data Shape of the referenced database table.
▪ referenceFieldName—The name of the field containing the value being referenced.
▪ identifier—The name of the entity in the database. If not specified, then the system automatically generates the value in the format <table_name>_<column_name>_fk. If specified, then the value must be unique for both specified values and any automatically generated values. The maximum length for the value is the maximum length allowed by the database for identifiers.
▪ onDelete—What happens, if anything, to instances of the current Data Shape when instances of the referenced Data Shape are deleted.
▪ deleteReference—What happens, if anything, to instances of the referenced Data Shape when instances of the current Data Shape are deleted.
For example, for the new MyObject Data Shape to have no indexed fields, a foreign key, and setting the length of the Location field to 4000 characters, enter the following:
{
"dataShapeName": "MyObject",
"indexedFields": [],
"foreignKeys": [{"name":"WorkDefinitionUID", "referenceDataShapeName":"PTC.SCA.SCO.WorkDefinition", "referenceFieldName":"UID"}],
"fields": [
{
"name": "Location",
"length": 4000
}
]
}
4. Click Done, then click Save to save the updated service.
Create CRUD Services
Create the CRUD services necessary for managing instances of the new Data Shape.
1. On the management Thing Shape for your building block (MyCompany.MyBuildingBlock.Management_TS), under Services, click Add and create the necessary services. Use the existing CRUD services for building block entities as models.
◦ A create service:
▪ Enter a service name. For this example, enter AddMyObjects.
▪ For the service input, add an input named MyObjects, with a Base Type of INFOTABLE. For Data Shape, select your Data Shape.
▪ For the service output, select INFOTABLE, and choose your Data Shape.
▪ In the script pane, enter code similar to the following:
var insertParams = {
infoTable: MyObjects,
dataShapeName: "MyObject"
};
var result = Things[me.GetDatabaseThingName()].Insert(insertParams);
◦ A delete service:
▪ Enter a service name. For this example, enter DeleteMyObject.
▪ For the service input, add an input named UID, with a Base Type of STRING.
▪ For the service output, select INFOTABLE, and choose your Data Shape.
▪ In the script pane, enter code similar to the following:
var params = {
UID: UID,
dataShapeName: "MyObject"
};
var result = Things[me.GetDatabaseThingName()].Delete(params);
◦ An update service:
▪ Enter a service name. For this example, enter UpdateMyObjects.
▪ For the service input, add an input named MyObjects, with a Base Type of INFOTABLE. For Data Shape, select your Data Shape.
▪ For the service output, select INFOTABLE, and choose your Data Shape.
▪ In the script pane, enter code similar to the following:
var params = {
infoTable: MyObjects,
dataShapeName: "MyObject"
};
var result = Things[me.GetDatabaseThingName()].Update(params);
◦ A service to retrieve an individual instance of this Data Shape:
▪ Enter a service name. For this example, enter GetMyObject.
▪ For the service input, add an input named UID, with a Base Type of STRING.
▪ For the service output, select INFOTABLE, and choose your Data Shape.
▪ In the script pane, enter code similar to the following:
var params = {
UID: UID,
dataShapeName: "MyObject"
};
var result = Things[me.GetDatabaseThingName()].GetEntity(params);
◦ A service to retrieve multiple instances of this Data Shape, optionally including filter, offset, and limit input parameters. If no input parameters are specified, all instances of MyObject are returned:
▪ Enter a service name. For this example, enter GetMyObjects.
▪ For the service input:
▪ Add an input named filter with a Base Type of JSON.
▪ Add an input named offset with a Base Type of INTEGER.
▪ Add an input named limit with a Base Type of INTEGER.
▪ For the service output, select INFOTABLE, and choose your Data Shape.
▪ In the script pane, enter code similar to the following:
var params = {
filter: filter,
dataShapeName: "MyObject",
offset: offset,
limit: limit
};
var result = Things[me.GetDatabaseThingName()].Query(params);
2. Click Save to save the new services on your Thing Shape.
Synchronize the Database Information and Database Schema
Add the new entity to the database by synchronizing the database information with the database schema. For more information, see
Synchronizing the Database Information and the Database Schema.