仓储

Testing Is Documentation

tests/Database/Ddd/RepositoryTest.php仓储 - 图1

仓储层可以看作是对实体的一种包装,通过构造器注入的实体。

Uses

  1. <?php
  2. use Leevel\Collection\Collection;
  3. use Leevel\Database\Ddd\Entity;
  4. use Leevel\Database\Ddd\ISpecification;
  5. use Leevel\Database\Ddd\Repository;
  6. use Leevel\Database\Ddd\Select;
  7. use Leevel\Database\Ddd\Specification;
  8. use Leevel\Database\Page;
  9. use Leevel\Page\Page as BasePage;
  10. use Tests\Database\DatabaseTestCase as TestCase;
  11. use Tests\Database\Ddd\Entity\DemoUnique;
  12. use Tests\Database\Ddd\Entity\Relation\Post;

基本使用方法

  1. public function testBase(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. $this->assertSame(
  5. 1,
  6. $connect
  7. ->table('post')
  8. ->insert([
  9. 'title' => 'hello world',
  10. 'user_id' => 1,
  11. 'summary' => 'post summary',
  12. 'delete_at' => 0,
  13. ])
  14. );
  15. $repository = new Repository(new Post());
  16. $newPost = $repository->findEntity(1);
  17. $this->assertInstanceof(Post::class, $newPost);
  18. $this->assertSame(1, $newPost->id);
  19. $this->assertSame(1, $newPost->userId);
  20. $this->assertSame('hello world', $newPost->title);
  21. $this->assertSame('post summary', $newPost->summary);
  22. $this->assertInstanceof(Post::class, $repository->entity());
  23. }

findEntity 通过主键查找实体

  1. public function testFindEntity(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. $this->assertSame(
  5. 1,
  6. $connect
  7. ->table('post')
  8. ->insert([
  9. 'title' => 'hello world',
  10. 'user_id' => 1,
  11. 'summary' => 'post summary',
  12. 'delete_at' => 0,
  13. ])
  14. );
  15. $repository = new Repository(new Post());
  16. $newPost = $repository->findEntity(1);
  17. $this->assertInstanceof(Post::class, $newPost);
  18. $this->assertSame(1, $newPost->id);
  19. $this->assertSame(1, $newPost->userId);
  20. $this->assertSame('hello world', $newPost->title);
  21. $this->assertSame('post summary', $newPost->summary);
  22. }

findOrFail 通过主键查找实体,未找到则抛出异常

  1. public function testFindOrFail(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. $this->assertSame(
  5. 1,
  6. $connect
  7. ->table('post')
  8. ->insert([
  9. 'title' => 'hello world',
  10. 'user_id' => 1,
  11. 'summary' => 'post summary',
  12. 'delete_at' => 0,
  13. ])
  14. );
  15. $repository = new Repository(new Post());
  16. $newPost = $repository->findOrFail(1);
  17. $this->assertInstanceof(Post::class, $newPost);
  18. $this->assertSame(1, $newPost->id);
  19. $this->assertSame(1, $newPost->userId);
  20. $this->assertSame('hello world', $newPost->title);
  21. $this->assertSame('post summary', $newPost->summary);
  22. }

findOrFail 通过主键查找实体,未找到则抛出异常例子

  1. public function testFindOrFailNotFound(): void
  2. {
  3. $this->expectException(\Leevel\Database\Ddd\EntityNotFoundException::class);
  4. $this->expectExceptionMessage(
  5. 'Entity `Tests\\Database\\Ddd\\Entity\\Relation\\Post` was not found.'
  6. );
  7. $repository = new Repository(new Post());
  8. $newPost = $repository->findOrFail(1);
  9. }

