Test Failed
Push — master ( 50dc03...2f2ddd )
by Petr
02:45
created

SQLiteNameTestRecord   A

Complexity

Total Complexity 1

Size/Duplication

Total Lines 9
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 1
eloc 6
c 1
b 0
f 0
dl 0
loc 9
rs 10
1
<?php
2
3
namespace StorageTests\Database\DeepQuery;
4
5
6
use CommonTestClass;
7
use kalanis\kw_mapper\Interfaces\IDriverSources;
8
use kalanis\kw_mapper\Interfaces\IEntryType;
9
use kalanis\kw_mapper\MapperException;
10
use kalanis\kw_mapper\Mappers\Database\ADatabase;
11
use kalanis\kw_mapper\Records\ASimpleRecord;
12
use kalanis\kw_mapper\Search\Search;
13
use kalanis\kw_mapper\Storage\Database\Config;
14
use kalanis\kw_mapper\Storage\Database\ConfigStorage;
15
use kalanis\kw_mapper\Storage\Database\DatabaseSingleton;
16
use kalanis\kw_mapper\Storage\Database\PDO\SQLite;
17
use PDO;
18
19
20
/**
21
 * Class SqLiteCircularTest
22
 * @package StorageTests\Database\DeepQuery
23
 * @requires extension PDO
24
 * @requires extension pdo_sqlite
25
 */
26
class SqLiteCircularTest extends CommonTestClass
27
{
28
    /** @var null|SQLite */
29
    protected $database = null;
30
31
    /**
32
     * @throws MapperException
33
     */
34
    protected function setUp(): void
35
    {
36
        $conf = Config::init()->setTarget(
37
                    IDriverSources::TYPE_PDO_SQLITE,
38
                    'test_sqlite_local',
39
                    ':memory:',
40
                    0,
41
                    null,
42
                    null,
43
                    ''
44
                );
45
        $conf->setParams(86000, true);
46
        ConfigStorage::getInstance()->addConfig($conf);
47
        $this->database = DatabaseSingleton::getInstance()->getDatabase($conf);
48
        $this->database->addAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
49
    }
50
51
    /**
52
     * @throws MapperException
53
     */
54
    public function testSimpleData(): void
55
    {
56
        $this->dataRefill();
57
58
        $search = new Search(new SQLiteNameTestRecord());
59
        $search->exact('name', 'Evgenij');
60
        $this->assertEquals(1, $search->getCount());
61
        $records = $search->getResults();
62
        $record = reset($records);
63
        $this->assertEquals(18, $record->id);
64
        $this->assertEquals('Evgenij', $record->name);
65
        $this->assertEmpty($record->pars);
66
    }
67
68
    /**
69
     * @throws MapperException
70
     * these records has common sub-record
71
     */
72
    public function testFirstLevelData(): void
73
    {
74
        $this->dataRefill();
75
76
        $search = new Search(new SQLiteNameTestRecord());
77
        $search->child('pars', '', '', 'chil'); // need own alias due table name
78
        $search->exact('chil.name', 'Jakub');
79
        $this->assertEquals(3, $search->getCount());
80
81
        $records = $search->getResults();
82
        $record = reset($records);
83
        $this->assertNotEmpty($record->pars);
84
        $parents = $record->pars;
85
        $parent = reset($parents);
86
87
        $this->assertEquals(4, $parent->id);
88
        $this->assertEquals('Jakub', $parent->name);
89
        $this->assertEquals(18, $parent->par);
90
        $this->assertEmpty($parent->pars);
91
92
        $record = next($records);
93
        $this->assertNotEmpty($record->pars);
94
        $parents = $record->pars;
95
        $this->assertEquals($parent, reset($parents));
96
97
        $record = next($records);
98
        $this->assertNotEmpty($record->pars);
99
        $parents = $record->pars;
100
        $this->assertEquals($parent, reset($parents));
101
    }
102
103
    /**
104
     * @throws MapperException
105
     */
106
    public function testSecondLevelData(): void
107
    {
108
        $this->dataRefill();
109
110
        $search = new Search(new SQLiteNameTestRecord());
111
        $search->child('pars', '', '', 'chil');
112
        $search->child('pars', '', 'chil', 'deep');
113
        $search->exact('deep.name', 'Radek');
114
        $this->assertEquals(1, $search->getCount());
115
116
        $records = $search->getResults();
117
        $record = reset($records);
118
        $this->assertEquals(14, $record->id);
119
        $this->assertEquals('Zbynek', $record->name);
120
    }
121
122
    /**
123
     * @throws MapperException
124
     */
125
    public function testNonExistingChild(): void
126
    {
127
        $this->dataRefill();
128
129
        $search = new Search(new SQLiteNameTestRecord());
130
        $this->expectException(MapperException::class); // sqlite does not know left outer join here
131
        $search->childNotExist('pars', 'par');
132
//        $this->assertEquals(2, $search->getCount());
133
    }
134
135
    /**
136
     * @throws MapperException
137
     */
138
    public function testConnectChildNotParent(): void
139
    {
140
        $search = new Search(new SQLiteNameTestRecord());
141
        $this->expectException(MapperException::class);
142
        $this->expectExceptionMessage('Unknown record for parent alias *not-known*');
143
        $search->child('chld', '', 'not-known');
144
    }
145
146
    /**
147
     * @throws MapperException
148
     */
149
    public function testConnectChildNotParentKey(): void
150
    {
151
        $search = new Search(new SQLiteNameTestRecord());
152
        $search->child('pars', '', '', 'chil');
153
        $this->expectException(MapperException::class);
154
        $this->expectExceptionMessage('Unknown alias *deep* in mapper for parent *chil*');
155
        $search->child('deep', '', 'chil', 'deep');
156
    }
157
158
    /**
159
     * @throws MapperException
160
     */
161
    public function testConnectColumnNotExists(): void
162
    {
163
        $search = new Search(new SQLiteNameTestRecord());
164
        $this->expectException(MapperException::class);
165
        $this->expectExceptionMessage('Unknown relation key *not-known* in mapper for table *x_name_test*');
166
        $search->exact('not-known', 'empty_value');
167
    }
168
169
    /**
170
     * @throws MapperException
171
     */
172
    protected function dataRefill(): void
173
    {
174
        $this->assertTrue($this->database->exec($this->dropTable(), []));
175
        $this->assertTrue($this->database->exec($this->basicTable(), []));
176
        $this->assertTrue($this->database->exec($this->fillTable(), []));
177
        $this->assertEquals(8, $this->database->rowCount());
178
    }
179
180
    protected function dropTable(): string
181
    {
182
        return 'DROP TABLE IF EXISTS "x_name_test"';
183
    }
184
185
    protected function basicTable(): string
186
    {
187
        return 'CREATE TABLE IF NOT EXISTS "x_name_test" (
188
  "x_id" INT AUTO_INCREMENT NOT NULL PRIMARY KEY ,
189
  "x_name" VARCHAR(20) NOT NULL,
190
  "x_par" INT NULL
191
)';
192
    }
