Converts a DB exception to a more concrete one if possible.

@param  \Exception $e
@param  string     $rawSql SQL that produced exception
@return Exception
194421
public function convertException(\Exception $e, $rawSql)
    {
        if ($e instanceof Exception) {
            return $e;
        }

        $exceptionClass = '\Zilf\Db\Exception';
        foreach ($this->exceptionMap as $error => $class) {
            if (strpos($e->getMessage(), $error) !== false) {
                $exceptionClass = $class;
            }
        }
        $message = $e->getMessage() . "\nThe SQL being executed was: $rawSql";
        $errorInfo = $e instanceof \PDOException ? $e->errorInfo : null;
        return new $exceptionClass($message, $errorInfo, (int) $e->getCode(), $e);
    }
589872
public static function exception($title, PhpException $e)
    {
        $exceptionMessage = (string) $e->getMessage();

        $content = (string) $title . PHP_EOL . 'Exception of type \'' . get_class($e) . '\': ' . $exceptionMessage;

        // need to add check if the log verbosity is info or debug. Look at old code
        self::$logger->exception(new PhpException($content, null, $e));

        return true;
    }
1182127
public static void throwException(SQLException exception, MariaDbConnection connection,
      MariaDbStatement statement) throws SQLException {
    throw getException(exception, connection, statement, false);
  }
1234932
public function getQuery(): Query
    {
        $bindings = new Bindings();

        if (count($this->data) == 0 && $this->select === null) {
            throw new Exception('Can not execute Insert query, no records to insert');
        }

        if ($this->table === null) {
            throw new Exception('Can not execute Insert query when table name is not set');
        }

        $hasFields = count($this->fields) > 0;

        $query = "INSERT INTO {$this->table}";

        if ($hasFields) {
            $query .= ' (';

            foreach ($this->fields as $field) {
                $query .= $field . ',';
            }

            $query = substr($query, 0, -1) . ')';
        }

        if ($this->select !== null) {
            if ($this->select instanceof Select || $this->select instanceof Query) {
                $query .= "\n(\n\t" . str_replace("\n", "\n\t", $this->select->__toString()) . "\n)";
                $bindings->addBindingsFromInstance($this->select->getBindings());
            } else {
                throw new Exception('Can not use non-Select or non-Query instance in INSERT INTO SELECT statement - use Query instance to pass Select query');
            }
        } else {
            $query .= "\nVALUES\n";
            foreach ($this->data as $i1 => $row) {
                $query .= "\t(";

                if ($hasFields) {

                    foreach ($this->fields as $field) {
                        if (isset($row[$field])) {
                            $val = $row[$field];

                            if ($val instanceof Expr) {
                                $query .= "{$val},";
                            } else {
                                //$key = 'i' . $i1 . Query::getKeyIndex();
	                            $key = $bindings->makeAndSet("i{$i1}", $val);
                                $query .= ":{$key},";
                            }
                        } else {
                            $query .= 'NULL,';
                        }
                    }

                    $query = substr($query, 0, -1);

                } else {
                    $values = array_values($row);

                    foreach ($values as $i2 => $val) {
                        if ($val instanceof Expr) {
                            $query .= "{$val},";
                        } else {
                            //$key = 'i' . $i2 . Query::getKeyIndex();
	                        $key = $bindings->makeAndSet("i{$i2}", $val);
                            $query .= ":{$key},";
                        }
                    }

                    $query = substr($query, 0, -1);
                }

                $query .= "),\n";
            }

            $query = substr($query, 0, -2);
        }

        return new Query($query, $bindings, $this->getAdapterConnection());
    }
597897
public function getQuery(): Query
    {
        if (count($this->what) == 0) {
            throw new Exception('Can not build UPDATE query, SET is not defined');
        }

        if ($this->table === null) {
            throw new Exception('Can not build UPDATE query when table name is not set');
        }

        $sql = "UPDATE {$this->table}\nSET\n";

        foreach ($this->what as $field => $value) {
            $sql .= "\t{$field} = ";
            if ($value instanceof Expr) {
                $sql .= "{$value},\n";
            } else {
                //$key = $this->bind($field, $value);
	            $key = $this->getBindings()->makeAndSet($field, $value);
                $sql .= ":{$key},\n";
            }
        }

        $sql = substr($sql, 0, -2);

        if ($this->hasWhere()) {
            $sql .= "\nWHERE{$this->getWhereSql()}";
        }

        if (count($this->orderBy) > 0) {
            $sql .= "\nORDER BY";
            foreach ($this->orderBy as $r) {
                $sql .= "\n\t{$r['field']} {$r['direction']},";
            }
            $sql = substr($sql, 0, -1);
        }

        return new Query($sql, $this->getBindings(), $this->getAdapterConnection());
    }
