Completed
Pull Request — master (#209)
by
unknown
07:58
created

DynamoDbModel::getItemCount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 7
ccs 5
cts 5
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace BaoPham\DynamoDb;
4
5
use Exception;
6
use DateTime;
7
use Illuminate\Database\Eloquent\Model;
8
9
/**
10
 * Class DynamoDbModel.
11
 */
12
abstract class DynamoDbModel extends Model
13
{
14
    /**
15
     * Always set this to false since DynamoDb does not support incremental Id.
16
     *
17
     * @var bool
18
     */
19
    public $incrementing = false;
20
21
    /**
22
     * @var \BaoPham\DynamoDb\DynamoDbClientInterface
23
     */
24
    protected static $dynamoDb;
25
26
    /**
27
     * @deprecated
28
     * @var \Aws\DynamoDb\Marshaler
29
     */
30
    protected $marshaler;
31
32
    /**
33
     * @deprecated
34
     * @var \BaoPham\DynamoDb\EmptyAttributeFilter
35
     */
36
    protected $attributeFilter;
37
38
    /**
39
     * Indexes.
40
     *   [
41
     *     '<simple_index_name>' => [
42
     *          'hash' => '<index_key>'
43
     *     ],
44
     *     '<composite_index_name>' => [
45
     *          'hash' => '<index_hash_key>',
46
     *          'range' => '<index_range_key>'
47
     *     ],
48
     *   ]
49
     *
50
     * @var array
51
     */
52
    protected $dynamoDbIndexKeys = [];
53
54
    /**
55
     * Array of your composite key.
56
     * ['<hash>', '<range>']
57
     *
58
     * @var array
59
     */
60
    protected $compositeKey = [];
61
62
    /**
63
     * Default Date format
64
     * ISO 8601 Compliant
65
     */
66
    protected $dateFormat = DateTime::ATOM;
67
68
69 131
    public function __construct(array $attributes = [])
70
    {
71 131
        $this->bootIfNotBooted();
72
73 131
        $this->syncOriginal();
74
75 131
        $this->fill($attributes);
76
77 131
        $this->setupDynamoDb();
78 131
    }
79
80
    /**
81
     * Get the DynamoDbClient service that is being used by the models.
82
     *
83
     * @return DynamoDbClientInterface
84
     */
85 3
    public static function getDynamoDbClientService()
86
    {
87 3
        return static::$dynamoDb;
88
    }
89
90
    /**
91
     * Set the DynamoDbClient used by models.
92
     *
93
     * @param DynamoDbClientInterface $dynamoDb
94
     *
95
     * @return void
96
     */
97 146
    public static function setDynamoDbClientService(DynamoDbClientInterface $dynamoDb)
98
    {
99 146
        static::$dynamoDb = $dynamoDb;
100 146
    }
101
102
    /**
103
     * Unset the DynamoDbClient service for models.
104
     *
105
     * @return void
106
     */
107 3
    public static function unsetDynamoDbClientService()
108
    {
109 3
        static::$dynamoDb = null;
110 3
    }
111
112 131
    protected function setupDynamoDb()
113
    {
114 131
        $this->marshaler = static::$dynamoDb->getMarshaler();
115 131
        $this->attributeFilter = static::$dynamoDb->getAttributeFilter();
116 131
    }
117
118 92
    public function newCollection(array $models = [], $index = null)
119
    {
120 92
        return new DynamoDbCollection($models, $index);
121
    }
122
123 8
    public function save(array $options = [])
124
    {
125 8
        $create = !$this->exists;
126
127 8
        if ($this->fireModelEvent('saving') === false) {
128
            return false;
129
        }
130
131 8
        if ($create && $this->fireModelEvent('creating')  === false) {
132
            return false;
133
        }
134
135 8
        if (!$create && $this->fireModelEvent('updating') === false) {
136
            return false;
137
        }
138
139 8
        if ($this->usesTimestamps()) {
140 8
            $this->updateTimestamps();
141
        }
142
143 8
        $saved = $this->newQuery()->save();
144
145 8
        if (!$saved) {
146
            return $saved;
147
        }
148
149 8
        $this->exists = true;
150 8
        $this->wasRecentlyCreated = $create;
151 8
        $this->fireModelEvent($create ? 'created' : 'updated', false);
152
153 8
        $this->finishSave($options);
154
155 8
        return $saved;
156
    }
157
158
    /**
159
     * Saves the model to DynamoDb asynchronously and returns a promise
160
     * @param array $options
161
     * @return bool|\GuzzleHttp\Promise\Promise
162
     */
163 6
    public function saveAsync(array $options = [])
164
    {
165 6
        $create = !$this->exists;
166
167 6
        if ($this->fireModelEvent('saving') === false) {
168
            return false;
169
        }
170
171 6
        if ($create && $this->fireModelEvent('creating')  === false) {
172
            return false;
173
        }
174
175 6
        if (!$create && $this->fireModelEvent('updating') === false) {
176
            return false;
177
        }
178
179 6
        if ($this->usesTimestamps()) {
180 6
            $this->updateTimestamps();
181
        }
182
183 6
        $savePromise = $this->newQuery()->saveAsync();
184
185
        $savePromise->then(function ($result) use ($create, $options) {
186 6
            if (array_get($result, '@metadata.statusCode') === 200) {
0 ignored issues
show
Deprecated Code introduced by
The function array_get() has been deprecated: Arr::get() should be used directly instead. Will be removed in Laravel 6.0. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

186
            if (/** @scrutinizer ignore-deprecated */ array_get($result, '@metadata.statusCode') === 200) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
187 6
                $this->exists = true;
188 6
                $this->wasRecentlyCreated = $create;
189 6
                $this->fireModelEvent($create ? 'created' : 'updated', false);
190
191 6
                $this->finishSave($options);
192
            }
193 6
        });
194
195 6
        return $savePromise;
196
    }
197
198 3
    public function update(array $attributes = [], array $options = [])
199
    {
200 3
        return $this->fill($attributes)->save();
201
    }
202
203 2
    public function updateAsync(array $attributes = [], array $options = [])
204
    {
205 2
        return $this->fill($attributes)->saveAsync($options);
206
    }
207
208
    public static function create(array $attributes = [])
209
    {
210
        $model = new static;
211
212
        $model->fill($attributes)->save();
213
214
        return $model;
215
    }
216
217 2
    public function delete()
218
    {
219 2
        if (is_null($this->getKeyName())) {
0 ignored issues
show
introduced by
The condition is_null($this->getKeyName()) is always false.
Loading history...
220
            throw new Exception('No primary key defined on model.');
221
        }
222
223 2
        if ($this->exists) {
224 2
            if ($this->fireModelEvent('deleting') === false) {
225
                return false;
226
            }
227
228 2
            $this->exists = false;
229
230 2
            $success = $this->newQuery()->delete();
231
232 2
            if ($success) {
233 2
                $this->fireModelEvent('deleted', false);
234
            }
235
236 2
            return $success;
237
        }
238
    }
239
240 2
    public function deleteAsync()
241
    {
242 2
        if (is_null($this->getKeyName())) {
0 ignored issues
show
introduced by
The condition is_null($this->getKeyName()) is always false.
Loading history...
243
            throw new Exception('No primary key defined on model.');
244
        }
245
246 2
        if ($this->exists) {
247 2
            if ($this->fireModelEvent('deleting') === false) {
248
                return false;
249
            }
250
251 2
            $this->exists = false;
252
253 2
            $deletePromise = $this->newQuery()->deleteAsync();
254
255
            $deletePromise->then(function () {
256 2
                $this->fireModelEvent('deleted', false);
257 2
            });
258
259 2
            return $deletePromise;
260
        }
261
    }
262
263 7
    public static function all($columns = [])
264
    {
265 7
        $instance = new static;
266
267 7
        return $instance->newQuery()->get($columns);
268
    }
269
270 2
    public function refresh()
271
    {
272 2
        if (! $this->exists) {
273
            return $this;
274
        }
275
276 2
        $query = $this->newQuery();
277
278 2
        $refreshed = $query->find($this->getKeys());
279
280 2
        $this->setRawAttributes($refreshed->toArray());
281
282 2
        return $this;
283
    }
284
285
    /**
286
     * @return DynamoDbQueryBuilder
287
     */
288 131
    public function newQuery()
289
    {
290 131
        $builder = new DynamoDbQueryBuilder($this);
291
292 131
        foreach ($this->getGlobalScopes() as $identifier => $scope) {
293 7
            $builder->withGlobalScope($identifier, $scope);
294
        }
295
296 131
        return $builder;
297
    }
298
299 110
    public function hasCompositeKey()
300
    {
301 110
        return !empty($this->compositeKey);
302
    }
303
304
    /**
305
     * @deprecated
306
     * @param $item
307
     * @return array
308
     */
309
    public function marshalItem($item)
310
    {
311
        return $this->marshaler->marshalItem($item);
312
    }
313
314
    /**
315
     * @deprecated
316
     * @param $value
317
     * @return array
318
     */
319
    public function marshalValue($value)
320
    {
321
        return $this->marshaler->marshalValue($value);
322
    }
323
324
    /**
325
     * @deprecated
326
     * @param $item
327
     * @return array|\stdClass
328
     */
329
    public function unmarshalItem($item)
330
    {
331
        return $this->marshaler->unmarshalItem($item);
332
    }
333
334 36
    public function setId($id)
335
    {
336 36
        if (!is_array($id)) {
337 14
            $this->setAttribute($this->getKeyName(), $id);
338
339 14
            return $this;
340
        }
341
342 24
        foreach ($id as $keyName => $value) {
343 24
            $this->setAttribute($keyName, $value);
344
        }
345
346 24
        return $this;
347
    }
348
349
    /**
350
     * @return \Aws\DynamoDb\DynamoDbClient
351
     */
352 131
    public function getClient()
353
    {
354 131
        return static::$dynamoDb->getClient($this->connection);
355
    }
356
357
    /**
358
     * Get the value of the model's primary key.
359
     *
360
     * @return mixed
361
     */
362
    public function getKey()
363
    {
364
        return $this->getAttribute($this->getKeyName());
365
    }
366
367
    /**
368
     * Get the value of the model's primary / composite key.
369
     * Use this if you always want the key values in associative array form.
370
     *
371
     * @return array
372
     *
373
     * ['id' => 'foo']
374
     *
375
     * or
376
     *
377
     * ['id' => 'foo', 'id2' => 'bar']
378
     */
379 46
    public function getKeys()
380
    {
381 46
        if ($this->hasCompositeKey()) {
382 22
            $key = [];
383
384 22
            foreach ($this->compositeKey as $name) {
385 22
                $key[$name] = $this->getAttribute($name);
386
            }
387
388 22
            return $key;
389
        }
390
391 24
        $name = $this->getKeyName();
392
393 24
        return [$name => $this->getAttribute($name)];
394
    }
395
396
    /**
397
     * Get the primary key for the model.
398
     *
399
     * @return string
400
     */
401 28
    public function getKeyName()
402
    {
403 28
        return $this->primaryKey;
404
    }
405
406
    /**
407
     * Get the primary/composite key for the model.
408
     *
409
     * @return array
410
     */
411 104
    public function getKeyNames()
412
    {
413 104
        return $this->hasCompositeKey() ? $this->compositeKey : [$this->primaryKey];
414
    }
415
416
    /**
417
     * @return array
418
     */
419 70
    public function getDynamoDbIndexKeys()
420
    {
421 70
        return $this->dynamoDbIndexKeys;
422
    }
423
424
    /**
425
     * @param array $dynamoDbIndexKeys
426
     */
427
    public function setDynamoDbIndexKeys($dynamoDbIndexKeys)
428
    {
429
        $this->dynamoDbIndexKeys = $dynamoDbIndexKeys;
430
    }
431
432
    /**
433
     * @deprecated
434
     * @return \Aws\DynamoDb\Marshaler
435
     */
436
    public function getMarshaler()
437
    {
438
        return $this->marshaler;
439
    }
440
441
    /**
442
     * Remove non-serializable properties when serializing.
443
     *
444
     * @return array
445
     */
446 2
    public function __sleep()
447
    {
448 2
        return array_keys(
449 2
            array_except(get_object_vars($this), ['marshaler', 'attributeFilter'])
0 ignored issues
show
Deprecated Code introduced by
The function array_except() has been deprecated: Arr::except() should be used directly instead. Will be removed in Laravel 6.0. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

449
            /** @scrutinizer ignore-deprecated */ array_except(get_object_vars($this), ['marshaler', 'attributeFilter'])

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
450
        );
451
    }
452
453
    /**
454
     * When a model is being unserialized, check if it needs to be booted and setup DynamoDB.
455
     *
456
     * @return void
457
     */
458 2
    public function __wakeup()
459
    {
460 2
        parent::__wakeup();
461 2
        $this->setupDynamoDb();
462 2
    }
463
464
    /**
465
     * Returns approximate count of items in DynamoDB table for current model
466
     * This item count is updated every six hours by AWS
467
     *
468
     * @return int
469
     */
470 1
    public static function getItemCount()
471
    {
472 1
        $model = new static;
473 1
        $describeTable = $model->getClient()->describeTable([
474 1
            'TableName' => $model->getTable()
475
        ]);
476 1
        return $describeTable->get('Table')['ItemCount'];
477
    }
478
}
479