Совместная работа ADO.NET, ADODB и OLEDB.

Привет всем.

На сайт IBProvider-а выложен новый пример на C#, с демонстрацией взаимодействия трех технологий: ADO.NET, ADODB, OLEDB. Достаточно короткий и простой:

Проект этого примера можно найти в дистрибутиве ADO.NET провайдера.

using(var oledbCn=new OleDbConnection(c_cn_str))
{
 oledbCn.Open(); /*1*/

 dynamic adodbCn=com_lib.object_utils.CreateInstance
                  ("ADODB.Connection",
                   com_lib.ClsCtxCode.CLSCTX_INPROC_SERVER).GetObject();

 adodb_lib.AdoDbConstructor.attach_adodb_cn_to_oledb_session
  (adodbCn,
   oledbCn.GetNativeSession()); /*2*/

 adodbCn.BeginTrans(); /*3*/

 dynamic genMng=com_lib.object_utils.CreateInstance
                  ("LCPI.IBP.Samples.IBGenManager.1",
                   com_lib.ClsCtxCode.CLSCTX_INPROC_SERVER).GetObject();

 genMng.Connection=adodbCn; /*4*/

 Console.WriteLine("[GenMng] Generate ID: {0}",
                   genMng.GenID("CUST_NO_GEN")); /*5*/
  
 adodbCn.CommitTrans(); /*6*/
}//using oledbCn
  1. ADO.NET провайдер создает подключение к базе данных
  2. Подключаем ADODB к ADO.NET
  3. ADODB инициирует транзакцию в этом подключении
  4. Создаем компонент IBGenManager и подключаем его к ADODB
  5. IBGenManager запрашивает и возвращает новый идентификатор
  6. ADODB завершает транзакцию

IBGenManager — это простенький ActiveX компонент для работы с генераторами базы данных. Он написан на C++ и работает с OLEDB провайдером через библиотеку на C++. От ADODB-подключения ему нужен только указатель на низкоуровневый OLEDB-объект (сессию).

Исходный код и готовые модули этой компоненты есть в дистрибутивах IBProvider-a — см. каталог «Program Files\LCPI\IBProvider.3\Samples\oledb\sample_com_object».

Собственно говоря, подобный компонент можно написать на чем угодно — хоть на Delphi, хоть на Visual Basic. Или на C#.

У меня была еще мысль создавать и выполнять IBGenManager внутри VB-скрипта (я даже готовый компонент на nuget.org нашел — ActiveScriptEngine), но решил что это будет уже перебор. Кстати, IBGenManager можно было написать на VBScript и вызывать его из C#.

В целом, конечно, это повторение пройденного — подобные вещи (за исключением ADO.NET) были доступны (и активно эксплуатировались) еще в 2001 году. Во времена Firebird 0.9.4, если мне не изменяет память.

Сейчас же все это (включая ADO.NET провайдер) всего лишь (с особым цинизмом) доведенные до ума идеи тех лет — «написанное однажды будет работать везде и всегда». На Windows, разумеется 🙂

Мост между .NET и COM миром.

Привет всем.

В ADO.NET провайдер (сборка 2465) добавлена пара методов, ради которых его проект и затевался:

  • OleDbConnection.GetNativeSession
  • OleDbConnection.AttachToNativeSession

Первый метод (GetNativeSession) возвращает указатель на COM-объект OLEDB-сессии подключения. Этот объект, к примеру, можно использовать для создания инициализированного ADODB подключения (см. интерфейсы ADOConnectionConstruction15, ADOConnectionConstruction).

Второй метод (AttachToNativeSession) подключает OleDbConnection к COM-объекту OLEDB-сессии. Это если у вас есть указатель на OLEDB-сессию, то можно подключить к нему ADO.NET провайдер и работать с этой сессией из .NET кода. Ранее обозначенные Construction-интерфейсы ADODB позволяют получать указатель на OLEDB-сессию ADODB-подключения.

