Completed
Push — master ( 36b4aa...109cdc )
by Dmitry
01:34
created

Temporal::toggleOverrideIdle()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 9.6333
c 0
b 0
f 0
cc 3
nc 2
nop 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Tarantool\Mapper\Plugin;
6
7
use Carbon\Carbon;
8
use Exception;
9
use Tarantool\Mapper\Mapper;
10
use Tarantool\Mapper\Entity;
11
use Tarantool\Mapper\Plugin;
12
use Tarantool\Mapper\Plugin\Temporal\Aggregator;
13
use Tarantool\Client\Schema\Criteria;
14
use Tarantool\Mapper\Plugin\Temporal\Schema;
15
16
class Temporal extends Plugin
17
{
18
    private $actor;
19
    private $timestamps = [];
20
    private $aggregator;
21
22
    public function __construct(Mapper $mapper)
23
    {
24
        $this->mapper = $mapper;
25
        $this->schema = new Schema($mapper);
0 ignored issues
show
Bug introduced by
The property schema does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
26
        $this->aggregator = new Aggregator($this);
27
    }
28
29
    public function getReference($entity, $id, $target, $date)
30
    {
31
        if (!$this->mapper->getSchema()->hasSpace('_temporal_reference_state')) {
32
            return;
33
        }
34
35
        $entity = $this->entityNameToId($entity);
36
        $target = $this->entityNameToId($target);
37
        $date = $this->getTimestamp($date);
38
39
        $rows = $this->mapper->getClient()->getSpace('_temporal_reference_state')
40
            ->select(Criteria::key([$entity, $id, $target, $date])->andLimit(1)->andLeIterator());
41
42
        if (count($rows)) {
43
            $row = $rows[0];
44
            if ([$entity, $id, $target] == [$row[0], $row[1], $row[2]]) {
45
                $state = $this->mapper->findOne('_temporal_reference_state', [
46
                    'entity' => $entity,
47
                    'id' => $id,
48
                    'target' => $target,
49
                    'begin' => $row[3]
50
                ]);
51
                if (!$state->end || $state->end >= $date) {
52
                    return $state->targetId;
53
                }
54
            }
55
        }
56
    }
57
58
    public function getAggregator()
59
    {
60
        return $this->aggregator;
61
    }
62
63
    public function getReferenceLog($entity, $id, $target)
64
    {
65
        if (!$this->mapper->getSchema()->hasSpace('_temporal_reference')) {
66
            return [];
67
        }
68
        $log = [];
69
        $params = [
70
            'entity' => $this->entityNameToId($entity),
71
            'id' => $id,
72
            'target' => $this->entityNameToId($target),
73
        ];
74
        foreach ($this->mapper->find('_temporal_reference', $params) as $reference) {
75
            $log[] = $reference;
76
        }
77
        return $log;
78
    }
79
80
    public function getReferenceStates($entity, $entityId, $target, $begin, $end)
81
    {
82
        if (!$this->mapper->getSchema()->hasSpace('_temporal_reference_state')) {
83
            return;
84
        }
85
86
        $states = $this->mapper->find('_temporal_reference_state', [
87
            'entity' => $this->entityNameToId($entity),
88
            'id' => $entityId,
89
            'target' => $this->entityNameToId($target),
90
        ]);
91
92
        $begin = $this->getTimestamp($begin);
93
        $end = $this->getTimestamp($end);
94
95
        $slices = [];
96
        foreach ($states as $state) {
97
            if ($state->begin < $end && ($begin < $state->end || !$state->end)) {
98
                $slices[] = [
99
                    'begin' => +date('Ymd', max($state->begin, $begin)),
100
                    'end' => +date('Ymd', min($state->end ?: $end, $end)),
101
                    'value' => $state->targetId,
102
                ];
103
            }
104
        }
105
106
        return $slices;
107
    }
108
109
    public function getReferences($target, $targetId, $source, $date)
110
    {
111
        if (!$this->mapper->getSchema()->hasSpace('_temporal_reference_aggregate')) {
112
            return [];
113
        }
114
115
        $target = $this->entityNameToId($target);
116
        $source = $this->entityNameToId($source);
117
        $date = $this->getTimestamp($date);
118
119
        $rows = $this->mapper->getClient()->getSpace('_temporal_reference_aggregate')
120
            ->select(Criteria::key([$target, $targetId, $source, $date])->andLimit(1)->andLeIterator());
121
122
        if (count($rows)) {
123
            $row = $rows[0];
124
            if ([$target, $targetId, $source] == [$row[0], $row[1], $row[2]]) {
125
                $state = $this->mapper->findOne('_temporal_reference_aggregate', [
126
                    'entity' => $target,
127
                    'id'     => $targetId,
128
                    'source' => $source,
129
                    'begin'  => $row[3]
130
                ]);
131
132
                if (!$state->end || $state->end > $date) {
133
                    return $state->data;
134
                }
135
            }
136
        }
137
        return [];
138
    }
139
140
    public function reference(array $reference)
141
    {
142
        $reference = $this->parseConfig($reference);
143
144
        foreach ($reference as $k => $v) {
145
            if (!in_array($k, ['entity', 'id', 'begin', 'end', 'data'])) {
146
                $reference['entity'] = $k;
147
                $reference['id'] = $v;
148
                unset($reference[$k]);
149
            }
150
        }
151
152
        if (!array_key_exists('entity', $reference)) {
153
            throw new Exception("no entity defined");
154
        }
155
156
        if (count($reference['data']) != 1) {
157
            throw new Exception("Invalid reference configuration");
158
        }
159
160
        [$targetName] = array_keys($reference['data']);
0 ignored issues
show
Bug introduced by
The variable $targetName does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
161
        $reference['target'] = $this->entityNameToId($targetName);
162
        $reference['targetId'] = $reference['data'][$targetName];
163
164
165
        // set entity id
166
        $entityName = $reference['entity'];
167
        $reference['entity'] = $this->entityNameToId($entityName);
168
        $reference['actor'] = $this->actor;
169
        $reference['timestamp'] = Carbon::now()->timestamp;
170
171
        $this->schema->init('reference');
172
        $this->mapper->create('_temporal_reference', $reference);
173
174
        $this->aggregator->updateReferenceState($entityName, $reference['id'], $targetName);
175
    }
176
177
    public function getLinksLog($entity, $entityId, $filter = [])
178
    {
179
        if (!$this->mapper->getSchema()->hasSpace('_temporal_link')) {
180
            return [];
181
        }
182
183
        $entity = $this->entityNameToId($entity);
184
185
        $nodes = $this->mapper->find('_temporal_link', [
186
            'entity' => $entity,
187
            'entityId' => $entityId,
188
        ]);
189
190
        $links = [];
191
192
        foreach ($nodes as $node) {
193
            foreach ($this->aggregator->getLeafs($node) as $leaf) {
194
                $entityName = $this->entityIdToName($leaf->entity);
195
                $link = [
196
                    $entityName => $leaf->entityId,
197
                    'id'        => $leaf->id,
198
                    'begin'     => $leaf->begin,
199
                    'end'       => $leaf->end,
200
                    'timestamp' => $leaf->timestamp,
201
                    'actor'     => $leaf->actor,
202
                    'idle'      => property_exists($leaf, 'idle') ? $leaf->idle : 0,
203
                ];
204
205
                $current = $leaf;
206
                while ($current->parent) {
207
                    $current = $this->mapper->findOne('_temporal_link', $current->parent);
208
                    $entityName = $this->entityIdToName($current->entity);
209
                    $link[$entityName] = $current->entityId;
210
                }
211
212
                if (count($filter)) {
213
                    foreach ($filter as $required) {
214
                        if (!array_key_exists($required, $link)) {
215
                            continue 2;
216
                        }
217
                    }
218
                }
219
                $links[] = $link;
220
            }
221
        }
222
223
        return $links;
224
    }
225
226
    public function getLinks($entity, $id, $date)
227
    {
228
        if (!$this->mapper->getSchema()->hasSpace('_temporal_link_aggregate')) {
229
            return [];
230
        }
231
232
        $links = $this->getData($entity, $id, $date, '_temporal_link_aggregate');
233
        foreach ($links as $i => $source) {
234
            $link = array_key_exists(1, $source) ? ['data' => $source[1]] : [];
235
            foreach ($source[0] as $spaceId => $entityId) {
236
                $spaceName = $this->mapper->findOne('_temporal_entity', $spaceId)->name;
0 ignored issues
show
Documentation introduced by
$spaceId is of type integer|string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
237
                $link[$spaceName] = $entityId;
238
            }
239
            $links[$i] = $link;
240
        }
241
        return $links;
242
    }
243
244
    public function getState($entity, $id, $date)
245
    {
246
        if (!$this->mapper->getSchema()->hasSpace('_temporal_override_aggregate')) {
247
            return [];
248
        }
249
250
        return $this->getData($entity, $id, $date, '_temporal_override_aggregate');
251
    }
252
253
    private function getData($entity, $id, $date, $space)
254
    {
255
        $entity = $this->entityNameToId($entity);
256
        $date = $this->getTimestamp($date);
257
258
        $rows = $this->mapper->getClient()->getSpace($space)
259
            ->select(Criteria::key([$entity, $id, $date])->andLimit(1)->andLeIterator());
260
261
        if (count($rows) && $rows[0][0] == $entity && $rows[0][1] == $id) {
262
            $state = $this->mapper->findOne($space, [
263
                'entity' => $entity,
264
                'id' => $id,
265
                'begin' => $rows[0][2]
266
            ]);
267
            if (!$state->end || $state->end >= $date) {
268
                return $state->data;
269
            }
270
        }
271
272
        return [];
273
    }
274
275
    public function getOverrides(string $entityName, int $id) : array
276
    {
277
        if (!$this->mapper->getSchema()->hasSpace('_temporal_override')) {
278
            return [];
279
        }
280
281
        return $this->mapper->find('_temporal_override', [
282
            'entity' => $this->entityNameToId($entityName),
283
            'id' => $id,
284
        ]);
285
    }
286
287
    public function override(array $override)
288
    {
289
        $override = $this->parseConfig($override);
290
291
        foreach ($override as $k => $v) {
292
            if (!in_array($k, ['entity', 'id', 'begin', 'end', 'data'])) {
293
                $override['entity'] = $k;
294
                $override['id'] = $v;
295
                unset($override[$k]);
296
            }
297
        }
298
299
        if (!array_key_exists('entity', $override)) {
300
            throw new Exception("no entity defined");
301
        }
302
303
        // set entity id
304
        $entityName = $override['entity'];
305
        $override['entity'] = $this->entityNameToId($entityName);
306
        $override['actor'] = $this->actor;
307
        $override['timestamp'] = Carbon::now()->timestamp;
308
309
        $this->schema->init('override');
310
        $this->mapper->create('_temporal_override', $override);
311
312
        $this->aggregator->updateOverrideAggregation($entityName, $override['id']);
313
    }
314
315
    public function setLinkIdle($id, $flag)
316
    {
317
        $link = $this->mapper->findOrFail('_temporal_link', $id);
318
319
        $idled = property_exists($link, 'idle') && $link->idle > 0;
0 ignored issues
show
Bug introduced by
The property idle does not seem to exist in Tarantool\Mapper\Entity.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
320
        if ($idled && !$flag || !$idled && $flag) {
321
            return $this->toggleLinkIdle($link);
322
        }
323
    }
324
325
    public function toggleLinkIdle(Entity $link)
326
    {
327
        if (property_exists($link, 'idle') && $link->idle) {
328
            $link->idle = 0;
0 ignored issues
show
Bug introduced by
The property idle does not seem to exist in Tarantool\Mapper\Entity.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
329
        } else {
330
            $link->idle = time();
331
        }
332
        $link->save();
333
334
        $this->aggregator->updateLinkAggregation($link);
335
    }
336
337
    public function setReferenceIdle($entity, $id, $target, $targetId, $begin, $actor, $timestamp, $flag)
338
    {
339
        $reference = $this->mapper->findOrFail('_temporal_reference', [
340
            'entity' => $this->entityNameToId($entity),
341
            'id' => $id,
342
            'target' => $this->entityNameToId($target),
343
            'targetId' => $targetId,
344
            'begin' => $begin,
345
            'actor' => $actor,
346
            'timestamp' => $timestamp,
347
        ]);
348
        $idled = property_exists($reference, 'idle') && $reference->idle > 0;
0 ignored issues
show
Bug introduced by
The property idle does not seem to exist in Tarantool\Mapper\Entity.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
349
        if ($idled && !$flag || !$idled && $flag) {
350
            return $this->toggleReferenceIdle($entity, $id, $target, $targetId, $begin, $actor, $timestamp);
351
        }
352
    }
353
354
    public function toggleReferenceIdle($entity, $id, $target, $targetId, $begin, $actor, $timestamp)
355
    {
356
        $reference = $this->mapper->findOrFail('_temporal_reference', [
357
            'entity' => $this->entityNameToId($entity),
358
            'id' => $id,
359
            'target' => $this->entityNameToId($target),
360
            'targetId' => $targetId,
361
            'begin' => $begin,
362
            'actor' => $actor,
363
            'timestamp' => $timestamp,
364
        ]);
365
366
        if (property_exists($reference, 'idle') && $reference->idle) {
367
            $reference->idle = 0;
0 ignored issues
show
Bug introduced by
The property idle does not seem to exist in Tarantool\Mapper\Entity.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
368
        } else {
369
            $reference->idle = time();
370
        }
371
        $reference->save();
372
373
        $this->aggregator->updateReferenceState($entity, $id, $target);
374
    }
375
376
    public function setOverrideIdle($entity, $id, $begin, $actor, $timestamp, $flag)
377
    {
378
        $override = $this->mapper->findOrFail('_temporal_override', [
379
            'entity' => $this->entityNameToId($entity),
380
            'id' => $id,
381
            'begin' => $begin,
382
            'actor' => $actor,
383
            'timestamp' => $timestamp,
384
        ]);
385
        $idled = property_exists($override, 'idle') && $override->idle > 0;
0 ignored issues
show
Bug introduced by
The property idle does not seem to exist in Tarantool\Mapper\Entity.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
386
        if ($idled && !$flag || !$idled && $flag) {
387
            return $this->toggleOverrideIdle($entity, $id, $begin, $actor, $timestamp);
388
        }
389
    }
390
391
    public function toggleOverrideIdle($entity, $id, $begin, $actor, $timestamp)
392
    {
393
        $override = $this->mapper->findOrFail('_temporal_override', [
394
            'entity' => $this->entityNameToId($entity),
395
            'id' => $id,
396
            'begin' => $begin,
397
            'actor' => $actor,
398
            'timestamp' => $timestamp,
399
        ]);
400
401
        if (property_exists($override, 'idle') && $override->idle) {
402
            $override->idle = 0;
0 ignored issues
show
Bug introduced by
The property idle does not seem to exist in Tarantool\Mapper\Entity.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
403
        } else {
404
            $override->idle = time();
405
        }
406
        $override->save();
407
408
        $this->aggregator->updateOverrideAggregation($entity, $id);
409
    }
410
411
    public function setReferenceEnd($entity, $id, $target, $targetId, $begin, $actor, $timestamp, $end)
412
    {
413
        $reference = $this->mapper->findOrFail('_temporal_reference', [
414
            'entity' => $this->entityNameToId($entity),
415
            'id' => $id,
416
            'target' => $this->entityNameToId($target),
417
            'targetId' => $targetId,
418
            'begin' => $begin,
419
            'actor' => $actor,
420
            'timestamp' => $timestamp,
421
        ]);
422
        if ($reference->end != $end) {
423
            $reference->end = $end;
0 ignored issues
show
Bug introduced by
The property end does not seem to exist in Tarantool\Mapper\Entity.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
424
            $reference->save();
425
            $this->aggregator->updateReferenceState($entity, $id, $target);
426
        }
427
    }
428
429
    public function setOverrideEnd($entity, $id, $begin, $actor, $timestamp, $end)
430
    {
431
        $override = $this->mapper->findOrFail('_temporal_override', [
432
            'entity' => $this->entityNameToId($entity),
433
            'id' => $id,
434
            'begin' => $begin,
435
            'actor' => $actor,
436
            'timestamp' => $timestamp,
437
        ]);
438
        if ($override->end != $end) {
439
            $override->end = $end;
0 ignored issues
show
Bug introduced by
The property end does not seem to exist in Tarantool\Mapper\Entity.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
440
            $override->save();
441
            $this->aggregator->updateOverrideAggregation($entity, $id);
442
        }
443
    }
444
445
446
    public function link(array $link)
447
    {
448
        $link = $this->parseConfig($link);
449
450
        $this->schema->init('link');
451
452
        $config = [];
453
        foreach ($link as $entity => $id) {
454
            if (!in_array($entity, ['begin', 'end', 'data'])) {
455
                $config[$entity] = $id;
456
            }
457
        }
458
459
        ksort($config);
460
        $node = null;
461
462
        foreach (array_keys($config) as $i => $entity) {
463
            $id = $config[$entity];
464
            $spaceId = $this->entityNameToId($entity);
465
            $params = [
466
                'entity'   => $spaceId,
467
                'entityId' => $id,
468
                'parent'   => $node ? $node->id : 0,
469
            ];
470
            if (count($config) == $i+1) {
471
                $params['begin'] = $link['begin'];
472
                $params['timestamp'] = 0;
473
            }
474
            $node = $this->mapper->findOrCreate('_temporal_link', $params);
475
        }
476
477
        if (!$node || !$node->parent) {
0 ignored issues
show
Bug introduced by
The property parent does not seem to exist in Tarantool\Mapper\Entity.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
478
            throw new Exception("Invalid link configuration");
479
        }
480
481
        $node->begin = $link['begin'];
0 ignored issues
show
Bug introduced by
The property begin does not seem to exist in Tarantool\Mapper\Entity.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
482
        $node->end = $link['end'];
0 ignored issues
show
Bug introduced by
The property end does not seem to exist in Tarantool\Mapper\Entity.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
483
        $node->actor = $this->actor;
0 ignored issues
show
Bug introduced by
The property actor does not seem to exist in Tarantool\Mapper\Entity.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
484
        $node->timestamp = Carbon::now()->timestamp;
0 ignored issues
show
Bug introduced by
The property timestamp does not seem to exist in Tarantool\Mapper\Entity.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
485
        if (array_key_exists('data', $link)) {
486
            $node->data = $link['data'];
0 ignored issues
show
Bug introduced by
The property data does not seem to exist in Tarantool\Mapper\Entity.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
487
        }
488
489
        $node->save();
490
491
        $this->aggregator->updateLinkAggregation($node);
492
    }
493
494
    public function getActor()
495
    {
496
        return $this->actor;
497
    }
498
499
    public function setActor($actor)
500
    {
501
        $this->actor = $actor;
502
        return $this;
503
    }
504
505
    private function getTimestamp($string)
506
    {
507
        if (Carbon::hasTestNow() || !array_key_exists($string, $this->timestamps)) {
508
            if (strlen(''.$string) == 8 && is_numeric($string)) {
509
                $value = Carbon::createFromFormat('Ymd', $string)->setTime(0, 0, 0)->timestamp;
510
            } else {
511
                $value = Carbon::parse($string)->timestamp;
512
            }
513
            if (Carbon::hasTestNow()) {
514
                return $value;
515
            }
516
            $this->timestamps[$string] = $value;
517
        }
518
        return $this->timestamps[$string];
519
    }
520
521
    private function parseConfig(array $data)
522
    {
523
        if (!$this->actor) {
524
            throw new Exception("actor is undefined");
525
        }
526
527
        if (array_key_exists('actor', $data)) {
528
            throw new Exception("actor is defined");
529
        }
530
531
        if (array_key_exists('timestamp', $data)) {
532
            throw new Exception("timestamp is defined");
533
        }
534
535
        foreach (['begin', 'end'] as $field) {
536
            if (array_key_exists($field, $data) && $data[$field]) {
537
                $data[$field] = $this->getTimestamp($data[$field]);
538
            } else {
539
                $data[$field] = 0;
540
            }
541
        }
542
543
        return $data;
544
    }
545
546
    public function entityNameToId($name)
547
    {
548
        if (!$this->mapper->hasPlugin(Sequence::class)) {
549
            $this->mapper->getPlugin(Sequence::class);
550
        }
551
552
        $this->mapper->getSchema()->once(__CLASS__.'@entity', function (Mapper $mapper) {
0 ignored issues
show
Unused Code introduced by
The parameter $mapper is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
553
            $this->mapper->getSchema()
554
                ->createSpace('_temporal_entity', [
555
                    'id'   => 'unsigned',
556
                    'name' => 'string',
557
                ])
558
                ->addIndex(['id'])
559
                ->addIndex(['name']);
560
        });
561
562
        return $this->mapper->findOrCreate('_temporal_entity', compact('name'))->id;
563
    }
564
565
    public function entityIdToName($id)
566
    {
567
        return $this->mapper->findOne('_temporal_entity', compact('id'))->name;
568
    }
569
}
570