public function query(string $sql, $binds = null, bool $setEscapeFlags = true, string $queryClass = 'CodeIgniter\\Database\\Query')
	{
		if (empty($this->connID))
		{
			$this->initialize();
		}

		$resultClass = str_replace('Connection', 'Result', get_class($this));
		/**
		 * @var Query $query
		 */
		$query = new $queryClass($this);

		$query->setQuery($sql, $binds, $setEscapeFlags);

		if (! empty($this->swapPre) && ! empty($this->DBPrefix))
		{
			$query->swapPrefix($this->DBPrefix, $this->swapPre);
		}

		$startTime = microtime(true);

		// Always save the last query so we can use
		// the getLastQuery() method.
		$this->lastQuery = $query;

		// Run the query for real
		if (! $this->pretend && false === ($this->resultID = $this->simpleQuery($query->getQuery())))
		{
			$query->setDuration($startTime, $startTime);

			// This will trigger a rollback if transactions are being used
			if ($this->transDepth !== 0)
			{
				$this->transStatus = false;
			}

			if ($this->DBDebug)
			{
				// We call this function in order to roll-back queries
				// if transactions are enabled. If we don't call this here
				// the error message will trigger an exit, causing the
				// transactions to remain in limbo.
				while ($this->transDepth !== 0)
				{
					$transDepth = $this->transDepth;
					$this->transComplete();

					if ($transDepth === $this->transDepth)
					{
						log_message('error', 'Database: Failure during an automated transaction commit/rollback!');
						break;
					}
				}

				return false;
			}

			if (! $this->pretend)
			{
				// Let others do something with this query.
				Events::trigger('DBQuery', $query);
			}

			return new $resultClass($this->connID, $this->resultID);
		}

		$query->setDuration($startTime);

		if (! $this->pretend)
		{
			// Let others do something with this query
			Events::trigger('DBQuery', $query);
		}

		// If $pretend is true, then we just want to return
		// the actual query object here. There won't be
		// any results to return.
		return $this->pretend ? $query : new $resultClass($this->connID, $this->resultID);
	}