spadefoot / kohana-orm-leap

An ORM module for the Kohana PHP framework that is designed to work with all major databases.
http://spadefoot.github.io/kohana-orm-leap/
100 stars 25 forks source link

Roles in Firebird are missing! #74

Closed ghost closed 11 years ago

ghost commented 11 years ago

I am testing your product and i have another feature request :)

i am using mySql, Oracle and Firebird. The Firebird Connector should become the ability to define a Database Role. This is very important by Firebird. to get this to work, i extended the datasource to accept a role property and extended the connection files of firebird to use this role.

and in 3.3 the pdo oracle connector does not work anymore, because the connector always needs a hostname. i reverted this to the old leap orm version of kohana 3.2 and it worked again.

bluesnowman commented 11 years ago

@viperneo Your feedback is much appreciated. I will be happy to implement this feature to Firebird Connector. If you have a working version and are willing to share it with the LEAP community, please send me either a pull request or paste the code here in this issue thread.

As for the Oracle connector for 3.3, I will look into why the connector seems to act differently. Are you able to do a file comparison on the two different versions of the code you have for 3.3 and 3.2 and let me know if you seem any differences? Or, if you have a solution, please let me know and I will definitely get it fixed asap.

ghost commented 11 years ago

Firebird Roles:

adding role to configuration file and parse it in Base_DB_DataSource.php

    $this->settings['role'] = (isset($settings['role']))
        ? (string) $settings['role']
        : '';

then my customized Base_DB_Firebird_Connection_Standard.php

    public function open() {
    if ( ! $this->is_connected()) {
        $connection_string = $this->data_source->host;
        if ( ! preg_match('/^localhost$/i', $connection_string)) {
            $port = $this->data_source->port;
            if ( ! empty($port)) {
                $connection_string .= '/' . $port;
            }
        }
        $connection_string .= ':' . $this->data_source->database;
        $username = $this->data_source->username;
        $password = $this->data_source->password;

        $role = (!empty($this->data_source->role)) ? $this->data_source->role : NULL;

        if ( ! empty($this->data_source->charset)) {
            $charset = strtoupper($this->data_source->charset);
            $this->resource_id = ($this->data_source->is_persistent())
                ? @ibase_pconnect($connection_string, $username, $password, $charset, null, 3, $role)
                : @ibase_connect($connection_string, $username, $password, $charset, null, 3, $role);
        }
        else {
            $this->resource_id = ($this->data_source->is_persistent())
                ? @ibase_pconnect($connection_string, $username, $password, 'NONE', null, 3, $role)
                : @ibase_connect($connection_string, $username, $password, 'NONE', null, 3, $role);
        }
        if ($this->resource_id === FALSE) {
            throw new Throwable_Database_Exception('Message: Failed to establish connection. Reason: :reason', array(':reason' => ibase_errmsg()));
        }
    }
}

and customized Base_DB_Firebird_Connection_PDO.php

    public function open() {
    if ( ! $this->is_connected()) {
        try {
            $connection_string  = 'firebird:';
            $connection_string .= 'dbname=' . $this->data_source->database;
            $connection_string .= ';host=' . $this->data_source->host;
            if ( ! preg_match('/^localhost$/i', $this->data_source->host)) {
                $port = $this->data_source->port;
                if ( ! empty($port)) {
                    $connection_string .= '/' . $port;
                }
            }
            if ( ! empty($this->data_source->charset)) {
                $connection_string .= ';charset=' . $this->data_source->charset;
            }

            if ( ! empty($this->data_source->role)) {
                $connection_string .= ';role=' . $this->data_source->role;
            }

            $attributes = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
            if ($this->data_source->is_persistent()) {
                $attributes[PDO::ATTR_PERSISTENT] = TRUE;
            }
            $this->connection = new PDO($connection_string, $this->data_source->username, $this->data_source->password, $attributes);
            $this->resource_id = static::$counter++;
        }
        catch (PDOException $ex) {
            $this->connection = NULL;
            throw new Throwable_Database_Exception('Message: Failed to establish connection. Reason: :reason', array(':reason' => $ex->getMessage()));
        }
    }
}
ghost commented 11 years ago

And Oracle Bug:

Current Oracle PDO Connection:

public function open() {
    if ( ! $this->is_connected()) {
        try {
            $connection_string  = 'oci:';
            $connection_string .= 'dbname=//'. $this->data_source->host;
            $port = $this->data_source->port; // default port is 1521
            if ( ! empty($port)) {
                $connection_string .= ':' . $port;
            }
            $connection_string .= '/' . $this->data_source->database;
            //if ( ! empty($this->data_source->charset)) {
            //    $connection_string .= ';charset=' . $this->data_source->charset;
            //}
            $attributes = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
            if ($this->data_source->is_persistent()) {
                $attributes[PDO::ATTR_PERSISTENT] = TRUE;
            }
            $this->connection = new PDO($connection_string, $this->data_source->username, $this->data_source->password, $attributes);
            $this->resource_id = static::$counter++;
        }
        catch (PDOException $ex) {
            $this->connection = NULL;
            throw new Throwable_Database_Exception('Message: Failed to establish connection. Reason: :reason', array(':reason' => $ex->getMessage()));
        }
    }
}

Should be this as it was in 3.2: public function open() { if ( ! $this->is_connected()) { try { $host = $this->data_source->host; $connection_string = 'oci:'; if ( ! empty($host) ) { $connection_string .= 'dbname=//'. $this->data_source->host; $port = $this->data_source->port; // default port is 1521 if ( ! empty($port)) { $connection_string .= ':' . $port; } $connection_string .= '/' . $this->data_source->database; } else { $connection_string .= 'dbname='. $this->data_source->database; } if ( ! empty($this->data_source->charset)) { $connection_string .= ';charset=' . $this->data_source->charset; }

            $attributes = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
            if ($this->data_source->is_persistent()) {
                $attributes[PDO::ATTR_PERSISTENT] = TRUE;
            }
            $this->connection = new PDO($connection_string, $this->data_source->username, $this->data_source->password, $attributes);
            $this->resource_id = static::$counter++;
        }
        catch (PDOException $ex) {
            $this->connection = NULL;
            throw new Throwable_Database_Exception('Message: Failed to establish connection. Reason: :reason', array(':reason' => $ex->getMessage()));
        }
    }
}
bluesnowman commented 11 years ago

@viperneo Thank you for posting the code! I will go through the code and push up the necessary changes.