(picture)

August 10, 2001

XML and binary. Continuation from

XML and binary. Continuation from a groovelog post:

First off, Groove storage and dynamics are separate. Storage deals with local databases (of XML and binary documents). Dynamics deals with distributed transactions on the system. The two are brought together with engines, which present a data-oriented or transaction-oriented API and tell dynamics how to route the transactions. The essential engine is RecordSetEngine, which looks (sort of) like a hierarchical recordset, with XML storage.

So, if I open the telespace database [PropertyList.OpenProperty(PROPERTY_TELESPACE_DATABASE)] I can put documents into it natively. With binary data that's very convenient. Alternatively (and more usually) just use the recordsetengine to create records with various typed data, and have them grooved (verb, huh?) through the space. Or, for efficiency, tell the engine to use dynamics at a more granular level [eg. RecordEngine.GeerateSetField(pDelta,name,value) where the pDelta is from the dynamics manager]. Three different things: storage, engines, and dynamics.

So, how do XML and binary data work together? Can you put binary data right into an XML document? .... yes, but not efficiently. The dynamics of binary data might be different. Certainly encoding the binary document in an XML-friendly text format is a big waste.

RecordSetEngine (and PropertyListEngine too, which is the other main groovey datastore) has a neat implementation of XLink which solves this dilemma. Basically, if you create a binary document in the telespace database, it'll stay on your machine (of course, because you use StorageMgr to create the document). But, if you create a record in the RecordSetEngine and a field's datatype is XML, the engine will look for Xlinks in that XML, and understand from the xlink whether it needs to move the binary document around.

Some code snippets as examples:

pDocument = TelespaceDatabase.CreateBinaryDocumentFromStream( pStream, sDocID )
- fine. Then:

pURI = pDocument.OpenURI();
pBinaryDocURL = g_StorageURISyntax.MakeRelative(pURI);
so we know how to address the binary document.

pEl = CreateNewElement( "urn:yourco.com:yourschema" );
pEl.SetLinkAttributes( pBinaryDocURL, sDocID, "",
GrooveXLinkShowOption_Replace,
GrooveXLinkActuateType_User,
GrooveXLinkSerializeOption_ByValue, false, false,
GrooveXLinkCompressOption_OnWire, "",
GrooveXLinkDeserializeOption_Replace);
pRecord.SetFieldAsElement( "fieldname", pEl );

... and the recordsetengine grooves the binary document along with the record. Plenty of control via the different xlink options. Getting at the binary document again is really easy, too:

pEl = RecordSetEngine.OpenFieldAsElement( "fieldname" );
pDoc = pEl.OpenLinkedBinaryDocument();
pDoc.OpenByteInputStream();
or whatever you need to do with the binary document.