193
194
    protected function fillTable(): string
195
    {
196
        return 'INSERT INTO "x_name_test" ("x_id", "x_name", "x_par") VALUES
197
( 3, "Vaclav", 4),
198
( 4, "Jakub", 18),
199
( 5, "Michal", 4),
200
( 7, "Vladan", 10),
201
(10, "Radek", null),
202
(11, "Vojtech", 4),
203
(14, "Zbynek", 7),
204
(18, "Evgenij", null)
205
';
206
    }
207
}
208
209
210
/**
211
 * Class SQLiteNameTestRecord
212
 * @property int id
213
 * @property string name
214
 * @property int par
215
 * @property SQLiteNameTestRecord[] pars
216
 */
217
class SQLiteNameTestRecord extends ASimpleRecord
218
{
219
    protected function addEntries(): void
220
    {
221
        $this->addEntry('id', IEntryType::TYPE_INTEGER, 64);
222
        $this->addEntry('name', IEntryType::TYPE_STRING, 250);
223
        $this->addEntry('par', IEntryType::TYPE_INTEGER, 64);
224
        $this->addEntry('pars', IEntryType::TYPE_ARRAY); // FK - makes the array of entries every time
225
        $this->setMapper('\StorageTests\Database\DeepQuery\SQLiteNameTestMapper');
226
    }
227
}
228
229
230
class SQLiteNameTestMapper extends ADatabase
231
{
232
    protected function setMap(): void
233
    {
234
        $this->setSource('test_sqlite_local');
235
        $this->setTable('x_name_test');
236
        $this->setRelation('id', 'x_id');
237
        $this->setRelation('name', 'x_name');
238
        $this->setRelation('par', 'x_par');
239
        $this->addPrimaryKey('id');
240
        $this->addForeignKey('pars', '\StorageTests\Database\DeepQuery\SQLiteNameTestRecord', 'par', 'id');
241
    }
242
}
243