规约闭包查询

  1. public function testSpecWithClosure(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. for ($i = 0; $i < 10; $i++) {
  5. $connect
  6. ->table('post')
  7. ->insert([
  8. 'title' => 'hello world',
  9. 'user_id' => 1,
  10. 'summary' => 'post summary',
  11. 'delete_at' => 0,
  12. ]);
  13. }
  14. $request = ['foo' => 'bar', 'hello' => 'world'];
  15. $repository = new Repository(new Post());
  16. $spec = new Specification(function (Entity $entity) use ($request) {
  17. return 'bar' === $request['foo'];
  18. }, function (Select $select, Entity $entity) {
  19. $select->where('id', '>', 3);
  20. });
  21. $andSpec = $spec->and(new Specification(function (Entity $entity) use ($request) {
  22. return 'world' === $request['hello'];
  23. }, function (Select $select, Entity $entity) {
  24. $select->where('id', '<', 8);
  25. }));
  26. $this->assertInstanceof(ISpecification::class, $andSpec);
  27. $this->assertInstanceof(Specification::class, $andSpec);
  28. $select = $repository->condition($andSpec);
  29. $result = $select->findAll();
  30. $sql = <<<'eot'
  31. SQL: [126] SELECT `post`.* FROM `post` WHERE `post`.`delete_at` = :post_delete_at AND `post`.`id` > :post_id AND `post`.`id` < :post_id_1 | Params: 3 | Key: Name: [15] :post_delete_at | paramno=0 | name=[15] ":post_delete_at" | is_param=1 | param_type=1 | Key: Name: [8] :post_id | paramno=1 | name=[8] ":post_id" | is_param=1 | param_type=1 | Key: Name: [10] :post_id_1 | paramno=2 | name=[10] ":post_id_1" | is_param=1 | param_type=1 (SELECT `post`.* FROM `post` WHERE `post`.`delete_at` = 0 AND `post`.`id` > 3 AND `post`.`id` < 8)
  32. eot;
  33. $this->assertSame(
  34. $sql,
  35. $select->getLastSql(),
  36. );
  37. $this->assertInstanceof(Select::class, $select);
  38. $this->assertInstanceof(Collection::class, $result);
  39. $this->assertCount(4, $result);
  40. }

from 转换为标准规约查询

fixture 定义

Tests\Database\Ddd\Demo1Specification

  1. namespace Tests\Database\Ddd;
  2. class Demo1Specification extends Specification
  3. {
  4. private $request;
  5. public function __construct(array $request)
  6. {
  7. $this->request = $request;
  8. }
  9. public function isSatisfiedBy(Entity $entity): bool
  10. {
  11. return 'bar' === $this->request['foo'];
  12. }
  13. public function handle(Select $select, Entity $entity): void
  14. {
  15. $select->where('id', '>', 3);
  16. }
  17. }

Tests\Database\Ddd\Demo2Specification

  1. namespace Tests\Database\Ddd;
  2. class Demo2Specification extends Specification
  3. {
  4. private $request;
  5. public function __construct(array $request)
  6. {
  7. $this->request = $request;
  8. }
  9. public function isSatisfiedBy(Entity $entity): bool
  10. {
  11. return 'world' === $this->request['hello'];
  12. }
  13. public function handle(Select $select, Entity $entity): void
  14. {
  15. $select->where('id', '<', 8);
  16. }
  17. }
  1. public function testSpecWithClass(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. for ($i = 0; $i < 10; $i++) {
  5. $connect
  6. ->table('post')
  7. ->insert([
  8. 'title' => 'hello world',
  9. 'user_id' => 1,
  10. 'summary' => 'post summary',
  11. 'delete_at' => 0,
  12. ]);
  13. }
  14. $request = ['foo' => 'bar', 'hello' => 'world'];
  15. $repository = new Repository(new Post());
  16. $spec = Specification::from(new Demo1Specification($request));
  17. $spec->and(new Demo2Specification($request));
  18. $this->assertInstanceof(ISpecification::class, $spec);
  19. $this->assertInstanceof(Specification::class, $spec);
  20. $select = $repository->condition($spec);
  21. $result = $select->findAll();
  22. $sql = <<<'eot'
  23. SQL: [126] SELECT `post`.* FROM `post` WHERE `post`.`delete_at` = :post_delete_at AND `post`.`id` > :post_id AND `post`.`id` < :post_id_1 | Params: 3 | Key: Name: [15] :post_delete_at | paramno=0 | name=[15] ":post_delete_at" | is_param=1 | param_type=1 | Key: Name: [8] :post_id | paramno=1 | name=[8] ":post_id" | is_param=1 | param_type=1 | Key: Name: [10] :post_id_1 | paramno=2 | name=[10] ":post_id_1" | is_param=1 | param_type=1 (SELECT `post`.* FROM `post` WHERE `post`.`delete_at` = 0 AND `post`.`id` > 3 AND `post`.`id` < 8)
  24. eot;
  25. $this->assertSame(
  26. $sql,
  27. $select->getLastSql(),
  28. );
  29. $this->assertInstanceof(Select::class, $select);
  30. $this->assertInstanceof(Collection::class, $result);
  31. $this->assertCount(4, $result);
  32. }

