The files needed for the HumeODC package include
Filename | Description |
en.msg | Definitions of English language messages for all English locales including en_US. The ODC uses the msgcat package to support multi-lingual deployment. |
od_load_data.tcl | Tcl code to load the ODC tables from a persistent database. |
od_save_subs_init.tcl | Tcl code to open table subscriptions for saving ODC data. |
od_schema_db_init.tcl | Tcl code to create the ODC schema in a persistent database. |
od_transient.tcl | Tcl code that implements the od_*transient* commands. |
odc.tcl | The core logic of the ODC. |
pkgIndex.tcl | An index of available Tcl packages in the directory. Needed by Tcl to find the HumeODC package when required. |
tclIndex | An index of available Tcl commands in the directory. Needed by Tcl to find the od_* commands after the HumeODC package has been required. |
Some applications that use the ODC will not use a persistent database, since the high-level array access to table data is also very useful just for in-memory SQL tables. When a persistent database is in use, the name of the mailbox that is used to process SQL commands for the persistent database is passed as an argument to the od_init call. When the persistent mailbox name is not blank, (1) the ODC logic create tables in the persistent database if they are not present, (2) the ODC loads the initial data into the in-memory tables from the persistent database, and (3) the ODC opens data saving table subscriptions. If for some reason a persistent database is in use but this initialization is not desired, pass an empty string for the mailbox name argument to the od_init call, and then when the call returns set the value of HumeODC::MB_DB to the persistent database mailbox name. The value of the persistent database mailbox name is needed after startup only for the od_*transient* commands.
You define your own types of items. To make this discussion more concrete, lets suppose we have defined a type of item called a LotBox which is type of container. Lets also define Wafer as an item type. The new types are easiest to define using Tcl code:
global ODCAs the result of executing the above statements, two new rows are added to the od_assoc table, and variable traces are created so that we can use LotBox and Wafer as global arrays. Now we can have instances of the new types. Suppose that every LotBox has a unique serial number, and that every Wafer has a unique identifying scribe. Suppose there are three Wafers, w1, w2, and w3, currently in LotBox lb100. We can save the association of these Wafers to the LotBox with the following statements:
lappend ODC(:Type) LotBox Wafer
global LotBoxLater in our code, we can easily determine the Wafer items associated with the LotBox:
set LotBox(lb100:Wafer) {w1 w2 w3}
puts $LotBox(lb100:Wafer)If you display the contents of table od_assoc, you will see three separate rows representing the association of each of these Wafer items to the LotBox.
w1 w2 w3
Data attributes are simply named values that we wish to use. Suppose we tested the wafers and we now have some test results we wish to save. Each result has a name, and a value. So the results can be saved as attribute data using statements like:
global WaferEach of the above assignment statements causes a row to be added to the od_attribute table. If we examine a particular item, such as Wafer w3, we can determine all of its attribute values by using a wildcard attribute name, *:
set Wafer(w1.bin1) 237
set Wafer(w2.bin1) 242
set Wafer(w3.bin1) 244
set Wafer(w1.Yield) 89.3
set Wafer(w2.Yield) 91.2
set Wafer(w3.Yield) 92.4
puts $Wafer(w3.*)The result is a list of alternating name and value elements.
Yield 92.4 bin1 244
The wildcard attribute expression also works for writing, too. We can add other name, value attributes to the list, and easily save them in one statement:
set Wafer(w3.*) {Yield 92.4 bin1 244 bin2 22 bin3 13}Another feature is the ability to save attribute values for the item type, and have them be the default values for item instances. Suppose that most of the Wafers in our example are 200mm diameter, but there are some whose sizes are different. We can set the default for all wafers as follows, and verify that it shows up for the particular wafer w3:
set Wafer(diameterMM) 200Wafer w99 is different. We can specifically set a different attribute value for it:
puts $Wafer(w3.*)
Yield 92.4 bin1 92.4 bin2 92.4 bin3 92.4 diameterMM 200
puts $Wafer(w99.*)
diameterMM 200
set Wafer(w99.diameterMM) 300
puts $Wafer(w99.*)
diameterMM 300
The system user defines a set of item_types, such as Lot, Event, etc. The item_types known to the system are stored in the od_assoc table. Tcl programming statements have simplified access to the table data using global arrays. Simplified access is supported for reading or writing.
The list of known item_type values in a newly installed system, includes only ODC. A new installation of the Event Processing Component (EPC) includes the following:
You can add new types to the od_assoc table using the SQL statements or the Datahub GUI. It is also simple to append them as list items to the current list:
global ODCIf you are using a persistent database, adding new types need only be done once.
lappend ODC(:Type) NewType1 NewType2 ...
The system user should configure new item_type values before attempting to use the global array access techniques.
There is simplified access to the attribute values of specific item_type instances using the following notation:
set item_type(item_id.attribute) valueThere is simplified access to the item_type level to create attribute values which are default values for any instances of the item_type. This data is stored in the table with the value of the item_id field set to *.global MID Lot
set MID(hp34au.Softbin) 24
set Lot(6809AUQ5.case_quantity) 100
set item_type(attribute) value ;# the implied item_id is '*'There is "inheritance" from the type to the instance. If a lookup for the value of item_type(item_id.attribute) is not found, the value of item_type(attribute) is returned if it exists - powerful and simple. The mechanism is convenient to configure defaults for the creation of new items, and for the compact representation of repeated items. If you explicitly write to item_type(item_id.attribute), it is written out for the instance whether or not it is the same as the type level default.$EPC(StateLogInterval) is the same as $EPC(*.StateLogInterval)
$EPC(EventLogInterval)
set Lot(case_quantity) 500
There is wildcard access to all the attributes for an instance. If you lookup $item_type(item_id.*) we specially trap the "*" and return a list of alternating name and value for all of the attribute values. We do this by looking up the attributes defined for the item_type first, $item_type(*.attribute), and then overlaying the instance data. There is direct writing of all the attributes of an instance, the exact reverse of the lookup. With this mode of writing, if the attribute of an instance is the same as it is for the item_type, it is not written out for the instance. Any attributes of the instance that are in the table but are not found in the wildcard write, are deleted.
set item_type(item_id.*) [list name1 value1 name2 value2 \You cannot use the Tcl upvar command to work with the arrays using a different name since the array name is a key to the table mapping.
name3 value3 ... nameNvalueN]set MID(hp34au.*) {Softbin 24 location h-15 engineer {J. Bond}\
IP_address 192.168.2.3 MID_class hp3000 ... }
There are a set of procedures, documented below, provided with the ODC to help manage transient data. There are some subtle aspects to how the subscriptions work that make using these procedures desirable. For example, if you simply update the is_transient field for selected attributes, the persistent database does not save that you want a non-zero is_transient value. So when you startup again, the attributes are back to being completely persistent. Using the od_transient procedure to declare specified attributes as being transient takes care of making sure the persistent database saves that the specified attributes are transient.
set item_type(item_id:child_type) id1 id2 ... idNUsing a different separator in the array subscript, the colon, :, tells the software that an association is implied.
If the item_id portion of the array subscript is blank, it defaults to '*'. So ODC(*:Type) or ODC(:Type) can both be used to access the same set of table records.
Similarly, if the child_type array subscript term is left blank, it defaults to the value * with a wildcard meaning. The wildcard behavior is not so useful for reading because child_id values of different child_type values are mixed, but it can be very powerful for deleting everything associated with an item by assigning an empty string. For example:
You optionally make use of the od_*transient*
calls to manage whether your attributes are transient.
Tcl Command Syntax
od_init {mb_db {}} {NAMELEN 32}Return Value
"Object Data Component (ODC) Initialized Successfully." is returned for the usual successful case.DescriptionThe procedure will return a Tcl error if the system cannot be initialized.
This is the entry procedure to initialize the ODC. The MB_DB argument is the DMH mailbox of the persistent database interface. If a persistent database is not being used, the MB_DB argument value should be an empty string. See the discussion of application initialization.The optional NAMELEN argument is passed through to the schema create logic where it sets the number of characters specified in the varchar( ) table fields that are used for names.
Tcl Command Syntax
od_schema_write {filename dc_schema.sql} {DBtype hub}Return Value
NoneDescription
This procedure calls od_schema and writes the result to a file with each create statement being written as a new line of text. The file is not used by the ODC, this procedure exists for your use. Set the DBtype argument to any value other than hub to have the primary table keys declared as NOT NULL.
Tcl Command Syntax
od_transient [attribute_name]+Return Value
od_not_transient [attribute_name]+
od_is_transient attribute_name
od_transient_save [attribute_name]+
od_transient, od_not_transient, od_transient_save: row_countDescription
od_is_transient: boolean
One of the key benefits of the ODC is the simplified access to SQL table data using the normal array variable syntax of the Tcl programming environment. The application is able to manipulate data with high-performance in the datahub process, and to have changes posted to the persistent database by the queuing of DMH subscription messages. By default, attributes that are manipulated in this way, and represented in the od_attribute table are persistent. In other words, their value changes are posted to the persistent database as they happen. The same simplified access to attribute data can also be used for manipulating less significant, transient data such as counts and state information that change many times per second. It is a desirable performance boost to hide these busy, and less significant data changes from the persistent database. The design of the od_attribute table supports this idea by having the column is_transient which is used as a boolean flag and set to 1 to hide the updates of selected rows from the persistent database.These procedures are used to help manage transient data. There are some subtle aspects to how the subscriptions work that make using these procedures desirable. For example, if you simply update the is_transient field for selected attributes, the persistent database does not save that you want a non-zero is_transient value. So when you startup again, the attributes are back to being completely persistent. Using the od_transient procedure to declare specified attributes as being transient takes care of making sure the persistent database saves that the specified attributes are transient.
The format of the attribute_name arguments is expected to be one of the following:
Case 1 identifies all existing attributes of a specified item. For this case, the od_is_transient call returns 1 if any of the existing attributes of the item are transient. Case 2 affects the single record for item_id='*' which is used as a default value for new instances, or as a working value for "Singleton" types. Case 3 affects the single record; a specific attribute of a specified item. For the od_transient call and case 3, if the record does not already exist, a table insertion is made with an empty value and the is_transient flag set. For this case and the od_not_transient call, no insertion is made if the row does not already exist since the default behavior will insert a new row as not being transient.
- Item_type(item_id.*)
- Item_type(*.attribute) or equivalently Item_type(attribute)
- Item_type(item_id.attribute)
The row_count value returned by the od_transient, od_not_transient, and od_transient_save calls show the number of table rows matching the input specifications and subject to the implied action of updating the is_transient value or being posted to the persistent database.
The suggested behavior for a configuration user interface follows. The list of known item_type values is consulted by the configuration GUI and the user is only allowed to configure instances, attributes, and associations of known types. There is also provision from the GUI to add or delete known types. The GUI is integrated with the DCC security features, and it requires a different privilege to add or delete types than to edit instances. The item_types that are in use have to be configured in order to setup variable traces to support the simplified access.
You cannot use upvar to work with the arrays using a different name since the name is a key to the table mapping.
The allowed size of child_id records is substantially smaller
than that allowed for attributes.
Column Name | Key | Type | Description |
item_type | PCK | varchar(32) | A system or user defined type such as EPC, Lot or MID. Should be a single alphanumeric token without imbedded whitespace or punctuation. |
item_id | PCK | varchar(32) | A user defined name for the instance of a type. May contain whitespace. Should not contain the colon, the period, or other punctuation. |
child_type | PCK | varchar(32) | Usually, a system or user defined type such as Lot or MID. Generally, the field can also be used as the name of the associated child_id value. Should be a single alphanumeric token without imbedded whitespace or punctuation. |
child_id | PCK | varchar(150) | Usually, an identifier for a child_type, but generally just an associated named value. The length of this field is limited because some persistent databases limit the total length of a composite key. |
The EPC runtime system assumes that there is a Type MID representing machines or state machines, and that instances of this type have the following attributes represented in this table:
Column Name | Key | Type | Description |
item_type | PCK | varchar(32) | A system or user defined type such as Lot or MID. Should be a single alphanumeric token without imbedded whitespace or punctuation. All types should be represented in the od_assoc table in order to access the table data as global Tcl arrays. |
item_id | PCK | varchar(32) | A user defined name for the instance of a type. May contain whitespace. Should not contain the colon, the period, or other punctuation. |
attribute | PCK | varchar(32) | A system defined or user defined name for an attribute such as state or recipe_id. |
value | varchar(2000) | The value of the named attribute for the instance of the type. | |
is_transient | int | A boolean flag to determine whether updates to the record should also be fed to the persistent database. Similar to the DCC dc_data discard_flag. If the value is 1, updates are not passed on to the persistent database. Inserts and deletes are always passed on to the persistent database so that records are present at startup. Initial values at startup are usually set by business rules. This field is desirable so the attribute system can be used for very busy data changes without worrying about the overhead. |
This document covers the Hume Integration Software developed Object Data Component which is available for the Tcl 8.3/Tk 8.3 environment on the Windows 2000/NT and UNIX/POSIX platforms.