Чтение онлайн

ЖАНРЫ

Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil

Востриков С М

Шрифт:

HRESULT Convert([in]BSTR GenName,

[in]LONG Count,

[out,retval]LONG* pResult);

};//interface IDBGenID

Реализация методов установки сессии:

//m_spADODBConnection - член класса,

// содержащий указатель на ADODB-подключение

//m_spSession - член класса,

// содержащий указатель на используемую OLEDB-сессию

//m_Cmd - команда (t_db_command) получения значения генератора

//IDBSessionObject interface ------------------------------

HRESULT _stdcall TDBGenID::SetDBSession(lUnknown* pSession)

{

::SetErrorlnfo(0,NULL);

HRESULT hr=S_OK;

_OLE_TRY_

{

//освобождаем ADODB connection

m_spADODBConnection.Release;

m_spSession=pSession;

//инициализируем

объекты взаимодействия с базой данных

m_Cmd destroy;

}

_OLE_DIS P_CATCHES_

return hr;

}//SetDBSession

HRESULT _stdcall TDBGenID::GetDBSession(lUnknown** ppSession)

{

::SetErrorlnfo(0,NULL);

return m_spSession.CopyTo(ppSession);

}//GetDBSession

//IOC2_ObjectLoader interface -----------

HRESULT _stdcall TDBGenID::put_Connection

(IDispatch* pConnection)

{

::SetErrorInf0(0,NULL);

HRESULT hr=NOERROR;

_OLE_TRY_

{

IDispatchPtr spConnection(pConnection) ; //блокируем в памяти

//освобождаем текущие подключения

SetDBSession(NULL);

if(pConnection) {

IUnknownPtr spDBSession;

get_adodb_session(pConnection,spDBSession); //throw

if(SUCCEEDED(hr=SetDBSession(spDBSession)))

m_spADODBConnection=pConnection;

}//pConnection!=NULL

}

_OLE_DISP_CATCHES_

return hr;

}//put_Connection

HRESULT _stdcall TDBGenID::get_Connection

(IDispatch** ppConnection)

{

::SetErrorlnfо(0,NULL);

if(ppConnection==NULL)

return E_POINTER;

*ppConnection=NULL;

HRESULT hr=S_OK;

_OLE_TRY_

{

if(!m_spADODBConnection && (bool)m_spSession)

{

IGetDataSourcePtr spGetDataSource(m_spSession);

if(i spGetDataSource)

t_ole_error::throw_error

("query IGetDataSource interface",spGetDataSource.m_hr);

IUnknownPtr spDataSource;

if(FAILED(hr=get_data_source(spGetDataSource,spDataSource)))

t_ole_error::throw_error("Получение источника данных",hr);

IDBPropertiesPtr spDBProperties(spDataSource);

if(!spDBProperties)

t_ole_error::throw_error

("query IDBProperties interface",spDBProperties.m_hr);

construct_adodb_connection(spDBProperties,m_spSession,

m_spADODBConnection);//throw

}//if - создание ADODB-объекта

hr=m_spADODBConnection.CopyTo(ppConnection);

}

_OLE_DISP_CATCHES_

return hr;

}//get_Connection

Реализация метода получения значения генератора:

HRESULT _stdcall TDBGenID::GenID(BSTR GenName,LONG Count,

LONG* pResult)

{

::SetErrorlnfо(0,NULL);

if(pResult==NULL)

return E_POINTER;

HRESULT hr=S_OK;

_OLE_TRY_

{

if(!m_spSession)

throw runtime_error("Объект неинициализирован");

if(!m_Cmd.is_created)

_THROW_OLEDB_FAILED(m_Cmd,create(m_spSession));

structure::str_formatter stmt

("select gen_id(%l,%2) from rdb$database");

t_db_row row(1);

_THROW_OLEDB_FAILED (m_Cmd, prepare ( stmt«GenName«Count, &row) )

_THROW_OLEDB_FAILED(m_Cmd,execute(NULL));

if(m_Cmd.fetch(row)==S_OK)

*pResult=row[0].as_integer;

else

{

//проверим

причину сбоя получения данных

_THROW_OLEDB_FAILED(m_Cmd,m_last_result)

throw runtime_error("Получено пустое множество");

}

}

_OLE_DIS P_CATCHES_

return hr;

}//GenID

Использование скриптов в клиентских приложениях базы данных InterBase

Время от времени у любого программиста появляется желание вынести часть логики своих приложений на уровень, который можно было бы изменять без перекомпиляции приложения. А для определенного класса задач это требование изначально является первоочередным. Как правило, когда речь заходит о добавлении такой возможности, сразу вспоминают серверы приложений. Однако существуют задачи, для которых то же самое эффективнее реализовывать на уровне отдельного клиента.

Использование такого рода "программ" разгружает основной код приложения от алгоритмов, сильно подверженных переменчивым желаниям пользователей. Например:

* Проверка достоверности данных при сохранении.

* Контроль прав на чтение и изменение данных.

* Правила движения документов.

* Настраиваемый пользовательский интерфейс.

* Печать выходных форм.

* Встроенные отчеты.

При этом не существует больших проблем с выполнением сценариев, поскольку реализовано и доступно достаточно много компонентов для быстрого решения этой задачи. В том числе и бесплатный ActiveX-компонент ScriptControl от Microsoft.

Основные трудности при реализации такого подхода приходятся на осуществление тесной интеграции основного кода приложения и кода сценария. В числе важных вопросов находится и обеспечение доступа сценария к базе данных.

Самым тривиальным решением было бы создание внутри сценария собственного подключения к база данных. Но, как уже было замечено ранее, это медленно и неэффективно. Другим решением является передача готового подключения из основного кода приложения. И вот здесь применение ADODB- и OLEDB- компонентов доступа дает максимальный эффект.

Компоненты ADODB изначально приспособлены для использования в ActiveX-сценариях. Впрочем, для передачи в сценарий соединения с базой данных ADODB.Connection с выделенной сессией могут потребоваться некоторые усилия. Решение этой задачи было приведено в разделе описания сессии.

Компоненты OLEDB нельзя непосредственно использовать в сценариях. Но их можно "обернуть" в ADODB-компоненты и таким образом использовать в коде сценария. Подробности можно посмотреть в примерах, входящих в дистрибутив IBProvider.

Поделиться с друзьями: