Новый триал IBProvider v3.50.0.28072

На сайт IBProvider загружен новый триал OLE DB провайдера — v3.50.0.28072, в котором исправлена структурная ошибка внутреннего представления данных из за которой были специфические затруднения с модификацией базы данных.

Суть проблемы заключалась в том, что провайдер не умел корректно обрабатывать DEFAULT-значения (они обрабатывались как NULL-значения). Для этого нужно было вместо пары {value, IsNull} работать с парой {value, Status}.

В новой сборке это досадное ограничение устранено и теперь IBProvider умеет передавать состояние данных через все свои слои — от верхнего до нижнего.

В самом низу с DEFAULT-значениями умеет работать только Firebird 2.5+ (и то очень ограничено). В FB2.5 появилась поддержка запроса:

INSERT INTO ... DEFAULT VALUES

Вот этот запрос теперь и используется при добавлении новых записей в «обновляемых» множествах.

На примере работы с провайдером через связанных сервер MSSQL это выглядит так:

Есть таблица TEST_MODIFY_ROW_WD, в которой для всех колонок (кроме первичного ключа) заданы DEFAULT-значения:

CREATE TABLE TEST_MODIFY_ROW_WD (
    TEST_ID         T_TEST_ID NOT NULL /* T_TEST_ID = BIGINT */,
    COL_SMALLINT    T_SMALLINT DEFAULT 2 /* T_SMALLINT = SMALLINT */,
    COL_INTEGER     T_INTEGER DEFAULT 4 /* T_INTEGER = INTEGER */,
    COL_DOUBLE      T_DOUBLE DEFAULT 8.5 /* T_DOUBLE = DOUBLE PRECISION */,
    COL_FLOAT       T_FLOAT DEFAULT 4.5 /* T_FLOAT = FLOAT */,
    COL_N_18_0      NUMERIC(18,0) DEFAULT 12345678901234567,
    COL_BIGINT      T_BIGINT DEFAULT -12345678901234567 /* T_BIGINT = BIGINT */,
    COL_CHAR_10     T_CHAR_10 DEFAULT ' ABCD54321' /* T_CHAR_10 = CHAR(10) */,
    COL_CHAR_32     T_CHAR_32 DEFAULT ' 9876543210987654321' /* T_CHAR_32 = CHAR(32) */,
    COL_VARCHAR_10  T_VARCHAR_10 DEFAULT ' 10 ' /* T_VARCHAR_10 = VARCHAR(10) */,
    COL_VARCHAR_32  T_VARCHAR_32 DEFAULT ' COL_VARCHAR_32  ' /* T_VARCHAR_32 = VARCHAR(32) */,
    COL_NUM_2_1     NUMERIC(2,1) DEFAULT 2.1,
    COL_NUM_6_1     NUMERIC(6,1) DEFAULT 65432.1,
    COL_NUM_15_1    NUMERIC(15,1) DEFAULT 12345012345678.9,
    COL_TIMESTAMP   T_TIMESTAMP DEFAULT '2018-03-21 11:25:03.1234' /* T_TIMESTAMP = TIMESTAMP */,
    COL_TYPE_DATE   T_TYPE_DATE DEFAULT '2018-03-18' /* T_TYPE_DATE = DATE */,
    COL_TYPE_TIME   T_TYPE_TIME DEFAULT '21:35:43.4321' /* T_TYPE_TIME = TIME */,
    COL_BOOLEAN     T_BOOLEAN DEFAULT TRUE /* T_BOOLEAN = BOOLEAN */,
    COL_BYTES_BLOB  T_BYTES_128 DEFAULT '1234' /* T_BYTES_128 = BLOB SUB_TYPE 0 SEGMENT SIZE 128 */,
    COL_TEXT_BLOB   T_TEXT_128 DEFAULT ' qwerty ' /* T_TEXT_128 = BLOB SUB_TYPE 1 SEGMENT SIZE 128 */
);

Если добавлять записи через предыдущие выпуски провайдера, то в колонки COL_xxx будет установлен NULL:

IBProvider v3.49.1.

Новый провайдер отработает этот запрос корректно:

IBProvider v3.50.

На этом вся поддержка и заканчивается. К сожалению, в Firebird этот вопрос не дожат и в нем нет поддержки запроса «UPDATE … SET FIELD=DEFAULT» и параметров с DEFAULT-состояниями.

Вот так всегда — только ты начнешь делать по-настоящему интересные вещи …

Другие изменения в v3.50

1. При работе с обновляемыми множествами, если вы попытаетесь прочитать значения колонок, значения которых не были указаны или были установлены как DEFAULT, провайдер вернет ошибку и статусы DBSTATUS_E_UNAVAILABLE. Здесь еще нужно дорабатывать провайдер — задействовать «INSERT … RETURNING VALUES», «UPDATE … RETURNING VALUES». Задел для этого уже был сделан, дело за «малым».

2. Что-то мне захотелось закрутить гайки в отношении свойства инициализации «named_param_prefix«. Если раньше в него можно было устанавливать что угодно, то теперь разрешены только три значения — пустая строка, стандартный префикс «:» и префикс в стиле MSSQL «@». Никаких пробелов и прочих извращений. Только эти три значения.

В целом

Шкала удовлетворенности состоянием IBProvider вернулась к 90%. Я эту штуку с DEFAULT вынашивал около семи лет. Последний раз пытался её осилить в октябре 2014 и не смог — слишком большой объем изменений и отсутствовало четкое осознание проблемы. Поэтому я тогда переключился на более актуальные вещи 🙂

2 комментария

hvlad  on Март 24th, 2018

> Суть проблемы заключалась в том, что провайдер не умел корректно обрабатывать DEFAULT-значения (они обрабатывались как NULL-значения). Для этого нужно было вместо пары {value, IsNull} работать с парой {value, Status}.

Насколько я помню, ADO (и, наверное OLEDB) прекрасно понимало значение Empty (Unassigned в Delphi) как маркер значения по-умолчанию.

> К сожалению, в Firebird этот вопрос не дожат и в нем нет поддержки запроса «UPDATE … SET FIELD=DEFAULT»

Есть в FB4.

> и параметров с DEFAULT-состояниями.

Это не делали. Уже не помню — почему 🙁

Dmitry Kovalenko  on Март 24th, 2018

Привет!

>Насколько я помню, ADO (и, наверное OLEDB) прекрасно понимало значение Empty (Unassigned в Delphi) как маркер значения по-умолчанию.

ADO и OLEDB понимали. Не понимал я — зачем оно надо. А когда понял … ну вообщем было модифицировано больше 1000 файлов.

>Есть в FB4.

Ни разу пока не собирал, но уже думал пару раз про него. Теперь буду думать чаще 🙂

>> и параметров с DEFAULT-состояниями.
> Это не делали. Уже не помню — почему 🙁

Ну, я до вашего уровня пропихнул. И пока там тупо конвертирую DEFAULT в NULL.

Вообще это нужная вещь.

С моей колокольни думается что SQLIND очень даже подходит для этого дела.

-1 это NULL
0 это значение
1 это DEFAULT

Как-то так.

А сервер, если не понимает куда этот DEFAULT приткнуть — пусть выкидывает ошибку.

Leave a Comment