MySQLTest::testSelectWithCalcFoundRows()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 12
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 20
rs 9.8666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace QB\Tests;
6
7
use PDO;
8
use PHPUnit\Framework\TestCase;
9
use QB\Extra\PDOWrapper;
10
use QB\Generic\Clause\Column;
11
use QB\Generic\Clause\Table;
12
use QB\Generic\Expr\Expr;
13
use QB\MySQL\QueryBuilder\QueryBuilder;
14
use QB\MySQL\Statement\Select;
15
16
class MySQLTest extends TestCase
17
{
18
    /** @var QueryBuilder */
19
    protected QueryBuilder $sut;
20
21
    protected PDO $pdo;
22
23
    protected PDOWrapper $pdoWrapper;
24
25
    public function setUp(): void
26
    {
27
        if (!getenv('MYSQL_USER')) {
28
            $this->markTestSkipped('no db');
29
        }
30
31
        $this->sut = new QueryBuilder();
32
33
        $dns      = sprintf(
34
            'mysql:dbname=%s;host=%s',
35
            getenv('MYSQL_DATABASE'),
36
            'mysql'
37
        );
38
        $username = getenv('MYSQL_USER');
39
        $password =getenv('MYSQL_PASSWORD');
40
        $options  = null;
41
42
        $this->pdo = new PDO($dns, $username, $password, $options);
43
44
        $this->pdoWrapper = new PDOWrapper($this->pdo);
45
    }
46
47
    public function testSelectOneCustomer()
48
    {
49
        $sql = (string)$this->sut->select()
50
            ->from('customers')
51
            ->columns('customerName')
52
            ->limit(1);
53
54
        $statement = $this->pdo->query($sql);
55
56
        $this->assertSame('Atelier graphique', $statement->fetchColumn());
57
    }
58
59
    public function testSelectComplex()
60
    {
61
        $limit = 5;
62
63
        $columnQuery = $this->sut->select()
64
            ->from(new Table('employees', 'boss'))
65
            ->columns('lastName')
66
            ->where(new Expr('boss.employeeNumber = employees.reportsTo'));
67
68
        $customerTypeColumn = new Column(new Expr("'customers'"), 'type');
69
        $employeeTypeColumn = new Column(new Expr("'employees'"), 'type');
70
71
        $unionQuery = $this->sut->select()
72
            ->from('customers')
73
            ->columns('contactLastName', 'NULL', $customerTypeColumn);
74
75
        $query = $this->sut->select()
76
            ->from('employees')
77
            ->columns('lastName', new Column($columnQuery, 'bossLastName'), $employeeTypeColumn)
78
            ->innerJoin(new Table('offices', 'o'), 'employees.officeCode = o.officeCode')
79
            ->where(new Expr('employees.jobTitle = ?', ['Sales Rep']))
80
            ->where('o.city = \'NYC\'')
81
            ->union($unionQuery)
82
            ->outerOrderBy('type', Select::DIRECTION_DESC)
83
            ->outerOrderBy('lastName')
84
            ->outerLimit($limit);
85
86
        $this->assertCount($limit, $this->pdoWrapper->fetchAll($query, PDO::FETCH_ASSOC));
87
    }
88
89
    /**
90
     * @deprecated feature, reasons below
91
     *
92
     * The SQL_CALC_FOUND_ROWS query modifier and accompanying FOUND_ROWS() function are deprecated as of MySQL 8.0.17
93
     * and will be removed in a future MySQL version.
94
     *
95
     * COUNT(*) is subject to certain optimizations. SQL_CALC_FOUND_ROWS causes some optimizations to be disabled.
96
     *
97
     * Use these queries instead:
98
     */
99
    public function testSelectWithCalcFoundRows()
100
    {
101
        $limit = 5;
102
103
        $sql = (string)$this->sut->select()
104
            ->from('customers')
105
            ->modifier(Select::SQL_CALC_FOUND_ROWS)
106
            ->columns('customerName')
107
            ->limit($limit);
108
109
        $statement = $this->pdo->query($sql);
110
111
        $this->assertCount($limit, $statement->fetchAll());
112
113
        $sql = (string)$this->sut->select()
114
            ->columns('FOUND_ROWS()');
115
116
        $statement = $this->pdo->query($sql);
117
118
        $this->assertGreaterThan($limit, (int)$statement->fetchColumn());
119
    }
120
121
    public function testInsertUpdateDelete()
122
    {
123
        try {
124
            $this->pdo->exec('BEGIN');
125
126
            // INSERT
127
            $query = $this->sut->insert()
128
                ->into(new Table('offices'))
129
                ->columns('officeCode', 'city', 'phone', 'addressLine1', 'country', 'postalCode', 'territory')
130
                ->values("'abc'", "'Berlin'", "'+49 101 123 4567'", "''", "'Germany'", "'10111'", "'NA'");
131
132
            $statement = $this->pdo->prepare((string)$query);
133
134
            $result = $statement->execute();
135
            $this->assertTrue($result);
136
137
            // UPDATE
138
            $query = $this->sut->update(new Table('offices'))
139
                ->values(['territory' => "'Berlin'"])
140
                ->where("officeCode = 'abc'");
141
142
            $this->assertTrue($this->pdoWrapper->execute($query));
143
144
            // DELETE
145
            $query = $this->sut->delete()
146
                ->from(new Table('offices'))
147
                ->where(new Expr('officeCode = ?', ['abc']));
148
149
            $this->assertTrue($this->pdoWrapper->execute($query));
150
151
            // COMMIT
152
            $this->pdo->exec('COMMIT');
153
        } catch (\Exception $e) {
154
            if ($this->pdo->inTransaction()) {
155
                $this->pdo->exec('ROLLBACK');
156
            }
157
            $this->fail($e->getMessage() . PHP_EOL . $e->getTraceAsString());
158
        }
159
    }
160
}
161