Thursday, 9 May 2013

How to update a document in a SilentOne document repository


Document repositories!  Yay.  You put your document there so it is safe yet accessible.  You index it by the important bits of information.  Sometimes that information changes and now your document repository is out of date.  Stink for you! Luckily your document repository has an API where you can change the field values for given documents right?  Cool!  Do you have any documentation for that API?  Well, not if you're a SilentOne customer. 

The basic steps for locating a document for a given field value, updating that field to a new value and saving the change are pretty standard, but using the supplied API is not as straight forward as you would hope.

You've got to roll like this:
  1. Connect to the API
  2. Query the repository for documents with the field value you're looking for
  3. Iterate over the results
    1. Lock the document for editing
    2. Change the field to have its new value
    3. Checkin and unlock the document

Connect to the API 


_axisLibrary = new AxisLibraryService();

_axisLibrary.setUri(Library);
_axisLibrary.PreAuthenticate = true;
// this takes the user that can be authenticated in the silentone library
_axisLibrary.Credentials = new NetworkCredential(Username, Password, Domain);




where the values passed in are something like this:

<add key="silentOneUsername" value="svc-silentOne" />

<add key="silentOnePassword" value="thesecretpassword" />

<add key="silentOneDomain" value="OurDomain" />

<add key="silentOneLibrary" value="http://silentonedev/axis/services/PhoenixService" />


Query the repository for documents with the field value you're looking for


The method you're looking for is called 'executeQuery'.  This takes a path to search from (so you can just include a subset of the repository in your search) and a Query object.  The queryString property of the Query object is a bit of a mystery, if yours differs to the below you will need to ask SilentOne what the value should be.

ResultList resultList = _axisLibrary.executeQuery(LocationToSearch, new Query { queryString = string.Format(DocumentSearchQuery, oldValue) });



config values associated with this look something like:

<add key="silentOneDocumentSearchQuery" value="@NameOfFieldToUpdate = &quot;{0}&quot;" />

<add key="silentOneLocationToSearch" value="/Store/Records" />



Where it says 'NameOfFieldToUpdate' put the name of your field.  For example your query value might be:
@PatientNumber = "ABC1234"
This will return all documents where the PatientNumber field has a value of ABC1234.

Iterate over the results


The executeQuery method returns a ResultList object, which exposes an items collection, so you can just use a foreach.

foreach (var result in resultList.items)


Lock the document for editing


First, get the document.  I don't know of an easy way to do this from the ResultListItem that we already have.  So instead, we have to go back and request the object again based on the uri that the ResultListItem has.  Then call the lockObject method.  I don't know why the lockObject method returns a value.

Document document = (Document) _axisLibrary.getObject(result.uri);

var lockInfo = _axisLibrary.lockObject(document.uri, "Locking for update", 1);

Change the field to have its new value


On the document locate the field with a name that matches the field we want to update, then update the current value to the new value.

document.attributes.First(a => a.name == "NameOfFieldToUpdate").value = newValue;

Checkin and unlock the document


Call the checkin and then unlockObject methods.  On the checkin ensure that the 3rd parameter is null and the 4th parameter is 0.  I believe the 3rd is only not null when creating a new document, but I'm not sure - the combination below that works was found by many hours of painful trial and error.  The unlockObject method may or may not be required (I dunno, I'm not your dad, you figure it out).

document.contentInfo = _axisLibrary.checkin(document.uri, document, null, 0, string.Format("Bulk update process, changing value from {0} to {1}.", oldValue, newValue));

_axisLibrary.unlockObject(document.uri);



Job done!

Some things to note:
  • If you need to do a bulk update you will find that after a certain amount of document updates the API will crash.  It is always the same number, I think it was around 6000.  We did ours in batches of 3000.
  • You need a license file to access the API - get this from SilentOne


No comments:

Post a Comment