787520
private function replace($rawSQL, $references)
    {
        $result = str_replace(array_keys($references), array_values($references), $rawSQL);

        if (false === strpos($result, '@ref[')) {
            return $result;
        } else {
            return $this->replace($result, $references);
        }
    }
1184535
public function execSql(string $sql): int
    {
        $result = $this->pdo->exec($sql);
        if ($result === false) {
            $err = $this->errorInfo();
            throw new \Exception('['.$err[0].']'.$err[2]);
        }
        return $result;
    }
774640
protected function convertMySqlException(\PDOException $e, \Exception $root)
	{
		$code = isset($e->errorInfo[1]) ? $e->errorInfo[1] : $e->getCode();
	
		switch($code)
		{
			case '1216':
			case '1217':
			case '1451':
			case '1452':
			case '1701':
				return new ForeignKeyConstraintViolationException($root->getMessage(), 0, $root);
			case '1062':
			case '1557':
			case '1569':
			case '1586':
				return new UniqueConstraintViolationException($root->getMessage(), 0, $root);
		}
	
		return new DatabaseException($root->getMessage(), 0, $root);
	}
1336561
public static void logSQLConsumerException(final Logger logger,
			final SQLConsumerException e)
	{

		logger.logException(Level.ERROR, "SQLConsumerException", e);
	}
693044
public SQLException exceptionWithQuery(ByteBuffer buffer, SQLException sqlEx,
      boolean explicitClosed) {
    if (options.dumpQueriesOnException || sqlEx.getErrorCode() == 1064 || explicitClosed) {
      return exceptionWithQuery(subQuery(buffer), sqlEx, explicitClosed);
    }
    return sqlEx;
  }
439350
public static DatabaseException toDatabaseException(Exception ex)
    {
        if (ex instanceof DatabaseException)
            return (DatabaseException)ex;
        int iErrorCode = DBConstants.ERROR_STRING;
        if (ex instanceof DBException)
            iErrorCode = ((DBException)ex).getErrorCode();
        String strMessage = ex.getMessage();
        if (strMessage != null)
            if (strMessage.startsWith(DBEXCEPTION_TEXT))
        {
            int iNextPos = strMessage.indexOf(' ', DBEXCEPTION_TEXT.length());
            if (iNextPos != -1)
            {
                iErrorCode = Integer.parseInt(strMessage.substring(DBEXCEPTION_TEXT.length(), iNextPos));
                if (iNextPos + 1 < strMessage.length())
                    strMessage = strMessage.substring(iNextPos + 1);
            }
        }
        return new DatabaseException(iErrorCode, strMessage);
    }
941225
public function logException($e) {
		if(!$this->isLogging())
			return;

		#PSRException with a given severity
		if($e instanceof PSRException) {
			$severity = $e->getseverity();
			$msg = $e->getMessage();
		}
		#PHP exception
		elseif($e instanceof \ErrorException) {
			$severity = static::getPHPErrorSeverity($e->getCode());
			$msg = 'PHP ('.static::getPHPError($e->getCode()).'): '.$e->getMessage();
		}
		#other exception
		else {
			$severity = \Psr\Log\LogLevel::ERROR;
			$msg = get_class($e).': '.$e->getMessage();
		}

		$trace = $this->getBacktraceFromException($e);

		$this->log($severity, $msg, $e->getFile(), $e->getLine(), $e, $trace);
	}
267240
public function exceptionHandler($e) {
        if (method_exists($e, 'getType')) {
            $this->addError($e->getMessage(), $e->getFile(), $e->getLine(), $e->getType());
        }
        else {
            $this->addError($e->getMessage(), $e->getFile(), $e->getLine(), gettype($e));
        }
    }
941584
public function fromException(\Exception $e)
    {
        return new Error(E_EXCEPTION, $e->__toString(), $e->getFile(), $e->getLine(), $e->getCode());
    }
1284129
protected function doException(\Exception $e)
    {
        $command = new DefaultConsoleCommand();
        $command->data = '"Error #' . $e->getCode() . ' - ' . $e->getMessage() . '"';
        $command->execute();

        $response = (new ResponseInjector)->build();
        $response = $response->withHeader('status', (string)(int)$command->result); // TODO: hack for select cli stream

        $stream = $response->getBody();
        $stream->write($command->message);

        return $response->withBody($stream);
    }
1274139
public static SQLConsumerException createSQLConsumerException(
			final ErrorKeys errorId, final String message, final Exception e)
	{

		return new SQLConsumerException(errorId.toString() + ":\r\n" + message,
				e);
	}
192256
private static boolean mySqlErrorCodeMatches(Exception e, int errorCode)
    {
        return Throwables.getCausalChain(e).stream()
                .filter(SQLException.class::isInstance)
                .map(SQLException.class::cast)
                .filter(t -> t.getErrorCode() == errorCode)
                .map(Throwable::getStackTrace)
                .anyMatch(isMySQLException());
    }