예제 #1
0
 /**
  * @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;
     }
 }
예제 #2
0
 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;
 }
예제 #3
0
 /**
  * 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;
 }
예제 #4
0
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;
}
예제 #5
0
 /**
  * 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;';
 }
예제 #6
0
 /**
  * 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;
 }
예제 #7
0
 /**
  * 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;
 }
예제 #8
0
파일: Db2.php 프로젝트: rafalwrzeszcz/zf2
 /**
  * @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;
     }
 }
예제 #9
0
 /**
  * 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;
 }
예제 #10
0
 function rollBack()
 {
     if (!db2_rollback($this->_conn)) {
         throw new DB2Exception(db2_conn_errormsg($this->_conn));
     }
     db2_autocommit($this->_conn, DB2_AUTOCOMMIT_ON);
 }
예제 #11
0
 /**
  * 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;
 }
예제 #12
0
 public static function beginTransaction($conn)
 {
     return db2_autocommit($conn, DB2_AUTOCOMMIT_OFF);
 }
예제 #13
0
 /**
  * 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;
 }
예제 #14
0
 /**
  * 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;
 }
예제 #15
0
 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;
 }
예제 #16
0
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;
}