English version Russian version

Работа с типами BOOLEAN и GUID в Firebird и Interbase

Суть проблемы:

  • Тип GUID на текущий момент не поддерживается ни одним сервером Firebird и Interbase , но нередко используется различными клиентами (к примеру, в ADO Entity Framework).
  • Тип Boolean поддерживается в Interbase начиная с 7-й версии и не поддерживается сервером Firebird. IBProvider умеет работать с этим типом, но не хватает поддержки со стороны остальных серверов.
В IBProvider поддержка типов Guid и Boolean была реализована на уровне драйвера, и теперь вы можете свободно использовать эти типы в своих приложениях независимо от версии сервера Firebird и Interbase.

Данные хранятся в типах, которые поддерживаются сервером. IBProvider просматривает домены данных и если обнаруживается домен, подходящий по маске, он выставляет колонке соответствующий тип Boolean или Guid.

Домены должны удовлетворять следующим условиям:
  • для типа BOOLEAN домен базируется на типе SMALLINT.
  • для типа GUID домен базируется на типе CHAR(16) с кодовой страницей OCTETS.

Свойства для включения эмуляции типов

Для того чтобы указать провайдеру какие данные следует интерпретировать как Boolean или Guid, в IBProvider добавлены два новых свойства инициализации: user_type_boolean, user_type_guid. В них определяется маска домена, который представляет эмулируемый тип. В маске поддерживаются символы «*» и «?». Маска чувствительна к регистру.

При несоблюдении этих условий, провайдер игнорирует имя домена и не пытается выполнять подмену типа.

Эмуляция работает для:
  • Колонок с простым типом;
  • Колонок с массивами;
  • OUT-параметров с простым типом;
  • OUT-параметров с массивами;
  • IN-параметров с массивами.

Ограничения эмуляции типов

Из-за ограничений ISC API (IB/FB), при использовании простых типов для входящих параметров команд, необходимо явно указывать тип параметра. Для колонок с массивами поддерживается автоматическое формирование описания параметра.

Эмуляция типов в метаданных

Эмуляция типов распространяется и на схемы метаданных. Провайдер обеспечивает согласованность типов, которые читаются при выполнении запросов и типов, которые отображаются в схемах COLUMNS, PROCEDURE_PARAMETERS, PROCEDURE_COLUMNS.

Рабочий пример

Для демонстрации работы нам понадобится: Для начала создадим тестовую таблицу и домены, в которых будут храниться данные эмулируемых типов.


CREATE DOMAIN D_BOOL_D1 AS SMALLINT;
CREATE DOMAIN D_GUID AS CHAR(16) CHARACTER SET OCTETS;

CREATE TABLE TYPE_EMULATOR (
	IDENTITY D_GUID,
      RESIDENT D_BOOL_D1 NOT NULL,
      FULLNAME VARCHAR(100));

Для того чтобы провайдер включил эмуляцию типов, необходимо в строке подключения задать маску, по которой будут отбираться домены:

user_type_boolean= D_BOOL_*;
user_type_guid= D_GUID;

Далее пример кода на Visual C#, демонстрирующего использование эмулятора типов:


[Test]
public void ComlexEmulatorTest()
{
    // retrive standard connection string parameters from config
    OleDbConnectionStringBuilder sb = ConnectionProvider.GetConnectionStringBuilderFromUDL();
    // add 2 masks for domains
    sb.Add("user_type_boolean", "D_BOOL*");
    sb.Add("user_type_guid", "D_GUID*");
    // disable resourse pooling because DROP operators are used
    sb.OleDbServices = OleDbServicesValues.EnableAll & ~OleDbServicesValues.ResourcePooling; 

    using (OleDbConnection cn = new OleDbConnection(sb.ToString()))
    {   
        cn.Open();

        // inserting...
        OleDbTransaction tran = cn.BeginTransaction(IsolationLevel.RepeatableRead);
        OleDbCommand cmd = new OleDbCommand(
		"insert into type_emulator (identity, resident, fullname) values (?,?,?) ", cn, tran);
        
        Guid guid = Guid.NewGuid();
        cmd.Parameters.Add("identity", OleDbType.Guid).Value = guid;  
        cmd.Parameters.Add("resident", OleDbType.Boolean).Value = true;
        cmd.Parameters.AddWithValue("fullname", "Resident of Russian Federation");
          
        Assert.AreEqual(cmd.ExecuteNonQuery(), 1);
        tran.Commit();

        // selecting and validating
        tran = cn.BeginTransaction(IsolationLevel.RepeatableRead);
        cmd = new OleDbCommand("select * from type_emulator", cn, tran);

        using (OleDbDataReader rdr = cmd.ExecuteReader())                
        {
            if (rdr.Read())
            {
                Console.WriteLine("Identity: {0} [type: {1}]", rdr["identity"], rdr["identity"].GetType().Name);
                Console.WriteLine("Resident: {0} [type: {1}]", rdr["resident"], rdr["resident"].GetType().Name);
                Console.WriteLine("Fullname: {0} [type: {1}]", rdr["fullname"], rdr["fullname"].GetType().Name);

                // check values
                Assert.AreEqual(guid, rdr["identity"]);
                Assert.AreEqual(rdr["resident"], true);    
            }
            else
                Assert.Fail("Row was not inserted");
        }

        tran.Commit();
    } // Dispose cn.close 
}

Если свойства user_type_boolean и user_type_guid установлены правильно и версия IBProvider Professional не ниже 3.0.0.7412, в консоли будет отображен следующий текст:


identity: 6ef41c55-03ff-4941-9382-290813ad46c2 [type: Guid]
Resident: True [type: Boolean]
Fullname: Resident of Russian Federation [type: String]

Обратите внимание на то, что значения и типы в ADO .Net определены правильно в соответствии с заданными масками для доменов. В случае если маска домена не задана или используется другой провайдер после выполнения данного примера на экране отобразится текст:


identity: System.Byte[] [type: Byte[]]
Resident: 1 [type: Int16]
Fullname: Resident of Russian Federation [type: String]

То есть вместо типов Guid и Boolean будут отображаться стандартные типы.

Исходные тексты примеров для ADO .Net можно скачать здесь: Firebird ADO .Net Samples
Автор:   

Забобрить эту страницу! Добавить на Memori.ru Mr Wong Добавить в закладки МоёМесто.ru Добавить на Rumarkz Добавить на Rucity Digg It Reddit Technorati Del.icio.us Google Bookmarks Slashdot StumbleUpon Yahoo MyWeb Все

Права на материал принадлежат: IBProvider. При перепечатке ссылка на сайт http://www.ibprovider.com обязательна. Версия для печати: Работа с типами BOOLEAN и GUID в Firebird и Interbase