Completed
Push — master ( 892c06...ada878 )
by Marco
11:56
created

ModelManager::updateOrInsert()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
namespace Childish\database;
3
4
use Childish\ChildishModel;
5
use Childish\query\Builder;
6
use Childish\support\Tools;
7
8
/**
9
 * ModelManager
10
 *
11
 * @author    Pu ShaoWei <[email protected]>
12
 * @date      2017/12/13
13
 * @package   Childish\database
14
 * @version   1.0
15
 */
16
class ModelManager
17
{
18
    /**
19
     * The base query builder instance.
20
     *
21
     * @var \Childish\query\Builder
22
     */
23
    protected $query;
24
25
    /**
26
     * The model being queried.
27
     *
28
     * @var \Childish\ChildishModel
29
     */
30
    protected $model;
31
32
    /**
33
     * The query union statements.
34
     *
35
     * @var array
36
     */
37
    public $unions;
38
    /**
39
     * The methods that should be returned from query builder.
40
     *
41
     * @var array
42
     */
43
    protected $passthru = [
44
        'insert', 'insertGetId', 'getBindings', 'toSql',
45
        'exists', 'count', 'min', 'max', 'avg', 'sum', 'getConnection',
46
    ];
47
48
49
    /**
50
     * Create a new Eloquent query builder instance.
51
     *
52
     * @param  \Childish\query\Builder $query
53
     * @return mixed|void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
54
     */
55
    public function __construct(Builder $query)
56
    {
57
        $this->query = $query;
58
    }
59
60
    /**
61
     * Set a model instance for the model being queried.
62
     *
63
     * @param  \Childish\ChildishModel $model
64
     * @return $this
65
     */
66
    public function setModel(ChildishModel $model)
67
    {
68
        $this->model = $model;
69
70
        $this->query->from($model->getTable());
71
72
        return $this;
73
    }
74
75
    /**
76
     * Get the model instance being queried.
77
     *
78
     * @return \Childish\ChildishModel
79
     */
80
    public function getModel()
81
    {
82
        return $this->model;
83
    }
84
85
    /**
86
     * update
87
     *
88
     * @param $values
89
     * @return int
90
     */
91
    public function update($values)
92
    {
93
        return $this->getQuery()->update($this->addUpdatedAtColumn($values));
94
    }
95
96
    /**
97
     * insert
98
     *
99
     * @param $values
100
     * @return int
101
     */
102
    public function insert($values)
103
    {
104
        return $this->getQuery()->insert($this->addInsertedAtColumn($values));
105
    }
106
107
    /**
108
     * insertGetId
109
     *
110
     * @param $values
111
     * @return int
112
     */
113
    public function insertGetId($values)
114
    {
115
        $result = $this->addInsertedAtColumn($this->model->checkData($values));
0 ignored issues
show
Bug introduced by
The method checkData() does not seem to exist on object<Childish\ChildishModel>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
116
        return $this->getQuery()->insertGetId($result);
117
    }
118
119
    /**
120
     * updateOrInsert
121
     *
122
     * @param $values
123
     * @return bool
124
     */
125
    public function updateOrInsert($values)
126
    {
127
        return $this->getQuery()->updateOrInsert($this->model->checkData($values));
0 ignored issues
show
Bug introduced by
The method checkData() does not seem to exist on object<Childish\ChildishModel>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
128
    }
129
130
    /**
131
     * Get a single column's value from the first result of a query.
132
     *
133
     * @param  string $column
134
     * @return mixed
135
     */
136
    public function value($column)
137
    {
138
        if ($result = $this->first([$column])) {
139
            return $result->{$column};
140
        }
141
    }
142
143
    /**
144
     * Execute the query as a "select" statement.
145
     *
146
     * @param  array $columns
147
     * @return \Childish\support\Collection|static[]\
0 ignored issues
show
Documentation introduced by
The doc-type \Childish\support\Collection|static[]\ could not be parsed: Expected "|" or "end of type", but got "\" at position 37. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
148
     */
149
    public function get($columns = ['*'])
150
    {
151
        return $this->query->get($columns);
152
    }
153
154
    /**
155
     * Get the hydrated models without eager loading.
156
     *
157
     * @param  array $columns
158
     * @return \Childish\ChildishModel[]
159
     */
160
    public function getModels($columns = ['*'])
161
    {
162
        return $this->model->hydrate(
0 ignored issues
show
Bug introduced by
The method hydrate() does not seem to exist on object<Childish\ChildishModel>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
163
            $this->query->get($columns)->all()
164
        )->all();
165
    }
166
167
    /**
168
     * Create a collection of models from plain arrays.
169
     *
170
     * @param  array $items
171
     * @return \Childish\support\Collection
172
     */
173
    public function hydrate(array $items)
174
    {
175
        $instance = $this->newModelInstance();
176
177
        return $instance->newCollection(array_map(function ($item) use ($instance) {
178
            return $instance->newFromBuilder($item);
179
        }, $items));
180
    }
181
182
    /**
183
     * Create a new instance of the model being queried.
184
     *
185
     * @param  array $attributes
186
     * @return \Childish\ChildishModel
187
     */
188
    public function newModelInstance($attributes = [])
189
    {
190
        return $this->model->newInstance($attributes)->setConnection(
191
            $this->query->getConnection()->getName()
192
        );
193
    }
194
195
196
    /**
197
     * Execute the query and get the first result.
198
     *
199
     * @param  array $columns
200
     * @return \Childish\ChildishModel|static|null
201
     */
202
    public function first($columns = ['*'])
203
    {
204
        return $this->take(1)->get($columns)->first();
205
    }
206
207
    /**
208
     * Alias to set the "limit" value of the query.
209
     *
210
     * @param  int $value
211
     * @return \Childish\query\Builder|static
212
     */
213
    public function take($value)
214
    {
215
        return $this->limit($value);
216
    }
217
218
    /**
219
     * Set the "limit" value of the query.
220
     *
221
     * @param  int $value
222
     * @return $this
223
     */
224
    public function limit($value)
225
    {
226
        $property = $this->unions ? 'unionLimit' : 'limit';
227
228
        if ($value >= 0) {
229
            $this->$property = $value;
230
        }
231
232
        return $this;
233
    }
234
235
236
    /**
237
     * Get the underlying query builder instance.
238
     *
239
     * @return \Childish\query\Builder
240
     */
241
    public function getQuery()
242
    {
243
        return $this->query;
244
    }
245
246
    /**
247
     * Set the underlying query builder instance.
248
     *
249
     * @param  \Childish\query\Builder $query
250
     * @return $this
251
     */
252
    public function setQuery($query)
253
    {
254
        $this->query = $query;
255
256
        return $this;
257
    }
258
259
260
    /**
261
     * Add the "updated at" column to an array of values.
262
     *
263
     * @param  array $values
264
     * @return array
265
     */
266
    protected function addUpdatedAtColumn(array $values)
267
    {
268
        if (!$this->model->timestamps) {
269
            return $values;
270
        }
271
272
        return Tools::add(
273
            $values, $this->model->getUpdatedAtColumn(),
274
            $this->model->freshTimestampString()
275
        );
276
    }
277
278
    /**
279
     * Add the "create_time at" column to an array of values.
280
     *
281
     * @param array $values
282
     * @return array
283
     */
284
    protected function addInsertedAtColumn(array $values)
285
    {
286
        if (!$this->model->timestamps) {
287
            return $values;
288
        }
289
290
        return Tools::add(
291
            $values, $this->model->getCreatedAtColumn(),
292
            $this->model->freshTimestampString()
293
        );
294
    }
295
296
297
    /**
298
     * Increment a column's value by a given amount.
299
     *
300
     * @param  string $column
301
     * @param  int    $amount
302
     * @param  array  $extra
303
     * @return int
304
     */
305
    public function increment($column, $amount = 1, array $extra = [])
306
    {
307
        return $this->getQuery()->increment(
308
            $column, $amount, $this->addUpdatedAtColumn($extra)
309
        );
310
    }
311
312
    /**
313
     * Delete a record from the database.
314
     *
315
     * @return mixed
316
     */
317
    public function delete()
318
    {
319
        return $this->getQuery()->delete();
320
    }
321
322
    /**
323
     * Dynamically handle calls into the query instance.
324
     *
325
     * @param  string $method
326
     * @param  array  $parameters
327
     * @return mixed
328
     */
329
    public function __call($method, $parameters)
330
    {
331
        if (in_array($method, $this->passthru)) {
332
            return $this->getQuery()->{$method}(...$parameters);
333
        }
334
        $this->query->{$method}(...$parameters);
335
        return $this;
336
    }
337
338
    /**
339
     * Force a clone of the underlying query builder when cloning.
340
     *
341
     * @return void
342
     */
343
    public function __clone()
344
    {
345
        $this->query = clone $this->query;
346
    }
347
}