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

ORM insert not working #25

Closed matesko closed 12 years ago

matesko commented 12 years ago

mysql

take simple model (id is autoincrement field):

    $this->fields = array(
      'id'    => new DB_ORM_Field_Integer($this, array()),
      'tekst' => new DB_ORM_Field_String($this, array())
    );

this code does not insert:

    $model = DB_ORM::model('testt');
    $values = array(
      'tekst' => time());
    $model->load($values);
    $model->save();

if i set id nothing happens also.

if id value exists in database update is executed.

matesko commented 12 years ago

when following methods in Base_DB_ORM_Model are changed as such, it works.

but please do verify

// do not append $buffer if null value
// return null if buffer empty

    protected function hash_code() {
        $self = get_class($this);
        $primary_key = call_user_func(array($self, 'primary_key'));
        if (is_array($primary_key) && !empty($primary_key)) {
            $buffer = '';
            foreach ($primary_key as $column) {
                if ( ! isset($this->fields[$column])) {
                    throw new Kohana_InvalidProperty_Exception('Message: Unable to generate hash code for model. Reason: Primary key contains a non-existent field name.', array(':primary_key' => $primary_key));
                }
                if ( ! is_null($this->fields[$column]->value)) {
                    $buffer .= "{$column}={$this->fields[$column]->value}";
                }
            }
            return $buffer == '' ? null : sha1($buffer);
        }
        throw new Kohana_EmptyCollection_Exception('Message: Unable to generate hash code for model. Reason: No primary key has been declared.', array(':primary_key' => $primary_key));
    }

// set metadata only if loaded from database
    public function load(Array $columns = array()) {
        if (empty($columns)) {
            $self = get_class($this);
            $primary_key = call_user_func(array($self, 'primary_key'));
            if ( ! is_array($primary_key) || empty($primary_key)) {
                throw new Kohana_Marshalling_Exception('Message: Failed to load record from database. Reason: No primary key has been declared.');
            }
            $data_source = call_user_func(array($self, 'data_source'));
            $table = call_user_func(array($self, 'table'));
            $builder = DB_SQL::select($data_source)->from($table)->limit(1);
            foreach ($primary_key as $column) {
                $builder->where($column, DB_SQL_Operator::_EQUAL_TO_, $this->fields[$column]->value);
            }
            $record = $builder->query();
            if ( ! $record->is_loaded()) {
                throw new Kohana_Marshalling_Exception('Message: Failed to load record from database. Reason: Unable to match primary key with a record.');
            }
            $columns = $record->fetch(0);

      $this->metadata['loaded'] = TRUE;
        $this->metadata['saved'] = $this->hash_code();
        }
        foreach ($columns as $column => $value) {
            if ($this->is_field($column)) {
                $this->fields[$column]->value = $value;
                $this->metadata['loaded'] = TRUE;
            }
            else if ($this->is_alias($column)) {
                $this->aliases[$column]->value = $value;
            }
            else if ($this->is_adaptor($column)) {
                $this->adaptors[$column]->value = $value;
            }
        }
    }
spadefoot commented 12 years ago

Yep, you are totally right. I really appreciate you taking the time to debug it and submit a fix.