Failed Conditions
Pull Request — 2.11.x (#3891)
by Malte
61:34
created

NamedParametersTest::prepareProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 40
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 23
c 2
b 0
f 0
dl 0
loc 40
rs 9.552
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Doctrine\Tests\DBAL\Functional;
4
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\FetchMode;
7
use Doctrine\DBAL\ParameterType;
8
use Doctrine\DBAL\Schema\Table;
9
use Doctrine\Tests\DbalFunctionalTestCase;
10
use Throwable;
11
use const CASE_LOWER;
12
use function array_change_key_case;
13
14
/**
15
 * @group DDC-1372
16
 */
17
class NamedParametersTest extends DbalFunctionalTestCase
18
{
19
    /**
20
     * @return iterable<int, array<string, mixed[], mixed[], mixed[]>>
21
     */
22
    public static function executeQueryProvider() : iterable
23
    {
24
        return [
25
            [
26
                'SELECT * FROM ddc1372_foobar f WHERE f.foo = :foo AND f.bar IN (:bar)',
27
                [
28
                    'foo' => 1,
29
                    'bar' => [1, 2, 3],
30
                ],
31
                [
32
                    'foo' => ParameterType::INTEGER,
33
                    'bar' => Connection::PARAM_INT_ARRAY,
34
                ],
35
                [
36
                    ['id' => 1, 'foo' => 1, 'bar' => 1],
37
                    ['id' => 2, 'foo' => 1, 'bar' => 2],
38
                    ['id' => 3, 'foo' => 1, 'bar' => 3],
39
                ],
40
            ],
41
42
            [
43
                'SELECT * FROM ddc1372_foobar f WHERE f.foo = :foo AND f.bar IN (:bar)',
44
                [
45
                    'foo' => 1,
46
                    'bar' => [1, 2, 3],
47
                ],
48
                [
49
                    'bar' => Connection::PARAM_INT_ARRAY,
50
                    'foo' => ParameterType::INTEGER,
51
                ],
52
                [
53
                    ['id' => 1, 'foo' => 1, 'bar' => 1],
54
                    ['id' => 2, 'foo' => 1, 'bar' => 2],
55
                    ['id' => 3, 'foo' => 1, 'bar' => 3],
56
                ],
57
            ],
58
59
            [
60
                'SELECT * FROM ddc1372_foobar f WHERE f.bar IN (:bar) AND f.foo = :foo',
61
                [
62
                    'foo' => 1,
63
                    'bar' => [1, 2, 3],
64
                ],
65
                [
66
                    'bar' => Connection::PARAM_INT_ARRAY,
67
                    'foo' => ParameterType::INTEGER,
68
                ],
69
                [
70
                    ['id' => 1, 'foo' => 1, 'bar' => 1],
71
                    ['id' => 2, 'foo' => 1, 'bar' => 2],
72
                    ['id' => 3, 'foo' => 1, 'bar' => 3],
73
                ],
74
            ],
75
76
            [
77
                'SELECT * FROM ddc1372_foobar f WHERE f.bar IN (:bar) AND f.foo = :foo',
78
                [
79
                    'foo' => 1,
80
                    'bar' => ['1', '2', '3'],
81
                ],
82
                [
83
                    'bar' => Connection::PARAM_STR_ARRAY,
84
                    'foo' => ParameterType::INTEGER,
85
                ],
86
                [
87
                    ['id' => 1, 'foo' => 1, 'bar' => 1],
88
                    ['id' => 2, 'foo' => 1, 'bar' => 2],
89
                    ['id' => 3, 'foo' => 1, 'bar' => 3],
90
                ],
91
            ],
92
93
            [
94
                'SELECT * FROM ddc1372_foobar f WHERE f.bar IN (:bar) AND f.foo IN (:foo)',
95
                [
96
                    'foo' => ['1'],
97
                    'bar' => [1, 2, 3, 4],
98
                ],
99
                [
100
                    'bar' => Connection::PARAM_STR_ARRAY,
101
                    'foo' => Connection::PARAM_INT_ARRAY,
102
                ],
103
                [
104
                    ['id' => 1, 'foo' => 1, 'bar' => 1],
105
                    ['id' => 2, 'foo' => 1, 'bar' => 2],
106
                    ['id' => 3, 'foo' => 1, 'bar' => 3],
107
                    ['id' => 4, 'foo' => 1, 'bar' => 4],
108
                ],
109
            ],
110
111
            [
112
                'SELECT * FROM ddc1372_foobar f WHERE f.bar IN (:bar) AND f.foo IN (:foo)',
113
                [
114
                    'foo' => 1,
115
                    'bar' => 2,
116
                ],
117
                [
118
                    'bar' => ParameterType::INTEGER,
119
                    'foo' => ParameterType::INTEGER,
120
                ],
121
                [
122
                    ['id' => 2, 'foo' => 1, 'bar' => 2],
123
                ],
124
            ],
125
126
            [
127
                'SELECT * FROM ddc1372_foobar f WHERE f.bar = :arg AND f.foo <> :arg',
128
                ['arg' => '1'],
129
                [
130
                    'arg' => ParameterType::STRING,
131
                ],
132
                [
133
                    ['id' => 5, 'foo' => 2, 'bar' => 1],
134
                ],
135
            ],
136
137
            [
138
                'SELECT * FROM ddc1372_foobar f WHERE f.bar NOT IN (:arg) AND f.foo IN (:arg)',
139
                [
140
                    'arg' => [1, 2],
141
                ],
142
                [
143
                    'arg' => Connection::PARAM_INT_ARRAY,
144
                ],
145
                [
146
                    ['id' => 3, 'foo' => 1, 'bar' => 3],
147
                    ['id' => 4, 'foo' => 1, 'bar' => 4],
148
                ],
149
            ],
150
        ];
151
    }
152
153
    /**
154
     * @return iterable<string, array<string, mixed[], mixed[]>>
155
     */
156
    public static function prepareProvider() : iterable
157
    {
158
        return [
159
            'single named parameter' => [
160
                'SELECT * FROM ddc1372_foobar f WHERE f.foo = :foo',
161
                ['foo' => 1],
162
                [
163
                    ['id' => 1, 'foo' => 1, 'bar' => 1],
164
                    ['id' => 2, 'foo' => 1, 'bar' => 2],
165
                    ['id' => 3, 'foo' => 1, 'bar' => 3],
166
                    ['id' => 4, 'foo' => 1, 'bar' => 4],
167
                ],
168
            ],
169
170
            'multiple parameters' => [
171
                'SELECT * FROM ddc1372_foobar f WHERE f.foo = :foo AND f.bar = :bar',
172
                [
173
                    'foo' => 1,
174
                    'bar' => 2,
175
                ],
176
                [
177
                    ['id' => 2, 'foo' => 1, 'bar' => 2],
178
                ],
179
            ],
180
181
            'same parameter at multiple positions' => [
182
                'SELECT * FROM ddc1372_foobar f WHERE f.foo = :foo AND f.foo IN (:foo)',
183
                ['foo' => 1],
184
                [
185
                    ['id' => 1, 'foo' => 1, 'bar' => 1],
186
                    ['id' => 2, 'foo' => 1, 'bar' => 2],
187
                    ['id' => 3, 'foo' => 1, 'bar' => 3],
188
                    ['id' => 4, 'foo' => 1, 'bar' => 4],
189
                ],
190
            ],
191
192
            'parameter with string value' => [
193
                'SELECT * FROM ddc1372_foobar f WHERE f.foo = :foo',
194
                ['foo' => '"\''],
195
                [],
196
            ],
197
        ];
198
    }
199
200
    protected function setUp() : void
201
    {
202
        parent::setUp();
203
204
        if ($this->connection->getSchemaManager()->tablesExist('ddc1372_foobar')) {
205
            return;
206
        }
207
208
        try {
209
            $table = new Table('ddc1372_foobar');
210
            $table->addColumn('id', 'integer');
211
            $table->addColumn('foo', 'string');
212
            $table->addColumn('bar', 'string');
213
            $table->setPrimaryKey(['id']);
214
215
            $sm = $this->connection->getSchemaManager();
216
            $sm->createTable($table);
217
218
            $this->connection->insert('ddc1372_foobar', [
219
                'id'  => 1,
220
                'foo' => 1,
221
                'bar' => 1,
222
            ]);
223
            $this->connection->insert('ddc1372_foobar', [
224
                'id'  => 2,
225
                'foo' => 1,
226
                'bar' => 2,
227
            ]);
228
            $this->connection->insert('ddc1372_foobar', [
229
                'id'  => 3,
230
                'foo' => 1,
231
                'bar' => 3,
232
            ]);
233
            $this->connection->insert('ddc1372_foobar', [
234
                'id'  => 4,
235
                'foo' => 1,
236
                'bar' => 4,
237
            ]);
238
            $this->connection->insert('ddc1372_foobar', [
239
                'id'  => 5,
240
                'foo' => 2,
241
                'bar' => 1,
242
            ]);
243
            $this->connection->insert('ddc1372_foobar', [
244
                'id'  => 6,
245
                'foo' => 2,
246
                'bar' => 2,
247
            ]);
248
        } catch (Throwable $e) {
249
            $this->fail($e->getMessage());
250
        }
251
    }
252
253
    /**
254
     * @param array<string, mixed>             $params
255
     * @param array<string, int>               $types
256
     * @param array<int, array<string, mixed>> $expected
257
     *
258
     * @dataProvider executeQueryProvider
259
     */
260
    public function testExecuteQuery(string $query, array $params, array $types, array $expected) : void
261
    {
262
        $stmt   = $this->connection->executeQuery($query, $params, $types);
263
        $result = $stmt->fetchAll(FetchMode::ASSOCIATIVE);
264
265
        foreach ($result as $k => $v) {
266
            $result[$k] = array_change_key_case($v, CASE_LOWER);
267
        }
268
269
        self::assertEquals($result, $expected);
270
    }
271
272
    /**
273
     * @param array<string, mixed>             $params
274
     * @param array<int, array<string, mixed>> $expected
275
     *
276
     * @dataProvider prepareProvider
277
     */
278
    public function testPrepare(string $query, array $params, array $expected) : void
279
    {
280
        $stmt = $this->connection->prepare($query);
281
        $stmt->execute($params);
282
        $result = $stmt->fetchAll(FetchMode::ASSOCIATIVE);
283
284
        foreach ($result as $k => $v) {
285
            $result[$k] = array_change_key_case($v, CASE_LOWER);
286
        }
287
288
        self::assertEquals($result, $expected);
289
    }
290
}
291