Completed
Push — master ( b43ecb...492467 )
by Eugene
07:09
created

PrepareTest   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 113
rs 10
c 0
b 0
f 0
wmc 7
lcom 1
cbo 2

7 Methods

Rating   Name   Duplication   Size   Complexity  
A testPreparePreparesSqlStatement() 0 18 1
A testExecuteQueryReturnsResult() 0 14 1
A testExecuteUpdateUpdatesRows() 0 17 1
A testCloseDeallocatesPreparedStatement() 0 7 1
A testCloseDeallocatesPreparedInLuaSqlStatement() 0 20 1
A testCloseFailsOnNonexistentPreparedStatement() 0 8 1
A testPrepareResetsPreviouslyBoundParameters() 0 13 1
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
use Tarantool\Client\Exception\RequestFailed;
17
use Tarantool\Client\PreparedStatement;
18
use Tarantool\Client\Tests\Integration\TestCase;
19
20
/**
21
 * @requires Tarantool ^2.3.2
22
 */
23
final class PrepareTest extends TestCase
24
{
25
    public function testPreparePreparesSqlStatement() : void
26
    {
27
        [$preparedCountBefore] = $this->client->evaluate('return box.info.sql().cache.stmt_count');
0 ignored issues
show
Bug introduced by
The variable $preparedCountBefore does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
28
        $stmt = $this->client->prepare('SELECT ?');
29
        [$preparedCountAfter] = $this->client->evaluate('return box.info.sql().cache.stmt_count');
0 ignored issues
show
Bug introduced by
The variable $preparedCountAfter does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
30
31
        try {
32
            self::assertSame($preparedCountBefore + 1, $preparedCountAfter);
33
            self::assertIsInt($stmt->getId());
34
            self::assertSame(1, $stmt->getBindCount());
35
            self::assertSame([['?', 'ANY']], $stmt->getBindMetadata());
36
            // If the data type of NULL cannot be determined from context, it is BOOLEAN.
37
            // @see https://www.tarantool.io/en/doc/2.2/reference/reference_sql/sql/#column-definition-data-type
38
            self::assertSame([['?', 'boolean']], $stmt->getMetadata());
39
        } finally {
40
            $stmt->close();
41
        }
42
    }
43
44
    public function testExecuteQueryReturnsResult() : void
45
    {
46
        $stmt = $this->client->prepare('SELECT :v1, :v2');
47
48
        $selectResult1 = $stmt->executeQuery([':v1' => 1], [':v2' => 2]);
49
        $selectResult2 = $stmt->executeQuery([':v1' => 3], [':v2' => 4]);
50
51
        try {
52
            self::assertSame([':v1' => 1, ':v2' => 2], $selectResult1[0]);
53
            self::assertSame([':v1' => 3, ':v2' => 4], $selectResult2[0]);
54
        } finally {
55
            $stmt->close();
56
        }
57
    }
58
59
    /**
60
     * @sql DROP TABLE IF EXISTS prepare_execute
61
     * @sql CREATE TABLE prepare_execute (id INTEGER PRIMARY KEY, name VARCHAR(50))
62
     */
63
    public function testExecuteUpdateUpdatesRows() : void
64
    {
65
        $stmt = $this->client->prepare('INSERT INTO prepare_execute VALUES(:id, :name)');
66
67
        $insertResult1 = $stmt->executeUpdate(1, 'foo');
68
        $insertResult2 = $stmt->executeUpdate([':name' => 'bar'], [':id' => 2]);
69
70
        $selectResult = $this->client->executeQuery('SELECT * FROM prepare_execute ORDER BY id');
71
72
        try {
73
            self::assertSame(1, $insertResult1->count());
74
            self::assertSame(1, $insertResult2->count());
75
            self::assertSame([[1, 'foo'], [2, 'bar']], $selectResult->getData());
76
        } finally {
77
            $stmt->close();
78
        }
79
    }
80
81
    public function testCloseDeallocatesPreparedStatement() : void
82
    {
83
        $stmt = $this->client->prepare('SELECT ?');
84
85
        $this->expectPreparedStatementToBeDeallocatedOnce();
86
        $stmt->close();
87
    }
88
89
    public function testCloseDeallocatesPreparedInLuaSqlStatement() : void
90
    {
91
        [$data] = $this->client->evaluate("s = box.prepare('SELECT ?') return {
0 ignored issues
show
Bug introduced by
The variable $data does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
92
            id=s.stmt_id, 
93
            bind_metadata=s.params, 
94
            metadata=s.metadata, 
95
            bind_count=s.param_count
96
        }");
97
98
        $stmt = new PreparedStatement(
99
            $this->client->getHandler(),
100
            $data['id'],
101
            $data['bind_count'],
102
            $data['bind_metadata'],
103
            $data['metadata']
104
        );
105
106
        $this->expectPreparedStatementToBeDeallocatedOnce();
107
        $stmt->close();
108
    }
109
110
    public function testCloseFailsOnNonexistentPreparedStatement() : void
111
    {
112
        $stmt = new PreparedStatement($this->client->getHandler(), 42, 0, [], []);
113
114
        $this->expectException(RequestFailed::class);
115
        $this->expectExceptionMessage('Prepared statement with id 42 does not exist');
116
        $stmt->close();
117
    }
118
119
    /**
120
     * @see https://github.com/tarantool/tarantool/issues/4825
121
     */
122
    public function testPrepareResetsPreviouslyBoundParameters() : void
123
    {
124
        $stmt = $this->client->prepare('SELECT :a, :b');
125
126
        // bind parameters to the current statement
127
        $stmt->execute([':a' => 1], [':b' => 2]);
128
129
        $result = $stmt->executeQuery([':a' => 1]);
130
        self::assertSame([1, null], $result->getData()[0]);
131
132
        $result = $stmt->executeQuery();
133
        self::assertSame([null, null], $result->getData()[0]);
134
    }
135
}
136