not 规约反操作

  1. public function testFindAllBySpecWithClosureForNot(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. for ($i = 0; $i < 10; $i++) {
  5. $connect
  6. ->table('post')
  7. ->insert([
  8. 'title' => 'hello world',
  9. 'user_id' => 1,
  10. 'summary' => 'post summary',
  11. 'delete_at' => 0,
  12. ]);
  13. }
  14. $request = ['foo' => 'bar', 'hello' => 'world'];
  15. $repository = new Repository(new Post());
  16. $spec = new Specification(function (Entity $entity) use ($request) {
  17. return 'bar' === $request['foo'];
  18. }, function (Select $select, Entity $entity) {
  19. $select->where('id', '>', 3);
  20. });
  21. $notSpec = $spec->not();
  22. $this->assertInstanceof(ISpecification::class, $notSpec);
  23. $this->assertInstanceof(Specification::class, $notSpec);
  24. $result = $repository->findAll($notSpec);
  25. $sql = <<<'eot'
  26. SQL: [70] SELECT `post`.* FROM `post` WHERE `post`.`delete_at` = :post_delete_at | Params: 1 | Key: Name: [15] :post_delete_at | paramno=0 | name=[15] ":post_delete_at" | is_param=1 | param_type=1 (SELECT `post`.* FROM `post` WHERE `post`.`delete_at` = 0)
  27. eot;
  28. $this->assertSame(
  29. $sql,
  30. $repository->getLastSql(),
  31. );
  32. $this->assertInstanceof(Collection::class, $result);
  33. $this->assertCount(10, $result);
  34. }

or 规约或操作

  1. public function testSpecWithOrFirstIsNo(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. for ($i = 0; $i < 10; $i++) {
  5. $connect
  6. ->table('post')
  7. ->insert([
  8. 'title' => 'hello world',
  9. 'user_id' => 1,
  10. 'summary' => 'post summary',
  11. 'delete_at' => 0,
  12. ]);
  13. }
  14. $request = ['foo' => 'bar', 'hello' => 'world'];
  15. $repository = new Repository(new Post());
  16. $spec = new Specification(function (Entity $entity) use ($request) {
  17. return 'bar_no' === $request['foo'];
  18. }, function (Select $select, Entity $entity) {
  19. $select->where('id', '>', 3);
  20. });
  21. $orSpec = $spec->or(new Specification(function (Entity $entity) use ($request) {
  22. return 'world' === $request['hello'];
  23. }, function (Select $select, Entity $entity) {
  24. $select->where('id', '<', 8);
  25. }));
  26. $this->assertInstanceof(ISpecification::class, $orSpec);
  27. $this->assertInstanceof(Specification::class, $orSpec);
  28. $select = $repository->condition($orSpec);
  29. $result = $select->findAll();
  30. $sql = <<<'eot'
  31. SQL: [97] SELECT `post`.* FROM `post` WHERE `post`.`delete_at` = :post_delete_at AND `post`.`id` < :post_id | Params: 2 | Key: Name: [15] :post_delete_at | paramno=0 | name=[15] ":post_delete_at" | is_param=1 | param_type=1 | Key: Name: [8] :post_id | paramno=1 | name=[8] ":post_id" | is_param=1 | param_type=1 (SELECT `post`.* FROM `post` WHERE `post`.`delete_at` = 0 AND `post`.`id` < 8)
  32. eot;
  33. $this->assertSame(
  34. $sql,
  35. $select->getLastSql(),
  36. );
  37. $this->assertInstanceof(Select::class, $select);
  38. $this->assertInstanceof(Collection::class, $result);
  39. $this->assertCount(7, $result);
  40. }

