Our team created for you one of the most innovative CRM systems that supports mainly business processes and allows for customization according to your needs. Be ahead of your competition and implement YetiForce!
<?php /***** The contents of this file are subject to the SugarCRM Public License Version 1.1.2 ("License"); You may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.sugarcrm.com/SPL 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. The Original Code is: SugarCRM Open Source The Initial Developer of the Original Code is SugarCRM, Inc. Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.; All Rights Reserved. Contributor(s): YetiForce.com ** */
class PearDatabase { protected $database; protected $stmt = false; public $dieOnError = false; private static $dbCache = false; protected $dbType; protected $dbHostName; protected $dbName; protected $userName; protected $userPassword; protected $port; // If you want to avoid executing PreparedStatement, set this to true // PreparedStatement will be converted to normal SQL statement for execution protected $avoidPreparedSql = false;
/ Performance tunning parameters (can be configured through performance.prefs.php) See the constructor for initialization. */ protected $isdb_default_utf8_charset = false; protected $hasActiveTransaction = false; protected $hasFailedTransaction = false; protected $transCnt = 0; protected $autoCommit = false;
const DEFAULT_QUOTE = '';<br><br> protected $types = [<br> PDO::PARAM_BOOL => 'bool',<br> PDO::PARAM_NULL => 'null',<br> PDO::PARAM_INT => 'int',<br> PDO::PARAM_LOB => 'blob',<br> PDO::PARAM_STR => 'string',<br> PDO::PARAM_STMT => 'statement',<br> ];<br><br> /**<br> * Constructor.<br> */<br> public function __construct($dbtype = '', $host = '', $dbname = '', $username = '', $passwd = '', $port = 3306)<br> {<br> $this->loadDBConfig($dbtype, $host, $dbname, $username, $passwd, $port);<br> $this->isdb_default_utf8_charset = AppConfig::performance('DB_DEFAULT_CHARSET_UTF8');<br> $this->setDieOnError(AppConfig::debug('SQL_DIE_ON_ERROR'));<br> $this->connect();<br> }<br><br> /**<br> * Manage instance usage of this class.<br> */<br> public static function &getInstance($type = 'base')<br> {<br> if (self::$dbCache !== false) {<br> return self::$dbCache;<br> }<br> $config = AppConfig::main('dbconfig');<br> if ($config === false) {<br> include 'config/config.inc.php';<br> if (file_exists('config/config_override.php')) {<br> include 'config/config_override.php';<br> }<br> $config = $dbconfig;<br> }<br> $db = new self($config['db_type'], $config['db_server'], $config['db_name'], $config['db_username'], $config['db_password'], $config['db_port']);<br><br> if ($db->database === null) {<br> \App\Log::error('Database getInstance: Error connecting to the database', 'error');<br> $db->checkError('Error connecting to the database');<br><br> return false;<br> } else {<br> self::$dbCache = $db;<br> }<br> return $db;<br> }<br><br> public function connect()<br> {<br> // Set DSN<br> $dsn = $this->dbType . ':host=' . $this->dbHostName . ';dbname=' . $this->dbName . ';port=' . $this->port;<br><br> // Set options<br> $options = [<br> PDO::ATTR_EMULATE_PREPARES => false,<br> PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,<br> PDO::ATTR_TIMEOUT => 5,<br> ];<br> // Create a new PDO instanace<br> try {<br> $this->database = new PDO($dsn, $this->userName, $this->userPassword, $options);<br> $this->database->exec('SET NAMES ' . $this->database->quote('utf8'));<br> } catch (\App\Exceptions\AppException $e) {<br> // Catch any errors<br> \App\Log::error('Database connect : ' . $e->getMessage());<br> $this->checkError($e->getMessage());<br> }<br> }<br><br> protected function loadDBConfig($dbtype, $host, $dbname, $username, $passwd, $port)<br> {<br> if ($host == '_SERVER_') {<br> \App\Log::error('No configuration for the database connection');<br> }<br> $this->dbType = $dbtype;<br> $this->dbHostName = $host;<br> $this->dbName = $dbname;<br> $this->userName = $username;<br> $this->userPassword = $passwd;<br> $this->port = $port;<br> }<br><br> public function setDBCache()<br> {<br> self::$dbCache = $this;<br> }<br><br> public function getDatabaseName()<br> {<br> return $this->dbName;<br> }<br><br> public function println($msg)<br> {<br> return $msg;<br> }<br><br> public function checkError($message, $dieOnError = false, $query = false, $params = false)<br> {<br> if ($this->hasActiveTransaction) {<br> $this->rollbackTransaction();<br> }<br> if ($this->dieOnError || $dieOnError) {<br> $backtrace = false;<br> if (AppConfig::debug('DISPLAY_EXCEPTION_BACKTRACE')) {<br> $backtrace = \App\Debuger::getBacktrace();<br> }<br> $message = [<br> 'message' => $message,<br> 'trace' => $backtrace,<br> 'query' => $query,<br> 'params' => $params,<br> ];<br> vtlib\Functions::throwNewException($message, true, 'DatabaseException.tpl');<br> }<br> }<br><br> public function errorMsg()<br> {<br> $error = $this->database->errorInfo();<br><br> return $error[2];<br> }<br><br> public function isMySQL()<br> {<br> return stripos($this->dbType, 'mysql') === 0;<br> }<br><br> public function isOracle()<br> {<br> return $this->dbType == 'oci8';<br> }<br><br> public function isPostgres()<br> {<br> return $this->dbType == 'pgsql';<br> }<br><br> public function setDieOnError($value)<br> {<br> $this->dieOnError = $value;<br> }<br><br> public function setAttribute($attribute, $value)<br> {<br> $this->database->setAttribute($attribute, $value);<br> }<br><br> public function startTransaction()<br> {<br> $this->transCnt += 1;<br><br> if ($this->hasActiveTransaction) {<br> return $this->hasActiveTransaction;<br> } else {<br> $this->autoCommit = false;<br> $this->hasActiveTransaction = $this->database->beginTransaction();<br><br> return $this->hasActiveTransaction;<br> }<br> }<br><br> public function completeTransaction()<br> {<br> $this->transCnt -= 1;<br><br> if ($this->transCnt == 0) {<br> $this->database->commit();<br> $this->autoCommit = false;<br> $this->hasActiveTransaction = false;<br> }<br> }<br><br> public function hasFailedTransaction()<br> {<br> return $this->hasFailedTransaction;<br> }<br><br> public function rollbackTransaction()<br> {<br> if ($this->hasActiveTransaction) {<br> $this->hasFailedTransaction = true;<br> $result = $this->database->rollback();<br> $this->autoCommit = false;<br> $this->transCnt -= 1;<br><br> return $result;<br> }<br> return false;<br> }<br><br> public function getRowCount(PDOStatement $result)<br> {<br> if (method_exists($result, 'rowCount')) {<br> return $result->rowCount();<br> }<br> App\Log::warning('No rowCount function');<br><br> return 0;<br> }<br><br> public function numRows(PDOStatement $result)<br> {<br> return $result->rowCount();<br> }<br><br> public function getFieldsCount(PDOStatement $result)<br> {<br> return $result->columnCount();<br> }<br><br> public function fetchArray(PDOStatement $result)<br> {<br> return $result->fetch(PDO::FETCH_ASSOC);<br> }<br><br> public function getSingleValue(PDOStatement $result)<br> {<br> return $result->fetchColumn();<br> }<br><br> public function getRow(PDOStatement $result)<br> {<br> return $result->fetch(PDO::FETCH_ASSOC);<br> }<br><br> public function getColumnByGroup(PDOStatement $result)<br> {<br> return $result->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_COLUMN);<br> }<br><br> public function getArray(PDOStatement $result)<br> {<br> return $result->fetchAll(PDO::FETCH_ASSOC);<br> }<br><br> public function getArrayColumn(PDOStatement $result, $column = 0)<br> {<br> return $result->fetchAll(PDO::FETCH_COLUMN, $column);<br> }<br><br> public function disconnect()<br> {<br> if (isset($this->database)) {<br> unset($this->database);<br> }<br> }<br><br> public function query($query, $dieOnError = false, $msg = '')<br> {<br> $this->stmt = false;<br> $sqlStartTime = microtime(true);<br><br> try {<br> \App\Log::beginProfile($query, __METHOD__);<br> $this->stmt = $this->database->query($query);<br> \App\Log::endProfile($query, __METHOD__);<br><br> $this->logSqlTime($sqlStartTime, microtime(true), $query);<br> } catch (PDOException $e) {<br> $error = $this->database->errorInfo();<br> \App\Log::error($msg . 'Query Failed: ' . $query . ' | ' . $error[2] . ' | ' . $e->getMessage());<br> $this->checkError($e->getMessage(), $dieOnError, $query);<br> }<br> return $this->stmt;<br> }<br><br> /* Prepared statement Execution<br> * @param $sql -- Prepared sql statement<br> * @param $params -- Parameters for the prepared statement<br> * @param $dieOnError -- Set to true, when query execution fails<br> * @param $msg -- Error message on query execution failure<br> */<br><br> public function pquery($query, $params = [], $dieOnError = false, $msg = '')<br> {<br> $this->stmt = false;<br> $sqlStartTime = microtime(true);<br> $params = $this->flattenArray($params);<br> if (empty($params)) {<br> return $this->query($query, $dieOnError, $msg);<br> }<br> try {<br> $this->stmt = $this->database->prepare($query);<br><br> \App\Log::beginProfile($query, __METHOD__);<br> $this->stmt->execute($params);<br> \App\Log::endProfile($query, __METHOD__);<br><br> $this->logSqlTime($sqlStartTime, microtime(true), $query, $params);<br> } catch (PDOException $e) {<br> $error = $this->database->errorInfo();<br> \App\Log::error($msg . 'Query Failed: ' . $query . ' | ' . $error[2] . ' | ' . $e->getMessage());<br> $this->checkError($e->getMessage(), $dieOnError, $query, $params);<br> }<br> return $this->stmt;<br> }<br><br> public function prepare($query)<br> {<br> $this->stmt = $this->database->prepare($query);<br><br> return $this->stmt;<br> }<br><br> public function bind($param, $value, $type = null)<br> {<br> if (is_null($type)) {<br> switch (true) {<br> case is_int($value):<br> $type = PDO::PARAM_INT;<br> break;<br> case is_bool($value):<br> $type = PDO::PARAM_BOOL;<br> break;<br> case is_null($value):<br> $type = PDO::PARAM_NULL;<br> break;<br> default:<br> $type = PDO::PARAM_STR;<br> }<br> }<br> $this->stmt->bindValue($param, $value, $type);<br> }<br><br> public function execute()<br> {<br> try {<br> $this->stmt->execute($params);<br> $this->logSqlTime($sqlStartTime, microtime(true), $query, $params);<br> } catch (\App\Exceptions\AppException $e) {<br> $error = $this->database->errorInfo();<br> \App\Log::error($msg . 'Query Failed: ' . $query . ' | ' . $error[2] . ' | ' . $e->getMessage());<br> $this->checkError($e->getMessage());<br> }<br> return $this->stmt;<br> }<br><br> /**<br> * A function to insert data into the database.<br> *<br> * @param string $table Table name<br> * @param array $data Query data<br> *<br> * @return array Row count and last insert id<br> */<br> public function insert($table, array $data)<br> {<br> if (!$table) {<br> \App\Log::error('Missing table name');<br> $this->checkError('Missing table name');<br><br> return false;<br> } elseif (!is_array($data)) {<br> \App\Log::error('Missing data, data must be an array');<br> $this->checkError('Missing table name');<br><br> return false;<br> }<br> $columns = '';<br> foreach ($data as $column => $cur) {<br> $columns .= ($columns ? ',' : '') . $this->quote($column, false);<br> }<br> $insert = 'INSERT INTO ' . $this->quote($table, false) . ' (' . $columns . ') VALUES (' . $this->generateQuestionMarks($data) . ')';<br> $this->pquery($insert, $data);<br><br> return ['rowCount' => $this->stmt->rowCount(), 'id' => $this->database->lastInsertId()];<br> }<br><br> /**<br> * A function to remove data from the database.<br> *<br> * @param string $table Table name<br> * @param string $where Conditions<br> * @param array $params Query data<br> *<br> * @return int Number of deleted records<br> */<br> public function delete($table, $where = '', array $params = [])<br> {<br> if (!$table) {<br> \App\Log::error('Missing table name');<br> $this->checkError('Missing table name');<br><br> return false;<br> }<br> if ($where != '') {<br> $where = sprintf('WHERE %s', $where);<br> }<br> if (count($params) === 0) {<br> $this->query(sprintf('DELETE FROM %s %s', $table, $where));<br> } else {<br> $this->pquery(sprintf('DELETE FROM %s %s', $table, $where), $params);<br> }<br> return $this->stmt->rowCount();<br> }<br><br> /**<br> * A function to update data in the database.<br> *<br> * @param string $table Table name<br> * @param array $columns Columns to update<br> * @param string $where Conditions<br> * @param array $params Query data<br> *<br> * @return int Number of updated records<br> */<br> public function update($table, array $columns, $where = false, array $params = [])<br> {<br> $query = "UPDATE $table SET ";<br> foreach ($columns as $column => $value) {<br> $query .= $this->quote($column, false) . ' = ?,';<br> $values[] = $value;<br> }<br> $query = trim($query, ',');<br> if ($where !== false) {<br> $query .= sprintf(' WHERE %s', $where);<br> }<br> $this->pquery(trim($query, ','), [array_merge($values, $params)]);<br><br> return $this->stmt->rowCount();<br> }<br><br> public function queryResult(&$result, $row, $col = 0)<br> {<br> return $this->queryResultRaw($result, $row, $col);<br> }<br><br> public function queryResultRaw(&$result, $row, $col = 0)<br> {<br> if (!is_object($result)) {<br> \App\Log::error('Result is not an object');<br> $this->checkError('Result is not an object');<br> }<br><br> if (!isset($result->tmp)) {<br> $result->tmp = $result->fetchAll(PDO::FETCH_ASSOC);<br> }<br> if (!isset($result->tmp[$row]) || !isset($result->tmp[$row][$col])) {<br> return null;<br> }<br> return $result->tmp[$row][$col];<br> }<br><br> // Function to get particular row from the query result<br> public function queryResultRowData(&$result, $row = 0)<br> {<br> return $this->rawQueryResultRowData($result, $row);<br> }<br><br> /**<br> * Get an array representing a row in the result set<br> * Unlike it's non raw siblings this method will not escape<br> * html entities in return strings.<br> *<br> * The case of all the field names is converted to lower case.<br> * as with the other methods.<br> *<br> * @param &$result The query result to fetch from<br> * @param $row The row number to fetch. It's default value is 0<br> */<br> public function rawQueryResultRowData(&$result, $row = 0)<br> {<br> if (!is_object($result)) {<br> \App\Log::error('Result is not an object');<br> $this->checkError('Result is not an object');<br> }<br> if (!isset($result->tmp)) {<br> $result->tmp = $result->fetchAll(PDO::FETCH_ASSOC);<br> }<br> return $result->tmp[$row];<br> }<br><br> /**<br> * Flatten the composite array into single value.<br> * Example:<br> * $input = array(10, 20, array(30, 40), array('key1' => '50', 'key2'=>array(60), 70));<br> * returns array(10, 20, 30, 40, 50, 60, 70);.<br> */<br> public function flattenArray($input, $output = null)<br> {<br> if (empty($input)) {<br> return null;<br> }<br> if (empty($output)) {<br> $output = [];<br> }<br> foreach ($input as $value) {<br> if (is_array($value)) {<br> $output = $this->flattenArray($value, $output);<br> } else {<br> array_push($output, $value);<br> }<br> }<br> return $output;<br> }<br><br> public function getColumnNames($tablename)<br> {<br> $stmt = $this->database->query('SHOW COLUMNS FROM ' . $tablename, PDO::FETCH_OBJ);<br> $columns = [];<br> foreach ($stmt as $col) {<br> $columns[] = $col->Field;<br> }<br> return $columns;<br> }<br><br> public function getColumnsMeta($tablename)<br> {<br> $stmt = $this->database->query('SHOW COLUMNS FROM ' . $tablename, PDO::FETCH_OBJ);<br> $columns = [];<br> foreach ($stmt as $col) {<br> if (strpos($col->Type, '(') !== false) {<br> $showType = explode('(', $col->Type); //PREG_SPLIT IS BETTER<br> }<br> $type = $showType[0];<br> $vals = explode(')', $showType[1]);<br> if (is_int((int) $vals[0])) {<br> $maxLength = $vals[0];<br> } elseif (strpos($vals[0], ',') !== false) {<br> $vs = explode(',', $vals[0]);<br> $vs = array_map('str_replace', $vs, ['\'', '', $vs[0]]);<br> $maxLength = [];<br> foreach ($vs as $v) {<br> $maxLength[] = $v;<br> }<br> }<br> $column = new stdClass();<br> $column->name = $col->Field;<br> $column->notNull = $col->null == 'NO' ? true : false;<br> $column->primaryKey = $col->Key == 'PRI' ? true : false;<br> $column->uniqueKey = $col->Key == 'UNI' ? true : false;<br> $column->hasDefault = $col->Default === null ? false : true;<br> if ($column->hasDefault) {<br> $column->default = $col->Default;<br> }<br> $column->maxLength = $maxLength;<br> $column->type = $type;<br> $columns[strtoupper($column->name)] = $column;<br> }<br> return $columns;<br> }<br><br> public function updateBlob($table, $column, $val, $where)<br> {<br> $success = $this->pquery("UPDATE $table SET $column=? WHERE $where", [$val]);<br><br> return $success;<br> }<br><br> public function getEmptyBlob()<br> {<br> return 'null';<br> }<br><br> public function fetchByAssoc(&$result, $rowNum = -1)<br> {<br> if (isset($result) && $rowNum < 0) {<br> $row = $this->getRow($result);<br><br> return $row;<br> }<br> if ($this->getRowCount($result) > $rowNum) {<br> $row = $this->rawQueryResultRowData($result, $rowNum);<br> }<br> return $row;<br> }<br><br> //To get a function name with respect to the database type which escapes strings in given text<br> public function sqlEscapeString($str, $type = false)<br> {<br> if ($type) {<br> $search = ['\\', "\0", "\n", "\r", "\x1a", "'", '"'];<br> $replace = ['\\\\', '\\0', '\\n', '\\r', "\Z", "\'", '\"'];<br><br> return str_replace($search, $replace, $str);<br> } else {<br> return $this->database->quote($str);<br> }<br> }<br><br> public function getUniqueID($seqname)<br> {<br> $tableName = $seqname . '_seq';<br> if ($this->checkExistTable($tableName)) {<br> $result = $this->query(sprintf('SELECT id FROM %s', $tableName));<br> $id = ((int) $this->getSingleValue($result)) + 1;<br> $this->database->query("update $tableName set id = $id");<br> } else {<br> $result = $this->query('SHOW COLUMNS FROM ' . $this->quote($seqname, false));<br> $column = $this->getSingleValue($result);<br> $result = $this->query("SELECT MAX($column ) AS max FROM " . $this->quote($seqname, false));<br> $id = ((int) $this->getSingleValue($result)) + 1;<br> }<br> return $id;<br> }<br><br> public function checkExistTable($tableName, $cache = true)<br> {<br> $tablePresent = Vtiger_Cache::get('checkExistTable', $tableName);<br> if ($tablePresent !== false && $cache) {<br> return $tablePresent;<br> }<br><br> $dieOnError = $this->dieOnError;<br> $this->dieOnError = false;<br><br> $tablename = $this->sqlEscapeString($tableName);<br> $tableCheck = $this->query("SHOW TABLES LIKE $tablename");<br> $tablePresent = 1;<br> if (empty($tableCheck) || $this->getRowCount($tableCheck) === 0) {<br> $tablePresent = 0;<br> }<br> $this->dieOnError = $dieOnError;<br> Vtiger_Cache::set('checkExistTable', $tableName, $tablePresent);<br><br> return $tablePresent;<br> }<br><br> // Function to get the last insert id based on the type of database<br> public function getLastInsertID()<br> {<br> $lastInsertID = $this->database->lastInsertId();<br><br> return $lastInsertID;<br> }<br><br> public function formatDate($datetime, $strip_quotes = false)<br> {<br> // remove single quotes to use the date as parameter for Prepared statement<br> if ($strip_quotes === true) {<br> return trim($datetime, "'");<br> }<br> return $datetime;<br> }<br><br> public function getOne($sql, $dieOnError = false, $msg = '')<br> {<br> $result = $this->query($sql, $dieOnError, $msg);<br> $val = $this->getSingleValue($result);<br><br> return $val;<br> }<br><br> public function getFieldsDefinition(PDOStatement $result)<br> {<br> $fieldArray = [];<br> if (!isset($result) || empty($result)) {<br> return 0;<br> }<br> foreach (range(0, $result->columnCount() - 1) as $columnIndex) {<br> $meta = $result->getColumnMeta($columnIndex);<br> $column = new stdClass();<br> $column->name = $meta['name'];<br> $column->type = $this->types[$meta['pdo_type']];<br> $column->max_length = $meta['len'];<br> array_push($fieldArray, $column);<br> }<br> return $fieldArray;<br> }<br><br> public function getFieldsArray(PDOStatement $result)<br> {<br> $fieldArray = [];<br> if (!isset($result) || empty($result)) {<br> return 0;<br> }<br> foreach (range(0, $result->columnCount() - 1) as $columnIndex) {<br> $meta = $result->getColumnMeta($columnIndex);<br> array_push($fieldArray, $meta['name']);<br> }<br> return $fieldArray;<br> }<br><br> /**<br> * Function to generate question marks for a given list of items.<br> */<br> public function generateQuestionMarks($items)<br> {<br> // array_map will call the function specified in the first parameter for every element of the list in second parameter<br> return implode(',', array_map(function ($a) {<br> return '?';<br> }, is_array($items) ? $items : explode(',', $items)));<br> }<br><br> public function concat($columns, $space = '" "')<br> {<br> $concat = 'CONCAT(';<br> foreach ($columns as $key => $column) {<br> if ($key != 0 && $space) {<br> $concat .= $space . ',';<br> }<br> $concat .= $column . ',';<br> }<br> return rtrim($concat, ',') . ')';<br> }<br><br> // create an IN expression from an array/list<br> public function sqlExprDatalist($array)<br> {<br> if (!is_array($array)) {<br> \App\Log::error('sqlExprDatalist: not an array');<br> $this->checkError('sqlExprDatalist: not an array');<br> }<br> if (!count($array)) {<br> \App\Log::error('sqlExprDatalist: empty arrays not allowed');<br> $this->checkError('sqlExprDatalist: empty arrays not allowed');<br> }<br> foreach ($array as $key => $val) {<br> $l .= ($l ? ',' : '') . $this->quote($val);<br> }<br> return ' ( ' . $l . ' ) ';<br> }<br><br> public function getAffectedRowCount(PDOStatement $result)<br> {<br> $rows = $result->rowCount();<br><br> return $rows;<br> }<br><br> public function requirePsSingleResult($sql, $params, $dieOnError = false, $msg = '')<br> {<br> $result = $this->pquery($sql, $params, $dieOnError, $msg);<br><br> if ($this->getRowCount($result) == 1) {<br> return $result;<br> }<br> \App\Log::error('Rows Returned:' . $this->getRowCount($result) . ' More than 1 row returned for ' . $sql);<br> $this->checkError('Rows Returned:' . $this->getRowCount($result) . ' More than 1 row returned for ' . $sql, $dieOnError);<br><br> return '';<br> }<br><br> public function columnMeta(PDOStatement $result, $col)<br> {<br> $meta = $result->getColumnMeta($col);<br> $column = new stdClass();<br> $column->name = $meta['name'];<br> $column->type = $this->types[$meta['pdo_type']];<br> $column->max_length = $meta['len'];<br><br> return $column;<br> }<br><br> public function quote($input, $quote = true, $type = null)<br> {<br> // handle int directly for better performance<br> if ($type == 'integer' || $type == 'int') {<br> return (int) $input;<br> }<br><br> if (is_null($input)) {<br> return 'NULL';<br> }<br><br> $map = [<br> 'bool' => PDO::PARAM_BOOL,<br> 'integer' => PDO::PARAM_INT,<br> ];<br><br> <span style="background-color:#f1c40f;"> $type = $map[$type] ?? PDO::PARAM_STR;</span><br><br> if ($quote) {<br> return strtr($this->database->quote($input, $type), [self::DEFAULT_QUOTE => self::DEFAULT_QUOTE . self::DEFAULT_QUOTE]);<br> } else {<br> return self::DEFAULT_QUOTE . $input . self::DEFAULT_QUOTE;<br> }<br> }<br><br> // SQLTime logging<br><br> protected $logSqlTimeID = false;<br> protected $logSqlTimeGroup = 1;<br><br> public function logSqlTime($startat, $endat, $sql, $params = false)<br> {<br> if (!AppConfig::performance('SQL_LOG_INCLUDE_CALLER')) {<br> return;<br> }<br> $db = self::getInstance('log');<br> $now = date('Y-m-d H:i:s');<br> $group = $this->logSqlTimeGroup;<br> $logTable = 'l_yf_sqltime';<br> $logQuery = 'INSERT INTO ' . $logTable . '(id,type,qtime,content,date,group`) VALUES (?,?,?,?,?,?)';
if ($this->logSqlTimeID === false) { $stmt = $db->database->query(sprintf('SELECT MAX(id) FROM %s', $logTable)); $this->logSqlTimeID = (int) $this->getSingleValue($stmt) + 1;
<?php
/ *****
The contents of this file are subject to the SugarCRM Public License Version 1.1.2
("License"); You may not use this file except in compliance with the
License. You may obtain a copy of the License at http://www.sugarcrm.com/SPL
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.
The Original Code is: SugarCRM Open Source
The Initial Developer of the Original Code is SugarCRM, Inc.
Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.;
All Rights Reserved.
Contributor(s): YetiForce.com
** */
class PearDatabase
{
protected $database;
protected $stmt = false;
public $dieOnError = false;
private static $dbCache = false;
protected $dbType;
protected $dbHostName;
protected $dbName;
protected $userName;
protected $userPassword;
protected $port;
// If you want to avoid executing PreparedStatement, set this to true
// PreparedStatement will be converted to normal SQL statement for execution
protected $avoidPreparedSql = false;
/
Performance tunning parameters (can be configured through performance.prefs.php)
See the constructor for initialization.
*/
protected $isdb_default_utf8_charset = false;
protected $hasActiveTransaction = false;
protected $hasFailedTransaction = false;
protected $transCnt = 0;
protected $autoCommit = false;
const DEFAULT_QUOTE = '
';<br><br> protected $types = [<br> PDO::PARAM_BOOL => 'bool',<br> PDO::PARAM_NULL => 'null',<br> PDO::PARAM_INT => 'int',<br> PDO::PARAM_LOB => 'blob',<br> PDO::PARAM_STR => 'string',<br> PDO::PARAM_STMT => 'statement',<br> ];<br><br> /**<br> * Constructor.<br> */<br> public function __construct($dbtype = '', $host = '', $dbname = '', $username = '', $passwd = '', $port = 3306)<br> {<br> $this->loadDBConfig($dbtype, $host, $dbname, $username, $passwd, $port);<br> $this->isdb_default_utf8_charset = AppConfig::performance('DB_DEFAULT_CHARSET_UTF8');<br> $this->setDieOnError(AppConfig::debug('SQL_DIE_ON_ERROR'));<br> $this->connect();<br> }<br><br> /**<br> * Manage instance usage of this class.<br> */<br> public static function &getInstance($type = 'base')<br> {<br> if (self::$dbCache !== false) {<br> return self::$dbCache;<br> }<br> $config = AppConfig::main('dbconfig');<br> if ($config === false) {<br> include 'config/config.inc.php';<br> if (file_exists('config/config_override.php')) {<br> include 'config/config_override.php';<br> }<br> $config = $dbconfig;<br> }<br> $db = new self($config['db_type'], $config['db_server'], $config['db_name'], $config['db_username'], $config['db_password'], $config['db_port']);<br><br> if ($db->database === null) {<br> \App\Log::error('Database getInstance: Error connecting to the database', 'error');<br> $db->checkError('Error connecting to the database');<br><br> return false;<br> } else {<br> self::$dbCache = $db;<br> }<br> return $db;<br> }<br><br> public function connect()<br> {<br> // Set DSN<br> $dsn = $this->dbType . ':host=' . $this->dbHostName . ';dbname=' . $this->dbName . ';port=' . $this->port;<br><br> // Set options<br> $options = [<br> PDO::ATTR_EMULATE_PREPARES => false,<br> PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,<br> PDO::ATTR_TIMEOUT => 5,<br> ];<br> // Create a new PDO instanace<br> try {<br> $this->database = new PDO($dsn, $this->userName, $this->userPassword, $options);<br> $this->database->exec('SET NAMES ' . $this->database->quote('utf8'));<br> } catch (\App\Exceptions\AppException $e) {<br> // Catch any errors<br> \App\Log::error('Database connect : ' . $e->getMessage());<br> $this->checkError($e->getMessage());<br> }<br> }<br><br> protected function loadDBConfig($dbtype, $host, $dbname, $username, $passwd, $port)<br> {<br> if ($host == '_SERVER_') {<br> \App\Log::error('No configuration for the database connection');<br> }<br> $this->dbType = $dbtype;<br> $this->dbHostName = $host;<br> $this->dbName = $dbname;<br> $this->userName = $username;<br> $this->userPassword = $passwd;<br> $this->port = $port;<br> }<br><br> public function setDBCache()<br> {<br> self::$dbCache = $this;<br> }<br><br> public function getDatabaseName()<br> {<br> return $this->dbName;<br> }<br><br> public function println($msg)<br> {<br> return $msg;<br> }<br><br> public function checkError($message, $dieOnError = false, $query = false, $params = false)<br> {<br> if ($this->hasActiveTransaction) {<br> $this->rollbackTransaction();<br> }<br> if ($this->dieOnError || $dieOnError) {<br> $backtrace = false;<br> if (AppConfig::debug('DISPLAY_EXCEPTION_BACKTRACE')) {<br> $backtrace = \App\Debuger::getBacktrace();<br> }<br> $message = [<br> 'message' => $message,<br> 'trace' => $backtrace,<br> 'query' => $query,<br> 'params' => $params,<br> ];<br> vtlib\Functions::throwNewException($message, true, 'DatabaseException.tpl');<br> }<br> }<br><br> public function errorMsg()<br> {<br> $error = $this->database->errorInfo();<br><br> return $error[2];<br> }<br><br> public function isMySQL()<br> {<br> return stripos($this->dbType, 'mysql') === 0;<br> }<br><br> public function isOracle()<br> {<br> return $this->dbType == 'oci8';<br> }<br><br> public function isPostgres()<br> {<br> return $this->dbType == 'pgsql';<br> }<br><br> public function setDieOnError($value)<br> {<br> $this->dieOnError = $value;<br> }<br><br> public function setAttribute($attribute, $value)<br> {<br> $this->database->setAttribute($attribute, $value);<br> }<br><br> public function startTransaction()<br> {<br> $this->transCnt += 1;<br><br> if ($this->hasActiveTransaction) {<br> return $this->hasActiveTransaction;<br> } else {<br> $this->autoCommit = false;<br> $this->hasActiveTransaction = $this->database->beginTransaction();<br><br> return $this->hasActiveTransaction;<br> }<br> }<br><br> public function completeTransaction()<br> {<br> $this->transCnt -= 1;<br><br> if ($this->transCnt == 0) {<br> $this->database->commit();<br> $this->autoCommit = false;<br> $this->hasActiveTransaction = false;<br> }<br> }<br><br> public function hasFailedTransaction()<br> {<br> return $this->hasFailedTransaction;<br> }<br><br> public function rollbackTransaction()<br> {<br> if ($this->hasActiveTransaction) {<br> $this->hasFailedTransaction = true;<br> $result = $this->database->rollback();<br> $this->autoCommit = false;<br> $this->transCnt -= 1;<br><br> return $result;<br> }<br> return false;<br> }<br><br> public function getRowCount(PDOStatement $result)<br> {<br> if (method_exists($result, 'rowCount')) {<br> return $result->rowCount();<br> }<br> App\Log::warning('No rowCount function');<br><br> return 0;<br> }<br><br> public function numRows(PDOStatement $result)<br> {<br> return $result->rowCount();<br> }<br><br> public function getFieldsCount(PDOStatement $result)<br> {<br> return $result->columnCount();<br> }<br><br> public function fetchArray(PDOStatement $result)<br> {<br> return $result->fetch(PDO::FETCH_ASSOC);<br> }<br><br> public function getSingleValue(PDOStatement $result)<br> {<br> return $result->fetchColumn();<br> }<br><br> public function getRow(PDOStatement $result)<br> {<br> return $result->fetch(PDO::FETCH_ASSOC);<br> }<br><br> public function getColumnByGroup(PDOStatement $result)<br> {<br> return $result->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_COLUMN);<br> }<br><br> public function getArray(PDOStatement $result)<br> {<br> return $result->fetchAll(PDO::FETCH_ASSOC);<br> }<br><br> public function getArrayColumn(PDOStatement $result, $column = 0)<br> {<br> return $result->fetchAll(PDO::FETCH_COLUMN, $column);<br> }<br><br> public function disconnect()<br> {<br> if (isset($this->database)) {<br> unset($this->database);<br> }<br> }<br><br> public function query($query, $dieOnError = false, $msg = '')<br> {<br> $this->stmt = false;<br> $sqlStartTime = microtime(true);<br><br> try {<br> \App\Log::beginProfile($query, __METHOD__);<br> $this->stmt = $this->database->query($query);<br> \App\Log::endProfile($query, __METHOD__);<br><br> $this->logSqlTime($sqlStartTime, microtime(true), $query);<br> } catch (PDOException $e) {<br> $error = $this->database->errorInfo();<br> \App\Log::error($msg . 'Query Failed: ' . $query . ' | ' . $error[2] . ' | ' . $e->getMessage());<br> $this->checkError($e->getMessage(), $dieOnError, $query);<br> }<br> return $this->stmt;<br> }<br><br> /* Prepared statement Execution<br> * @param $sql -- Prepared sql statement<br> * @param $params -- Parameters for the prepared statement<br> * @param $dieOnError -- Set to true, when query execution fails<br> * @param $msg -- Error message on query execution failure<br> */<br><br> public function pquery($query, $params = [], $dieOnError = false, $msg = '')<br> {<br> $this->stmt = false;<br> $sqlStartTime = microtime(true);<br> $params = $this->flattenArray($params);<br> if (empty($params)) {<br> return $this->query($query, $dieOnError, $msg);<br> }<br> try {<br> $this->stmt = $this->database->prepare($query);<br><br> \App\Log::beginProfile($query, __METHOD__);<br> $this->stmt->execute($params);<br> \App\Log::endProfile($query, __METHOD__);<br><br> $this->logSqlTime($sqlStartTime, microtime(true), $query, $params);<br> } catch (PDOException $e) {<br> $error = $this->database->errorInfo();<br> \App\Log::error($msg . 'Query Failed: ' . $query . ' | ' . $error[2] . ' | ' . $e->getMessage());<br> $this->checkError($e->getMessage(), $dieOnError, $query, $params);<br> }<br> return $this->stmt;<br> }<br><br> public function prepare($query)<br> {<br> $this->stmt = $this->database->prepare($query);<br><br> return $this->stmt;<br> }<br><br> public function bind($param, $value, $type = null)<br> {<br> if (is_null($type)) {<br> switch (true) {<br> case is_int($value):<br> $type = PDO::PARAM_INT;<br> break;<br> case is_bool($value):<br> $type = PDO::PARAM_BOOL;<br> break;<br> case is_null($value):<br> $type = PDO::PARAM_NULL;<br> break;<br> default:<br> $type = PDO::PARAM_STR;<br> }<br> }<br> $this->stmt->bindValue($param, $value, $type);<br> }<br><br> public function execute()<br> {<br> try {<br> $this->stmt->execute($params);<br> $this->logSqlTime($sqlStartTime, microtime(true), $query, $params);<br> } catch (\App\Exceptions\AppException $e) {<br> $error = $this->database->errorInfo();<br> \App\Log::error($msg . 'Query Failed: ' . $query . ' | ' . $error[2] . ' | ' . $e->getMessage());<br> $this->checkError($e->getMessage());<br> }<br> return $this->stmt;<br> }<br><br> /**<br> * A function to insert data into the database.<br> *<br> * @param string $table Table name<br> * @param array $data Query data<br> *<br> * @return array Row count and last insert id<br> */<br> public function insert($table, array $data)<br> {<br> if (!$table) {<br> \App\Log::error('Missing table name');<br> $this->checkError('Missing table name');<br><br> return false;<br> } elseif (!is_array($data)) {<br> \App\Log::error('Missing data, data must be an array');<br> $this->checkError('Missing table name');<br><br> return false;<br> }<br> $columns = '';<br> foreach ($data as $column => $cur) {<br> $columns .= ($columns ? ',' : '') . $this->quote($column, false);<br> }<br> $insert = 'INSERT INTO ' . $this->quote($table, false) . ' (' . $columns . ') VALUES (' . $this->generateQuestionMarks($data) . ')';<br> $this->pquery($insert, $data);<br><br> return ['rowCount' => $this->stmt->rowCount(), 'id' => $this->database->lastInsertId()];<br> }<br><br> /**<br> * A function to remove data from the database.<br> *<br> * @param string $table Table name<br> * @param string $where Conditions<br> * @param array $params Query data<br> *<br> * @return int Number of deleted records<br> */<br> public function delete($table, $where = '', array $params = [])<br> {<br> if (!$table) {<br> \App\Log::error('Missing table name');<br> $this->checkError('Missing table name');<br><br> return false;<br> }<br> if ($where != '') {<br> $where = sprintf('WHERE %s', $where);<br> }<br> if (count($params) === 0) {<br> $this->query(sprintf('DELETE FROM %s %s', $table, $where));<br> } else {<br> $this->pquery(sprintf('DELETE FROM %s %s', $table, $where), $params);<br> }<br> return $this->stmt->rowCount();<br> }<br><br> /**<br> * A function to update data in the database.<br> *<br> * @param string $table Table name<br> * @param array $columns Columns to update<br> * @param string $where Conditions<br> * @param array $params Query data<br> *<br> * @return int Number of updated records<br> */<br> public function update($table, array $columns, $where = false, array $params = [])<br> {<br> $query = "UPDATE $table SET ";<br> foreach ($columns as $column => $value) {<br> $query .= $this->quote($column, false) . ' = ?,';<br> $values[] = $value;<br> }<br> $query = trim($query, ',');<br> if ($where !== false) {<br> $query .= sprintf(' WHERE %s', $where);<br> }<br> $this->pquery(trim($query, ','), [array_merge($values, $params)]);<br><br> return $this->stmt->rowCount();<br> }<br><br> public function queryResult(&$result, $row, $col = 0)<br> {<br> return $this->queryResultRaw($result, $row, $col);<br> }<br><br> public function queryResultRaw(&$result, $row, $col = 0)<br> {<br> if (!is_object($result)) {<br> \App\Log::error('Result is not an object');<br> $this->checkError('Result is not an object');<br> }<br><br> if (!isset($result->tmp)) {<br> $result->tmp = $result->fetchAll(PDO::FETCH_ASSOC);<br> }<br> if (!isset($result->tmp[$row]) || !isset($result->tmp[$row][$col])) {<br> return null;<br> }<br> return $result->tmp[$row][$col];<br> }<br><br> // Function to get particular row from the query result<br> public function queryResultRowData(&$result, $row = 0)<br> {<br> return $this->rawQueryResultRowData($result, $row);<br> }<br><br> /**<br> * Get an array representing a row in the result set<br> * Unlike it's non raw siblings this method will not escape<br> * html entities in return strings.<br> *<br> * The case of all the field names is converted to lower case.<br> * as with the other methods.<br> *<br> * @param &$result The query result to fetch from<br> * @param $row The row number to fetch. It's default value is 0<br> */<br> public function rawQueryResultRowData(&$result, $row = 0)<br> {<br> if (!is_object($result)) {<br> \App\Log::error('Result is not an object');<br> $this->checkError('Result is not an object');<br> }<br> if (!isset($result->tmp)) {<br> $result->tmp = $result->fetchAll(PDO::FETCH_ASSOC);<br> }<br> return $result->tmp[$row];<br> }<br><br> /**<br> * Flatten the composite array into single value.<br> * Example:<br> * $input = array(10, 20, array(30, 40), array('key1' => '50', 'key2'=>array(60), 70));<br> * returns array(10, 20, 30, 40, 50, 60, 70);.<br> */<br> public function flattenArray($input, $output = null)<br> {<br> if (empty($input)) {<br> return null;<br> }<br> if (empty($output)) {<br> $output = [];<br> }<br> foreach ($input as $value) {<br> if (is_array($value)) {<br> $output = $this->flattenArray($value, $output);<br> } else {<br> array_push($output, $value);<br> }<br> }<br> return $output;<br> }<br><br> public function getColumnNames($tablename)<br> {<br> $stmt = $this->database->query('SHOW COLUMNS FROM ' . $tablename, PDO::FETCH_OBJ);<br> $columns = [];<br> foreach ($stmt as $col) {<br> $columns[] = $col->Field;<br> }<br> return $columns;<br> }<br><br> public function getColumnsMeta($tablename)<br> {<br> $stmt = $this->database->query('SHOW COLUMNS FROM ' . $tablename, PDO::FETCH_OBJ);<br> $columns = [];<br> foreach ($stmt as $col) {<br> if (strpos($col->Type, '(') !== false) {<br> $showType = explode('(', $col->Type); //PREG_SPLIT IS BETTER<br> }<br> $type = $showType[0];<br> $vals = explode(')', $showType[1]);<br> if (is_int((int) $vals[0])) {<br> $maxLength = $vals[0];<br> } elseif (strpos($vals[0], ',') !== false) {<br> $vs = explode(',', $vals[0]);<br> $vs = array_map('str_replace', $vs, ['\'', '', $vs[0]]);<br> $maxLength = [];<br> foreach ($vs as $v) {<br> $maxLength[] = $v;<br> }<br> }<br> $column = new stdClass();<br> $column->name = $col->Field;<br> $column->notNull = $col->null == 'NO' ? true : false;<br> $column->primaryKey = $col->Key == 'PRI' ? true : false;<br> $column->uniqueKey = $col->Key == 'UNI' ? true : false;<br> $column->hasDefault = $col->Default === null ? false : true;<br> if ($column->hasDefault) {<br> $column->default = $col->Default;<br> }<br> $column->maxLength = $maxLength;<br> $column->type = $type;<br> $columns[strtoupper($column->name)] = $column;<br> }<br> return $columns;<br> }<br><br> public function updateBlob($table, $column, $val, $where)<br> {<br> $success = $this->pquery("UPDATE $table SET $column=? WHERE $where", [$val]);<br><br> return $success;<br> }<br><br> public function getEmptyBlob()<br> {<br> return 'null';<br> }<br><br> public function fetchByAssoc(&$result, $rowNum = -1)<br> {<br> if (isset($result) && $rowNum < 0) {<br> $row = $this->getRow($result);<br><br> return $row;<br> }<br> if ($this->getRowCount($result) > $rowNum) {<br> $row = $this->rawQueryResultRowData($result, $rowNum);<br> }<br> return $row;<br> }<br><br> //To get a function name with respect to the database type which escapes strings in given text<br> public function sqlEscapeString($str, $type = false)<br> {<br> if ($type) {<br> $search = ['\\', "\0", "\n", "\r", "\x1a", "'", '"'];<br> $replace = ['\\\\', '\\0', '\\n', '\\r', "\Z", "\'", '\"'];<br><br> return str_replace($search, $replace, $str);<br> } else {<br> return $this->database->quote($str);<br> }<br> }<br><br> public function getUniqueID($seqname)<br> {<br> $tableName = $seqname . '_seq';<br> if ($this->checkExistTable($tableName)) {<br> $result = $this->query(sprintf('SELECT id FROM %s', $tableName));<br> $id = ((int) $this->getSingleValue($result)) + 1;<br> $this->database->query("update $tableName set id = $id");<br> } else {<br> $result = $this->query('SHOW COLUMNS FROM ' . $this->quote($seqname, false));<br> $column = $this->getSingleValue($result);<br> $result = $this->query("SELECT MAX($column ) AS max FROM " . $this->quote($seqname, false));<br> $id = ((int) $this->getSingleValue($result)) + 1;<br> }<br> return $id;<br> }<br><br> public function checkExistTable($tableName, $cache = true)<br> {<br> $tablePresent = Vtiger_Cache::get('checkExistTable', $tableName);<br> if ($tablePresent !== false && $cache) {<br> return $tablePresent;<br> }<br><br> $dieOnError = $this->dieOnError;<br> $this->dieOnError = false;<br><br> $tablename = $this->sqlEscapeString($tableName);<br> $tableCheck = $this->query("SHOW TABLES LIKE $tablename");<br> $tablePresent = 1;<br> if (empty($tableCheck) || $this->getRowCount($tableCheck) === 0) {<br> $tablePresent = 0;<br> }<br> $this->dieOnError = $dieOnError;<br> Vtiger_Cache::set('checkExistTable', $tableName, $tablePresent);<br><br> return $tablePresent;<br> }<br><br> // Function to get the last insert id based on the type of database<br> public function getLastInsertID()<br> {<br> $lastInsertID = $this->database->lastInsertId();<br><br> return $lastInsertID;<br> }<br><br> public function formatDate($datetime, $strip_quotes = false)<br> {<br> // remove single quotes to use the date as parameter for Prepared statement<br> if ($strip_quotes === true) {<br> return trim($datetime, "'");<br> }<br> return $datetime;<br> }<br><br> public function getOne($sql, $dieOnError = false, $msg = '')<br> {<br> $result = $this->query($sql, $dieOnError, $msg);<br> $val = $this->getSingleValue($result);<br><br> return $val;<br> }<br><br> public function getFieldsDefinition(PDOStatement $result)<br> {<br> $fieldArray = [];<br> if (!isset($result) || empty($result)) {<br> return 0;<br> }<br> foreach (range(0, $result->columnCount() - 1) as $columnIndex) {<br> $meta = $result->getColumnMeta($columnIndex);<br> $column = new stdClass();<br> $column->name = $meta['name'];<br> $column->type = $this->types[$meta['pdo_type']];<br> $column->max_length = $meta['len'];<br> array_push($fieldArray, $column);<br> }<br> return $fieldArray;<br> }<br><br> public function getFieldsArray(PDOStatement $result)<br> {<br> $fieldArray = [];<br> if (!isset($result) || empty($result)) {<br> return 0;<br> }<br> foreach (range(0, $result->columnCount() - 1) as $columnIndex) {<br> $meta = $result->getColumnMeta($columnIndex);<br> array_push($fieldArray, $meta['name']);<br> }<br> return $fieldArray;<br> }<br><br> /**<br> * Function to generate question marks for a given list of items.<br> */<br> public function generateQuestionMarks($items)<br> {<br> // array_map will call the function specified in the first parameter for every element of the list in second parameter<br> return implode(',', array_map(function ($a) {<br> return '?';<br> }, is_array($items) ? $items : explode(',', $items)));<br> }<br><br> public function concat($columns, $space = '" "')<br> {<br> $concat = 'CONCAT(';<br> foreach ($columns as $key => $column) {<br> if ($key != 0 && $space) {<br> $concat .= $space . ',';<br> }<br> $concat .= $column . ',';<br> }<br> return rtrim($concat, ',') . ')';<br> }<br><br> // create an IN expression from an array/list<br> public function sqlExprDatalist($array)<br> {<br> if (!is_array($array)) {<br> \App\Log::error('sqlExprDatalist: not an array');<br> $this->checkError('sqlExprDatalist: not an array');<br> }<br> if (!count($array)) {<br> \App\Log::error('sqlExprDatalist: empty arrays not allowed');<br> $this->checkError('sqlExprDatalist: empty arrays not allowed');<br> }<br> foreach ($array as $key => $val) {<br> $l .= ($l ? ',' : '') . $this->quote($val);<br> }<br> return ' ( ' . $l . ' ) ';<br> }<br><br> public function getAffectedRowCount(PDOStatement $result)<br> {<br> $rows = $result->rowCount();<br><br> return $rows;<br> }<br><br> public function requirePsSingleResult($sql, $params, $dieOnError = false, $msg = '')<br> {<br> $result = $this->pquery($sql, $params, $dieOnError, $msg);<br><br> if ($this->getRowCount($result) == 1) {<br> return $result;<br> }<br> \App\Log::error('Rows Returned:' . $this->getRowCount($result) . ' More than 1 row returned for ' . $sql);<br> $this->checkError('Rows Returned:' . $this->getRowCount($result) . ' More than 1 row returned for ' . $sql, $dieOnError);<br><br> return '';<br> }<br><br> public function columnMeta(PDOStatement $result, $col)<br> {<br> $meta = $result->getColumnMeta($col);<br> $column = new stdClass();<br> $column->name = $meta['name'];<br> $column->type = $this->types[$meta['pdo_type']];<br> $column->max_length = $meta['len'];<br><br> return $column;<br> }<br><br> public function quote($input, $quote = true, $type = null)<br> {<br> // handle int directly for better performance<br> if ($type == 'integer' || $type == 'int') {<br> return (int) $input;<br> }<br><br> if (is_null($input)) {<br> return 'NULL';<br> }<br><br> $map = [<br> 'bool' => PDO::PARAM_BOOL,<br> 'integer' => PDO::PARAM_INT,<br> ];<br><br> <span style="background-color:#f1c40f;"> $type = $map[$type] ?? PDO::PARAM_STR;</span><br><br> if ($quote) {<br> return strtr($this->database->quote($input, $type), [self::DEFAULT_QUOTE => self::DEFAULT_QUOTE . self::DEFAULT_QUOTE]);<br> } else {<br> return self::DEFAULT_QUOTE . $input . self::DEFAULT_QUOTE;<br> }<br> }<br><br> // SQLTime logging<br><br> protected $logSqlTimeID = false;<br> protected $logSqlTimeGroup = 1;<br><br> public function logSqlTime($startat, $endat, $sql, $params = false)<br> {<br> if (!AppConfig::performance('SQL_LOG_INCLUDE_CALLER')) {<br> return;<br> }<br> $db = self::getInstance('log');<br> $now = date('Y-m-d H:i:s');<br> $group = $this->logSqlTimeGroup;<br> $logTable = 'l_yf_sqltime';<br> $logQuery = 'INSERT INTO ' . $logTable . '(
id,
type,
qtime,
content,
date,
group`) VALUES (?,?,?,?,?,?)';if ($this->logSqlTimeID === false) {
$stmt = $db->database->query(sprintf('SELECT MAX(id) FROM %s', $logTable));
$this->logSqlTimeID = (int) $this->getSingleValue($stmt) + 1;
$type = PHP_SAPI;
$data = '';
if (isset($_SERVER['REQUEST_METHOD'])) {
$uri = $_SERVER['REQUEST_URI'];
$qmarkIndex = strpos($_SERVER['REQUEST_URI'], '?');
if ($qmarkIndex !== false) {
$uri = substr($uri, 0, $qmarkIndex);
}
$data = $uri . '?' . http_build_query($_SERVER['REQUEST_METHOD'] == 'GET' ? $_GET : $_POST);
}
$stmt = $db->database->prepare($logQuery);
$stmt->execute([$this->logSqlTimeID, $type, null, $data, $now, $group]);
}
$type = 'SQL';
$data = trim($sql);
if (is_array($params) && !empty($params)) {
$data .= '[' . implode(',', $params) . ']';
}
$qtime = round(($endat - $startat) * 1000) / 1000;
$stmt = $db->database->prepare($logQuery);
$stmt->execute([$this->logSqlTimeID, $type, $qtime, $data, $now, $group]);
$type = 'CALLERS';
$data = [];
$callers = debug_backtrace();
for ($calleridx = 0, $callerscount = count($callers); $calleridx < $callerscount; ++$calleridx) {
if ($calleridx == 0) {
continue;
}
if ($calleridx < $callerscount) {
$callerfunc = $callers[$calleridx + 1]['function'];
if (isset($callers[$calleridx + 1]['args'])) {
$args = '';
foreach ($callers[$calleridx + 1]['args'] as &$arg) {
if (!is_array($arg) && !is_object($arg) && !is_resource($arg)) {
$args .= "'$arg'";
}
$args .= ',';
}
$args = rtrim($args, ',');
}
if (!empty($callerfunc)) {
$callerfunc = " ($callerfunc)";
}
if (!empty($args)) {
$callerfunc .= "[$args] ";
}
}
$data[] = 'CALLER: (' . $callers[$calleridx]['line'] . ') ' . $callers[$calleridx]['file'] . $callerfunc;
}
$stmt = $db->database->prepare($logQuery);
$stmt->execute([$this->logSqlTimeID, $type, null, implode(PHP_EOL, $data), $now, $group]);
++$this->logSqlTimeGroup;
}
public static function whereEquals($val)
{
if (is_array($val)) {
if (count($val) > 1) {
return 'IN (\'' . implode("','", $val) . '\')';
} else {
$val = array_shift($val);
}
}
return '=\'' . $val . '\'';
}
}
Generated by YetiforceCRM ver. 4.4.0
PHP: 7.1.17
Server configuration errors:
session.gc_maxlifetime: 1440
auto_detect_line_endings: Off
Library errors:
exif_read_data
ldap_connect
opcache_get_configuration
apcu