| | <?php |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | namespace think\model\relation; |
| |
|
| | use think\db\Query; |
| | use think\Exception; |
| | use think\Loader; |
| | use think\Model; |
| | use think\model\Relation; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | abstract class OneToOne extends Relation |
| | { |
| | |
| | protected $eagerlyType = 1; |
| | |
| | protected $joinType; |
| | |
| | protected $bindAttr = []; |
| | |
| | protected $relation; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | public function joinType($type) |
| | { |
| | $this->joinType = $type; |
| | return $this; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function eagerly(Query $query, $relation, $subRelation, $closure, $first) |
| | { |
| | $name = Loader::parseName(basename(str_replace('\\', '/', get_class($query->getModel())))); |
| |
|
| | if ($first) { |
| | $table = $query->getTable(); |
| | $query->table([$table => $name]); |
| | if ($query->getOptions('field')) { |
| | $field = $query->getOptions('field'); |
| | $query->removeOption('field'); |
| | } else { |
| | $field = true; |
| | } |
| | $query->field($field, false, $table, $name); |
| | $field = null; |
| | } |
| |
|
| | |
| | $joinTable = $this->query->getTable(); |
| | $joinAlias = $relation; |
| | $query->via($joinAlias); |
| |
|
| | if ($this instanceof BelongsTo) { |
| | $query->join([$joinTable => $joinAlias], $name . '.' . $this->foreignKey . '=' . $joinAlias . '.' . $this->localKey, $this->joinType); |
| | } else { |
| | $query->join([$joinTable => $joinAlias], $name . '.' . $this->localKey . '=' . $joinAlias . '.' . $this->foreignKey, $this->joinType); |
| | } |
| |
|
| | if ($closure) { |
| | |
| | call_user_func_array($closure, [ & $query]); |
| | |
| | |
| | if ($query->getOptions('with_field')) { |
| | $field = $query->getOptions('with_field'); |
| | $query->removeOption('with_field'); |
| | } |
| | } elseif (isset($this->option['field'])) { |
| | $field = $this->option['field']; |
| | } |
| | $query->field(isset($field) ? $field : true, false, $joinTable, $joinAlias, $relation . '__'); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | abstract protected function eagerlySet(&$resultSet, $relation, $subRelation, $closure); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | abstract protected function eagerlyOne(&$result, $relation, $subRelation, $closure); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) |
| | { |
| | if (1 == $this->eagerlyType) { |
| | |
| | $this->eagerlySet($resultSet, $relation, $subRelation, $closure); |
| | } else { |
| | |
| | foreach ($resultSet as $result) { |
| | $this->match($this->model, $relation, $result); |
| | } |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function eagerlyResult(&$result, $relation, $subRelation, $closure) |
| | { |
| | if (1 == $this->eagerlyType) { |
| | |
| | $this->eagerlyOne($result, $relation, $subRelation, $closure); |
| | } else { |
| | |
| | $this->match($this->model, $relation, $result); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | public function save($data) |
| | { |
| | if ($data instanceof Model) { |
| | $data = $data->getData(); |
| | } |
| | $model = new $this->model; |
| | |
| | $data[$this->foreignKey] = $this->parent->{$this->localKey}; |
| | return $model->save($data) ? $model : false; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | public function setEagerlyType($type) |
| | { |
| | $this->eagerlyType = $type; |
| | return $this; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | public function getEagerlyType() |
| | { |
| | return $this->eagerlyType; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | public function bind($attr) |
| | { |
| | if (is_string($attr)) { |
| | $attr = explode(',', $attr); |
| | } |
| | $this->bindAttr = $attr; |
| | return $this; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | public function getBindAttr() |
| | { |
| | return $this->bindAttr; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function relationCount($result, $closure) |
| | { |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | protected function match($model, $relation, &$result) |
| | { |
| | |
| | foreach ($result->getData() as $key => $val) { |
| | if (strpos($key, '__')) { |
| | list($name, $attr) = explode('__', $key, 2); |
| | if ($name == $relation) { |
| | $list[$name][$attr] = $val; |
| | unset($result->$key); |
| | } |
| | } |
| | } |
| |
|
| | if (isset($list[$relation])) { |
| | $relationModel = new $model($list[$relation]); |
| | $relationModel->setParent(clone $result); |
| | $relationModel->isUpdate(true); |
| |
|
| | if (!empty($this->bindAttr)) { |
| | $this->bindAttr($relationModel, $result, $this->bindAttr); |
| | } |
| | } else { |
| | $relationModel = null; |
| | } |
| | $result->setRelation(Loader::parseName($relation), $relationModel); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | protected function bindAttr($model, &$result, $bindAttr) |
| | { |
| | foreach ($bindAttr as $key => $attr) { |
| | $key = is_numeric($key) ? $attr : $key; |
| | if (isset($result->$key)) { |
| | throw new Exception('bind attr has exists:' . $key); |
| | } else { |
| | $result->setAttr($key, $model ? $model->$attr : null); |
| | } |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | protected function eagerlyWhere($model, $where, $key, $relation, $subRelation = '', $closure = false) |
| | { |
| | $this->baseQuery = true; |
| |
|
| | |
| | if ($closure) { |
| | call_user_func_array($closure, [ & $model]); |
| | if ($field = $model->getOptions('with_field')) { |
| | $model->field($field)->removeOption('with_field'); |
| | } |
| | } |
| | $list = $model->where($where)->with($subRelation)->select(); |
| |
|
| | |
| | $data = []; |
| | foreach ($list as $set) { |
| | $data[$set->$key] = $set; |
| | } |
| | return $data; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function getRelationCountQuery($closure, &$name = null) |
| | { |
| | throw new Exception('relation not support: withCount'); |
| | } |
| | } |
| |
|