Wednesday, November 24, 2010

Using Oracle RAW(16) field with Microsoft .NET GUID field

The order of RAW(16) field is different when you read it as a byte array. When you compare the byte arrays of .NET Guid and Oracle RAW field guid, some elements have a different order.

So, I have created a class to convert these values into each other, and make it possible to use raw field of oracle in .NET:


public class IDField
{
private Guid OracleGUID { get; set; }
public Guid Value { get; private set; }

private IDField(byte[] gByte, bool isMicrosoftGuid)
{
if (isMicrosoftGuid)
{
Value
= new Guid(gByte);
SwapArrayElements(gByte);
OracleGUID = new Guid(gByte);
}
else
{
OracleGUID
= new Guid(gByte);
SwapArrayElements(gByte);
Value = new Guid(gByte);
}
}

/Convertion from one to other, doesn't matter which one it is at the moment the function is called
//the elements are not touching each other, so this method can be used both ways
private void SwapArrayElements(byte[] gByte)
{
//Microsoft { 3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15 };
//Oracle { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

//Oracle { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
gByte.Swap(0, 3);
//Oracle { 3, 1, 2, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
gByte.Swap(1, 2);
//Oracle { 3, 2, 1, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
gByte.Swap(4, 5);
//Oracle { 3, 2, 1, 0, 5, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
gByte.Swap(6, 7);
//Oracle { 3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15 };
}

public byte[] ToOracleByteArray()
{
return this.OracleGUID.ToByteArray();
}

public string ToLDAPString()
{
return this.Value.ToString().Replace("-", "");
}

public override string ToString()
{
return this.ToLDAPString();
}

public static IDField CreateFromOracleByteArray(byte[] gByte)
{
IDField id
= new IDField(gByte, false);
return
id;
}

public static IDField CreateFromMicrosoftByteArray(byte[] gByte)
{
IDField id
= new IDField(gByte, true);
return
id;
}

public static IDField CreateFromMicrosoftGuid(Guid g)
{
IDField id
= new IDField(g.ToByteArray(), true);
return
id;
}

public static IDField CreateFromLDAPGuidString(string id)
{
Guid g
= ConvertToGuid(id);
if
(g.Equals(Guid.Empty))
return null;
else
return
IDField.CreateFromMicrosoftGuid(g);
}

private static Guid ConvertToGuid(string s)
{
if (!string.IsNullOrEmpty(s))
{
try
{
//covert to guid
return new Guid(s);
}
catch
{
//not guid
}
}
return Guid.Empty;
}

}


and the extension method:

public static class Extensions
{
public static void Swap(this byte[] array, int i1, int i2)
{
byte temp = array[i1];
array[i1] = array[i2];
array[i2] = temp;
}
}




As you can see, I am also storing this field in LDAP as string.