make 创建规约表达式

  1. public function testSpecMake(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. for ($i = 0; $i < 10; $i++) {
  5. $connect
  6. ->table('post')
  7. ->insert([
  8. 'title' => 'hello world',
  9. 'user_id' => 1,
  10. 'summary' => 'post summary',
  11. 'delete_at' => 0,
  12. ]);
  13. }
  14. $request = ['foo' => 'bar', 'hello' => 'world'];
  15. $repository = new Repository(new Post());
  16. $spec = Specification::make(function (Entity $entity) use ($request) {
  17. return 'bar' === $request['foo'];
  18. }, function (Select $select, Entity $entity) {
  19. $select->where('id', '>', 4);
  20. });
  21. $select = $repository->condition($spec);
  22. $result = $select->findAll();
  23. $this->assertInstanceof(Select::class, $select);
  24. $this->assertInstanceof(Collection::class, $result);
  25. $this->assertCount(6, $result);
  26. }

and 规约与操作

  1. public function testFindCountWithAndFirstIsYes(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. for ($i = 0; $i < 10; $i++) {
  5. $connect
  6. ->table('post')
  7. ->insert([
  8. 'title' => 'hello world',
  9. 'user_id' => 1,
  10. 'summary' => 'post summary',
  11. 'delete_at' => 0,
  12. ]);
  13. }
  14. $request = ['foo' => 'bar', 'hello' => 'world'];
  15. $repository = new Repository(new Post());
  16. $specExpr = new Specification(function (Entity $entity) use ($request) {
  17. return 'bar' === $request['foo'];
  18. }, function (Select $select, Entity $entity) {
  19. $select->where('id', '>', 3);
  20. });
  21. $specExpr->and(new Specification(function (Entity $entity) use ($request) {
  22. return 'world' === $request['hello'];
  23. }, function (Select $select, Entity $entity) {
  24. $select->where('id', '<', 6);
  25. }));
  26. $this->assertInstanceof(ISpecification::class, $specExpr);
  27. $this->assertInstanceof(Specification::class, $specExpr);
  28. $result = $repository->findCount($specExpr);
  29. $this->assertSame(2, $result);
  30. }

__call 魔术方法访问实体查询

  1. public function testCall(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. $this->assertSame(
  5. 1,
  6. $connect
  7. ->table('post')
  8. ->insert([
  9. 'title' => 'hello world',
  10. 'user_id' => 1,
  11. 'summary' => 'post summary',
  12. 'delete_at' => 0,
  13. ])
  14. );
  15. $repository = new Repository(new Post());
  16. $newPost = $repository
  17. ->where('id', 5)
  18. ->findEntity(1);
  19. $this->assertInstanceof(Post::class, $newPost);
  20. $this->assertNull($newPost->id);
  21. $this->assertNull($newPost->userId);
  22. $this->assertNull($newPost->title);
  23. $this->assertNull($newPost->summary);
  24. }

createEntity 新增实体

  1. public function testCreateTwice(): void
  2. {
  3. $repository = new Repository(new Post());
  4. $repository->createEntity($post = new Post([
  5. 'id' => 5,
  6. 'title' => 'foo',
  7. 'user_id' => 0,
  8. ]));
  9. $this->assertSame('SQL: [147] INSERT INTO `post` (`post`.`id`,`post`.`title`,`post`.`user_id`) VALUES (:pdonamedparameter_id,:pdonamedparameter_title,:pdonamedparameter_user_id) | Params: 3 | Key: Name: [21] :pdonamedparameter_id | paramno=0 | name=[21] ":pdonamedparameter_id" | is_param=1 | param_type=1 | Key: Name: [24] :pdonamedparameter_title | paramno=1 | name=[24] ":pdonamedparameter_title" | is_param=1 | param_type=2 | Key: Name: [26] :pdonamedparameter_user_id | paramno=2 | name=[26] ":pdonamedparameter_user_id" | is_param=1 | param_type=1 (INSERT INTO `post` (`post`.`id`,`post`.`title`,`post`.`user_id`) VALUES (5,\'foo\',0))', $repository->getLastSql());
  10. $this->assertSame(5, $post->id);
  11. $this->assertSame('foo', $post->title);
  12. $this->assertSame(0, $post->userId);
  13. $this->assertSame([], $post->changed());
  14. $repository->createEntity($post);
  15. $this->assertSame('SQL: [31] INSERT INTO `post` () VALUES () | Params: 0 (INSERT INTO `post` () VALUES ())', $repository->getLastSql());
  16. $newPost = $repository->findEntity(5);
  17. $this->assertInstanceof(Post::class, $newPost);
  18. $this->assertSame(5, $newPost->id);
  19. $this->assertSame('foo', $newPost->title);
  20. $newPost = $repository->findEntity(6);
  21. $this->assertInstanceof(Post::class, $newPost);
  22. $this->assertSame(6, $newPost->id);
  23. $this->assertSame('', $newPost->title);
  24. }

