Completed
Push — master ( 65f66e...428edc )
by Michal
04:14
created

ParameterDefinition   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 136
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 136
ccs 52
cts 52
cp 1
rs 10
c 0
b 0
f 0
wmc 22
lcom 1
cbo 4

2 Methods

Rating   Name   Duplication   Size   Complexity  
D parse() 0 83 19
A build() 0 15 3
1
<?php
2
3
/**
4
 * The definition of a parameter of a function or procedure.
5
 */
6
7
namespace PhpMyAdmin\SqlParser\Components;
8
9
use PhpMyAdmin\SqlParser\Context;
10
use PhpMyAdmin\SqlParser\Component;
11
use PhpMyAdmin\SqlParser\Parser;
12
use PhpMyAdmin\SqlParser\Token;
13
use PhpMyAdmin\SqlParser\TokensList;
14
15
/**
16
 * The definition of a parameter of a function or procedure.
17
 *
18
 * @category   Components
19
 *
20
 * @license    https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+
21
 */
22
class ParameterDefinition extends Component
23
{
24
    /**
25
     * The name of the new column.
26
     *
27
     * @var string
28
     */
29
    public $name;
30
31
    /**
32
     * Parameter's direction (IN, OUT or INOUT).
33
     *
34
     * @var string
35
     */
36
    public $inOut;
37
38
    /**
39
     * The data type of thew new column.
40
     *
41
     * @var DataType
42
     */
43
    public $type;
44
45
    /**
46
     * @param Parser     $parser  the parser that serves as context
47
     * @param TokensList $list    the list of tokens that are being parsed
48
     * @param array      $options parameters for parsing
49
     *
50
     * @return ParameterDefinition[]
51
     */
52 19
    public static function parse(Parser $parser, TokensList $list, array $options = array())
53
    {
54 19
        $ret = array();
55
56 19
        $expr = new self();
57
58
        /**
59
         * The state of the parser.
60
         *
61
         * Below are the states of the parser.
62
         *
63
         *      0 -----------------------[ ( ]------------------------> 1
64
         *
65
         *      1 ----------------[ IN / OUT / INOUT ]----------------> 1
66
         *      1 ----------------------[ name ]----------------------> 2
67
         *
68
         *      2 -------------------[ data type ]--------------------> 3
69
         *
70
         *      3 ------------------------[ , ]-----------------------> 1
71
         *      3 ------------------------[ ) ]-----------------------> (END)
72
         *
73
         * @var int
74
         */
75 19
        $state = 0;
76
77 19
        for (; $list->idx < $list->count; ++$list->idx) {
78
            /**
79
             * Token parsed at this moment.
80
             *
81
             * @var Token
82
             */
83 19
            $token = $list->tokens[$list->idx];
84
85
            // End of statement.
86 19
            if ($token->type === Token::TYPE_DELIMITER) {
87 1
                break;
88
            }
89
90
            // Skipping whitespaces and comments.
91 19
            if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) {
92 16
                continue;
93
            }
94
95 19
            if ($state === 0) {
96 19
                if (($token->type === Token::TYPE_OPERATOR) && ($token->value === '(')) {
97 19
                    $state = 1;
98 19
                }
99 19
                continue;
100 19
            } elseif ($state === 1) {
101 19
                if (($token->value === 'IN') || ($token->value === 'OUT') || ($token->value === 'INOUT')) {
102 7
                    $expr->inOut = $token->value;
103 7
                    ++$list->idx;
104 19
                } elseif ($token->value === ')') {
105 3
                    ++$list->idx;
106 3
                    break;
107
                } else {
108 16
                    $expr->name = $token->value;
109 16
                    $state = 2;
110
                }
111 16
            } elseif ($state === 2) {
112 16
                $expr->type = DataType::parse($parser, $list);
113 16
                $state = 3;
114 16
            } elseif ($state === 3) {
115 16
                $ret[] = $expr;
116 16
                $expr = new self();
117 16
                if ($token->value === ',') {
118 3
                    $state = 1;
119 16
                } elseif ($token->value === ')') {
120 15
                    ++$list->idx;
121 15
                    break;
122
                }
123 3
            }
124 16
        }
125
126
        // Last iteration was not saved.
127 19
        if ((isset($expr->name)) && ($expr->name !== '')) {
128 1
            $ret[] = $expr;
129 1
        }
130
131 19
        --$list->idx;
132
133 19
        return $ret;
134
    }
135
136
    /**
137
     * @param ParameterDefinition[] $component the component to be built
138
     * @param array                 $options   parameters for building
139
     *
140
     * @return string
141
     */
142 1
    public static function build($component, array $options = array())
143
    {
144 1
        if (is_array($component)) {
145 1
            return '(' . implode(', ', $component) . ')';
146
        } else {
147 1
            $tmp = '';
148 1
            if (!empty($component->inOut)) {
149 1
                $tmp .= $component->inOut . ' ';
150 1
            }
151
152 1
            return trim(
153 1
                $tmp . Context::escape($component->name) . ' ' . $component->type
154 1
            );
155
        }
156
    }
157
}
158