OLEDB-сессия — это COM-объект для работы с транзакцией и создания команд с запросами.

Одним из сценариев, где все это может пригодится, является использование VBSсript из .NET приложений.

Вот, собственно говоря, и все. Не прошло и 10 лет… Хотя нет, прошло.

Работа с Firebird через ADO.NET провайдер.

Всем привет.

Вспоминая фразу агента Смита — «уставать я начал сильно, на трех работах кручусь», решил довести .NET провайдер до ума релиза.

Одним из самых эффективных способов оценить общее состояние продукта — это накатать небольшое руководство по эксплуатации.

Хотя я и боюсь не люблю это делать. Это же садомазохизм чистой воды.

Надо заметить, что я отделался малой кровью. Всего пара изменений в .NET провайдере и ни одного в IBProvider-е. Негативных эмоций практически не возникло …

Даже один раз подумал — «ну надо же!».


PS. Баг с VARCHAR массивами уже просто задолбал. Полтора часа угробил, пока понял и вспомнил.

Создание базы данных через ADO.NET провайдер.

Всем привет.

Добавил новый пример с демонстрацией «правильного» способа создания базы данных через .NET провайдер.

Первые 15 минут радовался — вот какой я молодец. А потом задумался. Вообще, с технологической точки зрения, «круто» было бы выполнять подобный CREATE DATABASE через команду. И этот «запрос» инициализировал бы родительский источник данных.

До кучи можно было бы еще и CONNECT аналогичным образом оформить.

OLEDB провайдер, то есть IBProvider, такое извращение скорее всего выдержит. А вот .NET провайдер вряд ли….

Эксперименты с подключением к FB

С пятницей.

Сто лет назад, в 2006, я озвучивал вслух мысль о том что «было бы неплохо иметь возможность получать информацию о сервере базы данных до подключения к самой базе данных». Сейчас, в рамках прямого подключения к FB через TCP/IP, в принципе можно сказать к какой версии FB мы подключаемся — на основе версии протокола, которая согласуется с сервером до подключения к базе данных. В ISC API, для аналогичного трюка, нужно разделить isc_attach_database на две функции — connect_to_server и attach_database. Первая подключается к серверу, вторая к базе данных. После подключения к серверу нужно разрешить выполнять isc_database_info для получения версии протокола.

А вообще хотелось бы, после подключения к серверу, получать данные для isc_info_firebird_version (id: 103).

В рамках этих мыслей провел два эксперимента с FB 2.5.x.
(далее…)

Формат строки подключения к FB через TCP/IP.

Затеял написать парсер строки с расположением базы данных при подключении к серверу через TCP/IP (INET).

Полез в исходники сервера (FB 2.5.x):

bool ISC_analyze_tcp(tstring& file_name, tstring& node_name)
{
/**************************************
 *
 *	I S C _ a n a l y z e _ t c p		( G E N E R I C )
 *
 **************************************
 *
 * Functional description
 *	Analyze a filename for a TCP node name on the front.  If
 *	one is found, extract the node name, compute the residual
 *	file name, and return true.  Otherwise return false.
 *
 **************************************/

	// Avoid trivial case

	if (!file_name.hasData())
		return false;

/* Scan file name looking for separator character */

	node_name.erase();
	const size p = file_name.find(INET_FLAG);
	if (p == npos || p == 0 || p == file_name.length() - 1)
		return false;

	node_name = file_name.substr(0, p);

#ifdef WIN_NT
/* For Windows NT, insure that a single character node name does
   not conflict with an existing drive letter. */

	if (p == 1)
	{
		const ULONG dtype = GetDriveType((node_name + ":\\").c_str());
		// Is it removable, fixed, cdrom or ramdisk?
		if (dtype > DRIVE_NO_ROOT_DIR && (dtype != DRIVE_REMOTE || Config::getRemoteFileOpenAbility()))
		{
			// CVC: If we didn't match, clean our garbage or we produce side effects
			// in the caller.
			node_name.erase();
			return false;
		}
	}
#endif

	file_name.erase(0, p + 1);
	return true;
}

