HEX
Server: Apache/2.2.15 (CentOS)
System: Linux ip-10-0-2-146.eu-west-1.compute.internal 2.6.32-754.35.1.el6.centos.plus.x86_64 #1 SMP Sat Nov 7 11:33:42 UTC 2020 x86_64
User: root (0)
PHP: 5.6.40
Disabled: NONE
Upload Files
File: /www/exchange0old/exchange/Bin/Db.php
<?php

class Bin_Db {

    static protected $instances = array();

	/**
     * @var mysqli
     *
     */
    protected $connection = null;
	protected $configPrefix;
	protected $saveQueries = false;
	protected $queries = array();
	protected $lastError = '';
	protected $transactionStatus = false;
	protected $transactionDepth = 0;
	protected $escapeIdentifierCharacter = '`';
	protected $escapeValueCharacter = "'";

	/**
	 * @param null $group
	 * @return $this
	 */
	public static function connect($group = null) {
        if (!isset(self::$instances[$group])) {
            self::$instances[$group] = new self($group);
        }
        return self::$instances[$group];
	}

    protected function __construct($group = null) {
        $this->configPrefix = 'database.' . ($group !== null ? $group . '.' : '');
        $this->setSaveQueries($this->getConfig('saveQueries', false));
        $this->initialize();
	}

	protected function initialize() {
        $this->connection = mysqli_init();
        $this->connection->real_connect(
            $this->getConfig('hostname'),
			$this->getConfig('username'),
			$this->getConfig('password'),
			$this->getConfig('database'));
	}

    public function getConfig($key, $default = null) {
        return Bin_Config::get($this->configPrefix.$key, $default);
	}

	public function affectedRows() {
        return $this->connection->affected_rows;
	}

	public function insertID() {
        return $this->connection->insert_id;
	}

	public function prefixTable($table) {
        return $this->getConfig('prefix') . $table;
	}

	public function getConnection() {
        return $this->connection;
	}

	/**
	 * Executes the query against the database.
	 *
	 * @param $sql
	 *
	 * @return mixed
	 */
    public function execute($sql) {
        return $this->connection->query($this->prepQuery($sql));
	}

	/**
	 * Prep the query
	 *
	 * If needed, each database adapter can prep the query string
	 *
	 * @param    string $sql an SQL query
	 *
	 * @return    string
	 */
    protected function prepQuery($sql) {
        // mysqli_affected_rows() returns 0 for "DELETE FROM TABLE" queries. This hack
		// modifies the query so that a proper number of affected rows is returned.
		if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql)) {
			return trim($sql) . ' WHERE 1 = 1';
		}
		return $sql;
	}

	public function query($sql, array $binds = array()) {
        $startTime = microtime(true);

		// Replace bind parts
		$sql = $binds ? strtr($sql, $binds) : $sql;

		if (false === ($result = $this->execute($sql))) {
            $this->lastError = $this->connection->error;
            if ($this->saveQueries) {
                $this->queries[] = $this->getStats($sql, $startTime, $startTime);
			}
			return false;
        }

        if ($this->saveQueries) {
            $this->queries[] = $this->getStats($sql, $startTime);
        }

		// For create table, struct, etc queries
        return new Bin_Db_Result($this, $result);
	}

	protected function getStats($query, $startTime, $endTime = null) {
        if($endTime === null) {
            $endTime = microtime(true);
        }

        return array(
            'query' => $query,
			'start' => $startTime,
			'duration' => $endTime-$startTime);
	}

    protected function beginTransaction($mode = null) {
        $this->connection->autocommit(false);

        if ($mode && !$this->query("SET TRANSACTION ISOLATION LEVEL $mode")) {
            throw new Exception($this->getLastError());
        }

        return (bool)$this->query('START TRANSACTION');
	}

	protected function finishTransaction() {
        if ((bool) $this->query('COMMIT')) {
            $this->connection->autocommit(true);
            return true;
		}
        return false;
	}

	protected function cancelTransaction() {
        if ((bool) $this->query('ROLLBACK')) {
            $this->connection->autocommit(true);
            return true;
		}
        return false;
    }

    public function transactionStart($mode = null) {
        if ($this->transactionDepth === 0) {
            $result = $this->beginTransaction($mode);
		} else {
            $result = (bool)$this->query("SAVEPOINT LEVEL{$this->transactionDepth}");
		}
		$this->transactionDepth++;
		return $result;
	}

	public function transactionCommit() {
        $this->transactionDepth--;

		if ($this->transactionDepth === 0) {
			return $this->finishTransaction();
		}
        return (bool)$this->query("RELEASE SAVEPOINT LEVEL{$this->transactionDepth}");
	}

	public function transactionRollback() {
        $this->transactionDepth--;

        if ($this->transactionDepth === 0) {
            return $this->cancelTransaction();
        }
        return (bool)$this->query("ROLLBACK TO SAVEPOINT LEVEL{$this->transactionDepth}");
	}

    public function getLastError() {
        return $this->lastError;
	}

	/**
	 * @return bool|mixed|null
	 */
    public function getSaveQueries() {
        return $this->saveQueries;
    }

    /**
	 * @param bool $saveQueries
	 * @return $this
	 */
	public function setSaveQueries($saveQueries) {
        $this->saveQueries = $saveQueries;
        return $this;
    }

    public function getQueriesLog() {
        return $this->queries;
    }

    /**
	 * Escapes special characters in a string for use in an SQL statement, taking into account the current charset of the connection
	 * @param $string
	 * @return string
	 */
	public function escapeString($string) {
        return $this->connection->escape_string($string);
	}

	public function escapeValue($value) {
        if ($value instanceof Bin_Db_Expr) {
            return $value->getExpr();
		}

        if (is_bool($value)) {
            $value = (int)$value;
        }

        if (is_null($value)) {
            return 'NULL';
        }

        if (is_numeric($value)) {
            return $value;
        }

        if ($value instanceof DateTime) {
            $value = $value->format('Y-m-d H:i:s');
        }

		if (is_array($value)) {
            return array_map(array($this, __FUNCTION__), $value);
		}
		return $this->escapeValueCharacter . $this->connection->escape_string($value) . $this->escapeValueCharacter;
	}

	public function escapeIdentifier($identifier) {
        return $this->escapeIdentifierCharacter . $identifier . $this->escapeIdentifierCharacter;
	}

	public function builder() {
        return new Bin_Db_Builder($this);
	}

    public function getTransactionDepth() {
        return $this->transactionDepth;
    }
}