Completed
Push — master ( 389cae...29b40e )
by Richard
06:27
created

Relation   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 6

Test Coverage

Coverage 83.33%

Importance

Changes 7
Bugs 0 Features 0
Metric Value
wmc 10
c 7
b 0
f 0
lcom 0
cbo 6
dl 0
loc 92
ccs 55
cts 66
cp 0.8333
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A fluid_interface() 0 7 2
A check_arguments() 0 11 3
A pprint() 0 3 1
A compile() 0 56 4
1
<?php
2
/******************************************************************************
3
 * An implementation of dicto (scg.unibe.ch/dicto) in and for PHP.
4
 *
5
 * Copyright (c) 2016 Richard Klees <[email protected]>
6
 *
7
 * This software is licensed under The MIT License. You should have received
8
 * a copy of the licence along with the code.
9
 */
10
11
namespace Lechimp\Dicto\Rules;
12
13
use Lechimp\Dicto\Definition as Def;
14
use Lechimp\Dicto\Analysis\Query;
15
use \Lechimp\Dicto\Variables\Variable;
16
17
/**
18
 * This is a rule that checks a relation between two entities
19
 * in the code.
20
 */
21
abstract class Relation extends Schema {
22
    /**
23
     * @inheritdoc
24
     */
25 150
    public function fluid_interface(Def\RuleDefinitionRT $rt, $name, $mode, array $arguments) {
26 150
        if (count($arguments) != 0) {
27
            throw new \InvalidArgumentException(
28
                "No arguments are allowed when using a relational rule schema.");
29
        }
30 150
        return new Def\Fluid\Relation($rt, $name, $mode, $this);
31
    }
32
33 190
    public function check_arguments(array $arguments) {
34 190
         if (count($arguments) != 1) {
35
            throw new \InvalidArgumentException(
36
                "One argument is required when using a relational rule schema.");
37
        }
38 190
       if (!($arguments[0] instanceof Variable)) {
39
            throw new \InvalidArgumentException(
40
                "Expected variable, got '".get_class($arguments[0])."' when using a relational schema.");
41
        }
42
43 190
    }
44
45
    /**
46
     * @inheritdoc
47
     */
48 3
    public function pprint(Rule $rule) {
49 3
        return $this->printable_name()." ".$rule->argument(0)->name();
50
    }
51
52
    /**
53
     * @inheritdoc
54
     */
55 35
    public function compile(Query $query, Rule $rule) {
56 35
        $builder = $query->builder();
57 35
        $b = $builder->expr();
58 35
        $mode = $rule->mode();
59 35
        $entity = $rule->checked_on();
60 35
        $reference = $rule->argument(0);
61 35
        if ($mode == Rule::MODE_CANNOT || $mode == Rule::MODE_ONLY_CAN) {
62
            return $builder
63 27
                ->select
64 27
                    ( "rel.entity_id as entity_id"
65 27
                    , "rel.reference_id as reference_id"
66 27
                    , "rel.file as file"
67 27
                    , "rel.line as line"
68 27
                    , "rel.source_line as source"
69 27
                    )
70 27
                ->from($query->relations_table(), "rel")
71 27
                ->innerJoin("rel", $query->entity_table(), "e", "rel.entity_id = e.id")
72 27
                ->innerJoin("rel", $query->reference_table(), "r", "rel.reference_id = r.id")
73
                ->where
74 27
                    ( $b->eq("rel.name", $b->literal($this->name()))
75 27
                    , $query->compile_var("e", $entity)
76 27
                    , $query->compile_var("r", $reference)
77 27
                    )
78 27
                ->execute();
79
        }
80 8
        if ($mode == Rule::MODE_MUST) {
81
            return $builder
82 8
                ->select
83 8
                    ( "e.id as entity_id"
84 8
                    , "e.file as file"
85 8
                    , "e.start_line as line"
86 8
                    , "e.source as source"
87 8
                    )
88 8
                ->from($query->entity_table(), "e")
89
                ->leftJoin
90 8
                    ("e", $query->relations_table(), "rel"
91 8
                    , $b->andX
92 8
                        ( $b->eq("rel.name", $b->literal($this->name()))
93 8
                        , $b->eq("rel.entity_id", "e.id")
94 8
                        )
95 8
                    )
96
                ->leftJoin
97 8
                    ("rel", $query->reference_table(), "r"
98 8
                    , $b->andX
99 8
                        ( $b->eq("rel.reference_id", "r.id")
100 8
                        , $query->compile_var("r", $reference)
101 8
                        )
102 8
                    )
103
                ->where
104 8
                    ( $query->compile_var("e", $entity)
105 8
                    , $b->isNull("r.id")
106 8
                    )
107 8
                ->execute();
108
        }
109
        throw new \LogicException("Unknown rule mode: '$mode'");
110
    }
111
112
}
113