2010-07-19

EOGlobalIDs And Primary Keys

What is a primary key?
Every document stored within OpenGroupware has a numeric id that is unique. In fact, almost every entry concerning anything in OpenGroupware has one of these ids. This id namespace is flat; that is: ids do not overlap between document types; if there is a person with an id of 99450 then there is no enterprise, file, appointment, or anything else with the id of 99450. When anything is created it is assigned one of these unique numbers, called the primary key (often abbreviated pkey or pk. And that is the id of that document for its entire lifetime.

One note of clarification: by "document" we don't mean "file". An enterprise, person, job, project, file, appointment, or resource are all documents. You could call them objects too, but that gets even more confusing. :)  Sometimes, especially in OpenGroupware Coils, they are referred to as entities;  all these are names of the same things.

What is an EOGlobalID / EOKeyGlobalID?
Serialized an EOKeyGlobalID looks something like
<0x0x82cb23c[EOKeyGlobalID]: Date 28260>
Yea, that was helpful wasn't it? But look at it... there is the string "Date" and a number of "28260". If you guessed that this refers to the date [appointment] document with a pkey [primary key] of 28260 then you are correct. Internally EOKeyGlogalIDs (often abbreviated as gid / gids) are what OpenGroupware uses, on the database level, in order to retrieve and store data. OGo Legacy / SOPE uses a database abstraction layer called GDL, apparently very much like the GDL from GNU-Step. You can think of the EOKeyGlobalID as a "handle" for the data related to a given document.

The EOKeyGlobalID object has the following accessors:
- (NSString *)entityName;
- (unsigned int)keyCount;
- (id *)keyValues;
- (NSArray *)keyValuesArray;

The entityName accessor will provide the type of document that the key refers like. The keyValuesArray provides access to the payload which is the pkey [primary key] of the object. Since the value of keyValuesArray is an NSArray and you almost certainly want just the single value which it contains you'd use code like:
[[key keyValuesArray] objectAtIndex: 0]
which in the above example would provide you with the value "28260" (as an NSNumber object).  Of course it is possible to have a composite primary key, which explains why keyValuesArray is an array, but this doesn't happen in OpenGroupware.

How to turn a pkey into an EOKeyGlobalId?
It is a very frequent case where you have a pkey or an NSArray of pkeys for which you need to marshal the corrsponding document objects. Marshalling an object requires having the EOKeyGlobalId (handle). Fortunately the OpenGroupware framework provides a very simple means to generate an EOKeyGlobalId from a pkey; this is via the typeManager object.
The first requirement for getting handles from typeManager is that your pkey or array of pkeys must be NSNumber objects. You cannot use NSString objects. If what you have are strings then use the NSString class's intValue method to produce NSNumber objects:
[NSNumber numberWithInt:[_arg intValue]]
where _arg is your NSString object. Of course the contents of _arg have to actually be numeric. Then you can invoke the typeManager object like:
gid = [[[self commandContext] typeManager] globalIDForPrimaryKey:_arg]
where _arg is the NSNumber object containing your pkey and you get an instance of the EOKeyGlobalId required to retrieve the specified document from the database.

No comments:

Post a Comment