summaryrefslogtreecommitdiffstats
path: root/reladminif/transactionif.pgc
diff options
context:
space:
mode:
Diffstat (limited to 'reladminif/transactionif.pgc')
-rw-r--r--reladminif/transactionif.pgc242
1 files changed, 242 insertions, 0 deletions
diff --git a/reladminif/transactionif.pgc b/reladminif/transactionif.pgc
new file mode 100644
index 0000000..6bd16f7
--- /dev/null
+++ b/reladminif/transactionif.pgc
@@ -0,0 +1,242 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************************
+ *
+ *
+ * PURPOSE:
+ * Code with embedded SQL for relational DBMS
+ *
+ *
+ * COMMENTS:
+ * - reconsider this 604 ignorance!
+ *
+ ***********************************************************************/
+
+static const char rcsid[] = "@(#)reladminif,TransactionIf: $Id: transactionif.ec,v 1.6 2003/12/27 23:11:43 rasdev Exp $";
+
+#include "debug.hh"
+
+// general embedded SQL related definitions
+EXEC SQL include sqlglobals.h;
+
+#include "transactionif.hh"
+#include "raslib/rmdebug.hh"
+#include "adminif.hh"
+#include "oidif.hh"
+#include "catalogmgr/typefactory.hh"
+#include "sqlerror.hh"
+#include "objectbroker.hh"
+#include "databaseif.hh"
+
+// PG stuff for libpg connection maintenance
+#include "libpq-fe.h"
+extern PGconn *pgConn;
+
+
+void
+TransactionIf::begin( bool readOnly ) throw ( r_Error )
+{
+ RMDBGENTER(2, RMDebug::module_adminif, "TransactionIf", "begin(" << readOnly << ")");
+ ENTER( "TransactionIf::begin, readOnly=" << readOnly );
+
+ isReadOnly = readOnly;
+ AdminIf::setAborted(false);
+ AdminIf::setReadOnlyTA(readOnly);
+
+ TALK( "EXEC SQL BEGIN WORK" );
+ EXEC SQL BEGIN WORK;
+ if (sqlca.sqlwarn[2] == 'W') // real error, not just a warning
+ {
+ SQLCODE = 0; // FIXME: bad hack, as PG can't reset error state and SQLCODE is queried in many places -- PB 2005-jan-09
+ }
+ else
+ {
+ RMDBGMIDDLE(4, RMDebug::module_adminif, "TransactionIf", "error occured while issuing BEGIN");
+ LEAVE( "TransactionIf::begin(): error during BEGIN: " << SQLCODE );
+ generateException();
+ }
+
+ if (readOnly)
+ {
+ TALK( "EXEC SQL SET TRANSACTION READ ONLY" );
+ EXEC SQL SET TRANSACTION READ ONLY;
+ // no error check, as this doesn't inhibit work
+ }
+
+ // prelim.:have additional libpq TA -- PB 2005-jan-09
+ TALK( "PQexec( pgConn, BEGIN )" );
+ PGresult *pgResult = PQexec( pgConn, "BEGIN" );
+ if (PQresultStatus(pgResult) != PGRES_COMMAND_OK)
+ {
+ LEAVE( "TransactionIf::begin() Error: cannot open libpq TA: " << PQerrorMessage(pgConn) );
+ generateException();
+ }
+
+#ifdef RMANBENCHMARK
+ DBObject::readTimer.start();
+ DBObject::readTimer.pause();
+
+ DBObject::updateTimer.start();
+ DBObject::updateTimer.pause();
+
+ DBObject::deleteTimer.start();
+ DBObject::deleteTimer.pause();
+
+ DBObject::insertTimer.start();
+ DBObject::insertTimer.pause();
+
+ OId::oidAlloc.start();
+ OId::oidAlloc.pause();
+
+ OId::oidResolve.start();
+ OId::oidResolve.pause();
+#endif
+
+ OId::initialize();
+ TypeFactory::initialize();
+
+ LEAVE( "TransactionIf::begin, SQLCODE=" << SQLCODE );
+ RMDBGEXIT(2, RMDebug::module_adminif, "TransactionIf", "begin(" << readOnly << ") ");
+}
+
+void
+TransactionIf::commit() throw ( r_Error )
+{
+ RMDBGENTER(2, RMDebug::module_adminif, "TransactionIf", "commit()");
+ ENTER( "TransactionIf::commit" );
+
+ if (isReadOnly)
+ {
+ RMDBGMIDDLE(9, RMDebug::module_adminif, "TransactionIf", "read only: aborting");
+ TALK( "TA is readonly: aborting" );
+ abort();
+ }
+ else
+ {
+ AdminIf::setAborted(false);
+ RMDBGMIDDLE(9, RMDebug::module_adminif, "TransactionIf", "set aborted false");
+ TypeFactory::freeTempTypes();
+ RMDBGMIDDLE(9, RMDebug::module_adminif, "TransactionIf", "freed temp types");
+ ObjectBroker::clearBroker();
+ RMDBGMIDDLE(9, RMDebug::module_adminif, "TransactionIf", "cleared broker");
+ OId::deinitialize();
+ RMDBGMIDDLE(9, RMDebug::module_adminif, "TransactionIf", "wrote oid counters");
+ AdminIf::setReadOnlyTA(false);
+ RMDBGMIDDLE(9, RMDebug::module_adminif, "TransactionIf", "committing");
+
+ // prelim.:have additional libpq TA -- PB 2005-jan-09
+ TALK( "PQexec( pgConn, END )" );
+ PGresult *pgResult = PQexec( pgConn, "END" );
+ if (PQresultStatus(pgResult) != PGRES_COMMAND_OK)
+ {
+ LEAVE( "TransactionIf::commit() Error: cannot commit libpq TA: " << PQerrorMessage(pgConn) );
+ generateException();
+ }
+
+ TALK( "EXEC SQL COMMIT WORK" );
+ EXEC SQL COMMIT WORK;
+ if (SQLCODE == -604) // = "no TA open" - seems to be a hickup from our double transaction
+ // so we ignore it; FIXME: reinvestigate! -- PB 25-aug-2005
+ {
+ TALK( "TransactionIf::commit(): ignoring 'no TA open' error (SQLCODE -604) during COMMIT." );
+ }
+ else if (check("TransactionIf::begin() COMMIT\0"))
+ {
+ RMDBGMIDDLE(4, RMDebug::module_adminif, "TransactionIf", "error occured while issuing COMMIT");
+ LEAVE( "TransactionIf::commit(): error during COMMIT:" << SQLCODE );
+ generateException();
+ }
+ if (lastBase)
+ {
+ RMDBGMIDDLE(9, RMDebug::module_adminif, "TransactionIf", "closing dbms");
+ lastBase->baseDBMSClose();
+ }
+ }
+
+#ifdef RMANBENCHMARK
+ DBObject::readTimer.stop();
+
+ DBObject::updateTimer.stop();
+
+ DBObject::deleteTimer.stop();
+
+ DBObject::insertTimer.stop();
+
+ OId::oidAlloc.stop();
+
+ OId::oidResolve.stop();
+#endif
+
+ LEAVE( "TransactionIf::commit" );
+ RMDBGEXIT(2, RMDebug::module_adminif, "TransactionIf", "commit() " << endl << endl);
+}
+
+void
+TransactionIf::abort()
+{
+ RMDBGENTER(2, RMDebug::module_adminif, "TransactionIf", "abort()");
+ ENTER( "TransactionIf::abort" );
+
+ // prelim.:have additional libpq TA -- PB 2005-jan-09
+ TALK( "PQexec( pgConn, ABORT )" );
+ PGresult *pgResult = PQexec( pgConn, "ABORT" );
+ if (PQresultStatus(pgResult) != PGRES_COMMAND_OK)
+ {
+ LEAVE( "TransactionIf::abort() Error: cannot abort libpq TA: " << PQerrorMessage(pgConn) );
+ generateException();
+ }
+
+ AdminIf::setAborted(true);
+ TypeFactory::freeTempTypes();
+ ObjectBroker::clearBroker();
+ OId::deinitialize();
+ AdminIf::setReadOnlyTA(false);
+
+ TALK( "EXEC SQL ROLLBACK WORK" );
+ EXEC SQL ROLLBACK WORK;
+ if (check("TransactionIf::abort() ROLLBACK\0"))
+ {
+ RMDBGMIDDLE(4, RMDebug::module_adminif, "TransactionIf", "error occured while issuing ROLLBACK");
+ TALK( "TransactionIf::abort(): error during ROLLBACK, still continuing: " << SQLCODE );
+ }
+ if(lastBase)
+ lastBase->baseDBMSClose();
+
+#ifdef RMANBENCHMARK
+ DBObject::readTimer.stop();
+
+ DBObject::updateTimer.stop();
+
+ DBObject::deleteTimer.stop();
+
+ DBObject::insertTimer.stop();
+
+ OId::oidAlloc.stop();
+
+ OId::oidResolve.stop();
+#endif
+
+ LEAVE( "TransactionIf::abort, SQLCODE=" << SQLCODE );
+ RMDBGEXIT(2, RMDebug::module_adminif, "TransactionIf", "abort() " << endl << endl);
+}
+