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