| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- <?php
- namespace Test\Michel\SqlMapper;
- use PDO;
- use Michel\SqlMapper\QL\JoinQL;
- use Michel\UniTester\TestCase;
- class JoinQLTest extends TestCase
- {
- private PDO $connection;
- protected function setUp(): void
- {
- $this->connection = new PDO(
- 'sqlite::memory:',
- null,
- null,
- [PDO::ATTR_EMULATE_PREPARES => false]
- );
- $this->setUpDatabaseSchema();
- }
- protected function tearDown(): void
- {
- }
- protected function execute(): void
- {
- $this->testRealRelations();
- $this->testSelect();
- $this->testAddSelect();
- $this->testWhere();
- $this->testOrderBy();
- $this->testLeftJoin();
- $this->testInnerJoin();
- $this->testWithLimit();
- $this->testWithParams();
- $this->testPaginationWithOffsetAndLimit();
- }
- public function testSelect(): void
- {
- $joinQl = new JoinQL($this->connection);
- $joinQl->select('table', 'alias', ['column', 'column2' => 'alias__column']);
- $this->assertEquals('SELECT alias.column AS alias__column, alias.column2 AS alias__alias__column FROM table AS alias', $joinQl->getQuery());
- }
- public function testAddSelect(): void
- {
- $joinQl = new JoinQL($this->connection);
- $joinQl->select('table', 'alias', ['column']);
- $joinQl->addSelect('alias', ['column']);
- $this->assertEquals('SELECT alias.column AS alias__column, alias.column AS alias__column FROM table AS alias', $joinQl->getQuery());
- }
- public function testWhere(): void
- {
- $joinQl = new JoinQL($this->connection);
- $joinQl->select('table', 'alias', ['column']);
- $joinQl->where('alias.column = value');
- $this->assertEquals('SELECT alias.column AS alias__column FROM table AS alias WHERE alias.column = value', $joinQl->getQuery());
- }
- public function testOrderBy(): void
- {
- $joinQl = new JoinQL($this->connection);
- $joinQl->select('table', 'alias', ['column']);
- $joinQl->orderBy('column');
- $this->assertEquals('SELECT alias.column AS alias__column FROM table AS alias ORDER BY column ASC', $joinQl->getQuery());
- }
- public function testLeftJoin(): void
- {
- $joinQl = new JoinQL($this->connection);
- $joinQl->select('table', 'alias', ['column']);
- $joinQl->leftJoin('table', 'table2', 'alias2', ['column = column'], false, 'relation');
- $this->assertEquals('SELECT alias.column AS alias__column FROM table AS alias LEFT JOIN table2 alias2 ON column = column', $joinQl->getQuery());
- }
- public function testInnerJoin(): void
- {
- $joinQl = new JoinQL($this->connection);
- $joinQl->select('table', 'alias', ['column']);
- $joinQl->innerJoin('table', 'table2', 'alias2', ['column = column'], false, 'relation');
- $this->assertEquals('SELECT alias.column AS alias__column FROM table AS alias INNER JOIN table2 alias2 ON column = column', $joinQl->getQuery());
- }
- private function testRealRelations(): void
- {
- $joinQl = new JoinQL($this->connection, 'id', 5);
- $joinQl
- ->select('user', 'u', ['id', 'firstname' => 'firstname', 'lastname', 'email' => 'email_address', 'password', 'is_active', 'created_at'])
- ->addSelect('p', ['id', 'title', 'user_id', 'content', 'created_at'])
- ->addSelect('t', ['id', 'name' => 'tag_name', 'post_id'])
- ->addSelect('c', ['id', 'body', 'post_id'])
- ->leftJoin('user', 'post', 'p', ['u.id = p.user_id'], true, 'posts', 'user_id')
- ->leftJoin('post', 'tag', 't', ['p.id = t.post_id'], true, 'tags', 'post_id')
- ->leftJoin('post', 'comment', 'c', ['p.id = c.post_id'], true, 'comments', 'post_id');
- foreach ($joinQl->getResult() as $row) {
- $this->testRowOneToMany($row);
- }
- $row = $joinQl->getOneOrNullResult();
- $this->testRowOneToMany($row);
- foreach ($joinQl->getResultIterator() as $row) {
- $this->testRowOneToMany($row);
- }
- $row = $joinQl->getOneOrNullResult();
- $this->testRowOneToMany($row);
- $joinQl = new JoinQL($this->connection);
- $joinQl
- ->select('post', 'p', ['id', 'title', 'user_id', 'content', 'created_at'])
- ->addSelect('u', ['id', 'firstname' , 'lastname', 'email' , 'password', 'is_active', 'created_at'])
- ->addSelect('t', ['id', 'name', 'post_id'])
- ->addSelect('c', ['id', 'body', 'post_id'])
- ->leftJoin('post', 'user', 'u', ['u.id = p.user_id'], false, 'user', 'user_id')
- ->leftJoin('post', 'tag', 't', ['p.id = t.post_id'], true, 'tags', 'post_id')
- ->leftJoin('post', 'comment', 'c', ['p.id = c.post_id'], true, 'comments', 'post_id')
- ->orderBy('p.id', 'desc')
- ->setMaxResults(3);
- $data = $joinQl->getResult();
- $this->assertEquals( 3 , count($data));
- foreach ($data as $row) {
- $this->assertTrue(array_key_exists('user', $row));
- $this->assertTrue(array_key_exists('comments', $row));
- $this->assertTrue(array_key_exists('tags', $row));
- }
- $count = $joinQl->count();
- $this->assertEquals( 10 , $count);
- }
- private function testWithLimit()
- {
- $joinQl = new JoinQL($this->connection);
- $joinQl
- ->select('post', 'p', ['id', 'title', 'user_id', 'content', 'created_at'])
- ->setMaxResults(1000000);
- $data = $joinQl->getResult();
- $this->assertEquals( 10 , count($data));
- $count = $joinQl->count();
- $this->assertEquals( 10 , $count);
- }
- public function testWithParams(): void {
- $joinQl = new JoinQL($this->connection);
- $joinQl
- ->select('post', 'p', ['id', 'title', 'user_id', 'content', 'created_at'])
- ->where('id > :id')
- ->setParam('id', 5)
- ->setMaxResults(1000000);
- $data = $joinQl->getResult();
- $this->assertEquals( 5 , count($data));
- $this->assertEquals( 5 , $joinQl->count());
- }
- public function testPaginationWithOffsetAndLimit(): void
- {
- $joinQl = new JoinQL($this->connection);
- // Page 1 : OFFSET 0 LIMIT 2
- $page1 = $joinQl
- ->select('post', 'p', ['id', 'title'])
- ->setFirstResult(0)
- ->setMaxResults(2)
- ->getResult();
- $this->assertEquals(2, count($page1));
- $this->assertEquals(1, $page1[0]['id']);
- $this->assertEquals(2, $page1[1]['id']);
- // Page 2 : OFFSET 2 LIMIT 2
- $joinQl = new JoinQL($this->connection);
- $page2 = $joinQl
- ->select('post', 'p', ['id', 'title'])
- ->setFirstResult(2)
- ->setMaxResults(2)
- ->getResult();
- $this->assertEquals(2, count($page2));
- $this->assertEquals(3, $page2[0]['id']);
- $this->assertEquals(4, $page2[1]['id']);
- // Vérifier que le count() ignore la pagination
- $total = $joinQl->count();
- $this->assertEquals(10, $total);
- }
- private function testRowOneToMany($row)
- {
- $this->assertTrue(is_array($row));
- $this->assertTrue(array_key_exists('id', $row));
- $this->assertTrue(array_key_exists('firstname', $row));
- $this->assertTrue(array_key_exists('lastname', $row));
- $this->assertTrue(array_key_exists('email_address', $row));
- $this->assertTrue(array_key_exists('password', $row));
- $this->assertTrue(array_key_exists('is_active', $row));
- $this->assertTrue(array_key_exists('posts', $row));
- $this->assertTrue(array_key_exists('tags', $row['posts'][0]));
- $this->assertTrue(array_key_exists('comments', $row['posts'][0]));
- $this->assertTrue(array_key_exists('tag_name', $row['posts'][0]['tags'][0]));
- $this->assertEquals(2, count($row['posts']));
- }
- protected function setUpDatabaseSchema(): void
- {
- $this->connection->exec('CREATE TABLE user (
- id INTEGER PRIMARY KEY,
- firstname VARCHAR(255),
- lastname VARCHAR(255),
- email VARCHAR(255),
- password VARCHAR(255),
- is_active BOOLEAN,
- created_at DATETIME DEFAULT CURRENT_TIMESTAMP
- );');
- $this->connection->exec('CREATE TABLE post (
- id INTEGER PRIMARY KEY,
- user_id INTEGER,
- title VARCHAR(255),
- content VARCHAR(255),
- created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
- FOREIGN KEY (user_id) REFERENCES user (id)
- );');
- $this->connection->exec('CREATE TABLE tag (
- id INTEGER PRIMARY KEY,
- post_id INTEGER,
- name VARCHAR(255)
- )');
- $this->connection->exec('CREATE TABLE comment (
- id INTEGER PRIMARY KEY,
- post_id INTEGER,
- body VARCHAR(255)
- )');
- for ($i = 0; $i < 5; $i++) {
- $user = [
- 'firstname' => 'John' . $i,
- 'lastname' => 'Doe' . $i,
- 'email' => $i . 'bqQpB@example.com',
- 'password' => 'password123',
- 'is_active' => true,
- ];
- $this->connection->exec("INSERT INTO user (firstname, lastname, email, password, is_active) VALUES (
- '{$user['firstname']}',
- '{$user['lastname']}',
- '{$user['email']}',
- '{$user['password']}',
- '{$user['is_active']}'
- )");
- }
- for ($i = 0; $i < 5; $i++) {
- $id = uniqid('post_', true);
- $post = [
- 'user_id' => $i + 1,
- 'title' => 'Post ' . $id,
- 'content' => 'Content ' . $id,
- ];
- $this->connection->exec("INSERT INTO post (user_id, title, content) VALUES (
- '{$post['user_id']}',
- '{$post['title']}',
- '{$post['content']}'
- )");
- $id = uniqid('post_', true);
- $post = [
- 'user_id' => $i + 1,
- 'title' => 'Post ' . $id,
- 'content' => 'Content ' . $id,
- ];
- $this->connection->exec("INSERT INTO post (user_id, title, content) VALUES (
- '{$post['user_id']}',
- '{$post['title']}',
- '{$post['content']}'
- )");
- }
- for ($i = 0; $i < 10; $i++) {
- $id = uniqid('tag_', true);
- $tag = [
- 'post_id' => $i + 1,
- 'name' => 'Tag ' . $id,
- ];
- $this->connection->exec("INSERT INTO tag (post_id, name) VALUES (
- '{$tag['post_id']}',
- '{$tag['name']}'
- )");
- $id = uniqid('tag_', true);
- $tag = [
- 'post_id' => $i + 1,
- 'name' => 'Tag ' . $id,
- ];
- $this->connection->exec("INSERT INTO tag (post_id, name) VALUES (
- '{$tag['post_id']}',
- '{$tag['name']}'
- )");
- }
- for ($i = 0; $i < 10; $i++) {
- $id = uniqid('comment_', true);
- $comment = [
- 'post_id' => $i + 1,
- 'body' => 'Comment ' . $id,
- ];
- $this->connection->exec("INSERT INTO comment (post_id, body) VALUES (
- '{$comment['post_id']}',
- '{$comment['body']}'
- )");
- }
- }
- }
|