Пример #1
0
 public function setInformation(array $info)
 {
     parent::setInformation($info);
     $this->cm->attribute = isset($info['key_from']) ? $info['key_from'] : 'id';
     $this->cm->column = $this->cm->t->columnRealName($this->cm->attribute);
     $this->lm->attribute = isset($info['key_to']) ? $info['key_to'] : call_user_func(Cfg::get('buildForeignKey'), $this->cm->t->modelBaseName);
     $this->lm->column = $this->lm->t->columnRealName($this->lm->attribute);
 }
Пример #2
0
 /**
  * @covers SimpleAR\Database\Builder\WhereBuilder::getQueryOptionRelationSeparator
  * @covers WhereBuilder::setQueryOptionRelationSeparator
  */
 public function testQueryOptionRelationSeparator()
 {
     $b = new WhereBuilder();
     $this->assertEquals(Cfg::get('queryOptionRelationSeparator'), $b->getQueryOptionRelationSeparator());
     $b->setQueryOptionRelationSeparator('#');
     $this->assertEquals('#', $b->getQueryOptionRelationSeparator());
     Cfg::set('queryOptionRelationSeparator', '@');
     $b = new WhereBuilder();
     $this->assertEquals('@', $b->getQueryOptionRelationSeparator());
     // Reset the default config option.
     Cfg::set('queryOptionRelationSeparator', '/');
 }
Пример #3
0
 public function setInformation(array $info)
 {
     parent::setInformation($info);
     $this->cm->attribute = isset($info['key_from']) ? $info['key_from'] : 'id';
     $this->cm->column = (array) $this->cm->t->columnRealName($this->cm->attribute);
     $this->lm->attribute = isset($info['key_to']) ? $info['key_to'] : 'id';
     $this->lm->column = (array) $this->lm->t->columnRealName($this->lm->attribute);
     $this->jm = new \StdClass();
     if (isset($info['join_model'])) {
         $this->jm->class = $s = $info['join_model'] . Cfg::get('modelClassSuffix');
         $this->jm->t = $s::table();
         $this->jm->table = $this->jm->t->name;
         $this->jm->from = (array) $this->jm->t->columnRealName(isset($info['join_from']) ? $info['join_from'] : call_user_func(Cfg::get('buildForeignKey'), $this->cm->t->modelBaseName));
         $this->jm->to = (array) $this->jm->t->columnRealName(isset($info['join_to']) ? $info['join_to'] : call_user_func(Cfg::get('buildForeignKey'), $this->lm->t->modelBaseName));
     } else {
         $this->jm->class = null;
         $this->jm->table = isset($info['join_table']) ? $info['join_table'] : $this->cm->table . '_' . $this->lm->table;
         $this->jm->from = (array) (isset($info['join_from']) ? $info['join_from'] : decamelize($this->cm->t->modelBaseName) . '_id');
         $this->jm->to = (array) (isset($info['join_to']) ? $info['join_to'] : decamelize($this->lm->t->modelBaseName) . '_id');
     }
 }
Пример #4
0
 /**
  * Get the separation character of relation names in options.
  *
  * If the separator is not set yet, it fetches it from Config and cache it
  * in current builder instance.
  *
  * @return string The separator.
  *
  * @see Config::$_queryOptionRelationSeparator
  */
 public function getQueryOptionRelationSeparator()
 {
     // Not here? Fetch it.
     if (!$this->_queryOptionRelationSeparator) {
         $sep = Cfg::get('queryOptionRelationSeparator');
         $this->setQueryOptionRelationSeparator($sep);
     }
     return $this->_queryOptionRelationSeparator;
 }
Пример #5
0
 public function setInformation(array $info)
 {
     $this->lm = new \StdClass();
     $this->lm->class = $s = $info['model'] . Cfg::get('modelClassSuffix');
     $this->lm->t = $s::table();
     $this->lm->table = $this->lm->t->name;
     //$this->lm->pk    = $this->lm->t->primaryKey;
     foreach (array('filter', 'conditions', 'order') as $item) {
         if (isset($info[$item])) {
             $this->{$item} = $info[$item];
         }
     }
     if (!empty($info['scope'])) {
         $this->setScope($info['scope']);
     }
 }
