Completed
Pull Request — master (#32)
by
unknown
03:30
created

JoinKeyword   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 90.38%

Importance

Changes 9
Bugs 3 Features 2
Metric Value
wmc 20
c 9
b 3
f 2
lcom 1
cbo 6
dl 0
loc 153
ccs 47
cts 52
cp 0.9038
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
D parse() 0 87 18
A build() 0 9 2
1
<?php
2
3
/**
4
 * `JOIN` keyword parser.
5
 *
6
 * @package    SqlParser
7
 * @subpackage Components
8
 */
9
namespace SqlParser\Components;
10
11
use SqlParser\Component;
12
use SqlParser\Parser;
13
use SqlParser\Token;
14
use SqlParser\TokensList;
15
16
/**
17
 * `JOIN` keyword parser.
18
 *
19
 * @category   Keywords
20
 * @package    SqlParser
21
 * @subpackage Components
22
 * @author     Dan Ungureanu <[email protected]>
23
 * @license    http://opensource.org/licenses/GPL-2.0 GNU Public License
24
 */
25
class JoinKeyword extends Component
26
{
27
28
    /**
29
     * Types of join.
30
     *
31
     * @var array
32
     */
33
    public static $JOINS = array(
34
        'FULL JOIN'                     => 'FULL',
35
        'INNER JOIN'                    => 'INNER',
36
        'JOIN'                          => 'JOIN',
37
        'LEFT JOIN'                     => 'LEFT',
38
        'LEFT OUTER JOIN'               => 'LEFT',
39
        'RIGHT JOIN'                    => 'RIGHT',
40
        'RIGHT OUTER JOIN'              => 'RIGHT',
41
        'STRAIGHT_JOIN'                 => 'STRAIGHT',
42
    );
43
44
    /**
45
     * Type of this join.
46
     *
47
     * @see static::$JOINS
48
     * @var string
49
     */
50
    public $type;
51
52
    /**
53
     * Join expression.
54
     *
55
     * @var Expression
56
     */
57
    public $expr;
58
59
    /**
60
     * Join conditions.
61
     *
62
     * @var Condition[]
63
     */
64
    public $on;
65
    public $using;
66
67
    /**
68
     * @param Parser     $parser  The parser that serves as context.
69
     * @param TokensList $list    The list of tokens that are being parsed.
70
     * @param array      $options Parameters for parsing.
71
     *
72
     * @return JoinKeyword[]
73
     */
74 6
    public static function parse(Parser $parser, TokensList $list, array $options = array())
75
    {
76 6
        $ret = array();
77
78 6
        $expr = new JoinKeyword();
79
80
        /**
81
         * The state of the parser.
82
         *
83
         * Below are the states of the parser.
84
         *
85
         *      0 -----------------------[ JOIN ]----------------------> 1
86
         *
87
         *      1 -----------------------[ expr ]----------------------> 2
88
         *
89
         *      2 ---------------------[ ON|USING ]--------------------> 3/4
90
         *
91
         *      3 --------------------[ conditions ]-------------------> 0
92
         *
93
         *      4 ----------------------[ colums ]---------------------> 0
94
         *
95
         * @var int $state
96
         */
97 6
        $state = 0;
98
99
        // By design, the parser will parse first token after the keyword.
100
        // In this case, the keyword must be analyzed too, in order to determine
101
        // the type of this join.
102 6
        if ($list->idx > 0) {
103 4
            --$list->idx;
104 4
        }
105
106 6
        for (; $list->idx < $list->count; ++$list->idx) {
107
            /**
108
             * Token parsed at this moment.
109
             *
110
             * @var Token $token
111
             */
112 6
            $token = $list->tokens[$list->idx];
113
114
            // End of statement.
115 6
            if ($token->type === Token::TYPE_DELIMITER) {
116 5
                break;
117
            }
118
119
            // Skipping whitespaces and comments.
120 6
            if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) {
121 6
                continue;
122
            }
123
124 6
            if ($state === 0) {
125 6
                if (($token->type === Token::TYPE_KEYWORD)
126 6
                    && (!empty(static::$JOINS[$token->value]))
127 6
                ) {
128 6
                    $expr->type = static::$JOINS[$token->value];
129 6
                    $state = 1;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
130 6
                } else {
131 1
                    break;
132
                }
133 6
            } elseif ($state === 1) {
134 6
                $expr->expr = Expression::parse($parser, $list, array('field' => 'table'));
135 6
                $state = 2;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
136 6
            } elseif ($state === 2) {
137 5
                if (($token->type === Token::TYPE_KEYWORD) && ($token->value === 'ON' || $token->value === 'USING')) {
138 5
                    $state = $token->value === 'ON' ? 3 : 4;
139 5
                }
140 5
            } elseif ($state === 3) {
141 5
                $expr->on = Condition::parse($parser, $list);
142 5
                $ret[] = $expr;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
143 5
                $expr = new JoinKeyword();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
144 5
                $state = 0;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
145 5
            } elseif ($state === 4) {
146
                $expr->using = ArrayObj::parse($parser, $list);
147
                $ret[] = $expr;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
148
                $expr = new JoinKeyword();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 8 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
149
                $state = 0;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
150
            }
151
152 6
        }
153
154 6
        if (!empty($expr->type)) {
155 1
            $ret[] = $expr;
156 1
        }
157
158 6
        --$list->idx;
159 6
        return $ret;
160
    }
161
162
    /**
163
     * @param JoinKeyword[] $component The component to be built.
164
     * @param array         $options   Parameters for building.
165
     *
166
     * @return string
167
     */
168 2
    public static function build($component, array $options = array())
169
    {
170 2
        $ret = array();
171 2
        foreach ($component as $c) {
172 2
            $ret[] = array_search($c->type, static::$JOINS) . ' '
173 2
                . $c->expr . ' ON ' . Condition::build($c->on);
174 2
        }
175 2
        return implode(' ', $ret);
176
    }
177
}
178