Passed
Push — main ( b157b0...77200e )
by Peter
02:25
created

MySQLTest   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 76
dl 0
loc 139
rs 10
c 0
b 0
f 0
wmc 8

5 Methods

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