/** * @param integer $mode * @return void */ public function _setExecuteMode($mode) { switch ($mode) { case DB2_AUTOCOMMIT_OFF: case DB2_AUTOCOMMIT_ON: $this->_execute_mode = $mode; db2_autocommit($this->_connection, $mode); break; default: /** * @see Zend_Db_Adapter_Db2_Exception */ require_once 'Zend/Db/Adapter/Db2/Exception.php'; throw new Zend_Db_Adapter_Db2_Exception("execution mode not supported"); break; } }
function RollbackTrans() { if ($this->transOff) { return true; } if ($this->transCnt) { $this->transCnt -= 1; } $this->_autocommit = true; $ret = db2_rollback($this->_connectionID); db2_autocommit($this->_connectionID, true); return $ret; }
/** * Makes sure each database and extension handles BEGIN, COMMIT and ROLLBACK * * @param string &$sql The SQL to check for a transaction query * @param string $result_class The type of result object to create * @return mixed `FALSE` if normal processing should continue, otherwise an object of the type $result_class */ private function handleTransactionQueries(&$sql, $result_class) { // SQL Server supports transactions, but starts then with BEGIN TRANSACTION if ($this->type == 'mssql' && preg_match('#^\\s*(begin|start(\\s+transaction)?)\\s*#i', $sql)) { $sql = 'BEGIN TRANSACTION'; } $begin = FALSE; $commit = FALSE; $rollback = FALSE; // Track transactions since most databases don't support nesting if (preg_match('#^\\s*(begin|start)(\\s+(transaction|work))?\\s*$#iD', $sql)) { if ($this->inside_transaction) { throw new fProgrammerException('A transaction is already in progress'); } $this->inside_transaction = TRUE; $begin = TRUE; } elseif (preg_match('#^\\s*(commit)(\\s+(transaction|work))?\\s*$#iD', $sql)) { if (!$this->inside_transaction) { throw new fProgrammerException('There is no transaction in progress'); } $this->inside_transaction = FALSE; $commit = TRUE; } elseif (preg_match('#^\\s*(rollback)(\\s+(transaction|work))?\\s*$#iD', $sql)) { if (!$this->inside_transaction) { throw new fProgrammerException('There is no transaction in progress'); } $this->inside_transaction = FALSE; $rollback = TRUE; } if (!$begin && !$commit && !$rollback) { return FALSE; } // The PDO, OCI8 and SQLSRV extensions require special handling through methods and functions $is_pdo = $this->extension == 'pdo'; $is_oci = $this->extension == 'oci8'; $is_sqlsrv = $this->extension == 'sqlsrv'; $is_ibm_db2 = $this->extension == 'ibm_db2'; if (!$is_pdo && !$is_oci && !$is_sqlsrv && !$is_ibm_db2) { return FALSE; } $this->statement = $sql; // PDO seems to act weird if you try to start transactions through a normal query call if ($is_pdo) { try { $is_mssql = $this->type == 'mssql' && substr($this->database, 0, 4) != 'dsn:'; $is_oracle = $this->type == 'oracle' && substr($this->database, 0, 4) != 'dsn:'; if ($begin) { // The SQL Server PDO object hasn't implemented transactions if ($is_mssql) { $this->connection->exec('BEGIN TRANSACTION'); } elseif ($is_oracle) { $this->connection->setAttribute(PDO::ATTR_AUTOCOMMIT, FALSE); } else { $this->connection->beginTransaction(); } } elseif ($commit) { if ($is_mssql) { $this->connection->exec('COMMIT'); } elseif ($is_oracle) { $this->connection->exec('COMMIT'); $this->connection->setAttribute(PDO::ATTR_AUTOCOMMIT, TRUE); } else { $this->connection->commit(); } } elseif ($rollback) { if ($is_mssql) { $this->connection->exec('ROLLBACK'); } elseif ($is_oracle) { $this->connection->exec('ROLLBACK'); $this->connection->setAttribute(PDO::ATTR_AUTOCOMMIT, TRUE); } else { $this->connection->rollBack(); } } } catch (Exception $e) { $db_type_map = array('db2' => 'DB2', 'mssql' => 'MSSQL', 'mysql' => 'MySQL', 'oracle' => 'Oracle', 'postgresql' => 'PostgreSQL', 'sqlite' => 'SQLite'); throw new fSQLException('%1$s error (%2$s) in %3$s', $db_type_map[$this->type], $e->getMessage(), $sql); } } elseif ($is_oci) { if ($commit) { oci_commit($this->connection); } elseif ($rollback) { oci_rollback($this->connection); } } elseif ($is_sqlsrv) { if ($begin) { sqlsrv_begin_transaction($this->connection); } elseif ($commit) { sqlsrv_commit($this->connection); } elseif ($rollback) { sqlsrv_rollback($this->connection); } } elseif ($is_ibm_db2) { if ($begin) { db2_autocommit($this->connection, FALSE); } elseif ($commit) { db2_commit($this->connection); db2_autocommit($this->connection, TRUE); } elseif ($rollback) { db2_rollback($this->connection); db2_autocommit($this->connection, TRUE); } } if ($result_class) { $result = new $result_class($this); $result->setSQL($sql); $result->setResult(TRUE); return $result; } return TRUE; }
function DBrollback() { global $DB; $result = false; switch ($DB['TYPE']) { case ZBX_DB_MYSQL: $result = DBexecute('ROLLBACK'); break; case ZBX_DB_POSTGRESQL: $result = DBexecute('ROLLBACK'); break; case ZBX_DB_ORACLE: $result = oci_rollback($DB['DB']); break; case ZBX_DB_DB2: $result = db2_rollback($DB['DB']); db2_autocommit($DB['DB'], DB2_AUTOCOMMIT_ON); break; case ZBX_DB_SQLITE3: $result = DBexecute('ROLLBACK'); unlock_sqlite3_access(); break; } return $result; }
/** * This function rollbacks a transaction. * * @access public * @override * @throws Throwable_SQL_Exception indicates that the executed * statement failed * * @see http://www.php.net/manual/en/function.db2-rollback.php */ public function rollback() { if (!$this->is_connected()) { throw new Throwable_SQL_Exception('Message: Failed to rollback SQL transaction. Reason: Unable to find connection.'); } $command = @db2_rollback($this->resource); if ($command === FALSE) { throw new Throwable_SQL_Exception('Message: Failed to rollback SQL transaction. Reason: :reason', array(':reason' => @db2_conn_error($this->resource))); } @db2_autocommit($this->resource, DB2_AUTOCOMMIT_ON); $this->sql = 'ROLLBACK;'; }
/** * Makes sure each database and extension handles BEGIN, COMMIT and ROLLBACK * * @param string|fStatement &$statement The SQL to check for a transaction query * @param string $result_class The type of result object to create * @return mixed `FALSE` if normal processing should continue, otherwise an object of the type $result_class */ private function handleTransactionQueries(&$statement, $result_class) { if (is_object($statement)) { $sql = $statement->getSQL(); } else { $sql = $statement; } // SQL Server supports transactions, but the statements are slightly different. // For the interest of convenience, we do simple transaction right here. if ($this->type == 'mssql') { if (preg_match('#^\\s*(BEGIN|START(\\s+TRANSACTION)?)\\s*$#i', $sql)) { $statement = 'BEGIN TRANSACTION'; } elseif (preg_match('#^\\s*SAVEPOINT\\s+("?\\w+"?)\\s*$#i', $sql, $match)) { $statement = 'SAVE TRANSACTION ' . $match[1]; } elseif (preg_match('#^\\s*ROLLBACK\\s+TO\\s+SAVEPOINT\\s+("?\\w+"?)\\s*$#i', $sql, $match)) { $statement = 'ROLLBACK TRANSACTION ' . $match[1]; } } $begin = FALSE; $commit = FALSE; $rollback = FALSE; // Track transactions since most databases don't support nesting if (preg_match('#^\\s*(BEGIN|START)(\\s+(TRAN|TRANSACTION|WORK))?\\s*$#iD', $sql)) { if ($this->inside_transaction) { throw new fProgrammerException('A transaction is already in progress'); } $this->inside_transaction = TRUE; $begin = TRUE; } elseif (preg_match('#^\\s*COMMIT(\\s+(TRAN|TRANSACTION|WORK))?\\s*$#iD', $sql)) { if (!$this->inside_transaction) { throw new fProgrammerException('There is no transaction in progress'); } $this->inside_transaction = FALSE; $commit = TRUE; } elseif (preg_match('#^\\s*ROLLBACK(\\s+(TRAN|TRANSACTION|WORK))?\\s*$#iD', $sql)) { if (!$this->inside_transaction) { throw new fProgrammerException('There is no transaction in progress'); } $this->inside_transaction = FALSE; $rollback = TRUE; // MySQL needs to use this construct for starting transactions when using LOCK tables } elseif ($this->type == 'mysql' && preg_match('#^\\s*SET\\s+autocommit\\s*=\\s*(0|1)#i', $sql, $match)) { $this->inside_transaction = TRUE; if ($match[1] == '0') { $this->schema_info['mysql_autocommit'] = TRUE; } else { unset($this->schema_info['mysql_autocommit']); } // We have to track LOCK TABLES for MySQL because UNLOCK TABLES only implicitly commits if LOCK TABLES was used } elseif ($this->type == 'mysql' && preg_match('#^\\s*LOCK\\s+TABLES#i', $sql)) { // This command always implicitly commits $this->inside_transaction = FALSE; $this->schema_info['mysql_lock_tables'] = TRUE; // MySQL has complex handling of UNLOCK TABLES } elseif ($this->type == 'mysql' && preg_match('#^\\s*UNLOCK\\s+TABLES#i', $sql)) { // This command only implicitly commits if LOCK TABLES was used if (isset($this->schema_info['mysql_lock_tables'])) { $this->inside_transaction = FALSE; } unset($this->schema_info['mysql_lock_tables']); // These databases issue implicit commit commands when the following statements are run } elseif ($this->type == 'mysql' && preg_match('#^\\s*(ALTER|CREATE(?!\\s+TEMPORARY)|DROP|RENAME|TRUNCATE|LOAD|UNLOCK|GRANT|REVOKE|SET\\s+PASSWORD|CACHE|ANALYSE|CHECK|OPTIMIZE|REPAIR|FLUSH|RESET)\\b#i', $sql)) { $this->inside_transaction = FALSE; } elseif ($this->type == 'oracle' && preg_match('#^\\s*(CREATE|ALTER|DROP|TRUNCATE|GRANT|REVOKE|REPLACE|ANALYZE|AUDIT|COMMENT)\\b#i', $sql)) { $this->inside_transaction = FALSE; } elseif ($this->type == 'db2' && preg_match('#^\\s*CALL\\s+SYSPROC\\.ADMIN_CMD\\(\'REORG\\s+TABLE\\b#i', $sql)) { $this->inside_transaction = FALSE; // It appears PDO tracks the transactions, but doesn't know about implicit commits if ($this->extension == 'pdo') { $this->connection->commit(); } } // If MySQL autocommit it set to 0 a new transaction is automatically started if (!empty($this->schema_info['mysql_autocommit'])) { $this->inside_transaction = TRUE; } if (!$begin && !$commit && !$rollback) { return FALSE; } // The PDO, OCI8 and SQLSRV extensions require special handling through methods and functions $is_pdo = $this->extension == 'pdo'; $is_oci = $this->extension == 'oci8'; $is_sqlsrv = $this->extension == 'sqlsrv'; $is_ibm_db2 = $this->extension == 'ibm_db2'; if (!$is_pdo && !$is_oci && !$is_sqlsrv && !$is_ibm_db2) { return FALSE; } $this->statement = $statement; // PDO seems to act weird if you try to start transactions through a normal query call if ($is_pdo) { try { $is_mssql = $this->type == 'mssql'; $is_oracle = $this->type == 'oracle'; if ($begin) { // The SQL Server PDO object hasn't implemented transactions if ($is_mssql) { $this->connection->exec('BEGIN TRANSACTION'); } elseif ($is_oracle) { $this->connection->setAttribute(PDO::ATTR_AUTOCOMMIT, FALSE); } else { $this->connection->beginTransaction(); } } elseif ($commit) { if ($is_mssql) { $this->connection->exec('COMMIT'); } elseif ($is_oracle) { $this->connection->exec('COMMIT'); $this->connection->setAttribute(PDO::ATTR_AUTOCOMMIT, TRUE); } else { $this->connection->commit(); } } elseif ($rollback) { if ($is_mssql) { $this->connection->exec('ROLLBACK'); } elseif ($is_oracle) { $this->connection->exec('ROLLBACK'); $this->connection->setAttribute(PDO::ATTR_AUTOCOMMIT, TRUE); } else { $this->connection->rollBack(); } } } catch (Exception $e) { $db_type_map = array('db2' => 'DB2', 'mssql' => 'MSSQL', 'mysql' => 'MySQL', 'oracle' => 'Oracle', 'postgresql' => 'PostgreSQL', 'sqlite' => 'SQLite'); throw new fSQLException('%1$s error (%2$s) in %3$s', $db_type_map[$this->type], $e->getMessage(), $sql); } } elseif ($is_oci) { if ($commit) { oci_commit($this->connection); } elseif ($rollback) { oci_rollback($this->connection); } } elseif ($is_sqlsrv) { if ($begin) { sqlsrv_begin_transaction($this->connection); } elseif ($commit) { sqlsrv_commit($this->connection); } elseif ($rollback) { sqlsrv_rollback($this->connection); } } elseif ($is_ibm_db2) { if ($begin) { db2_autocommit($this->connection, FALSE); } elseif ($commit) { db2_commit($this->connection); db2_autocommit($this->connection, TRUE); } elseif ($rollback) { db2_rollback($this->connection); db2_autocommit($this->connection, TRUE); } } if ($result_class) { $result = new $result_class($this); $result->setSQL($sql); $result->setResult(TRUE); return $result; } return TRUE; }
/** * Rollback a transaction * * @param unknown_type $model * @return boolean True on success, false on fail * (i.e. if the database/model does not support transactions, * or a transaction has not started). */ function rollback(&$model) { if (parent::rollback($model)) { $this->_transactionStarted = false; db2_autocommit($this->connection, DB2_AUTOCOMMIT_ON); return db2_rollback($this->connection); } return false; }
/** * @param integer $mode * @return void */ public function _setExecuteMode($mode) { switch ($mode) { case Db2_AUTOCOMMIT_OFF: case Db2_AUTOCOMMIT_ON: $this->_execute_mode = $mode; db2_autocommit($this->_connection, $mode); break; default: throw new Db2Exception("execution mode not supported"); break; } }
/** * Cancel a transaction */ protected function doRollback($fname = 'DatabaseIbm_db2::rollback') { db2_rollback($this->mConn); // turn auto-commit back on // not sure if this is appropriate db2_autocommit($this->mConn, DB2_AUTOCOMMIT_ON); $this->mTrxLevel = 0; }
function rollBack() { if (!db2_rollback($this->_conn)) { throw new DB2Exception(db2_conn_errormsg($this->_conn)); } db2_autocommit($this->_conn, DB2_AUTOCOMMIT_ON); }
/** * Execute data manipulation statement, then roll it back * @param $type * @param $table * @param $query * @return string */ protected function verifyGenericQueryRollback($type, $table, $query) { $db = $this->database; $this->log->debug("verifying {$type} statement"); $stmt = db2_prepare($db, $query); if (!$stmt) { return 'Cannot prepare statement'; } $ac = db2_autocommit($db); db2_autocommit($db, DB2_AUTOCOMMIT_OFF); // try query, but don't generate result set and do not commit $res = db2_execute($stmt, OCI_DESCRIBE_ONLY | OCI_NO_AUTO_COMMIT); // just in case, rollback all changes $error = $this->lastError(); db2_rollback($db); db2_free_stmt($stmt); // It would be a good idea to keep this and reuse it. db2_autocommit($db, $ac); if (!$res) { return 'Query failed to execute'; } return $error; }
public static function beginTransaction($conn) { return db2_autocommit($conn, DB2_AUTOCOMMIT_OFF); }
/** * Rollback * * @return Connection */ public function rollback() { if (!$this->isConnected()) { throw new Exception\RuntimeException('Must be connected before you can rollback.'); } if (!$this->inTransaction()) { throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback.'); } if (!db2_rollback($this->resource)) { throw new Exception\RuntimeException('The rollback has not been successful'); } if ($this->prevAutocommit) { db2_autocommit($this->resource, $this->prevAutocommit); } $this->inTransaction = false; return $this; }
/** * INSERT wrapper, inserts an array into a table * * $args may be a single associative array, or an array of these with numeric keys, * for multi-row insert * * @param array $table String: Name of the table to insert to. * @param array $args Array: Items to insert into the table. * @param array $fname String: Name of the function, for profiling * @param mixed $options String or Array. Valid options: IGNORE * * @return bool Success of insert operation. IGNORE always returns true. */ public function insert($table, $args, $fname = 'DatabaseIbm_db2::insert', $options = array()) { wfDebug("DB2::insert({$table})\n"); if (!count($args)) { return true; } $table = $this->tableName($table); if (!is_array($options)) { $options = array($options); } if (isset($args[0]) && is_array($args[0])) { } else { $args = array($args); } $keys = array_keys($args[0]); // If IGNORE is set, we use savepoints to emulate mysql's behavior $ignore = in_array('IGNORE', $options) ? 'mw' : ''; // Cache autocommit value at the start $oldautocommit = db2_autocommit($this->mConn); // If we are not in a transaction, we need to be for savepoint trickery $didbegin = 0; if (!$this->mTrxLevel) { $this->begin(); $didbegin = 1; } if ($ignore) { $olde = error_reporting(0); // For future use, we may want to track the number of actual inserts // Right now, insert (all writes) simply return true/false $numrowsinserted = 0; } $sql = "INSERT INTO {$table} (" . implode(',', $keys) . ') VALUES '; if (!$ignore) { $first = true; foreach ($args as $row) { if ($first) { $first = false; } else { $sql .= ','; } $sql .= '(' . $this->makeListSmart($table, $row) . ')'; } $res = (bool) $this->query($sql, $fname, $ignore); } else { $res = true; $origsql = $sql; foreach ($args as $row) { $tempsql = $origsql; $tempsql .= '(' . $this->makeListSmart($table, $row) . ')'; if ($ignore) { db2_exec($this->mConn, "SAVEPOINT {$ignore}"); } $tempres = (bool) $this->query($tempsql, $fname, $ignore); if ($ignore) { $bar = db2_stmt_error(); if ($bar != false) { db2_exec($this->mConn, "ROLLBACK TO SAVEPOINT {$ignore}"); } else { db2_exec($this->mConn, "RELEASE SAVEPOINT {$ignore}"); $numrowsinserted++; } } // If any of them fail, we fail overall for this function call // Note that this will be ignored if IGNORE is set if (!$tempres) { $res = false; } } } if ($didbegin) { $this->commit(); } else { if ($oldautocommit) { $this->commit(); } } if ($ignore) { $olde = error_reporting($olde); // Set the affected row count for the whole operation $this->mAffectedRows = $numrowsinserted; // IGNORE always returns true return true; } return $res; }
protected function _auto_commit($curr, $new) { if (!$curr && $new) { $this->commit(false); } if (!$new) { $status = db2_autocommit($this->handle, DB2_AUTOCOMMIT_OFF); } else { $status = db2_autocommit($this->handle, DB2_AUTOCOMMIT_ON); } if ($status) { if (!$new && !$this->trans_started) { $this->start_trans(); } else { $this->trans_started = false; } return true; } return false; }
function DBrollback() { global $DB; $result = false; if (isset($DB['DB']) && !empty($DB['DB'])) { switch ($DB['TYPE']) { case 'MYSQL': $result = DBexecute('rollback'); break; case 'POSTGRESQL': $result = DBexecute('rollback'); break; case 'ORACLE': $result = ocirollback($DB['DB']); break; case 'IBM_DB2': $result = db2_rollback($DB['DB']); db2_autocommit($DB['DB'], DB2_AUTOCOMMIT_ON); break; case 'SQLITE3': $result = DBexecute('rollback'); unlock_db_access(); break; } } return $result; }