Completed
Push — master ( 322d21...4a7f1b )
by Richard
05:35
created

Relation::compile()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 71
Code Lines 55

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 52
CRAP Score 4.0107

Importance

Changes 5
Bugs 0 Features 0
Metric Value
c 5
b 0
f 0
dl 0
loc 71
ccs 52
cts 57
cp 0.9123
rs 8.7238
cc 4
eloc 55
nc 3
nop 2
crap 4.0107

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Analysis\Violation;
16
use \Lechimp\Dicto\Variables\Variable;
17
18
/**
19
 * This is a rule that checks a relation between two entities
20
 * in the code.
21
 */
22
abstract class Relation extends Schema {
23
    /**
24
     * @inheritdoc
25
     */
26 146
    public function fluid_interface(Def\RT $rt, $name, $mode, array $arguments) {
27 146
        if (count($arguments) != 0) {
28
            throw new \InvalidArgumentException(
29
                "No arguments are allowed when using a relational rule schema.");
30
        }
31 146
        return new Def\Fluid\Relation($rt, $name, $mode, $this);
32
    }
33
34 188
    public function check_arguments(array $arguments) {
35 188
         if (count($arguments) != 1) {
36
            throw new \InvalidArgumentException(
37
                "One argument is required when using a relational rule schema.");
38
        }
39 188
       if (!($arguments[0] instanceof Variable)) {
40
            throw new \InvalidArgumentException(
41
                "Expected variable, got '".get_class($arguments[0])."' when using a relational schema.");
42
        }
43
44 188
    }
45
46
    /**
47
     * @inheritdoc
48
     */
49 3
    public function pprint(Rule $rule) {
50 3
        return $this->printable_name()." ".$rule->argument(0)->name();
51
    }
52
53
    /**
54
     * @inheritdoc
55
     */
56 37
    public function compile(Query $query, Rule $rule) {
57 37
        $builder = $query->builder();
58 37
        $b = $builder->expr();
59 37
        $mode = $rule->mode();
60 37
        $entity = $rule->checked_on();
61 37
        $reference = $rule->argument(0);
62 37
        if ($mode == Rule::MODE_CANNOT || $mode == Rule::MODE_ONLY_CAN) {
63
            return $builder
64 29
                ->select
65 29
                    ( "rel.entity_id as entity_id"
66 29
                    , "rel.reference_id as reference_id"
67 29
                    , "rel.file as file"
68 29
                    , "rel.line as line"
69 29
                    , "src.source as source"
70 29
                    )
71 29
                ->from($query->relations_table(), "rel")
72 29
                ->innerJoin("rel", $query->entity_table(), "e", "rel.entity_id = e.id")
73 29
                ->innerJoin("rel", $query->reference_table(), "r", "rel.reference_id = r.id")
74
                ->innerJoin
75 29
                    ( "rel", $query->source_file_table(), "src"
76 29
                    , $b->andX
77 29
                        ( $b->eq("rel.line", "src.line")
78 29
                        , $b->eq("rel.file", "src.name")
79 29
                        )
80
                    )
81 8
                ->where
82
                    ( $b->eq("rel.name", $b->literal($this->name()))
83 8
                    , $query->compile_var("e", $entity)
84 8
                    , $query->compile_var("r", $reference)
85 8
                    )
86 8
                ->execute();
87 8
        }
88 8
        if ($mode == Rule::MODE_MUST) {
89 8
            return $builder
90
                ->select
91 8
                    ( "e.id as entity_id"
92 8
                    , "e.file as file"
93 8
                    , "e.start_line as line"
94 8
                    , "src.source as source"
95 8
                    )
96 8
                ->from($query->entity_table(), "e")
97
                ->leftJoin
98 8
                    ("e", $query->relations_table(), "rel"
99 8
                    , $b->andX
100 8
                        ( $b->eq("rel.name", $b->literal($this->name()))
101 8
                        , $b->eq("rel.entity_id", "e.id")
102 8
                        )
103 8
                    )
104
                ->leftJoin
105 8
                    ("rel", $query->reference_table(), "r"
106 8
                    , $b->andX
107 8
                        ( $b->eq("rel.reference_id", "r.id")
108 8
                        , $query->compile_var("r", $reference)
109
                        )
110
                    )
111
                ->innerJoin
112
                    ( "e", $query->source_file_table(), "src"
113 1
                    , $b->andX
114
                        ( $b->eq("e.start_line", "src.line")
115 1
                        , $b->eq("e.file", "src.name")
116 1
                        )
117 1
                    )
118 1
119 1
                ->where
120
                    ( $query->compile_var("e", $entity)
121
                    , $b->isNull("r.id")
122
                    )
123
                ->execute();
124
        }
125
        throw new \LogicException("Unknown rule mode: '$mode'");
126
    }
127
}
128