Passed
Pull Request — master (#84)
by
unknown
10:17 queued 01:37
created

ExecuteTest::testExecuteQueryFetchesNoRows()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the tarantool/client package.
5
 *
6
 * (c) Eugene Leonovich <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Tarantool\Client\Tests\Integration\Requests;
15
16
require __DIR__.'/../../../examples/bootstrap.php';
17
18
use Tarantool\Client\Keys;
19
use Tarantool\Client\Tests\Integration\ClientBuilder;
20
use Tarantool\Client\Tests\Integration\TestCase;
21
22
/**
23
 * @requires Tarantool >=2
24
 *
25
 * @sql DROP TABLE IF EXISTS exec_query
26
 * @sql CREATE TABLE exec_query (id INTEGER PRIMARY KEY, name VARCHAR(50))
27
 * @sql INSERT INTO exec_query VALUES (1, 'A'), (2, 'B')
28
 */
29
final class ExecuteTest extends TestCase
30
{
31
    private function provideScanQuery() : string
32
    {
33
        /**
34
         * SEQSCAN keyword is explicitly allowing to use seqscan:
35
         * https://github.com/tarantool/tarantool/commit/77648827326ad268ec0ffbcd620c2371b65ef2b4
36
         * It was introduced in Tarantool 2.11.0-rc1. If compat.sql_seq_scan_default set to "new"
37
         * (default value since 3.0), query returns error when trying to scan without keyword.
38
         */
39
        if (server_version_at_least('2.11', $this->client)) {
0 ignored issues
show
Bug introduced by
It seems like $this->client can also be of type null; however, parameter $client of server_version_at_least() does only seem to accept Tarantool\Client\Client, maybe add an additional type check? ( Ignorable by Annotation )

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

39
        if (server_version_at_least('2.11', /** @scrutinizer ignore-type */ $this->client)) {
Loading history...
40
            return 'SELECT * FROM SEQSCAN exec_query';
41
        }
42
43
        return 'SELECT * FROM exec_query';
44
    }
45
46
    /**
47
     * @sql DROP TABLE IF EXISTS exec_update
48
     * @sql CREATE TABLE exec_update (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(50))
49
     */
50
    public function testExecuteInsertsRows() : void
51
    {
52
        $response = $this->client->execute(
0 ignored issues
show
Bug introduced by
The method execute() does not exist on null. ( Ignorable by Annotation )

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

52
        /** @scrutinizer ignore-call */ 
53
        $response = $this->client->execute(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
53
            'INSERT INTO exec_update VALUES (5, :name1), (null, :name2)',
54
            [':name1' => 'A'], [':name2' => 'B']
55
        );
56
57
        $expectedSqlInfo = [
58
            Keys::SQL_INFO_ROW_COUNT => 2,
59
            Keys::SQL_INFO_AUTO_INCREMENT_IDS => [6],
60
        ];
61
62
        self::assertSame($expectedSqlInfo, $response->getBodyField(Keys::SQL_INFO));
63
    }
64
65
    public function testExecuteFetchesAllRows() : void
66
    {
67
        $response = $this->client->execute(self::provideScanQuery());
0 ignored issues
show
Bug Best Practice introduced by
The method Tarantool\Client\Tests\I...est::provideScanQuery() is not static, but was called statically. ( Ignorable by Annotation )

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

67
        $response = $this->client->execute(self::/** @scrutinizer ignore-call */ provideScanQuery());
Loading history...
68
69
        self::assertSame([[1, 'A'], [2, 'B']], $response->getBodyField(Keys::DATA));
70
    }
71
72
    /**
73
     * @sql DROP TABLE IF EXISTS exec_update
74
     * @sql CREATE TABLE exec_update (id INTEGER PRIMARY KEY, name VARCHAR(50))
75
     */
76
    public function testExecuteUpdateInsertsRows() : void
77
    {
78
        $result = $this->client->executeUpdate(
79
            'INSERT INTO exec_update VALUES (1, :name1), (2, :name2)',
80
            [':name1' => 'A'], [':name2' => 'B']
81
        );
82
83
        self::assertSame([], $result->getAutoincrementIds());
84
        self::assertSame(2, $result->count());
85
    }
86
87
    /**
88
     * @sql DROP TABLE IF EXISTS exec_update
89
     * @sql CREATE TABLE exec_update (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(50))
90
     */
91
    public function testExecuteUpdateInsertsRowsWithAutoIncrementedIds() : void
92
    {
93
        $result = $this->client->executeUpdate("INSERT INTO exec_update VALUES (100, 'A'), (null, 'B'), (120, 'C'), (null, 'D')");
94
95
        self::assertSame([101, 121], $result->getAutoincrementIds());
96
        self::assertSame(4, $result->count());
97
    }
98
99
    /**
100
     * @sql DROP TABLE IF EXISTS exec_update
101
     * @sql CREATE TABLE exec_update (id INTEGER PRIMARY KEY, name VARCHAR(50))
102
     * @sql INSERT INTO exec_update VALUES (1, 'A'), (2, 'B')
103
     */
104
    public function testExecuteUpdateUpdatesRow() : void
105
    {
106
        $result = $this->client->executeUpdate('UPDATE exec_update SET name = ? WHERE id = ?', 'BB', 2);
107
108
        self::assertSame([], $result->getAutoincrementIds());
109
        self::assertSame(1, $result->count());
110
    }
111
112
    public function testExecuteQueryFetchesAllRows() : void
113
    {
114
        $result = $this->client->executeQuery(self::provideScanQuery());
0 ignored issues
show
Bug Best Practice introduced by
The method Tarantool\Client\Tests\I...est::provideScanQuery() is not static, but was called statically. ( Ignorable by Annotation )

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

114
        $result = $this->client->executeQuery(self::/** @scrutinizer ignore-call */ provideScanQuery());
Loading history...
115
116
        self::assertSame([[1, 'A'], [2, 'B']], $result->getData());
117
        self::assertSame(2, $result->count());
118
    }
119
120
    public function testExecuteQueryFetchesOneRow() : void
121
    {
122
        $result = $this->client->executeQuery('SELECT * FROM exec_query WHERE id = 1');
123
124
        self::assertSame([[1, 'A']], $result->getData());
125
        self::assertSame(1, $result->count());
126
    }
127
128
    public function testExecuteQueryFetchesNoRows() : void
129
    {
130
        $result = $this->client->executeQuery('SELECT * FROM exec_query WHERE id = -1');
131
132
        self::assertSame([], $result->getData());
133
        self::assertSame(0, $result->count());
134
    }
135
136
    public function testExecuteQueryBindsPositionalParameters() : void
137
    {
138
        $result = $this->client->executeQuery('SELECT ?, ?', 2, 'B');
139
140
        self::assertSame([[2, 'B']], $result->getData());
141
        self::assertSame(1, $result->count());
142
    }
143
144
    public function testExecuteQueryBindsNamedParameters() : void
145
    {
146
        $result = $this->client->executeQuery('SELECT :id, :name', [':name' => 'B'], [':id' => 2]);
147
148
        self::assertSame([[2, 'B']], $result->getData());
149
        self::assertSame(1, $result->count());
150
    }
151
152
    public function testExecuteQueryBindsMixedParameters() : void
153
    {
154
        $result = $this->client->executeQuery('SELECT ?, :name', 2, [':name' => 'B']);
155
156
        self::assertSame([[2, 'B']], $result->getData());
157
        self::assertSame(1, $result->count());
158
    }
159
160
    /**
161
     * @see https://github.com/tarantool/tarantool/issues/4782
162
     */
163
    public function testExecuteQueryBindsMixedParametersAndSubstitutesPositionalOnes() : void
164
    {
165
        $result = $this->client->executeQuery('SELECT :id, ?', 'B', [':id' => 2]);
166
167
        self::assertSame([[2, null]], $result->getData());
168
        self::assertSame(1, $result->count());
169
    }
170
171
    public function testSqlQueryResultHoldsMetadata() : void
172
    {
173
        $client = ClientBuilder::createFromEnv()->build();
174
175
        $response = $client->executeQuery(self::provideScanQuery());
0 ignored issues
show
Bug Best Practice introduced by
The method Tarantool\Client\Tests\I...est::provideScanQuery() is not static, but was called statically. ( Ignorable by Annotation )

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

175
        $response = $client->executeQuery(self::/** @scrutinizer ignore-call */ provideScanQuery());
Loading history...
176
177
        self::assertSame([[
178
            Keys::METADATA_FIELD_NAME => 'ID',
179
            Keys::METADATA_FIELD_TYPE => 'integer',
180
        ], [
181
            Keys::METADATA_FIELD_NAME => 'NAME',
182
            Keys::METADATA_FIELD_TYPE => 'string',
183
        ]], $response->getMetadata());
184
    }
185
186
    /**
187
     * @requires Tarantool >=2.6
188
     *
189
     * @sql DROP TABLE IF EXISTS %target_method%
190
     * @sql CREATE TABLE %target_method% (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(50) COLLATE "unicode_ci")
191
     */
192
    public function testSqlQueryResultHoldsExtendedMetadata() : void
193
    {
194
        $client = ClientBuilder::createFromEnv()->build();
195
        $client->execute('SET SESSION "sql_full_metadata" = true');
196
197
        $tableName = $this->resolvePlaceholders('%target_method%');
198
199
        /**
200
         * SEQSCAN keyword is explicitly allowing to use seqscan:
201
         * https://github.com/tarantool/tarantool/commit/77648827326ad268ec0ffbcd620c2371b65ef2b4
202
         * It was introduced in Tarantool 2.11.0-rc1. If compat.sql_seq_scan_default set to "new"
203
         * (default value since 3.0), query returns error when trying to scan without keyword.
204
         */
205
        if (server_version_at_least('2.11', $this->client)) {
0 ignored issues
show
Bug introduced by
It seems like $this->client can also be of type null; however, parameter $client of server_version_at_least() does only seem to accept Tarantool\Client\Client, maybe add an additional type check? ( Ignorable by Annotation )

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

205
        if (server_version_at_least('2.11', /** @scrutinizer ignore-type */ $this->client)) {
Loading history...
206
            $scan_query = "SELECT id, name as full_name FROM SEQSCAN $tableName";
207
        } else {
208
            $scan_query = "SELECT id, name as full_name FROM $tableName";
209
        }
210
        $response = $client->executeQuery($scan_query);
211
212
        self::assertSame([[
213
            Keys::METADATA_FIELD_NAME => 'ID',
214
            Keys::METADATA_FIELD_TYPE => 'integer',
215
            Keys::METADATA_FIELD_IS_NULLABLE => false,
216
            Keys::METADATA_FIELD_IS_AUTOINCREMENT => true,
217
            Keys::METADATA_FIELD_SPAN => 'id',
218
        ], [
219
            Keys::METADATA_FIELD_NAME => 'FULL_NAME',
220
            Keys::METADATA_FIELD_TYPE => 'string',
221
            Keys::METADATA_FIELD_COLL => 'unicode_ci',
222
            Keys::METADATA_FIELD_IS_NULLABLE => true,
223
            Keys::METADATA_FIELD_SPAN => 'name',
224
        ]], $response->getMetadata());
225
    }
226
}
227