Not an Issue
Details
Details
Assignee
Unassigned
UnassignedReporter
Eugenyi (ssdi) Vinogradnyi
Eugenyi (ssdi) VinogradnyiComponents
Affects versions
Priority
Who's Looking?
Open Who's Looking?
Created April 2, 2011 at 6:53 AM
Updated April 19, 2011 at 4:35 AM
Resolved April 19, 2011 at 4:35 AM
Firebird 2.5 store Uuid into left to right convetion as "CHAR(16) CHARACTER SET OCTETS" (see http://www.firebirdfaq.org/faq98/). But NHibernate into GuidType constructs System.Guid with System.Guid(byte[]) constructor, but System.GuidType shoul be constructed with Guid(int a, short b, short c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k) for correct representation. Also see Firebird 2.5 embeded fuctions UUID_TO_CHAR() and CHAR_TO_UUID().
System.Guid reflection:
{{{
// Creates a new guid from an array of bytes.
//
public Guid(byte[] b)
{
if (b==null)
throw new ArgumentNullException("b");
if (b.Length != 16)
throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Arg_GuidArrayCtor"), "16"));
_a = ((int)b[3] << 24) | ((int)b[2] << 16) | ((int)b[1] << 8) | b[0];
_b = (short)(((int)b[5] << 8) | b[4]);
_c = (short)(((int)b[7] << 8) | b[6]);
_d = b[8];
_e = b[9];
_f = b[10];
_g = b[11];
_h = b[12];
_i = b[13];
_j = b[14];
_k = b[15];
}
// Creates a new GUID initialized to the value represented by the
// arguments. The bytes are specified like this to avoid endianness issues.
//
public Guid(int a, short b, short c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k)
{
_a = a;
_b = b;
_c = c;
_d = d;
_e = e;
_f = f;
_g = g;
_h = h;
_i = i;
_j = j;
_k = k;
}
}}}
Database SQL script example:
{{{
CREATE DOMAIN FGUID_D_KEY AS CHAR(16) CHARACTER SET OCTETS NOT NULL;
CREATE DOMAIN FGUID_D AS CHAR(16) CHARACTER SET OCTETS;
CREATE TABLE SYSTEM$DATABASE (
SYSTEM_GUID FGUID_D_KEY,
SUBSYSTEM_GUID FGUID_D_KEY
);
SET TERM ^ ;
CREATE OR ALTER TRIGGER SYSTEM$DATABASE_BI0 FOR SYSTEM$DATABASE
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
/* Gen SYSTEM_GUID if not defined */
IF (NEW.SYSTEM_GUID IS NULL) THEN
BEGIN
NEW.SYSTEM_GUID = GEN_UUID();
END
/* Gen SUBSYSTEM_GUID if not defined */
IF (NEW.SUBSYSTEM_GUID IS NULL) THEN
BEGIN
NEW.SUBSYSTEM_GUID = GEN_UUID();
END
END
^
SET TERM ; ^
INSERT INTO SYSTEM$DATABASE (SYSTEM_GUID, SUBSYSTEM_GUID) VALUES (NULL, NULL);
}}}
Symbolic example of NUnit test:
{{{
...
private class Guids
{
public Guid MsGuid { get; set; }
public string FbStrGuid { get; set; }
}
[Test]
public void TestFunc()
{
tempDbWrapper.WrapSession(
session =>
{
var guids =
session.CreateSQLQuery(
"SELECT SYSTEM_GUID, UUID_TO_CHAR(SYSTEM_GUID) AS SYSTEM_GUID2 FROM SYSTEM$DATABASE")
.SetResultTransformer(
new FuzzyAliasToBeanResultTransformer<Guids>()
.AddBeanProp("SYSTEM_GUID", "MsGuid")
.AddBeanProp("SYSTEM_GUID2", "FbStrGuid"))
.UniqueResult<Guids>();
var fbGuid = new Guid(guids.FbStrGuid);
Console.WriteLine("MSGuid = {0}", guids.MsGuid);
Console.WriteLine("DBGuid = {0}", fbGuid);
Assert.AreEqual(guids.MsGuid, fbGuid);
});
}
}}}
Execution Result:
{{{
TestFunc : Failed
NHibernate: SELECT SYSTEM_GUID, UUID_TO_CHAR(SYSTEM_GUID) AS SYSTEM_GUID2 FROM SYSTEM$DATABASE
MSGuid = cbe4709d-5cea-4078-b1f5-2adabdcdb1f7
DBGuid = 9d70e4cb-ea5c-7840-b1f5-2adabdcdb1f7
Expected: cbe4709d-5cea-4078-b1f5-2adabdcdb1f7
But was: 9d70e4cb-ea5c-7840-b1f5-2adabdcdb1f7
}}}
Best regards,
Eugenyi Vinogradnyi (aka ssdi).