Из штатного алгоритма видим, что (в случае Windows) проблема только с однобуквенным именем хоста — возможен конфликт с именем локального диска. Если честно, мне раньше и в голову не приходила мысль давать компьютеру имя из одной буквы. Наверное, потому что я еще ни разу не писал подобный парсер.

Нашел вот такой документ — «Connection to the sample database». Из которого узнал, что в Linux локальный путь к базе данных может начинаться с символа ‘/’ — «servername:/filesystem-path/database-file». То есть, формально, строка «с:/windows/system32/cmd.exe» может быть интерпретирована как путь к локальному файлу в Windows, так и к сетевому ресурсу на Linux (хост «C», ресурс «/windows/system32/cmd.exe»).

Вот сижу теперь и думаю — наверное не зря все таки придумали всякие префиксы «http://», «ftp://».

Был бы формат «inet://host:local_path», и не было бы никакой неоднозначности.

Уверен, что я не первый кто про это подумал 🙂

Тестовая сборка IBProvider’a [17404].

Привет всем.

Доступен для скачивания новый триал IBProvider’a — 3.22.0.17404.

— Восстановлена возможность подключения к IB4, IB5. В последнем релизе я слишком сильно закрутил гайки. Почему-то вспомнился второй сервис пак для XP, который (в чистом виде) не работал на Intel Prescott.

— Исправлена очередная группа древних замысловатых багов. Выявлены новой тестовой системой, тестирующей прямое подключение к Firebird через TCP/IP. Эти тесты не то чтобы парализовали движение вперед, но как-то очень сильно его затормозили… Пока все топчусь на этапе инициализации подключения. Черт, третий месяц уже. Правда тестов уже не 3, а 83.

— Добавлено новое информационное свойство «IB Database ODS Version», которое публикует версию ODS в виде строки «major_num.minor_num». Свойства «IB ODS Version» и «IB ODS Minor Version» помечены как устаревшие.

Дедушка Мороз… а прочем ладно.

Хотел попросить тебя задарить мне в этом году Xeon. 10 ядерный.

Я хорошо себя вел в прошлом году, честное пионерское. Старался, по-крайней мере.

Но почитав fb-devel, решил — ладно, я подожду.


Facepalm
Компиляция FB3 на нетбуке.

Вести с полей.

Привет всем.

Сегодня закончил(?) работу над очередным выпуском IBProvider-а и .Net провайдера. Это будет продолжение немного затянувшегося исправления ошибок и переписывания старого плюсового кода с реализацией корявых конструкций на самом нижнем, инфраструктурном уровне, созданных в период бурной молодости 🙂 Такого осталось уже совсем немного.

Основное изменение в .Net провайдере — запрет неявного коммита «вложенных» транзакций. Добил затеянное два с половиной года назад. Вернуть старое поведение можно через новое (специализированное) свойство строки подключения «NetProv: NestedTransRules». Допустимые значения перечислены в OleDbPropertiesVaules.NetProvider.NestedTransRules (обожаю эти километровые имена).

Ну и под занавес, я освоил создание NuGet-пакетов (Задача элементарная, по сравнению с нормальным инсталлятором. Но сутки я на неё все равно угробил.). Так что наш Ado.Net провайдер теперь можно загружать и с NuGet.org. В пакет включены релизные сборки провайдера (под все версии FW) и PDB файлы. Пользуясь случаем передаю привет Ксении Кузнецовой, которая год назад предложила эту затею.

Вести с полей.

Всем привет.

Соорудил новый пример по работе с массивами через .NET провайдер.

С горечью могу констатировать факт — всю жизнь стремился создать профессиональную библиотеку для высокоуровневой работы с FB/IB на C++, а создал её на C#.