Пример #6
0
 /**
  * Updates a instance.
  *
  * @throws Exception if a database error occurs.
  * @return $this
  *
  * @see SimpleAR\Model::_onBeforeUpdate()
  * @see SimpleAR\Model::_onAfterUpdate()
  */
 private function _update()
 {
     $this->_onBeforeUpdate();
     $table = static::table();
     $columns = array_diff_key($table->columns, $table->deprecated);
     // Keys will be attribute names; Values will be attributes values.
     $fields = array();
     // Will contains LM to save in cascade.
     $linkedModels = array();
     // Avoid retrieving config option several times.
     $dateTimeFormat = Cfg::get('databaseDateTimeFormat');
     foreach ($this->_attributes as $key => $value) {
         // Handles actual columns.
         if (isset($columns[$key])) {
             // Transform DateTime object into a database-formatted string.
             if ($value instanceof \DateTime) {
                 $value = $value->format($dateTimeFormat);
             }
             $fields[$key] = $value;
             continue;
         }
         // Handle linked models.
         // $value can be:
         // - a Model instance not saved yet (BelongsTo or HasOne relations);
         // - a Model instance ID (BelongsTo or HasOne relations) (Not
         // implemented).
         //
         // - a Model instance array (HasMany or ManyMany relations);
         // - a Model instance ID array (HasMany or ManyMany relations).
         if (isset(static::$_relations[$key])) {
             $relation = static::relation($key);
             // If it is linked by a BelongsTo instance, update local field.
             if ($relation instanceof Relation\BelongsTo) {
                 if ($value) {
                     // Save in cascade.
                     $value->save();
                     // We use array_merge() and array_combine() in order to handle composed keys.
                     $fields = array_merge($fields, array_combine((array) $relation->cm->attribute, (array) $value->id));
                 }
             } else {
                 $linkedModels[] = array('relation' => static::relation($key), 'object' => $value);
             }
         }
     }
     try {
         $pk = self::table()->getPrimaryKey();
         $query = self::query()->update()->set($fields)->where($pk, array($this->id()))->run();
         // I know code seems (is) redundant, but I am convinced that it is
         // better this way. Treatment of linked model can be different
         // during insert than during update. See ManyMany treatment for
         // example: we delete before inserting.
         foreach ($linkedModels as $a) {
             // Avoid multiple array accesses.
             $relation = $a['relation'];
             $object = $a['object'];
             // Ignore if not Model instance.
             if ($relation instanceof Relation\HasOne) {
                 if ($object instanceof Model) {
                     $attrs = array_combine((array) $relation->lm->attribute, $this->id());
                     $object->set($attrs);
                     $object->save();
                 }
             } elseif ($relation instanceof Relation\HasMany) {
                 // Ignore if not Model instance.
                 // Array cast allows user not to bother to necessarily set an array.
                 foreach ((array) $object as $o) {
                     if ($o instanceof Model) {
                         $attrs = array_combine((array) $relation->lm->attribute, $this->id());
                         $o->set($attrs);
                         $o->save();
                     }
                 }
             } else {
                 // We want to:
                 //  - save linked model instances if not done yet;
                 //  - consider integers as linked model instance IDs;
                 //  - save instances on cascade.
                 //  - link these instances with current model via the
                 //  relation join table. To do this:
                 //      1) Delete all rows of join table that concerns
                 //      current model;
                 //      2) Insert new rows.
                 // Remove all rows from join table. (Easier this way.)
                 self::query()->delete($relation->jm->table)->where((array) $relation->jm->from, $this->id())->run();
                 $values = array();
                 // Array cast allows user not to bother to necessarily set an array.
                 foreach ((array) $object as $m) {
                     if ($m instanceof Model) {
                         $m->save();
                         $values[] = array($this->id(), $m->id());
                     } else {
                         $values[] = array($this->id(), $m);
                     }
                 }
                 // Run insert query only if there are values to insert. It
                 // would throw a PDO Exception otherwise.
                 if ($values) {
                     $fields = array($relation->jm->from, $relation->jm->to);
                     $query = self::query()->insert($relation->jm->table)->fields($fields)->values($values)->run();
                 }
             }
         }
     } catch (DatabaseEx $ex) {
         throw $ex;
     } catch (Exception $ex) {
         throw new Exception('Update failed for ' . get_class($this) . ' with ID: ' . var_export($this->id(), true) . '.', 0, $ex);
     }
     $this->_onAfterUpdate();
     return $this;
 }