public static function update_counters($model, $ids, array $counters) { $query = Jam::update($model); foreach ($counters as $name => $change) { $change = (int) $change; $operator = $change < 0 ? '-' : '+'; $query->value($name, DB::expr(strtr('(COALESCE(:name, 0) :operator :value)', array(':value' => abs($change), ':operator' => $operator, ':name' => Database::instance($query->meta()->db())->quote_column($name))))); } return $query->where(':primary_key', 'IN', (array) $ids); }
public function model_after_save(Jam_Model $model, Jam_Event_Data $data, $changed) { if ($value = Arr::get($changed, $this->name)) { if ($item = $model->{$this->name}) { $old_path = $model->children_path(); $model->update_fields('path', $item->children_path()); $new_path = $model->children_path(); Jam::update($model)->where('path', 'LIKE', $old_path . '%')->update_children($old_path, $new_path)->execute(); } } }
public function model_call_move_position_to(Jam_Model $model, Jam_Event_Data $data, Jam_Model $to) { $builder = Jam::update($this->_model)->where_in_scope($model); if ($model->{$this->_field} !== $to->{$this->_field}) { if ($model->{$this->_field} > $to->{$this->_field}) { $builder->where($this->_field, '>=', $to->{$this->_field})->where($this->_field, '<', $model->{$this->_field})->value($this->_field, DB::expr($this->_field . ' + 1')); } else { $builder->where($this->_field, '<=', $to->{$this->_field})->where($this->_field, '>', $model->{$this->_field})->value($this->_field, DB::expr($this->_field . ' - 1')); } $builder->execute(); $model->update_fields($this->_field, $to->{$this->_field}); } else { $model->update_fields($this->_field, $model->{$this->_field} + 1); } }
/** * Called after save. * If the slug uses the primary key it is built after save and it is updated * with an additional database query. * * @param Jam_Model $model */ public function model_after_save(Jam_Model $model) { if ($this->auto_save() and $this->uses_primary_key() and !$model->changed('slug')) { // Use the built in slug transformation $model->slug = $model->build_slug(); if ($model->slug != $model->original('slug')) { Jam::update($this->_model)->where_key($model->id())->value('slug', $model->slug)->execute(); } } }
/** * Persist this collection in the database * @param Jam_Model $model */ public function model_after_delete(Jam_Model $model) { $path = $model->children_path(); Jam::update($model)->where('path', 'LIKE', $path . '%')->update_children($path, '')->execute(); }
/** * Creates or updates the current record. * * @param bool|null $validate * @return Kohana_Jam_Model */ public function save($validate = NULL) { if ($this->_is_saving) { throw new Kohana_Exception("Cannot save a model that is already in the process of saving"); } $key = $this->_original[$this->meta()->primary_key()]; // Run validation if ($validate !== FALSE) { $this->check_insist(); } $this->_is_saving = TRUE; // These will be processed later $values = $defaults = array(); if ($this->meta()->events()->trigger('model.before_save', $this, array($this->_changed)) === FALSE) { return $this; } // Trigger callbacks and ensure we should proceed $event_type = $key ? 'update' : 'create'; if ($this->meta()->events()->trigger('model.before_' . $event_type, $this, array($this->_changed)) === FALSE) { return $this; } $this->_move_retrieved_to_changed(); // Iterate through all fields in original in case any unchanged fields // have convert() behavior like timestamp updating... // foreach (array_merge($this->_original, $this->_changed) as $column => $value) { if ($field = $this->meta()->field($column)) { // Only save in_db values if ($field->in_db) { // See if field wants to alter the value on save() $value = $field->convert($this, $value, $key); // Only set the value to be saved if it's changed from the original if ($value !== $this->_original[$column]) { $values[$field->column] = $value; } elseif (!$key and (!$this->changed($field->name) or $field->default === $value) and !$field->primary) { $defaults[$field->column] = $field->default; } } } } // If we have a key, we're updating if ($key) { // Do we even have to update anything in the row? if ($values) { Jam::update($this)->where_key($key)->set($values)->execute(); } } else { $insert_values = array_merge($defaults, $values); list($id) = Jam::insert($this)->columns(array_keys($insert_values))->values(array_values($insert_values))->execute(); // Gotta make sure to set this $key = $values[$this->meta()->primary_key()] = $id; } // Re-set any saved values; they may have changed $this->set($values); $this->_loaded = $this->_saved = TRUE; $this->meta()->events()->trigger('model.after_save', $this, array($this->_changed, $event_type)); $this->meta()->events()->trigger('model.after_' . $event_type, $this, array($this->_changed)); // Set the changed data back as original $this->_original = array_merge($this->_original, $this->_changed); $this->_changed = array(); foreach ($this->_retrieved as $name => $retrieved) { if ($association = $this->meta()->association($name)) { if ($association instanceof Jam_Association_Collection) { $retrieved->clear_changed(); } } elseif ($field = $this->meta()->field($name) and $field->in_db) { unset($this->_retrieved[$name]); } } $this->_is_saving = FALSE; return $this; }
/** * $model->restore_delete() Perform this to "undelete" a model * * @param Jam_Model $model * @param Jam_Event_Data $data */ public function model_call_restore_delete(Jam_Model $model) { Jam::update($this->_model)->where_key($model->id())->deleted(Jam_Behavior_Paranoid::DELETED)->value($this->_field, FALSE)->execute(); }
/** * @covers ::builder_call_update_children */ public function test_update_children() { $category = Jam::update('category')->where('id', '=', 8)->update_children('1/3', '1/3/6'); $expected = "UPDATE `categories` SET `path` = TRIM(BOTH '/' FROM REPLACE(path, '1/3', '1/3/6')) WHERE `categories`.`id` = 8"; $this->assertEquals($expected, (string) $category); $this->setExpectedException('InvalidArgumentException', 'Can only be used on "update" queries'); $category = Jam::all('category')->where('id', '=', 8)->update_children('1/3', '1/3/6'); }