updateEntity 更新实体

  1. public function testUpdateTwiceAndDoNothing(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. $this->assertSame(
  5. 1,
  6. $connect
  7. ->table('post')
  8. ->insert([
  9. 'title' => 'hello world',
  10. 'user_id' => 1,
  11. 'summary' => 'post summary',
  12. 'delete_at' => 0,
  13. ])
  14. );
  15. $repository = new Repository(new Post());
  16. $this->assertSame(1, $repository->updateEntity($post = new Post(['id' => 1, 'title' => 'new title'])));
  17. $this->assertSame('SQL: [96] UPDATE `post` SET `post`.`title` = :pdonamedparameter_title WHERE `post`.`id` = :post_id LIMIT 1 | Params: 2 | Key: Name: [24] :pdonamedparameter_title | paramno=0 | name=[24] ":pdonamedparameter_title" | is_param=1 | param_type=2 | Key: Name: [8] :post_id | paramno=1 | name=[8] ":post_id" | is_param=1 | param_type=1 (UPDATE `post` SET `post`.`title` = \'new title\' WHERE `post`.`id` = 1 LIMIT 1)', $repository->getLastSql());
  18. $this->assertSame([], $post->changed());
  19. $this->assertNull($repository->updateEntity($post));
  20. }

replaceEntity 替换实体

  1. public function testReplaceTwiceAndFindExistData(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. $this->assertSame(
  5. 1,
  6. $connect
  7. ->table('post')
  8. ->insert([
  9. 'title' => 'hello world',
  10. 'user_id' => 1,
  11. 'summary' => 'post summary',
  12. 'delete_at' => 0,
  13. ])
  14. );
  15. $repository = new Repository(new Post());
  16. $affectedRow = $repository->replaceEntity($post = new Post([
  17. 'id' => 1,
  18. 'title' => 'new title',
  19. 'user_id' => 1,
  20. ]));
  21. $this->assertSame('SQL: [142] UPDATE `post` SET `post`.`title` = :pdonamedparameter_title,`post`.`user_id` = :pdonamedparameter_user_id WHERE `post`.`id` = :post_id LIMIT 1 | Params: 3 | Key: Name: [24] :pdonamedparameter_title | paramno=0 | name=[24] ":pdonamedparameter_title" | is_param=1 | param_type=2 | Key: Name: [26] :pdonamedparameter_user_id | paramno=1 | name=[26] ":pdonamedparameter_user_id" | is_param=1 | param_type=1 | Key: Name: [8] :post_id | paramno=2 | name=[8] ":post_id" | is_param=1 | param_type=1 (UPDATE `post` SET `post`.`title` = \'new title\',`post`.`user_id` = 1 WHERE `post`.`id` = 1 LIMIT 1)', $repository->getLastSql());
  22. $this->assertSame(1, $affectedRow);
  23. $this->assertSame([], $post->changed());
  24. $repository->replaceEntity($post); // 新增一条数据.
  25. $this->assertSame('SQL: [31] INSERT INTO `post` () VALUES () | Params: 0 (INSERT INTO `post` () VALUES ())', $repository->getLastSql());
  26. $updatedPost = $repository->findEntity(1);
  27. $this->assertSame(1, $updatedPost->id);
  28. $this->assertSame('new title', $updatedPost->title);
  29. $this->assertSame(1, $updatedPost->userId);
  30. $this->assertSame('post summary', $updatedPost->summary);
  31. $newPost2 = $repository->findEntity(2);
  32. $this->assertInstanceof(Post::class, $newPost2);
  33. $this->assertSame(2, $newPost2->id);
  34. $this->assertSame('', $newPost2->title);
  35. $this->assertSame('', $newPost2->summary);
  36. }

