X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/8c6fa3fbaccc22127280bf77a48fab5a3ee0716e..46b0747592074017ff0ea4b33d4a7194235886e5:/stglibs/ibpp.lib/database.cpp diff --git a/stglibs/ibpp.lib/database.cpp b/stglibs/ibpp.lib/database.cpp deleted file mode 100644 index 64b705d2..00000000 --- a/stglibs/ibpp.lib/database.cpp +++ /dev/null @@ -1,483 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// File : $Id: database.cpp,v 1.1 2007/05/05 17:00:42 faust Exp $ -// Subject : IBPP, Database class implementation -// -/////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright 2000-2006 T.I.P. Group S.A. and the IBPP Team (www.ibpp.org) -// -// The contents of this file are subject to the IBPP License (the "License"); -// you may not use this file except in compliance with the License. You may -// obtain a copy of the License at http://www.ibpp.org or in the 'license.txt' -// file which must have been distributed along with this file. -// -// This software, distributed under the License, is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations -// under the License. -// -/////////////////////////////////////////////////////////////////////////////// -// -// COMMENTS -// * Tabulations should be set every four characters when editing this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifdef _MSC_VER -#pragma warning(disable: 4786 4996) -#ifndef _DEBUG -#pragma warning(disable: 4702) -#endif -#endif - -#include "_ibpp.h" - -#ifdef HAS_HDRSTOP -#pragma hdrstop -#endif - -#include - -using namespace ibpp_internals; - -// (((((((( OBJECT INTERFACE IMPLEMENTATION )))))))) - -void DatabaseImpl::Create(int dialect) -{ - if (mHandle != 0) - throw LogicExceptionImpl("Database::Create", _("Database is already connected.")); - if (mDatabaseName.empty()) - throw LogicExceptionImpl("Database::Create", _("Unspecified database name.")); - if (mUserName.empty()) - throw LogicExceptionImpl("Database::Create", _("Unspecified user name.")); - if (dialect != 1 && dialect != 3) - throw LogicExceptionImpl("Database::Create", _("Only dialects 1 and 3 are supported.")); - - // Build the SQL Create Statement - std::string create; - create.assign("CREATE DATABASE '"); - if (! mServerName.empty()) create.append(mServerName).append(":"); - create.append(mDatabaseName).append("' "); - - create.append("USER '").append(mUserName).append("' "); - if (! mUserPassword.empty()) - create.append("PASSWORD '").append(mUserPassword).append("' "); - - if (! mCreateParams.empty()) create.append(mCreateParams); - - // Call ExecuteImmediate to create the database - isc_tr_handle tr_handle = 0; - IBS status; - (*gds.Call()->m_dsql_execute_immediate)(status.Self(), &mHandle, &tr_handle, - 0, const_cast(create.c_str()), short(dialect), NULL); - if (status.Errors()) - throw SQLExceptionImpl(status, "Database::Create", _("isc_dsql_execute_immediate failed")); - - Disconnect(); -} - -void DatabaseImpl::Connect() -{ - if (mHandle != 0) return; // Already connected - - if (mDatabaseName.empty()) - throw LogicExceptionImpl("Database::Connect", _("Unspecified database name.")); - if (mUserName.empty()) - throw LogicExceptionImpl("Database::Connect", _("Unspecified user name.")); - - // Build a DPB based on the properties - DPB dpb; - dpb.Insert(isc_dpb_user_name, mUserName.c_str()); - dpb.Insert(isc_dpb_password, mUserPassword.c_str()); - if (! mRoleName.empty()) dpb.Insert(isc_dpb_sql_role_name, mRoleName.c_str()); - if (! mCharSet.empty()) dpb.Insert(isc_dpb_lc_ctype, mCharSet.c_str()); - - std::string connect; - if (! mServerName.empty()) - connect.assign(mServerName).append(":"); - connect.append(mDatabaseName); - - IBS status; - (*gds.Call()->m_attach_database)(status.Self(), (short)connect.size(), - const_cast(connect.c_str()), &mHandle, dpb.Size(), dpb.Self()); - if (status.Errors()) - { - mHandle = 0; // Should be, but better be sure... - throw SQLExceptionImpl(status, "Database::Connect", _("isc_attach_database failed")); - } - - // Now, get ODS version information and dialect. - // If ODS major is lower of equal to 9, we reject the connection. - // If ODS major is 10 or higher, this is at least an InterBase 6.x Server - // OR FireBird 1.x Server. - - char items[] = {isc_info_ods_version, - isc_info_db_SQL_dialect, - isc_info_end}; - RB result(100); - - status.Reset(); - (*gds.Call()->m_database_info)(status.Self(), &mHandle, sizeof(items), items, - result.Size(), result.Self()); - if (status.Errors()) - { - status.Reset(); - (*gds.Call()->m_detach_database)(status.Self(), &mHandle); - mHandle = 0; // Should be, but better be sure... - throw SQLExceptionImpl(status, "Database::Connect", _("isc_database_info failed")); - } - - int ODS = result.GetValue(isc_info_ods_version); - if (ODS <= 9) - { - status.Reset(); - (*gds.Call()->m_detach_database)(status.Self(), &mHandle); - mHandle = 0; // Should be, but better be sure... - throw LogicExceptionImpl("Database::Connect", - _("Unsupported Server : wrong ODS version (%d), at least '10' required."), ODS); - } - - mDialect = result.GetValue(isc_info_db_SQL_dialect); - if (mDialect != 1 && mDialect != 3) - { - status.Reset(); - (*gds.Call()->m_detach_database)(status.Self(), &mHandle); - mHandle = 0; // Should be, but better be sure... - throw LogicExceptionImpl("Database::Connect", _("Dialect 1 or 3 required")); - } - - // Now, verify the GDS32.DLL we are using is compatible with the server - if (ODS >= 10 && gds.Call()->mGDSVersion < 60) - { - status.Reset(); - (*gds.Call()->m_detach_database)(status.Self(), &mHandle); - mHandle = 0; // Should be, but better be sure... - throw LogicExceptionImpl("Database::Connect", _("GDS32.DLL version 5 against IBSERVER 6")); - } -} - -void DatabaseImpl::Inactivate() -{ - if (mHandle == 0) return; // Not connected anyway - - IBS status; - - // Rollback any started transaction... - for (unsigned i = 0; i < mTransactions.size(); i++) - { - if (mTransactions[i]->Started()) - mTransactions[i]->Rollback(); - } - - // Cancel all pending event traps - for (unsigned i = 0; i < mEvents.size(); i++) - mEvents[i]->Clear(); - - // Let's detach from all Blobs - while (mBlobs.size() > 0) - mBlobs.back()->DetachDatabaseImpl(); - - // Let's detach from all Arrays - while (mArrays.size() > 0) - mArrays.back()->DetachDatabaseImpl(); - - // Let's detach from all Statements - while (mStatements.size() > 0) - mStatements.back()->DetachDatabaseImpl(); - - // Let's detach from all Transactions - while (mTransactions.size() > 0) - mTransactions.back()->DetachDatabaseImpl(this); - - // Let's detach from all Events - while (mEvents.size() > 0) - mEvents.back()->DetachDatabaseImpl(); -} - -void DatabaseImpl::Disconnect() -{ - if (mHandle == 0) return; // Not connected anyway - - // Put the connection to rest - Inactivate(); - - // Detach from the server - IBS status; - (*gds.Call()->m_detach_database)(status.Self(), &mHandle); - - // Should we throw, set mHandle to 0 first, because Disconnect() may - // be called from Database destructor (keeps the object coherent). - mHandle = 0; - if (status.Errors()) - throw SQLExceptionImpl(status, "Database::Disconnect", _("isc_detach_database failed")); -} - -void DatabaseImpl::Drop() -{ - if (mHandle == 0) - throw LogicExceptionImpl("Database::Drop", _("Database must be connected.")); - - // Put the connection to a rest - Inactivate(); - - IBS vector; - (*gds.Call()->m_drop_database)(vector.Self(), &mHandle); - if (vector.Errors()) - throw SQLExceptionImpl(vector, "Database::Drop", _("isc_drop_database failed")); - - mHandle = 0; -} - -void DatabaseImpl::Info(int* ODSMajor, int* ODSMinor, - int* PageSize, int* Pages, int* Buffers, int* Sweep, - bool* Sync, bool* Reserve) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Database::Info", _("Database is not connected.")); - - char items[] = {isc_info_ods_version, - isc_info_ods_minor_version, - isc_info_page_size, - isc_info_allocation, - isc_info_num_buffers, - isc_info_sweep_interval, - isc_info_forced_writes, - isc_info_no_reserve, - isc_info_end}; - IBS status; - RB result(256); - - status.Reset(); - (*gds.Call()->m_database_info)(status.Self(), &mHandle, sizeof(items), items, - result.Size(), result.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Database::Info", _("isc_database_info failed")); - - if (ODSMajor != 0) *ODSMajor = result.GetValue(isc_info_ods_version); - if (ODSMinor != 0) *ODSMinor = result.GetValue(isc_info_ods_minor_version); - if (PageSize != 0) *PageSize = result.GetValue(isc_info_page_size); - if (Pages != 0) *Pages = result.GetValue(isc_info_allocation); - if (Buffers != 0) *Buffers = result.GetValue(isc_info_num_buffers); - if (Sweep != 0) *Sweep = result.GetValue(isc_info_sweep_interval); - if (Sync != 0) - *Sync = result.GetValue(isc_info_forced_writes) == 1 ? true : false; - if (Reserve != 0) - *Reserve = result.GetValue(isc_info_no_reserve) == 1 ? false : true; -} - -void DatabaseImpl::Statistics(int* Fetches, int* Marks, int* Reads, int* Writes) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Database::Statistics", _("Database is not connected.")); - - char items[] = {isc_info_fetches, - isc_info_marks, - isc_info_reads, - isc_info_writes, - isc_info_end}; - IBS status; - RB result(128); - - status.Reset(); - (*gds.Call()->m_database_info)(status.Self(), &mHandle, sizeof(items), items, - result.Size(), result.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Database::Statistics", _("isc_database_info failed")); - - if (Fetches != 0) *Fetches = result.GetValue(isc_info_fetches); - if (Marks != 0) *Marks = result.GetValue(isc_info_marks); - if (Reads != 0) *Reads = result.GetValue(isc_info_reads); - if (Writes != 0) *Writes = result.GetValue(isc_info_writes); -} - -void DatabaseImpl::Counts(int* Insert, int* Update, int* Delete, - int* ReadIdx, int* ReadSeq) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Database::Counts", _("Database is not connected.")); - - char items[] = {isc_info_insert_count, - isc_info_update_count, - isc_info_delete_count, - isc_info_read_idx_count, - isc_info_read_seq_count, - isc_info_end}; - IBS status; - RB result(1024); - - status.Reset(); - (*gds.Call()->m_database_info)(status.Self(), &mHandle, sizeof(items), items, - result.Size(), result.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Database::Counts", _("isc_database_info failed")); - - if (Insert != 0) *Insert = result.GetCountValue(isc_info_insert_count); - if (Update != 0) *Update = result.GetCountValue(isc_info_update_count); - if (Delete != 0) *Delete = result.GetCountValue(isc_info_delete_count); - if (ReadIdx != 0) *ReadIdx = result.GetCountValue(isc_info_read_idx_count); - if (ReadSeq != 0) *ReadSeq = result.GetCountValue(isc_info_read_seq_count); -} - -void DatabaseImpl::Users(std::vector& users) -{ - if (mHandle == 0) - throw LogicExceptionImpl("Database::Users", _("Database is not connected.")); - - char items[] = {isc_info_user_names, - isc_info_end}; - IBS status; - RB result(8000); - - status.Reset(); - (*gds.Call()->m_database_info)(status.Self(), &mHandle, sizeof(items), items, - result.Size(), result.Self()); - if (status.Errors()) - { - status.Reset(); - throw SQLExceptionImpl(status, "Database::Users", _("isc_database_info failed")); - } - - users.clear(); - char* p = result.Self(); - while (*p == isc_info_user_names) - { - p += 3; // Get to the length byte (there are two undocumented bytes which we skip) - int len = (int)(*p); - ++p; // Get to the first char of username - if (len != 0) users.push_back(std::string().append(p, len)); - p += len; // Skip username - } - return; -} - -IBPP::IDatabase* DatabaseImpl::AddRef() -{ - ASSERTION(mRefCount >= 0); - ++mRefCount; - return this; -} - -void DatabaseImpl::Release() -{ - // Release cannot throw, except in DEBUG builds on assertion - ASSERTION(mRefCount >= 0); - --mRefCount; - try { if (mRefCount <= 0) delete this; } - catch (...) { } -} - -// (((((((( OBJECT INTERNAL METHODS )))))))) - -void DatabaseImpl::AttachTransactionImpl(TransactionImpl* tr) -{ - if (tr == 0) - throw LogicExceptionImpl("Database::AttachTransaction", - _("Transaction object is null.")); - - mTransactions.push_back(tr); -} - -void DatabaseImpl::DetachTransactionImpl(TransactionImpl* tr) -{ - if (tr == 0) - throw LogicExceptionImpl("Database::DetachTransaction", - _("ITransaction object is null.")); - - mTransactions.erase(std::find(mTransactions.begin(), mTransactions.end(), tr)); -} - -void DatabaseImpl::AttachStatementImpl(StatementImpl* st) -{ - if (st == 0) - throw LogicExceptionImpl("Database::AttachStatement", - _("Can't attach a null Statement object.")); - - mStatements.push_back(st); -} - -void DatabaseImpl::DetachStatementImpl(StatementImpl* st) -{ - if (st == 0) - throw LogicExceptionImpl("Database::DetachStatement", - _("Can't detach a null Statement object.")); - - mStatements.erase(std::find(mStatements.begin(), mStatements.end(), st)); -} - -void DatabaseImpl::AttachBlobImpl(BlobImpl* bb) -{ - if (bb == 0) - throw LogicExceptionImpl("Database::AttachBlob", - _("Can't attach a null Blob object.")); - - mBlobs.push_back(bb); -} - -void DatabaseImpl::DetachBlobImpl(BlobImpl* bb) -{ - if (bb == 0) - throw LogicExceptionImpl("Database::DetachBlob", - _("Can't detach a null Blob object.")); - - mBlobs.erase(std::find(mBlobs.begin(), mBlobs.end(), bb)); -} - -void DatabaseImpl::AttachArrayImpl(ArrayImpl* ar) -{ - if (ar == 0) - throw LogicExceptionImpl("Database::AttachArray", - _("Can't attach a null Array object.")); - - mArrays.push_back(ar); -} - -void DatabaseImpl::DetachArrayImpl(ArrayImpl* ar) -{ - if (ar == 0) - throw LogicExceptionImpl("Database::DetachArray", - _("Can't detach a null Array object.")); - - mArrays.erase(std::find(mArrays.begin(), mArrays.end(), ar)); -} - -void DatabaseImpl::AttachEventsImpl(EventsImpl* ev) -{ - if (ev == 0) - throw LogicExceptionImpl("Database::AttachEventsImpl", - _("Can't attach a null Events object.")); - - mEvents.push_back(ev); -} - -void DatabaseImpl::DetachEventsImpl(EventsImpl* ev) -{ - if (ev == 0) - throw LogicExceptionImpl("Database::DetachEventsImpl", - _("Can't detach a null Events object.")); - - mEvents.erase(std::find(mEvents.begin(), mEvents.end(), ev)); -} - -DatabaseImpl::DatabaseImpl(const std::string& ServerName, const std::string& DatabaseName, - const std::string& UserName, const std::string& UserPassword, - const std::string& RoleName, const std::string& CharSet, - const std::string& CreateParams) : - - mRefCount(0), mHandle(0), - mServerName(ServerName), mDatabaseName(DatabaseName), - mUserName(UserName), mUserPassword(UserPassword), mRoleName(RoleName), - mCharSet(CharSet), mCreateParams(CreateParams), - mDialect(3) -{ -} - -DatabaseImpl::~DatabaseImpl() -{ - try { if (Connected()) Disconnect(); } - catch(...) { } -} - -// -// EOF -//