Completed
Push — master ( f5eef4...aa2564 )
by Dmitry
01:36
created

Procedure::invoke()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 2
1
<?php
2
3
namespace Tarantool\Mapper\Plugin;
4
5
use Tarantool\Mapper\Plugin;
6
use Tarantool\Mapper\Procedure as BaseProcedure;
7
use Exception;
8
9
class Procedure extends Plugin
10
{
11
    public function get($class)
12
    {
13
        return $this->register($class);
14
    }
15
16
    public function invoke(BaseProcedure $procedure, $params)
17
    {
18
        $nick = $this->getNick(get_class($procedure));
19
        $result = $this->mapper->getClient()->call($nick, $params);
20
        return $result->getData()[0];
21
    }
22
23
    public function isRegistered($class)
24
    {
25
        return !!$this->mapper->findOne('_procedure', ['name' => $class]);
26
    }
27
28
    public function register($class)
29
    {
30
        if (!is_subclass_of($class, BaseProcedure::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Tarantool\Mapper\Procedure::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
31
            throw new Exception("Procedure should extend ".BaseProcedure::class.' class');
32
        }
33
        $this->initSchema();
34
35
        $instance = $this->mapper->findOrCreate('_procedure', ['name' => $class]);
36
37
        $procedure = new $class($this);
38
39
        if($instance->hash != md5($procedure->getBody())) {
40
            $nick = $this->getNick($class);
41
            $params = implode(', ', $procedure->getParams());
42
            $body = $procedure->getBody();
43
44
            $script = "
45
            $nick = function($params) $body end
46
            box.schema.func.create('$nick', {if_not_exists=true})
47
            ";
48
            $this->mapper->getClient()->evaluate($script);
49
            $instance->hash = md5($body);
50
        }
51
52
        return $procedure;
53
    }
54
55
    private function initSchema()
56
    {
57
        $this->mapper->getSchema()->once(__CLASS__, function($mapper) {
58
            $mapper->getSchema()
59
                ->createSpace('_procedure')
60
                ->addProperties([
61
                    'name' => 'string',
62
                    'hash' => 'string',
63
                ])
64
                ->addIndex([
65
                    'fields' => ['name'],
66
                    'type' => 'hash',
67
                ]);
68
69
        });
70
    }
71
72
    private function getNick($className)
73
    {
74
        return 'php_'.strtolower(implode('_', explode('\\', $className)));
75
    }
76
}
77