deleteEntity 响应删除

  1. public function testSoftDeleteTwice(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. $this->assertSame(
  5. 1,
  6. $connect
  7. ->table('post')
  8. ->insert([
  9. 'title' => 'hello world',
  10. 'user_id' => 1,
  11. 'summary' => 'post summary',
  12. 'delete_at' => 0,
  13. ])
  14. );
  15. $repository = new Repository(new Post());
  16. $repository->deleteEntity($post = new Post(['id' => 1, 'title' => 'new title']));
  17. $sql = 'SQL: [104] UPDATE `post` SET `post`.`delete_at` = :pdonamedparameter_delete_at WHERE `post`.`id` = :post_id LIMIT 1 | Params: 2 | Key: Name: [28] :pdonamedparameter_delete_at | paramno=0 | name=[28] ":pdonamedparameter_delete_at" | is_param=1 | param_type=1 | Key: Name: [8] :post_id | paramno=1 | name=[8] ":post_id" | is_param=1 | param_type=1 (UPDATE `post` SET `post`.`delete_at` = %d WHERE `post`.`id` = 1 LIMIT 1)';
  18. $this->assertTrue(in_array($repository->getLastSql(), [
  19. sprintf($sql, time() - 1),
  20. sprintf($sql, time()),
  21. sprintf($sql, time() + 1),
  22. ], true));
  23. $repository->deleteEntity($post); // 将会更新 `delete_at` 字段.
  24. $sql = 'SQL: [104] UPDATE `post` SET `post`.`delete_at` = :pdonamedparameter_delete_at WHERE `post`.`id` = :post_id LIMIT 1 | Params: 2 | Key: Name: [28] :pdonamedparameter_delete_at | paramno=0 | name=[28] ":pdonamedparameter_delete_at" | is_param=1 | param_type=1 | Key: Name: [8] :post_id | paramno=1 | name=[8] ":post_id" | is_param=1 | param_type=1 (UPDATE `post` SET `post`.`delete_at` = %s WHERE `post`.`id` = 1 LIMIT 1)';
  25. $this->assertTrue(in_array($repository->getLastSql(), [
  26. sprintf($sql, time() - 1),
  27. sprintf($sql, time()),
  28. sprintf($sql, time() + 1),
  29. ], true));
  30. $newPost = $repository->findEntity(1);
  31. $this->assertInstanceof(Post::class, $newPost);
  32. $this->assertNull($newPost->id);
  33. $this->assertNull($newPost->userId);
  34. $this->assertNull($newPost->title);
  35. $this->assertNull($newPost->summary);
  36. }

forceDeleteEntity 强制删除实体

  1. public function testForceDeleteTwice(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. $this->assertSame(
  5. 1,
  6. $connect
  7. ->table('post')
  8. ->insert([
  9. 'title' => 'hello world',
  10. 'user_id' => 1,
  11. 'summary' => 'post summary',
  12. 'delete_at' => 0,
  13. ])
  14. );
  15. $repository = new Repository(new Post());
  16. $repository->forceDeleteEntity($post = new Post(['id' => 1, 'title' => 'new title']));
  17. $this->assertSame('SQL: [55] DELETE FROM `post` WHERE `post`.`id` = :post_id LIMIT 1 | Params: 1 | Key: Name: [8] :post_id | paramno=0 | name=[8] ":post_id" | is_param=1 | param_type=1 (DELETE FROM `post` WHERE `post`.`id` = 1 LIMIT 1)', $repository->getLastSql());
  18. $repository->forceDeleteEntity($post); // 会执行 SQL,因为已经删除,没有任何影响.
  19. $this->assertSame('SQL: [55] DELETE FROM `post` WHERE `post`.`id` = :post_id LIMIT 1 | Params: 1 | Key: Name: [8] :post_id | paramno=0 | name=[8] ":post_id" | is_param=1 | param_type=1 (DELETE FROM `post` WHERE `post`.`id` = 1 LIMIT 1)', $repository->getLastSql());
  20. $newPost = $repository->findEntity(1);
  21. $this->assertInstanceof(Post::class, $newPost);
  22. $this->assertNull($newPost->id);
  23. $this->assertNull($newPost->userId);
  24. $this->assertNull($newPost->title);
  25. $this->assertNull($newPost->summary);
  26. }

