Completed
Push — master ( 07fa0a...a5b00e )
by Edgard
10:14
created

Command::refreshTableSchema()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 9.4285
c 1
b 0
f 0
cc 2
eloc 3
nc 2
nop 0
crap 2
1
<?php
2
/**
3
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace edgardmessias\db\firebird;
9
10
/**
11
 *
12
 * @author Edgard Lorraine Messias <[email protected]>
13
 * @since 2.0
14
 */
15
class Command extends \yii\db\Command
16
{
17
18
    /**
19
     * @var array pending parameters to be bound to the current PDO statement.
20
     */
21
    private $_pendingParams = [];
22
23
    /**
24
     * @var string the SQL statement that this command represents
25
     */
26
    private $_sql;
27
28
    /**
29
     * @var string name of the table, which schema, should be refreshed after command execution.
30
     */
31
    private $_refreshTableName;
32
33
    /**
34
     * Binds a parameter to the SQL statement to be executed.
35
     * @param string|integer $name parameter identifier. For a prepared statement
36
     * using named placeholders, this will be a parameter name of
37
     * the form `:name`. For a prepared statement using question mark
38
     * placeholders, this will be the 1-indexed position of the parameter.
39
     * @param mixed $value Name of the PHP variable to bind to the SQL statement parameter
40
     * @param integer $dataType SQL data type of the parameter. If null, the type is determined by the PHP type of the value.
41
     * @param integer $length length of the data type
42
     * @param mixed $driverOptions the driver-specific options
43
     * @return static the current command being executed
44
     * @see http://www.php.net/manual/en/function.PDOStatement-bindParam.php
45
     */
46 1
    public function bindParam($name, &$value, $dataType = null, $length = null, $driverOptions = null)
47
    {
48 1
        if ($dataType == \PDO::PARAM_BOOL) {
49 1
            $dataType = \PDO::PARAM_INT;
50 1
        }
51 1
        return parent::bindParam($name, $value, $dataType, $length, $driverOptions);
52
    }
53
    /**
54
     * Binds pending parameters that were registered via [[bindValue()]] and [[bindValues()]].
55
     * Note that this method requires an active [[pdoStatement]].
56
     */
57 128
    protected function bindPendingParams()
58
    {
59 128
        foreach ($this->_pendingParams as $name => $value) {
60 84
            if ($value[1] == 'blob') {
61 8
                $this->pdoStatement->bindParam($name, $value[0]);
62 8
            } else {
63 84
                $this->pdoStatement->bindValue($name, $value[0], $value[1]);
64
            }
65 128
        }
66 128
        $this->_pendingParams = [];
67 128
    }
68
69
    /**
70
     * Returns the SQL statement for this command.
71
     * @return string the SQL statement to be executed
72
     */
73 131
    public function getSql()
74
    {
75 131
        return $this->_sql;
76
    }
77
78
    /**
79
     * Specifies the SQL statement to be executed.
80
     * The previous SQL execution (if any) will be cancelled, and [[params]] will be cleared as well.
81
     * @param string $sql the SQL statement to be set.
82
     * @return static this command instance
83
     */
84 136
    public function setSql($sql)
85
    {
86 136
        $refreshTableName = null;
87
        
88 136
        $matches = null;
89 136
        if (preg_match("/^\s*DROP TABLE IF EXISTS (['\"]?([^\s\;]+)['\"]?);?\s*$/i", $sql, $matches)) {
90
            if ($this->db->getSchema()->getTableSchema($matches[2]) !== null) {
91
                $sql = $this->db->getQueryBuilder()->dropTable($matches[2]);
92
            } else {
93
                $sql = 'select 1 from RDB$DATABASE;'; //Prevent Drop Table
94
            }
95
            $refreshTableName = $matches[2];
96
        }
97
        
98 136
        if ($sql !== $this->_sql) {
99 136
            $this->cancel();
100 136
            $this->_sql = $this->db->quoteSql($sql);
101 136
            $this->_pendingParams = [];
102 136
            $this->params = [];
103 136
            $this->_refreshTableName = $refreshTableName;
104 136
        }
105
106 136
        return $this;
107
    }
108
109
    /**
110
     * Returns the raw SQL by inserting parameter values into the corresponding placeholders in [[sql]].
111
     * Note that the return value of this method should mainly be used for logging purpose.
112
     * It is likely that this method returns an invalid SQL due to improper replacement of parameter placeholders.
113
     * @return string the raw SQL with parameter values inserted into the corresponding placeholders in [[sql]].
114
     */
115 132
    public function getRawSql()
116
    {
117 132
        if (empty($this->params)) {
118 121
            return $this->_sql;
119
        }
120 89
        $params = [];
121 89
        foreach ($this->params as $name => $value) {
122 89
            if (is_string($name) && strncmp(':', $name, 1)) {
123 3
                $name = ':' . $name;
124 3
            }
125 89
            if (is_string($value)) {
126 38
                $params[$name] = $this->db->quoteValue($value);
127 89
            } elseif (is_bool($value)) {
128 2
                $params[$name] = ($value ? 'TRUE' : 'FALSE');
129 78
            } elseif ($value === null) {
130 9
                $params[$name] = 'NULL';
131 77
            } elseif (!is_object($value) && !is_resource($value)) {
132 76
                $params[$name] = $value;
133 76
            }
134 89
        }
135 89
        if (!isset($params[1])) {
136 89
            return strtr($this->_sql, $params);
137
        }
138
        $sql = '';
139
        foreach (explode('?', $this->_sql) as $i => $part) {
140
            $sql .= (isset($params[$i]) ? $params[$i] : '') . $part;
141
        }
142
        return $sql;
143
    }
144
145
    /**
146
     * Binds a value to a parameter.
147
     * @param string|integer $name Parameter identifier. For a prepared statement
148
     * using named placeholders, this will be a parameter name of
149
     * the form `:name`. For a prepared statement using question mark
150
     * placeholders, this will be the 1-indexed position of the parameter.
151
     * @param mixed $value The value to bind to the parameter
152
     * @param integer $dataType SQL data type of the parameter. If null, the type is determined by the PHP type of the value.
153
     * @return static the current command being executed
154
     * @see http://www.php.net/manual/en/function.PDOStatement-bindValue.php
155
     */
156 2
    public function bindValue($name, $value, $dataType = null)
157
    {
158 2
        if ($dataType === null) {
159 2
            $dataType = $this->db->getSchema()->getPdoType($value);
160 2
        }
161 2
        if ($dataType == \PDO::PARAM_BOOL) {
162
            $dataType = \PDO::PARAM_INT;
163
        }
164 2
        $this->_pendingParams[$name] = [$value, $dataType];
165 2
        $this->params[$name] = $value;
166
167 2
        return $this;
168
    }
169
170
    /**
171
     * Binds a list of values to the corresponding parameters.
172
     * This is similar to [[bindValue()]] except that it binds multiple values at a time.
173
     * Note that the SQL data type of each value is determined by its PHP type.
174
     * @param array $values the values to be bound. This must be given in terms of an associative
175
     * array with array keys being the parameter names, and array values the corresponding parameter values,
176
     * e.g. `[':name' => 'John', ':age' => 25]`. By default, the PDO type of each value is determined
177
     * by its PHP type. You may explicitly specify the PDO type by using an array: `[value, type]`,
178
     * e.g. `[':name' => 'John', ':profile' => [$profile, \PDO::PARAM_LOB]]`.
179
     * @return static the current command being executed
180
     */
181 136
    public function bindValues($values)
182
    {
183 136
        if (empty($values)) {
184 126
            return $this;
185
        }
186
187 88
        $schema = $this->db->getSchema();
188 88
        foreach ($values as $name => $value) {
189 88
            if (is_array($value)) {
190
                $this->_pendingParams[$name] = $value;
191
                $this->params[$name] = $value[0];
192
            } else {
193 88
                $type = $schema->getPdoType($value);
194 88
                $this->_pendingParams[$name] = [$value, $type];
195 88
                $this->params[$name] = $value;
196
            }
197 88
        }
198
199 88
        return $this;
200
    }
201
202
    /**
203
     * Marks a specified table schema to be refreshed after command execution.
204
     * @param string $name name of the table, which schema should be refreshed.
205
     * @return $this this command instance
206
     * @since 2.0.6
207
     */
208 4
    protected function requireTableSchemaRefresh($name)
209
    {
210 4
        $this->_refreshTableName = $name;
211 4
        return $this;
212
    }
213
214
    /**
215
     * Refreshes table schema, which was marked by [[requireTableSchemaRefresh()]]
216
     * @since 2.0.6
217
     */
218 42
    protected function refreshTableSchema()
219
    {
220 42
        if ($this->_refreshTableName !== null) {
221 4
            $this->db->getSchema()->refreshTableSchema($this->_refreshTableName);
222 4
        }
223 42
    }
224
}
225