Relativity Pre Save Event Handler – Custom Labels

After a long pause, I finally have time to share some more stuff with you guys. This time, the topic is a different one as the other articles here. I recently worked a lot in the field of eDiscovery, particularly with a software called Relativity. The software suite is used widely for document review purposes and helps a lot in structuring and conducting reviews of unstructured data.

relativity_logo

In a recent project, I had the chance to really deep-dive into the implementation and administration of this solution. This article is about so called event handlers. If you didn’t work with Relativity yet, this might be a bit a crash start, but in general a event handler is a piece of custom code, that automatically performs actions triggered by events a Relativity user causes (e.g. an event handler might be fired, if a user clicks on the “Save” button in Relativity).

The piece of (C#) code posted here could be of interest for you, if you use pre-save event handlers to validate user input (such as field values etc.) and want to create meaningful custom error messages.
Now, when you set up your Relativity instance, you define so called “fields”, which are structures that hold any kind of data. You are free to name these fields as you like and many name them in rather technical looking ways, e.g. “revDate” as the field name for a field holding the date something was reviewed etc.
At a later stage, when you put these fields on layouts, so that users can enter data in them, you might use so called “labels” to give the field a more user friendly name, such as “Review Date”. The problem now is, that if you have an event handler that warns if the field “Review Date” is empty, the error message displayed might look like “Field revDate is empty”.
The code below allows you to use the label value in error messages, to make it easier for the user to see where the error is coming from. It’s developed for version 7.5 of Relativity, I don’t know if it works for newer ones.

First we need a read-only database account that can access the workspace tables and define the connection parameters to the database:


// Database connection credentials
public static string DbUser = "rel_evthandler";
public static string DbPassword = "rel_evthandler";
public static string DbServer = "localhost";

// Set current layout properties
documentArtifactId = Fields["Artifact ID"].Value.Value.ToString();
layoutArtifactId = this.ActiveLayout.ArtifactID;
layoutName = this.ActiveLayout.Name.ToString();

// SQL connection string
sqlConn = new SqlConnection(
    "user id=" + DbUser + ";" +
    "password=" + DbPassword + ";" +
    "server=" + DbServer + ";" +
    "database=EDDS" + this.Application.ArtifactID + ";" +
    "connection timeout=30"
);

Then we create a helper function that returns the label value for the specified ArtifactId of the field:


// Function: getFieldCustomLabel
//
// Resolves a fieldname to its corresponding custom label value
//
private static string getFieldCustomLabel(int fieldArtifactId)
{
    // SQL query to resolve custom label
    SqlCommand fieldCustomLabelCommand = new SqlCommand(
        "SELECT NameValue " +
        " FROM [EDDSDBO].[LayoutField] " +
        " WHERE [EDDSDBO].LayoutField.FieldArtifactID = @fieldArtifactId " +
        " AND [EDDSDBO].LayoutField.LayoutArtifactID = @layoutArtifactId",
        sqlConn
    );
    fieldCustomLabelCommand.Parameters.Add("@fieldArtifactId", SqlDbType.Int);
    fieldCustomLabelCommand.Parameters.Add("@layoutArtifactId", SqlDbType.Int);
    fieldCustomLabelCommand.Parameters["@fieldArtifactId"].Value = fieldArtifactId;
    fieldCustomLabelCommand.Parameters["@layoutArtifactId"].Value = layoutArtifactId;

    try
    {
        sqlConn.Open();
        string fieldCustomLabel = (string)fieldCustomLabelCommand.ExecuteScalar();
        sqlConn.Close();
        return fieldCustomLabel;
    }

    catch (Exception e)
    {
        throw e;
    }
}

Now you can use the function by passing the ArtifactId of the desired field to it:


string fieldCustomLabel = getFieldCustomLabel((int)Fields[field].ArtifactID);

Here you can find some more infos about Relativity event handlers:
https://www.kcura.com/relativity/Portals/0/Documents/7.5%20Platform%20Site/index.htm#Event Handlers/Event handlers overview.htm