public function connect()
    {
        if ($this->connected) {
            return $this;
        }

        # Set that we are connected here, because queries can be run as part of the below code, which would cause an infinite loop
        $this->connected = true;

        switch ($this->mode) {

            case "mysql":
                $this->server = new \Mysqli($this->options["hostname"], $this->options["username"], $this->options["password"]);
                if ($this->server->connect_error) {
                    $this->error();
                }
                if ($this->options["charset"]) {
                    $this->server->set_charset($this->options["charset"]);
                }
                if ($timezone = $this->options["timezone"]) {
                    if ($timezone === self::USE_PHP_TIMEZONE) {
                        $timezone = ini_get("date.timezone");
                    }
                    $this->query("SET time_zone='" . $timezone . "'");
                }
                if ($database = $this->options["database"]) {
                    if (!$this->server->select_db($database)) {
                        $this->error();
                    }
                }
                break;

            case "postgres":
            case "redshift":
                $connect = "host=" . $this->options["hostname"] . " ";
                $connect .= "user=" . $this->options["username"] . " ";
                $connect .= "password=" . $this->options["password"] . " ";
                $connect .= "dbname= " . $this->options["database"] . " ";
                $this->server = pg_connect($connect, PGSQL_CONNECT_FORCE_NEW);
                break;

            case "odbc":
                $this->server = odbc_connect($this->options["hostname"], $this->options["username"], $this->options["password"]);
                break;

            case "sqlite":
                $this->server = new \Sqlite3($this->options["database"]);
                break;

            case "mssql":
                $this->server = mssql_connect($this->options["hostname"], $this->options["username"], $this->options["password"]);
                break;

            case "mssqlsrv":
                if (!$port = $this->options["port"]) {
                    $port = 1433;
                }
                $this->server = sqlsrv_connect("tcp:" . $this->options["hostname"] . ",{$port}", [
                    "Uid"   =>  $this->options["username"],
                    "PWD"   =>  $this->options["password"],
                ]);
                break;
        }

        if (!$this->server) {
            $this->error();
        }

        return $this;
    }