condition 条件查询器支持闭包

  1. public function testConditionIsClosure(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. for ($i = 0; $i < 10; $i++) {
  5. $connect
  6. ->table('post')
  7. ->insert([
  8. 'title' => 'hello world',
  9. 'user_id' => 1,
  10. 'summary' => 'post summary',
  11. 'delete_at' => 0,
  12. ]);
  13. }
  14. $request = ['foo' => 'no-bar', 'hello' => 'no-world'];
  15. $repository = new Repository(new Post());
  16. $condition = function (Select $select, Entity $entity) use ($request) {
  17. $select->where('id', '<', 8);
  18. };
  19. $select = $repository->condition($condition);
  20. $result = $select->findAll();
  21. $this->assertInstanceof(Select::class, $select);
  22. $this->assertInstanceof(Collection::class, $result);
  23. $this->assertCount(7, $result);
  24. }

findPage 分页查询

  1. public function testFindPage(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. for ($i = 0; $i < 10; $i++) {
  5. $connect
  6. ->table('post')
  7. ->insert([
  8. 'title' => 'hello world',
  9. 'user_id' => 1,
  10. 'summary' => 'post summary',
  11. 'delete_at' => 0,
  12. ]);
  13. }
  14. $repository = new Repository(new Post());
  15. $page = $repository->findPage(1, 10);
  16. $result = $page->getData();
  17. $this->assertInstanceof(BasePage::class, $page);
  18. $this->assertInstanceof(Page::class, $page);
  19. $this->assertInstanceof(Collection::class, $result);
  20. $this->assertCount(10, $result);
  21. }

findPage 分页查询支持条件过滤

  1. public function testFindPageWithCondition(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. for ($i = 0; $i < 10; $i++) {
  5. $connect
  6. ->table('post')
  7. ->insert([
  8. 'title' => 'hello world',
  9. 'user_id' => 1,
  10. 'summary' => 'post summary',
  11. 'delete_at' => 0,
  12. ]);
  13. }
  14. $request = ['foo' => 'no-bar', 'hello' => 'no-world'];
  15. $repository = new Repository(new Post());
  16. $condition = function (Select $select, Entity $entity) use ($request) {
  17. $select->where('id', '<', 8);
  18. };
  19. $page = $repository->findPage(1, 10, $condition);
  20. $result = $page->getData();
  21. $this->assertInstanceof(BasePage::class, $page);
  22. $this->assertInstanceof(Page::class, $page);
  23. $this->assertInstanceof(Collection::class, $result);
  24. $this->assertCount(7, $result);
  25. }

findPageMacro 创建一个无限数据的分页查询

  1. public function testFindPageMacro(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. for ($i = 0; $i < 10; $i++) {
  5. $connect
  6. ->table('post')
  7. ->insert([
  8. 'title' => 'hello world',
  9. 'user_id' => 1,
  10. 'summary' => 'post summary',
  11. 'delete_at' => 0,
  12. ]);
  13. }
  14. $repository = new Repository(new Post());
  15. $page = $repository->findPageMacro(1, 10);
  16. $result = $page->getData();
  17. $this->assertInstanceof(BasePage::class, $page);
  18. $this->assertInstanceof(Page::class, $page);
  19. $this->assertInstanceof(Collection::class, $result);
  20. $this->assertCount(10, $result);
  21. }

findPageMacro 创建一个无限数据的分页查询支持条件过滤

  1. public function testFindPageMacroWithCondition(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. for ($i = 0; $i < 10; $i++) {
  5. $connect
  6. ->table('post')
  7. ->insert([
  8. 'title' => 'hello world',
  9. 'user_id' => 1,
  10. 'summary' => 'post summary',
  11. 'delete_at' => 0,
  12. ]);
  13. }
  14. $request = ['foo' => 'no-bar', 'hello' => 'no-world'];
  15. $repository = new Repository(new Post());
  16. $condition = function (Select $select, Entity $entity) use ($request) {
  17. $select->where('id', '<', 8);
  18. };
  19. $page = $repository->findPageMacro(1, 10, $condition);
  20. $result = $page->getData();
  21. $this->assertInstanceof(BasePage::class, $page);
  22. $this->assertInstanceof(Page::class, $page);
  23. $this->assertInstanceof(Collection::class, $result);
  24. $this->assertCount(7, $result);
  25. }

