Passed
Push — main ( 312896...5e0bcd )
by Peter
02:18
created

PostgreSQLTest::testSelectComplex()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 39
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 28
nc 3
nop 0
dl 0
loc 39
rs 9.472
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace QB\Test;
6
7
use PHPUnit\Framework\TestCase;
8
use QB\Generic\Clause\Column;
9
use QB\Generic\Clause\Table;
10
use QB\Generic\Expr\Expr;
11
use QB\PostgreSQL\Factory\Factory;
12
13
class PostgreSQLTest extends TestCase
14
{
15
    /** @var Factory */
16
    protected Factory $sut;
17
18
    protected \PDO $pdo;
19
20
    public function setUp(): void
21
    {
22
        $this->sut = new Factory();
23
24
        $dns      = sprintf(
25
            'pgsql:dbname=%s;host=%s',
26
            $_ENV['POSTGRES_DB'],
27
            'postgres'
28
        );
29
        $username = $_ENV['POSTGRES_USER'];
30
        $password = $_ENV['POSTGRES_PASSWORD'];
31
        $options  = null;
32
33
        $this->pdo = new \PDO($dns, $username, $password, $options);
34
    }
35
36
    public function testSelectOneCustomer()
37
    {
38
        $sql = (string)$this->sut->select()
39
            ->addFrom('customers')
40
            ->addColumns('customerName')
41
            ->setLimit(1);
42
43
        $statement = $this->pdo->query($sql);
44
45
        $this->assertSame('Atelier graphique', $statement->fetchColumn());
46
    }
47
48
    public function testSelectComplex()
49
    {
50
        $limit = 5;
51
52
        $columnQuery = $this->sut->select()
53
            ->addFrom(new Table('employees', 'boss'))
54
            ->addColumns('lastName')
55
            ->addWhere(new Expr('boss.employeeNumber = employees.reportsTo'));
56
57
        $customerTypeColumn = new Column(new Expr("'customer'"), 'type');
58
        $employeeTypeColumn = new Column(new Expr("'employee'"), 'type');
59
60
        $unionQuery = $this->sut->select()
61
            ->addFrom('customers')
62
            ->addColumns('contactLastName', 'NULL', $customerTypeColumn);
63
64
        $query = $this->sut->select()
65
            ->addFrom('employees')
66
            ->addColumns('lastName', new Column($columnQuery, 'bossLastName'), $employeeTypeColumn)
67
            ->addInnerJoin('offices', 'employees.officeCode = o.officeCode', 'o')
68
            ->addWhere(new Expr('employees.jobTitle = ?', ['Sales Rep']))
69
            ->addWhere('o.city = \'NYC\'')
70
            ->addUnion($unionQuery)
71
            ->addOuterOrderBy('type', 'DESC')
72
            ->addOuterOrderBy('lastName')
73
            ->setOuterLimit($limit);
74
75
        $statement = $this->pdo->prepare((string)$query);
76
        foreach ($query->getParams() as $k => $v) {
77
            if (is_numeric($k)) {
78
                $statement->bindParam($k + 1, $v[0], $v[1]);
79
            } else {
80
                $statement->bindParam($k, $v[0], $v[1]);
81
            }
82
        }
83
84
        $statement->execute();
85
86
        $this->assertCount($limit, $statement->fetchAll(\PDO::FETCH_ASSOC));
87
    }
88
89
    public function testInsertUpdateDelete()
90
    {
91
        try {
92
            $this->pdo->exec('BEGIN');
93
94
            // INSERT
95
            $query = $this->sut->insert()
96
                ->addFrom(new Table('offices'))
97
                ->addColumns('officeCode', 'city', 'phone', 'addressLine1', 'country', 'postalCode', 'territory')
98
                ->addValues('abc', 'Berlin', '+49 101 123 4567', '', 'Germany', '10111', 'NA');
99
100
            $statement = $this->pdo->prepare((string)$query);
101
102
            $result = $statement->execute($query->getValues()[0]);
103
            $this->assertTrue($result);
104
105
            // UPDATE
106
            $query = $this->sut->update()
107
                ->addFrom(new Table('offices'))
108
                ->setValues(['territory' => 'Berlin'])
109
                ->addWhere('officeCode = \'oc\'');
110
111
            $num    = 1;
112
            $sql    = (string)$query;
113
            $values = $query->getValues();
114
            $params = $query->getParams();
115
116
            $statement = $this->pdo->prepare($sql);
117
            foreach ($values as $value) {
118
                $statement->bindParam($num++, $value);
119
            }
120
            foreach ($params as $k => $v) {
121
                if (is_numeric($k)) {
122
                    $statement->bindParam($num++, $v[0], $v[1]);
123
                } else {
124
                    $statement->bindParam($k, $v[0], $v[1]);
125
                }
126
            }
127
            $result = $statement->execute($values);
128
            $this->assertTrue($result);
129
130
            // DELETE
131
            $query = $this->sut->delete()
132
                ->addFrom(new Table('offices'))
133
                ->addWhere(new Expr('officeCode = ?', ['abc']));
134
135
            $sql    = (string)$query;
136
            $params = $query->getParams();
137
138
            $statement = $this->pdo->prepare($sql);
139
            foreach ($params as $k => $v) {
140
                if (is_numeric($k)) {
141
                    $statement->bindParam($k + 1, $v[0], $v[1]);
142
                } else {
143
                    $statement->bindParam($k, $v[0], $v[1]);
144
                }
145
            }
146
            $result = $statement->execute();
147
            $this->assertTrue($result);
148
149
            // COMMIT
150
            $this->pdo->exec('COMMIT');
151
        } catch (\Exception $e) {
152
            if ($this->pdo->inTransaction()) {
153
                $this->pdo->exec('ROLLBACK');
154
            }
155
            $this->fail($e->getMessage());
156
        }
157
    }
158
}
159