/**
  * Query auf Datenbank ausführen und die entsprechenden Bindings durchführen.
  * ACHTUNG: Funktion fängt derzeit nicht ab, wenn Leerzeichn im Feldnamen
  * stehen, aber das sollte man sowieso nicht machen.
  * @param string $sql
  * @param array|null $params
  * @return $this
  */
 public function query($sql, $params = null)
 {
     if (!$this->connected) {
         $this->connect();
     }
     // Falls noch ein Statement aktiv ist, dieses abbrechen
     if ($this->statement !== null) {
         $this->closeStatement();
     }
     // TODO
     if ($this->engine === self::DB_MSSQL) {
         $sql = str_replace('CURDATE()', 'Convert(date, getdate())', $sql);
         $sql = str_replace('curdate()', 'Convert(date, getdate())', $sql);
     }
     $startTime = microtime(true);
     $this->prepareQueryAndBindParameter($sql, $params);
     $prepareTime = microtime(true);
     Profiler::startSection('database.execute', $sql);
     $errorMsg = '';
     try {
         $success = $this->statement->execute();
     } catch (Exception $e) {
         $errorMsg = $e->getMessage();
         $success = false;
     }
     $executeTime = microtime(true);
     Profiler::endSection('database.execute');
     if ($this->logQueries || !$success) {
         if ($success) {
             QueryLog::success($sql, $params, round(($executeTime - $prepareTime) * 1000), round(($prepareTime - $startTime) * 1000));
         } else {
             $info = $this->statement->errorInfo();
             Logging::error('Query konnte nicht ausgeführt werden: ' . $info[2] . $errorMsg . $sql);
             //error_log("Query konnte nicht ausgeführt werden: " . $info[2] . "\n" . $errorMsg . "\n" . $sql . "\n" . print_r(debug_backtrace(~DEBUG_BACKTRACE_PROVIDE_OBJECT), true));
             QueryLog::fail($sql, $params, round(($executeTime - $prepareTime) * 1000), round(($prepareTime - $startTime) * 1000), $info[2] . $errorMsg);
         }
     }
     return $this;
 }