public function query(string $sql, array $driverOptions = []): QueryResult
    {
        if (null === $this->pdo) {
            $this->connect();
        }

        try {
            if (!isset($driverOptions['fetchMode'])) {
                return new PdoQueryResult($this->pdo->query($sql));
            }

            switch ($driverOptions['fetchMode']) {
                case PDO::FETCH_COLUMN:
                    if (!isset($driverOptions['colNo'])) {
                        throw new \InvalidArgumentException(
                                'Fetch mode COLUMN requires driver option colNo.'
                        );
                    }

                    $pdoStatement = $this->pdo->query(
                            $sql,
                            $driverOptions['fetchMode'],
                            $driverOptions['colNo']
                    );
                    break;

                case PDO::FETCH_INTO:
                    if (!isset($driverOptions['object'])) {
                        throw new \InvalidArgumentException(
                                'Fetch mode INTO requires driver option object.'
                        );
                    }

                    $pdoStatement = $this->pdo->query(
                            $sql,
                            $driverOptions['fetchMode'],
                            $driverOptions['object']
                    );
                    break;

                case PDO::FETCH_CLASS:
                    if (!isset($driverOptions['classname'])) {
                        throw new \InvalidArgumentException(
                                'Fetch mode CLASS requires driver option classname.'
                        );
                    }

                    $pdoStatement = $this->pdo->query(
                            $sql,
                            $driverOptions['fetchMode'],
                            $driverOptions['classname'],
                            $driverOptions['ctorargs'] ?? []
                    );
                    break;

                default:
                    $pdoStatement = $this->pdo->query(
                            $sql,
                            $driverOptions['fetchMode']
                    );
            }

            return new PdoQueryResult($pdoStatement);
        } catch (PDOException $pdoe) {
            throw new DatabaseException($pdoe->getMessage(), $pdoe);
        }
    }