X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/8c6fa3fbaccc22127280bf77a48fab5a3ee0716e..46b0747592074017ff0ea4b33d4a7194235886e5:/stglibs/ibpp.lib/service.cpp diff --git a/stglibs/ibpp.lib/service.cpp b/stglibs/ibpp.lib/service.cpp deleted file mode 100644 index 26726ea1..00000000 --- a/stglibs/ibpp.lib/service.cpp +++ /dev/null @@ -1,774 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// File : $Id: service.cpp,v 1.1 2007/05/05 17:00:43 faust Exp $ -// Subject : IBPP, Service 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 - -using namespace ibpp_internals; - -#ifdef IBPP_UNIX -#include -#define Sleep(x) usleep(x) -#endif - -// (((((((( OBJECT INTERFACE IMPLEMENTATION )))))))) - -void ServiceImpl::Connect() -{ - if (mHandle != 0) return; // Already connected - - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - if (mUserName.empty()) - throw LogicExceptionImpl("Service::Connect", _("Unspecified user name.")); - if (mUserPassword.empty()) - throw LogicExceptionImpl("Service::Connect", _("Unspecified user password.")); - - // Attach to the Service Manager - IBS status; - SPB spb; - std::string connect; - - // Build a SPB based on the properties - spb.Insert(isc_spb_version); - spb.Insert(isc_spb_current_version); - spb.InsertString(isc_spb_user_name, 1, mUserName.c_str()); - spb.InsertString(isc_spb_password, 1, mUserPassword.c_str()); - - if (! mServerName.empty()) - { - connect = mServerName; - connect += ":"; - } - - connect += "service_mgr"; - - (*gds.Call()->m_service_attach)(status.Self(), (short)connect.size(), (char*)connect.c_str(), - &mHandle, spb.Size(), spb.Self()); - if (status.Errors()) - { - mHandle = 0; // Should be, but better be sure... - throw SQLExceptionImpl(status, "Service::Connect", _("isc_service_attach failed")); - } -} - -void ServiceImpl::Disconnect() -{ - if (mHandle == 0) return; // Already disconnected - - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - - IBS status; - - // Detach from the service manager - (*gds.Call()->m_service_detach)(status.Self(), &mHandle); - - // Set mHandle to 0 now, just in case we need to throw, because Disconnect() - // is called from Service destructor and we want to maintain a coherent state. - mHandle = 0; - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::Disconnect", _("isc_service_detach failed")); -} - -void ServiceImpl::GetVersion(std::string& version) -{ - // Based on a patch provided by Torsten Martinsen (SourceForge 'bullestock') - - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - if (mHandle == 0) - throw LogicExceptionImpl("Service::GetVersion", _("Service is not connected.")); - - IBS status; - SPB spb; - RB result(250); - - spb.Insert(isc_info_svc_server_version); - - (*gds.Call()->m_service_query)(status.Self(), &mHandle, 0, 0, 0, spb.Size(), spb.Self(), - result.Size(), result.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::GetVersion", _("isc_service_query failed")); - - result.GetString(isc_info_svc_server_version, version); -} - -void ServiceImpl::AddUser(const IBPP::User& user) -{ - if (gds.Call()->mGDSVersion >= 60 && mHandle == 0) - throw LogicExceptionImpl("Service::AddUser", _("Service is not connected.")); - if (user.username.empty()) - throw LogicExceptionImpl("Service::AddUser", _("Username required.")); - if (user.password.empty()) - throw LogicExceptionImpl("Service::AddUser", _("Password required.")); - - IBS status; - SPB spb; - spb.Insert(isc_action_svc_add_user); - spb.InsertString(isc_spb_sec_username, 2, user.username.c_str()); - spb.InsertString(isc_spb_sec_password, 2, user.password.c_str()); - if (! user.firstname.empty()) - spb.InsertString(isc_spb_sec_firstname, 2, user.firstname.c_str()); - if (! user.middlename.empty()) - spb.InsertString(isc_spb_sec_middlename, 2, user.middlename.c_str()); - if (! user.lastname.empty()) - spb.InsertString(isc_spb_sec_lastname, 2, user.lastname.c_str()); - if (user.userid != 0) - spb.InsertQuad(isc_spb_sec_userid, (int32_t)user.userid); - if (user.groupid != 0) - spb.InsertQuad(isc_spb_sec_groupid, (int32_t)user.groupid); - - (*gds.Call()->m_service_start)(status.Self(), &mHandle, 0, spb.Size(), spb.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::AddUser", _("isc_service_start failed")); - - Wait(); -} - -void ServiceImpl::ModifyUser(const IBPP::User& user) -{ - if (gds.Call()->mGDSVersion >= 60 && mHandle == 0) - throw LogicExceptionImpl("Service::ModifyUser", _("Service is not connected.")); - if (user.username.empty()) - throw LogicExceptionImpl("Service::ModifyUser", _("Username required.")); - - IBS status; - SPB spb; - - spb.Insert(isc_action_svc_modify_user); - spb.InsertString(isc_spb_sec_username, 2, user.username.c_str()); - if (! user.password.empty()) - spb.InsertString(isc_spb_sec_password, 2, user.password.c_str()); - if (! user.firstname.empty()) - spb.InsertString(isc_spb_sec_firstname, 2, user.firstname.c_str()); - if (! user.middlename.empty()) - spb.InsertString(isc_spb_sec_middlename, 2, user.middlename.c_str()); - if (! user.lastname.empty()) - spb.InsertString(isc_spb_sec_lastname, 2, user.lastname.c_str()); - if (user.userid != 0) - spb.InsertQuad(isc_spb_sec_userid, (int32_t)user.userid); - if (user.groupid != 0) - spb.InsertQuad(isc_spb_sec_groupid, (int32_t)user.groupid); - - (*gds.Call()->m_service_start)(status.Self(), &mHandle, 0, spb.Size(), spb.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::ModifyUser", _("isc_service_start failed")); - - Wait(); -} - -void ServiceImpl::RemoveUser(const std::string& username) -{ - - if (gds.Call()->mGDSVersion >= 60 && mHandle == 0) - throw LogicExceptionImpl("Service::RemoveUser", _("Service is not connected.")); - if (username.empty()) - throw LogicExceptionImpl("Service::RemoveUser", _("Username required.")); - - IBS status; - SPB spb; - - spb.Insert(isc_action_svc_delete_user); - spb.InsertString(isc_spb_sec_username, 2, username.c_str()); - - (*gds.Call()->m_service_start)(status.Self(), &mHandle, 0, spb.Size(), spb.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::RemoveUser", _("isc_service_start failed")); - - Wait(); -} - -void ServiceImpl::GetUser(IBPP::User& user) -{ - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - if (mHandle == 0) - throw LogicExceptionImpl("Service::GetUser", _("Service is not connected.")); - if (user.username.empty()) - throw LogicExceptionImpl("Service::GetUser", _("Username required.")); - - SPB spb; - spb.Insert(isc_action_svc_display_user); - spb.InsertString(isc_spb_sec_username, 2, user.username.c_str()); - - IBS status; - (*gds.Call()->m_service_start)(status.Self(), &mHandle, 0, spb.Size(), spb.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::GetUser", _("isc_service_start failed")); - - RB result(8000); - char request[] = {isc_info_svc_get_users}; - status.Reset(); - (*gds.Call()->m_service_query)(status.Self(), &mHandle, 0, 0, 0, - sizeof(request), request, result.Size(), result.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::GetUser", _("isc_service_query failed")); - - char* p = result.Self(); - if (*p != isc_info_svc_get_users) - throw SQLExceptionImpl(status, "Service::GetUser", _("isc_service_query returned unexpected answer")); - - p += 3; // Skips the 'isc_info_svc_get_users' and its total length - user.clear(); - while (*p != isc_info_end) - { - if (*p == isc_spb_sec_userid) - { - user.userid = (uint32_t)(*gds.Call()->m_vax_integer)(p+1, 4); - p += 5; - } - else if (*p == isc_spb_sec_groupid) - { - user.groupid = (uint32_t)(*gds.Call()->m_vax_integer)(p+1, 4); - p += 5; - } - else - { - unsigned short len = (unsigned short)(*gds.Call()->m_vax_integer)(p+1, 2); - switch (*p) - { - case isc_spb_sec_username : - // For each user, this is the first element returned - if (len != 0) user.username.assign(p+3, len); - break; - case isc_spb_sec_password : - if (len != 0) user.password.assign(p+3, len); - break; - case isc_spb_sec_firstname : - if (len != 0) user.firstname.assign(p+3, len); - break; - case isc_spb_sec_middlename : - if (len != 0) user.middlename.assign(p+3, len); - break; - case isc_spb_sec_lastname : - if (len != 0) user.lastname.assign(p+3, len); - break; - } - p += (3 + len); - } - } -} - -void ServiceImpl::GetUsers(std::vector& users) -{ - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - if (mHandle == 0) - throw LogicExceptionImpl("Service::GetUsers", _("Service is not connected.")); - - SPB spb; - spb.Insert(isc_action_svc_display_user); - - IBS status; - (*gds.Call()->m_service_start)(status.Self(), &mHandle, 0, spb.Size(), spb.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::GetUsers", _("isc_service_start failed")); - - RB result(8000); - char request[] = {isc_info_svc_get_users}; - status.Reset(); - (*gds.Call()->m_service_query)(status.Self(), &mHandle, 0, 0, 0, - sizeof(request), request, result.Size(), result.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::GetUsers", _("isc_service_query failed")); - - users.clear(); - char* p = result.Self(); - if (*p != isc_info_svc_get_users) - throw SQLExceptionImpl(status, "Service::GetUsers", _("isc_service_query returned unexpected answer")); - - p += 3; // Skips the 'isc_info_svc_get_users' and its total length - IBPP::User user; - while (*p != isc_info_end) - { - if (*p == isc_spb_sec_userid) - { - user.userid = (uint32_t)(*gds.Call()->m_vax_integer)(p+1, 4); - p += 5; - } - else if (*p == isc_spb_sec_groupid) - { - user.groupid = (uint32_t)(*gds.Call()->m_vax_integer)(p+1, 4); - p += 5; - } - else - { - unsigned short len = (unsigned short)(*gds.Call()->m_vax_integer)(p+1, 2); - switch (*p) - { - case isc_spb_sec_username : - // For each user, this is the first element returned - if (! user.username.empty()) users.push_back(user); // Flush previous user - user.clear(); - if (len != 0) user.username.assign(p+3, len); - break; - case isc_spb_sec_password : - if (len != 0) user.password.assign(p+3, len); - break; - case isc_spb_sec_firstname : - if (len != 0) user.firstname.assign(p+3, len); - break; - case isc_spb_sec_middlename : - if (len != 0) user.middlename.assign(p+3, len); - break; - case isc_spb_sec_lastname : - if (len != 0) user.lastname.assign(p+3, len); - break; - } - p += (3 + len); - } - } - if (! user.username.empty()) users.push_back(user); // Flush last user -} - -void ServiceImpl::SetPageBuffers(const std::string& dbfile, int buffers) -{ - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - if (mHandle == 0) - throw LogicExceptionImpl("Service::SetPageBuffers", _("Service is not connected.")); - if (dbfile.empty()) - throw LogicExceptionImpl("Service::SetPageBuffers", _("Main database file must be specified.")); - - IBS status; - SPB spb; - - spb.Insert(isc_action_svc_properties); - spb.InsertString(isc_spb_dbname, 2, dbfile.c_str()); - spb.InsertQuad(isc_spb_prp_page_buffers, buffers); - - (*gds.Call()->m_service_start)(status.Self(), &mHandle, 0, spb.Size(), spb.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::SetPageBuffers", _("isc_service_start failed")); - - Wait(); -} - -void ServiceImpl::SetSweepInterval(const std::string& dbfile, int sweep) -{ - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - if (mHandle == 0) - throw LogicExceptionImpl("Service::SetSweepInterval", _("Service is not connected.")); - if (dbfile.empty()) - throw LogicExceptionImpl("Service::SetSweepInterval", _("Main database file must be specified.")); - - IBS status; - SPB spb; - - spb.Insert(isc_action_svc_properties); - spb.InsertString(isc_spb_dbname, 2, dbfile.c_str()); - spb.InsertQuad(isc_spb_prp_sweep_interval, sweep); - - (*gds.Call()->m_service_start)(status.Self(), &mHandle, 0, spb.Size(), spb.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::SetSweepInterval", _("isc_service_start failed")); - - Wait(); -} - -void ServiceImpl::SetSyncWrite(const std::string& dbfile, bool sync) -{ - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - if (mHandle == 0) - throw LogicExceptionImpl("Service::SetSyncWrite", _("Service is not connected.")); - if (dbfile.empty()) - throw LogicExceptionImpl("Service::SetSyncWrite", _("Main database file must be specified.")); - - IBS status; - SPB spb; - - spb.Insert(isc_action_svc_properties); - spb.InsertString(isc_spb_dbname, 2, dbfile.c_str()); - if (sync) spb.InsertByte(isc_spb_prp_write_mode, (char)isc_spb_prp_wm_sync); - else spb.InsertByte(isc_spb_prp_write_mode, (char)isc_spb_prp_wm_async); - - (*gds.Call()->m_service_start)(status.Self(), &mHandle, 0, spb.Size(), spb.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::SetSyncWrite", _("isc_service_start failed")); - - Wait(); -} - -void ServiceImpl::SetReadOnly(const std::string& dbfile, bool readonly) -{ - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - if (mHandle == 0) - throw LogicExceptionImpl("Service::SetReadOnly", _("Service is not connected.")); - if (dbfile.empty()) - throw LogicExceptionImpl("Service::SetReadOnly", _("Main database file must be specified.")); - - IBS status; - SPB spb; - - spb.Insert(isc_action_svc_properties); - spb.InsertString(isc_spb_dbname, 2, dbfile.c_str()); - if (readonly) spb.InsertByte(isc_spb_prp_access_mode, (char)isc_spb_prp_am_readonly); - else spb.InsertByte(isc_spb_prp_access_mode, (char)isc_spb_prp_am_readwrite); - - (*gds.Call()->m_service_start)(status.Self(), &mHandle, 0, spb.Size(), spb.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::SetReadOnly", _("isc_service_start failed")); - - Wait(); -} - -void ServiceImpl::SetReserveSpace(const std::string& dbfile, bool reserve) -{ - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - if (mHandle == 0) - throw LogicExceptionImpl("Service::SetReserveSpace", _("Service is not connected.")); - if (dbfile.empty()) - throw LogicExceptionImpl("Service::SetReserveSpace", _("Main database file must be specified.")); - - IBS status; - SPB spb; - - spb.Insert(isc_action_svc_properties); - spb.InsertString(isc_spb_dbname, 2, dbfile.c_str()); - if (reserve) spb.InsertByte(isc_spb_prp_reserve_space, (char)isc_spb_prp_res); - else spb.InsertByte(isc_spb_prp_reserve_space, (char)isc_spb_prp_res_use_full); - - (*gds.Call()->m_service_start)(status.Self(), &mHandle, 0, spb.Size(), spb.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::SetReserveSpace", _("isc_service_start failed")); - - Wait(); -} - -void ServiceImpl::Shutdown(const std::string& dbfile, IBPP::DSM mode, int sectimeout) -{ - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - if (mHandle == 0) - throw LogicExceptionImpl("Service::Shutdown", _("Service is not connected.")); - if (dbfile.empty()) - throw LogicExceptionImpl("Service::Shutdown", _("Main database file must be specified.")); - - IBS status; - SPB spb; - - spb.Insert(isc_action_svc_properties); - spb.InsertString(isc_spb_dbname, 2, dbfile.c_str()); - switch (mode) - { - case IBPP::dsDenyAttach : - spb.InsertQuad(isc_spb_prp_deny_new_attachments, sectimeout); - break; - case IBPP::dsDenyTrans : - spb.InsertQuad(isc_spb_prp_deny_new_transactions, sectimeout); - break; - case IBPP::dsForce : - spb.InsertQuad(isc_spb_prp_shutdown_db, sectimeout); - break; - } - - (*gds.Call()->m_service_start)(status.Self(), &mHandle, 0, spb.Size(), spb.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::Shutdown", _("isc_service_start failed")); - - Wait(); -} - -void ServiceImpl::Restart(const std::string& dbfile) -{ - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - if (mHandle == 0) - throw LogicExceptionImpl("Service::Restart", _("Service is not connected.")); - if (dbfile.empty()) - throw LogicExceptionImpl("Service::Restart", _("Main database file must be specified.")); - - IBS status; - SPB spb; - - spb.Insert(isc_action_svc_properties); - spb.InsertString(isc_spb_dbname, 2, dbfile.c_str()); - spb.InsertQuad(isc_spb_options, isc_spb_prp_db_online); - - (*gds.Call()->m_service_start)(status.Self(), &mHandle, 0, spb.Size(), spb.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::Restart", _("isc_service_start failed")); - - Wait(); -} - -void ServiceImpl::Sweep(const std::string& dbfile) -{ - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - if (mHandle == 0) - throw LogicExceptionImpl("Service::Sweep", _("Service is not connected.")); - if (dbfile.empty()) - throw LogicExceptionImpl("Service::Sweep", _("Main database file must be specified.")); - - IBS status; - SPB spb; - - spb.Insert(isc_action_svc_repair); - spb.InsertString(isc_spb_dbname, 2, dbfile.c_str()); - spb.InsertQuad(isc_spb_options, isc_spb_rpr_sweep_db); - - (*gds.Call()->m_service_start)(status.Self(), &mHandle, 0, spb.Size(), spb.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::Sweep", _("isc_service_start failed")); - - Wait(); -} - -void ServiceImpl::Repair(const std::string& dbfile, IBPP::RPF flags) -{ - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - if (mHandle == 0) - throw LogicExceptionImpl("Service::Repair", _("Service is not connected.")); - if (dbfile.empty()) - throw LogicExceptionImpl("Service::Repair", _("Main database file must be specified.")); - - IBS status; - SPB spb; - - spb.Insert(isc_action_svc_repair); - spb.InsertString(isc_spb_dbname, 2, dbfile.c_str()); - - unsigned int mask; - if (flags & IBPP::rpValidateFull) mask = (isc_spb_rpr_full | isc_spb_rpr_validate_db); - else if (flags & IBPP::rpValidatePages) mask = isc_spb_rpr_validate_db; - else if (flags & IBPP::rpMendRecords) mask = isc_spb_rpr_mend_db; - else throw LogicExceptionImpl("Service::Repair", - _("One of rpMendRecords, rpValidatePages, rpValidateFull is required.")); - - if (flags & IBPP::rpReadOnly) mask |= isc_spb_rpr_check_db; - if (flags & IBPP::rpIgnoreChecksums) mask |= isc_spb_rpr_ignore_checksum; - if (flags & IBPP::rpKillShadows) mask |= isc_spb_rpr_kill_shadows; - - spb.InsertQuad(isc_spb_options, mask); - - (*gds.Call()->m_service_start)(status.Self(), &mHandle, 0, spb.Size(), spb.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::Repair", _("isc_service_start failed")); - - Wait(); -} - -void ServiceImpl::StartBackup(const std::string& dbfile, - const std::string& bkfile, IBPP::BRF flags) -{ - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - if (mHandle == 0) - throw LogicExceptionImpl("Service::Backup", _("Service is not connected.")); - if (dbfile.empty()) - throw LogicExceptionImpl("Service::Backup", _("Main database file must be specified.")); - if (bkfile.empty()) - throw LogicExceptionImpl("Service::Backup", _("Backup file must be specified.")); - - IBS status; - SPB spb; - - spb.Insert(isc_action_svc_backup); - spb.InsertString(isc_spb_dbname, 2, dbfile.c_str()); - spb.InsertString(isc_spb_bkp_file, 2, bkfile.c_str()); - if (flags & IBPP::brVerbose) spb.Insert(isc_spb_verbose); - - unsigned int mask = 0; - if (flags & IBPP::brIgnoreChecksums) mask |= isc_spb_bkp_ignore_checksums; - if (flags & IBPP::brIgnoreLimbo) mask |= isc_spb_bkp_ignore_limbo; - if (flags & IBPP::brMetadataOnly) mask |= isc_spb_bkp_metadata_only; - if (flags & IBPP::brNoGarbageCollect) mask |= isc_spb_bkp_no_garbage_collect; - if (flags & IBPP::brNonTransportable) mask |= isc_spb_bkp_non_transportable; - if (flags & IBPP::brConvertExtTables) mask |= isc_spb_bkp_convert; - if (mask != 0) spb.InsertQuad(isc_spb_options, mask); - - (*gds.Call()->m_service_start)(status.Self(), &mHandle, 0, spb.Size(), spb.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::Backup", _("isc_service_start failed")); -} - -void ServiceImpl::StartRestore(const std::string& bkfile, const std::string& dbfile, - int pagesize, IBPP::BRF flags) -{ - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - if (mHandle == 0) - throw LogicExceptionImpl("Service::Restore", _("Service is not connected.")); - if (bkfile.empty()) - throw LogicExceptionImpl("Service::Restore", _("Backup file must be specified.")); - if (dbfile.empty()) - throw LogicExceptionImpl("Service::Restore", _("Main database file must be specified.")); - - IBS status; - SPB spb; - - spb.Insert(isc_action_svc_restore); - spb.InsertString(isc_spb_bkp_file, 2, bkfile.c_str()); - spb.InsertString(isc_spb_dbname, 2, dbfile.c_str()); - if (flags & IBPP::brVerbose) spb.Insert(isc_spb_verbose); - if (pagesize != 0) spb.InsertQuad(isc_spb_res_page_size, pagesize); - - unsigned int mask; - if (flags & IBPP::brReplace) mask = isc_spb_res_replace; - else mask = isc_spb_res_create; // Safe default mode - - if (flags & IBPP::brDeactivateIdx) mask |= isc_spb_res_deactivate_idx; - if (flags & IBPP::brNoShadow) mask |= isc_spb_res_no_shadow; - if (flags & IBPP::brNoValidity) mask |= isc_spb_res_no_validity; - if (flags & IBPP::brPerTableCommit) mask |= isc_spb_res_one_at_a_time; - if (flags & IBPP::brUseAllSpace) mask |= isc_spb_res_use_all_space; - if (mask != 0) spb.InsertQuad(isc_spb_options, mask); - - (*gds.Call()->m_service_start)(status.Self(), &mHandle, 0, spb.Size(), spb.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "Service::Restore", _("isc_service_start failed")); -} - -const char* ServiceImpl::WaitMsg() -{ - IBS status; - SPB req; - RB result(1024); - - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - - req.Insert(isc_info_svc_line); // Request one line of textual output - - // _service_query will only block until a line of result is available - // (or until the end of the task if it does not report information) - (*gds.Call()->m_service_query)(status.Self(), &mHandle, 0, 0, 0, - req.Size(), req.Self(), result.Size(), result.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "ServiceImpl::Wait", _("isc_service_query failed")); - - // If message length is zero bytes, task is finished - if (result.GetString(isc_info_svc_line, mWaitMessage) == 0) return 0; - - // Task is not finished, but we have something to report - return mWaitMessage.c_str(); -} - -void ServiceImpl::Wait() -{ - IBS status; - SPB spb; - RB result(1024); - std::string msg; - - if (gds.Call()->mGDSVersion < 60) - throw LogicExceptionImpl("Service", _("Requires the version 6 of GDS32.DLL")); - - spb.Insert(isc_info_svc_line); - for (;;) - { - // Sleeps 1 millisecond upfront. This will release the remaining - // timeslot of the thread. Doing so will give a good chance for small - // services tasks to finish before we check if they are still running. - // The deal is to limit (in that particular case) the number of loops - // polling _service_query that will happen. - - Sleep(1); - - // _service_query will only block until a line of result is available - // (or until the end of the task if it does not report information) - (*gds.Call()->m_service_query)(status.Self(), &mHandle, 0, 0, 0, - spb.Size(), spb.Self(), result.Size(), result.Self()); - if (status.Errors()) - throw SQLExceptionImpl(status, "ServiceImpl::Wait", _("isc_service_query failed")); - - // If message length is zero bytes, task is finished - if (result.GetString(isc_info_svc_line, msg) == 0) return; - - status.Reset(); - result.Reset(); - } -} - -IBPP::IService* ServiceImpl::AddRef() -{ - ASSERTION(mRefCount >= 0); - ++mRefCount; - return this; -} - -void ServiceImpl::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 ServiceImpl::SetServerName(const char* newName) -{ - if (newName == 0) mServerName.erase(); - else mServerName = newName; -} - -void ServiceImpl::SetUserName(const char* newName) -{ - if (newName == 0) mUserName.erase(); - else mUserName = newName; -} - -void ServiceImpl::SetUserPassword(const char* newPassword) -{ - if (newPassword == 0) mUserPassword.erase(); - else mUserPassword = newPassword; -} - -ServiceImpl::ServiceImpl(const std::string& ServerName, - const std::string& UserName, const std::string& UserPassword) - : mRefCount(0), mHandle(0), - mServerName(ServerName), mUserName(UserName), mUserPassword(UserPassword) -{ -} - -ServiceImpl::~ServiceImpl() -{ - try { if (Connected()) Disconnect(); } - catch (...) { } -} - -// -// Eof -//