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

Firebird BLOB fields are unsupported #76

Closed ghost closed 11 years ago

ghost commented 11 years ago

Hey guys,

today i would like to read data from my firebird tables. i am using the Standard Connection, because its lot faster than the PDO Connection. Problem is, BLOB fields are read as hex and couldnt be parsed at t he moment. if i am changing to PDO everything works fine.

greetz

ghost commented 11 years ago

Here is my customized query Method in Firebird/Connection/Standard.php

works very well so far.

public function query($sql, $type = 'array') {
    if ( ! $this->is_connected()) {
        throw new Throwable_SQL_Exception('Message: Failed to query SQL statement. Reason: Unable to find connection.');
    }
    $result_set = $this->cache($sql, $type);
    if ($result_set !== NULL) {
        $this->sql = $sql;
        return $result_set;
    }
    $command_id = @ibase_query($this->resource_id, $sql);
    if ($command_id === FALSE) {
        throw new Throwable_SQL_Exception('Message: Failed to query SQL statement. Reason: :reason', array(':reason' => ibase_errmsg()));
    }

    $columns = ibase_num_fields($command_id);
    $blob_fields = array();
    for ($i = 0; $i < $columns; $i++) {
        $col_info = ibase_field_info($command_id, $i);
        if ($col_info["type"]=="BLOB") {
            $blob_fields[] = $col_info["name"];
        }
    }

    $records = array();
    $size = 0;
    while ($record = ibase_fetch_assoc($command_id)) {

        foreach ($blob_fields as $field_name) {
            $blob_info = ibase_blob_info($this->resource_id, $record[$field_name]);
            if ($blob_info['isnull']) {
                continue;
            }
            $blob_handle = ibase_blob_open($this->resource_id, $record[$field_name]);

            $new_value = '';
            for ($i = 0; $i < $blob_info[1]; $i++){
                $read_size = $blob_info[2];
                if ($i == ($blob_info[1] - 1)){
                    $read_size = $blob_info[0] - (($blob_info[1] - 1) * $blob_info[2]);
                }
                $new_value .= ibase_blob_get($blob_handle, $read_size);
            }

            if (strlen($new_value)) {
                $record[$field_name] = $new_value;
            }

            ibase_blob_close($blob_handle);
        }

        $records[] = DB_Connection::type_cast($type, $record);
        $size++;
    }
    @ibase_free_result($command_id);
    $result_set = $this->cache($sql, $type, new DB_ResultSet($records, $size, $type));
    $this->sql = $sql;
    return $result_set;
}
ghost commented 11 years ago

Solution above is not a good idea...slows down everything and should be moved into the blob field source. I am working on a Solution and will post it here. I will do this also for the other database types.