Completed
Pull Request — master (#3104)
by Joas
63:33
created

testNamedParametersAfterEscapeFirstMatches()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 15
rs 9.4285
cc 2
eloc 9
nc 2
nop 1
1
<?php
2
3
namespace Doctrine\Tests\DBAL\Functional\Ticket;
4
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\FetchMode;
7
use Doctrine\DBAL\ParameterType;
8
use Doctrine\DBAL\Platforms\SqlitePlatform;
9
use Doctrine\DBAL\Schema\Table;
10
use const CASE_LOWER;
11
use function array_change_key_case;
12
13
/**
14
 * @group DDC-1372
15
 */
16
class NamedParametersTest extends \Doctrine\Tests\DbalFunctionalTestCase
17
{
18
    public function ticketProvider()
19
    {
20
        return [
21
            [
22
                'SELECT * FROM ddc1372_foobar f WHERE f.foo = :foo AND f.bar IN (:bar)',
23
                [
24
                    'foo' => 1,
25
                    'bar' => [1, 2, 3],
26
                ],
27
                [
28
                    'foo' => ParameterType::INTEGER,
29
                    'bar' => Connection::PARAM_INT_ARRAY,
30
                ],
31
                [
32
                    ['id' => 1, 'foo' => 1, 'bar' => 1],
33
                    ['id' => 2, 'foo' => 1, 'bar' => 2],
34
                    ['id' => 3, 'foo' => 1, 'bar' => 3],
35
                ],
36
            ],
37
38
            [
39
                'SELECT * FROM ddc1372_foobar f WHERE f.foo = :foo AND f.bar IN (:bar)',
40
                [
41
                    'foo' => 1,
42
                    'bar' => [1, 2, 3],
43
                ],
44
                [
45
                    'bar' => Connection::PARAM_INT_ARRAY,
46
                    'foo' => ParameterType::INTEGER,
47
                ],
48
                [
49
                    ['id' => 1, 'foo' => 1, 'bar' => 1],
50
                    ['id' => 2, 'foo' => 1, 'bar' => 2],
51
                    ['id' => 3, 'foo' => 1, 'bar' => 3],
52
                ],
53
            ],
54
55
            [
56
                'SELECT * FROM ddc1372_foobar f WHERE f.bar IN (:bar) AND f.foo = :foo',
57
                [
58
                    'foo' => 1,
59
                    'bar' => [1, 2, 3],
60
                ],
61
                [
62
                    'bar' => Connection::PARAM_INT_ARRAY,
63
                    'foo' => ParameterType::INTEGER,
64
                ],
65
                [
66
                    ['id' => 1, 'foo' => 1, 'bar' => 1],
67
                    ['id' => 2, 'foo' => 1, 'bar' => 2],
68
                    ['id' => 3, 'foo' => 1, 'bar' => 3],
69
                ],
70
            ],
71
72
            [
73
                'SELECT * FROM ddc1372_foobar f WHERE f.bar IN (:bar) AND f.foo = :foo',
74
                [
75
                    'foo' => 1,
76
                    'bar' => ['1', '2', '3'],
77
                ],
78
                [
79
                    'bar' => Connection::PARAM_STR_ARRAY,
80
                    'foo' => ParameterType::INTEGER,
81
                ],
82
                [
83
                    ['id' => 1, 'foo' => 1, 'bar' => 1],
84
                    ['id' => 2, 'foo' => 1, 'bar' => 2],
85
                    ['id' => 3, 'foo' => 1, 'bar' => 3],
86
                ],
87
            ],
88
89
            [
90
                'SELECT * FROM ddc1372_foobar f WHERE f.bar IN (:bar) AND f.foo IN (:foo)',
91
                [
92
                    'foo' => ['1'],
93
                    'bar' => [1, 2, 3, 4],
94
                ],
95
                [
96
                    'bar' => Connection::PARAM_STR_ARRAY,
97
                    'foo' => Connection::PARAM_INT_ARRAY,
98
                ],
99
                [
100
                    ['id' => 1, 'foo' => 1, 'bar' => 1],
101
                    ['id' => 2, 'foo' => 1, 'bar' => 2],
102
                    ['id' => 3, 'foo' => 1, 'bar' => 3],
103
                    ['id' => 4, 'foo' => 1, 'bar' => 4],
104
                ],
105
            ],
106
107
            [
108
                'SELECT * FROM ddc1372_foobar f WHERE f.bar IN (:bar) AND f.foo IN (:foo)',
109
                [
110
                    'foo' => 1,
111
                    'bar' => 2,
112
                ],
113
                [
114
                    'bar' => ParameterType::INTEGER,
115
                    'foo' => ParameterType::INTEGER,
116
                ],
117
                [
118
                    ['id' => 2, 'foo' => 1, 'bar' => 2],
119
                ],
120
            ],
121
122
            [
123
                'SELECT * FROM ddc1372_foobar f WHERE f.bar = :arg AND f.foo <> :arg',
124
                ['arg' => '1'],
125
                [
126
                    'arg' => ParameterType::STRING,
127
                ],
128
                [
129
                    ['id' => 5, 'foo' => 2, 'bar' => 1],
130
                ],
131
            ],
132
133
            [
134
                'SELECT * FROM ddc1372_foobar f WHERE f.bar NOT IN (:arg) AND f.foo IN (:arg)',
135
                [
136
                    'arg' => [1, 2],
137
                ],
138
                [
139
                    'arg' => Connection::PARAM_INT_ARRAY,
140
                ],
141
                [
142
                    ['id' => 3, 'foo' => 1, 'bar' => 3],
143
                    ['id' => 4, 'foo' => 1, 'bar' => 4],
144
                ],
145
            ],
146
        ];
147
    }
148
149
    protected function setUp()
150
    {
151
        parent::setUp();
152
153
        if (! $this->_conn->getSchemaManager()->tablesExist('ddc1372_foobar')) {
0 ignored issues
show
Bug introduced by
'ddc1372_foobar' of type string is incompatible with the type array expected by parameter $tableNames of Doctrine\DBAL\Schema\Abs...aManager::tablesExist(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

153
        if (! $this->_conn->getSchemaManager()->tablesExist(/** @scrutinizer ignore-type */ 'ddc1372_foobar')) {
Loading history...
154
            try {
155
                $table = new Table('ddc1372_foobar');
156
                $table->addColumn('id', 'integer');
157
                $table->addColumn('foo', 'string');
158
                $table->addColumn('bar', 'string');
159
                $table->setPrimaryKey(['id']);
160
161
                $sm = $this->_conn->getSchemaManager();
162
                $sm->createTable($table);
163
164
                $this->_conn->insert('ddc1372_foobar', [
165
                    'id'  => 1,
166
                    'foo' => 1,
167
                    'bar' => 1,
168
                ]);
169
                $this->_conn->insert('ddc1372_foobar', [
170
                    'id'  => 2,
171
                    'foo' => 1,
172
                    'bar' => 2,
173
                ]);
174
                $this->_conn->insert('ddc1372_foobar', [
175
                    'id'  => 3,
176
                    'foo' => 1,
177
                    'bar' => 3,
178
                ]);
179
                $this->_conn->insert('ddc1372_foobar', [
180
                    'id'  => 4,
181
                    'foo' => 1,
182
                    'bar' => 4,
183
                ]);
184
                $this->_conn->insert('ddc1372_foobar', [
185
                    'id'  => 5,
186
                    'foo' => 2,
187
                    'bar' => 1,
188
                ]);
189
                $this->_conn->insert('ddc1372_foobar', [
190
                    'id'  => 6,
191
                    'foo' => 2,
192
                    'bar' => 2,
193
                ]);
194
            } catch(\Exception $e) {
195
                $this->fail($e->getMessage());
196
            }
197
        }
198
    }
199
200
    /**
201
     * @dataProvider ticketProvider
202
     * @param string $query
203
     * @param array  $params
204
     * @param array  $types
205
     * @param array  $expected
206
     */
207
    public function testTicket($query,$params,$types,$expected)
208
    {
209
        $stmt   = $this->_conn->executeQuery($query, $params, $types);
210
        $result = $stmt->fetchAll(FetchMode::ASSOCIATIVE);
211
212
        foreach ($result as $k => $v) {
213
            $result[$k] = array_change_key_case($v, CASE_LOWER);
214
        }
215
216
        self::assertEquals($expected, $result);
217
    }
218
219
    public function namedParametersAfterEscapeProvider()
220
    {
221
        return [
222
            ["SELECT 1 FROM ddc1372_foobar WHERE (:param_0 LIKE :find ESCAPE '{{escape}}') OR (:param_1 LIKE :find ESCAPE '{{escape}}') LIMIT 1"],
223
            ['SELECT 1 FROM ddc1372_foobar WHERE (:param_0 LIKE :find ESCAPE \'{{escape}}\') OR (:param_1 LIKE :find ESCAPE "{{escape}}") LIMIT 1'],
224
            ['SELECT 1 FROM ddc1372_foobar WHERE (:param_0 LIKE :find ESCAPE "{{escape}}") OR (:param_1 LIKE :find ESCAPE \'{{escape}}\') LIMIT 1'],
225
            ['SELECT 1 FROM ddc1372_foobar WHERE (:param_0 LIKE :find ESCAPE "{{escape}}") OR (:param_1 LIKE :find ESCAPE "{{escape}}") LIMIT 1'],
226
        ];
227
    }
228
229
    /**
230
     * @dataProvider namedParametersAfterEscapeProvider
231
     * @param string $query
232
     */
233
    public function testNamedParametersAfterEscapeFirstMatches($query)
234
    {
235
        $escapeChar = $this->_conn->getDatabasePlatform() instanceof SqlitePlatform ? '\\' : '\\\\';
236
        $query = str_replace('{{escape}}', $escapeChar, $query);
237
238
        $stmt = $this->_conn->executeQuery(
239
            $query,
240
            ['param_0' => 'bar', 'param_1' => 'foo', 'find' => '%a%'],
241
            ['param_0' => 2, 'param_1' => 2, 'find' => 2]
242
        );
243
        $result = $stmt->fetchAll(FetchMode::COLUMN);
244
245
        self::assertEquals([
246
            1,
247
        ], $result);
248
    }
249
250
    /**
251
     * @dataProvider namedParametersAfterEscapeProvider
252
     * @param string $query
253
     */
254
    public function testNamedParametersAfterEscapeSecondMatches($query)
255
    {
256
        $escapeChar = $this->_conn->getDatabasePlatform() instanceof SqlitePlatform ? '\\' : '\\\\';
257
        $query = str_replace('{{escape}}', $escapeChar, $query);
258
259
        $stmt = $this->_conn->executeQuery(
260
            $query,
261
            ['param_0' => 'bar', 'param_1' => 'foo', 'find' => '%o%'],
262
            ['param_0' => 2, 'param_1' => 2, 'find' => 2]
263
        );
264
        $result = $stmt->fetchAll(FetchMode::COLUMN);
265
266
        self::assertEquals([
267
            1,
268
        ], $result);
269
    }
270
}
271