findPagePrevNext 创建一个只有上下页的分页查询

  1. public function testFindPagePrevNext(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. for ($i = 0; $i < 10; $i++) {
  5. $connect
  6. ->table('post')
  7. ->insert([
  8. 'title' => 'hello world',
  9. 'user_id' => 1,
  10. 'summary' => 'post summary',
  11. 'delete_at' => 0,
  12. ]);
  13. }
  14. $repository = new Repository(new Post());
  15. $page = $repository->findPagePrevNext(1, 10);
  16. $result = $page->getData();
  17. $this->assertInstanceof(BasePage::class, $page);
  18. $this->assertInstanceof(Page::class, $page);
  19. $this->assertInstanceof(Collection::class, $result);
  20. $this->assertCount(10, $result);
  21. }

findPagePrevNext 创建一个只有上下页的分页查询支持条件过滤

  1. public function testFindPagePrevNextWithCondition(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. for ($i = 0; $i < 10; $i++) {
  5. $connect
  6. ->table('post')
  7. ->insert([
  8. 'title' => 'hello world',
  9. 'user_id' => 1,
  10. 'summary' => 'post summary',
  11. 'delete_at' => 0,
  12. ]);
  13. }
  14. $request = ['foo' => 'no-bar', 'hello' => 'no-world'];
  15. $repository = new Repository(new Post());
  16. $condition = function (Select $select, Entity $entity) use ($request) {
  17. $select->where('id', '<', 8);
  18. };
  19. $page = $repository->findPagePrevNext(1, 10, $condition);
  20. $result = $page->getData();
  21. $this->assertInstanceof(BasePage::class, $page);
  22. $this->assertInstanceof(Page::class, $page);
  23. $this->assertInstanceof(Collection::class, $result);
  24. $this->assertCount(7, $result);
  25. }

findList 返回一列数据

  1. public function testFindList(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. for ($i = 0; $i < 10; $i++) {
  5. $connect
  6. ->table('post')
  7. ->insert([
  8. 'title' => 'hello world'.$i,
  9. 'user_id' => 1,
  10. 'summary' => 'post summary',
  11. 'delete_at' => 0,
  12. ]);
  13. }
  14. $repository = new Repository(new Post());
  15. $result = $repository->findList(null, 'summary', 'title');
  16. $this->assertIsArray($result);
  17. $data = <<<'eot'
  18. {
  19. "hello world0": "post summary",
  20. "hello world1": "post summary",
  21. "hello world2": "post summary",
  22. "hello world3": "post summary",
  23. "hello world4": "post summary",
  24. "hello world5": "post summary",
  25. "hello world6": "post summary",
  26. "hello world7": "post summary",
  27. "hello world8": "post summary",
  28. "hello world9": "post summary"
  29. }
  30. eot;
  31. $this->assertSame(
  32. $data,
  33. $this->varJson(
  34. $result
  35. )
  36. );
  37. }

findList 返回一列数据支持条件过滤

  1. public function testFindListWithCondition(): void
  2. {
  3. $connect = $this->createDatabaseConnect();
  4. for ($i = 0; $i < 10; $i++) {
  5. $connect
  6. ->table('post')
  7. ->insert([
  8. 'title' => 'hello world'.$i,
  9. 'user_id' => 1,
  10. 'summary' => 'post summary',
  11. 'delete_at' => 0,
  12. ]);
  13. }
  14. $repository = new Repository(new Post());
  15. $result = $repository->findList(function (Select $select) {
  16. $select->where('id', '>', 5);
  17. }, ['summary', 'title']);
  18. $this->assertIsArray($result);
  19. $data = <<<'eot'
  20. {
  21. "hello world5": "post summary",
  22. "hello world6": "post summary",
  23. "hello world7": "post summary",
  24. "hello world8": "post summary",
  25. "hello world9": "post summary"
  26. }
  27. eot;
  28. $this->assertSame(
  29. $data,
  30. $this->varJson(
  31. $result
  32. )
  33. );
  34. }