Completed
Push — master ( 689ba3...487dca )
by Richard
05:45
created

CompilesVars::compile_var()   D

Complexity

Conditions 16
Paths 52

Size

Total Lines 101
Code Lines 54

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 49
CRAP Score 17.9482

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 101
ccs 49
cts 61
cp 0.8033
rs 4.8736
cc 16
eloc 54
nc 52
nop 3
crap 17.9482

How to fix   Long Method    Complexity   

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, 2015 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\Analysis;
12
13
use Lechimp\Dicto\Variables as Vars;
14
use Lechimp\Dicto\Variables\Variable;
15
16
/**
17
 * Implementation for Query::compile_var.
18
 */
19
trait CompilesVars {
20
    /**
21
     * Get a builder to create queries.
22
     *
23
     * @return  QueryBuilder
24
     */
25
    abstract public function builder();
26
27
    /**
28
     * Compile a variable to an SQL statement over a named table.
29
     *
30
     * @param   string          $table_name
31
     * @param   Vars\Variable   $var
32
     * @param   bool            $negate
33
     * @return  string|CompositeExpression
34
     */ 
35 48
    public function compile_var($table_name, Vars\Variable $var, $negate = false) {
36 48
        $b = $this->builder()->expr();
37
        // Since SQL does not have a statement for negating while expressions,
38
        // we need to negate the single conditions in the expression, which
39
        // most often is the equality operator here.
40 48
        if (!$negate) {
41
            $eq_op = function($l, $r) use ($b) {
42 48
                return $b->eq($l, $r);
43 48
            };
44 48
        }
45
        else {
46
            $eq_op = function($l, $r) use ($b) {
47 18
                return $b->neq($l, $r);
48 18
            };
49
        }
50
51
        // sugar:
52 48
        $compile = function($dir, Vars\Compound $var, $negate = false) use ($table_name) {
53 21
            return $this->compile_var($table_name, $var->$dir(), $negate);
54 48
        };
55
56
        // Pattern matching on variable type.
57
58 48
        if ($var instanceof Vars\AsWellAs) {
59
            // normal case: left_condition or right_condition
60 3
            if (!$negate) {
61 3
                return $b->orX
62 3
                    ( $compile("left", $var)
63 3
                    , $compile("right", $var)
64 3
                    );
65
            }
66
            // negated case: not (left_condition or right_condition)
67
            //             = not left_condition and not right_condition
68
            if ($negate) {
69
                return $b->andX
70
                    ( $compile("left", $var, true)
71
                    , $compile("right", $var, true)
72
                    );
73
            }
74
        }
75 48
        if ($var instanceof Vars\ButNot) {
76 18
            return $b->andX
77 18
                ( $compile("left", $var)
78 18
                , $compile("right", $var, true)
79 18
                );
80
        }
81 48
        if ($var instanceof Vars\Classes) {
82 42
            return $eq_op("$table_name.type", $b->literal(Variable::CLASS_TYPE));
83
        }
84 44
        if ($var instanceof Vars\Everything) {
85 23
            return $eq_op($b->literal(1), $b->literal(1));
86
        }
87 44
        if ($var instanceof Vars\Files) {
88
            return $eq_op("$table_name.type", $b->literal(Variable::FILE_TYPE));
89
        }
90 44
        if ($var instanceof Vars\Functions) {
91 13
            return $eq_op("$table_name.type", $b->literal(Variable::FUNCTION_TYPE));
92
        }
93 41
        if ($var instanceof Vars\Globals) {
94 19
            return $eq_op("$table_name.type", $b->literal(Variable::GLOBAL_TYPE));
95
        }
96 35
        if ($var instanceof Vars\LanguageConstruct) {
97
            // normal case : language construct and name matches
98 7
            if (!$negate) {
99 7
                return $b->andX
100 7
                    ( $eq_op("$table_name.type", $b->literal(Variable::LANGUAGE_CONSTRUCT_TYPE))
101 7
                    , $eq_op("$table_name.name", $b->literal($var->construct_name()))
102 7
                    );
103
            }
104
            // negated case: not (language construct and name matches)
105
            //             = not language construct or not name matches
106
            else {
107
108
                return $b->orX
109
                    ( $eq_op("$table_name.type", $b->literal(Variable::LANGUAGE_CONSTRUCT_TYPE))
110
                    , $eq_op("$table_name.name", $b->literal($var->construct_name()))
111
                    );
112
            }
113
        }
114 30
        if ($var instanceof Vars\Methods) {
115 1
            return $eq_op("$table_name.type", $b->literal(Variable::METHOD_TYPE));
116
        }
117 29
        if ($var instanceof Vars\WithName) {
118
            // normal case : left_condition AND regexp matches
119 29
            if (!$negate) {
120 11
                return $b->andX
121 11
                    ( $this->compile_var($table_name, $var->variable())
122 11
                    , "$table_name.name REGEXP ".$b->literal('^'.$var->regexp().'$')
123 11
                    );
124
            }
125
            // negated case: not (left_condition_left and regexp matches)
126
            //             = not left_condition and not regexp matches
127
            else {
128 18
                return $b->orX
129 18
                    ( $this->compile_var($table_name, $var->variable(), true)
130 18
                    , "$table_name.name NOT REGEXP ".$b->literal('^'.$var->regexp().'$')
131 18
                    );
132
            }
133
        }
134
        throw new \LogicException("Can't compile var-type '".get_class($var)."'");
135
    }
136
137
}
138