PageRenderTime 52ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/Doctrine/ODM/MongoDB/Tests/Functional/QueryTest.php

https://github.com/jmikola/mongodb-odm
PHP | 444 lines | 367 code | 72 blank | 5 comment | 1 complexity | d28f8cee9d095118e64162df08904f44 MD5 | raw file
  1. <?php
  2. declare(strict_types=1);
  3. namespace Doctrine\ODM\MongoDB\Tests\Functional;
  4. use Doctrine\ODM\MongoDB\Tests\BaseTest;
  5. use Documents\Article;
  6. use Documents\CmsComment;
  7. use Documents\Group;
  8. use Documents\IndirectlyReferencedUser;
  9. use Documents\Phonenumber;
  10. use Documents\ReferenceUser;
  11. use Documents\User;
  12. use MongoDB\BSON\ObjectId;
  13. use MongoDB\BSON\UTCDateTime;
  14. use function array_values;
  15. use function get_class;
  16. use function iterator_to_array;
  17. use function strtotime;
  18. class QueryTest extends BaseTest
  19. {
  20. public function setUp()
  21. {
  22. parent::setUp();
  23. $this->user = new User();
  24. $this->user->setUsername('boo');
  25. $this->dm->persist($this->user);
  26. $this->dm->flush();
  27. }
  28. public function testAddElemMatch()
  29. {
  30. $user = new User();
  31. $user->setUsername('boo');
  32. $phonenumber = new Phonenumber('6155139185');
  33. $user->addPhonenumber($phonenumber);
  34. $this->dm->persist($user);
  35. $this->dm->flush();
  36. $qb = $this->dm->createQueryBuilder(User::class);
  37. $embeddedQb = $this->dm->createQueryBuilder(Phonenumber::class);
  38. $qb->field('phonenumbers')->elemMatch($embeddedQb->expr()->field('phonenumber')->equals('6155139185'));
  39. $query = $qb->getQuery();
  40. $user = $query->getSingleResult();
  41. $this->assertNotNull($user);
  42. }
  43. public function testAddElemMatchWithDeepFields()
  44. {
  45. $user1 = new User();
  46. $user1->setUsername('ben');
  47. $user2 = new User();
  48. $user2->setUsername('boo');
  49. $phonenumber = new Phonenumber('2125550123', $user1);
  50. $user2->addPhonenumber($phonenumber);
  51. $this->dm->persist($user1);
  52. $this->dm->persist($user2);
  53. $this->dm->flush();
  54. $qb = $this->dm->createQueryBuilder(User::class);
  55. $embeddedQb = $this->dm->createQueryBuilder(Phonenumber::class);
  56. $qb->field('phonenumbers')->elemMatch($embeddedQb->expr()->field('lastCalledBy.$id')->equals(new ObjectId($user1->getId())));
  57. $query = $qb->getQuery();
  58. $user = $query->getSingleResult();
  59. $this->assertNotNull($user);
  60. }
  61. public function testAddNot()
  62. {
  63. $user = new User();
  64. $user->setUsername('boo');
  65. $this->dm->persist($user);
  66. $this->dm->flush();
  67. $qb = $this->dm->createQueryBuilder(User::class);
  68. $qb->field('username')->not($qb->expr()->in(['boo']));
  69. $query = $qb->getQuery();
  70. $user = $query->getSingleResult();
  71. $this->assertNull($user);
  72. $qb->field('username')->not($qb->expr()->in(['1boo']));
  73. $query = $qb->getQuery();
  74. $user = $query->getSingleResult();
  75. $this->assertNotNull($user);
  76. }
  77. public function testDistinct()
  78. {
  79. $user = new User();
  80. $user->setUsername('distinct_test');
  81. $user->setCount(1);
  82. $this->dm->persist($user);
  83. $user = new User();
  84. $user->setUsername('distinct_test');
  85. $user->setCount(1);
  86. $this->dm->persist($user);
  87. $user = new User();
  88. $user->setUsername('distinct_test');
  89. $user->setCount(2);
  90. $this->dm->persist($user);
  91. $user = new User();
  92. $user->setUsername('distinct_test');
  93. $user->setCount(3);
  94. $this->dm->persist($user);
  95. $this->dm->flush();
  96. $qb = $this->dm->createQueryBuilder(User::class)
  97. ->distinct('count')
  98. ->field('username')->equals('distinct_test');
  99. $q = $qb->getQuery();
  100. $results = $q->execute();
  101. $this->assertEquals([1, 2, 3], $results);
  102. $results = $this->dm->createQueryBuilder(User::class)
  103. ->distinct('count')
  104. ->field('username')->equals('distinct_test')
  105. ->getQuery()
  106. ->execute();
  107. $this->assertEquals([1, 2, 3], $results);
  108. }
  109. public function testDistinctWithDifferentDbName()
  110. {
  111. $c1 = new CmsComment();
  112. $c1->authorIp = '127.0.0.1';
  113. $c2 = new CmsComment();
  114. $c3 = new CmsComment();
  115. $c2->authorIp = $c3->authorIp = '192.168.0.1';
  116. $this->dm->persist($c1);
  117. $this->dm->persist($c2);
  118. $this->dm->persist($c3);
  119. $this->dm->flush();
  120. $this->dm->clear();
  121. $results = $this->dm->createQueryBuilder(get_class($c1))
  122. ->distinct('authorIp')
  123. ->getQuery()
  124. ->execute();
  125. $this->assertEquals(['127.0.0.1', '192.168.0.1'], $results);
  126. }
  127. public function testFindQuery()
  128. {
  129. $qb = $this->dm->createQueryBuilder(User::class)
  130. ->where("function() { return this.username == 'boo' }");
  131. $query = $qb->getQuery();
  132. $user = $query->getSingleResult();
  133. $this->assertEquals('boo', $user->getUsername());
  134. }
  135. public function testUpdateQuery()
  136. {
  137. $qb = $this->dm->createQueryBuilder(User::class)
  138. ->updateOne()
  139. ->field('username')
  140. ->set('crap')
  141. ->equals('boo');
  142. $query = $qb->getQuery();
  143. $result = $query->execute();
  144. $this->dm->refresh($this->user);
  145. $this->assertEquals('crap', $this->user->getUsername());
  146. }
  147. public function testUpsertUpdateQuery()
  148. {
  149. $qb = $this->dm->createQueryBuilder(User::class)
  150. ->updateOne()
  151. ->upsert(true)
  152. ->field('username')
  153. ->set('crap')
  154. ->equals('foo');
  155. $query = $qb->getQuery();
  156. $result = $query->execute();
  157. $qb = $this->dm->createQueryBuilder(User::class)
  158. ->find()
  159. ->field('username')->equals('crap');
  160. $query = $qb->getQuery();
  161. $user = $query->getSingleResult();
  162. $this->assertNotNull($user);
  163. }
  164. public function testMultipleUpdateQuery()
  165. {
  166. $user = new User();
  167. $user->setUsername('multiple_test');
  168. $user->setCount(1);
  169. $this->dm->persist($user);
  170. $user = new User();
  171. $user->setUsername('multiple_test');
  172. $user->setCount(1);
  173. $this->dm->persist($user);
  174. $user = new User();
  175. $user->setUsername('multiple_test');
  176. $user->setCount(2);
  177. $this->dm->persist($user);
  178. $user = new User();
  179. $user->setUsername('multiple_test');
  180. $user->setCount(3);
  181. $this->dm->persist($user);
  182. $this->dm->flush();
  183. $qb = $this->dm->createQueryBuilder(User::class)
  184. ->updateMany()
  185. ->field('username')->equals('multiple_test')
  186. ->field('username')->set('foo');
  187. $q = $qb->getQuery();
  188. $results = $q->execute();
  189. $qb = $this->dm->createQueryBuilder(User::class)
  190. ->find()
  191. ->field('username')->equals('foo');
  192. $q = $qb->getQuery();
  193. $users = array_values($q->execute()->toArray());
  194. $this->assertCount(4, $users);
  195. }
  196. /**
  197. * @expectedException InvalidArgumentException
  198. */
  199. public function testRemoveQuery()
  200. {
  201. $this->dm->remove($this->user);
  202. // should invoke exception because $this->user doesn't exist anymore
  203. $this->dm->refresh($this->user);
  204. }
  205. public function testIncUpdateQuery()
  206. {
  207. $qb = $this->dm->createQueryBuilder(User::class)
  208. ->updateOne()
  209. ->field('hits')->inc(5)
  210. ->field('username')->equals('boo');
  211. $query = $qb->getQuery();
  212. $query->execute();
  213. $query->execute();
  214. $qb->find(User::class)
  215. ->hydrate(false);
  216. $query = $qb->getQuery();
  217. $user = $query->getSingleResult();
  218. $this->assertEquals(10, $user['hits']);
  219. }
  220. public function testUnsetFieldUpdateQuery()
  221. {
  222. $qb = $this->dm->createQueryBuilder(User::class)
  223. ->updateOne()
  224. ->field('hits')->unsetField()
  225. ->field('username')->equals('boo');
  226. $query = $qb->getQuery();
  227. $result = $query->execute();
  228. $qb->find(User::class)
  229. ->hydrate(false);
  230. $query = $qb->getQuery();
  231. $user = $query->getSingleResult();
  232. $this->assertArrayNotHasKey('hits', $user);
  233. }
  234. public function testUnsetField()
  235. {
  236. $qb = $this->dm->createQueryBuilder()
  237. ->updateOne(User::class)
  238. ->field('nullTest')
  239. ->type('null')
  240. ->unsetField('nullTest');
  241. $query = $qb->getQuery();
  242. $query->execute();
  243. $qb = $this->dm->createQueryBuilder(User::class)
  244. ->field('nullTest')->type('null');
  245. $query = $qb->getQuery();
  246. $user = $query->getSingleResult();
  247. $this->assertNull($user);
  248. }
  249. public function testDateRange()
  250. {
  251. $article1 = new Article();
  252. $article1->setTitle('test');
  253. $article1->setBody('test');
  254. $article1->setCreatedAt('1985-09-01 00:00:00');
  255. $article2 = new Article();
  256. $article2->setTitle('test');
  257. $article2->setBody('test');
  258. $article2->setCreatedAt('1985-09-02 00:00:00');
  259. $article3 = new Article();
  260. $article3->setTitle('test');
  261. $article3->setBody('test');
  262. $article3->setCreatedAt('1985-09-03 00:00:00');
  263. $article4 = new Article();
  264. $article4->setTitle('test');
  265. $article4->setBody('test');
  266. $article4->setCreatedAt('1985-09-04 00:00:00');
  267. $this->dm->persist($article1);
  268. $this->dm->persist($article2);
  269. $this->dm->persist($article3);
  270. $this->dm->persist($article4);
  271. $this->dm->flush();
  272. $this->dm->clear();
  273. $qb = $this->dm->createQueryBuilder(Article::class);
  274. $qb->field('createdAt')->range(
  275. new UTCDateTime(strtotime('1985-09-01 01:00:00') * 1000),
  276. new UTCDateTime(strtotime('1985-09-04') * 1000)
  277. );
  278. $query = $qb->getQuery();
  279. $articles = array_values($query->execute()->toArray());
  280. $this->assertCount(2, $articles);
  281. $this->assertEquals('1985-09-02', $articles[0]->getCreatedAt()->format('Y-m-d'));
  282. $this->assertEquals('1985-09-03', $articles[1]->getCreatedAt()->format('Y-m-d'));
  283. }
  284. public function testQueryIsIterable()
  285. {
  286. $article = new Article();
  287. $article->setTitle('test');
  288. $this->dm->persist($article);
  289. $this->dm->flush();
  290. $qb = $this->dm->createQueryBuilder(Article::class);
  291. $query = $qb->getQuery();
  292. $this->assertInstanceOf(\IteratorAggregate::class, $query);
  293. foreach ($query as $article) {
  294. $this->assertEquals(Article::class, get_class($article));
  295. }
  296. }
  297. public function testQueryReferences()
  298. {
  299. $group = new Group('Test Group');
  300. $user = new User();
  301. $user->setUsername('cool');
  302. $user->addGroup($group);
  303. $this->dm->persist($user);
  304. $this->dm->flush();
  305. $qb = $this->dm->createQueryBuilder(User::class)
  306. ->field('groups')->references($group);
  307. $query = $qb->getQuery();
  308. $user2 = $query->getSingleResult();
  309. $this->assertSame($user, $user2);
  310. }
  311. public function testNestedQueryReference()
  312. {
  313. $referencedUser = new User();
  314. $referencedUser->setUsername('boo');
  315. $phonenumber = new Phonenumber('6155139185');
  316. $referencedUser->addPhonenumber($phonenumber);
  317. $indirectlyReferencedUser = new IndirectlyReferencedUser();
  318. $indirectlyReferencedUser->user = $referencedUser;
  319. $user = new ReferenceUser();
  320. $user->indirectlyReferencedUsers[] = $indirectlyReferencedUser;
  321. $this->dm->persist($referencedUser);
  322. $this->dm->persist($user);
  323. $this->dm->flush();
  324. $qb = $this->dm->createQueryBuilder('Documents\ReferenceUser');
  325. $referencedUsersQuery = $qb
  326. ->field('indirectlyReferencedUsers.user.id')->equals(new ObjectId($referencedUser->getId()))
  327. ->getQuery();
  328. $referencedUsers = iterator_to_array($referencedUsersQuery->execute(), false);
  329. $this->assertCount(1, $referencedUsers);
  330. $this->assertSame($user, $referencedUsers[0]);
  331. }
  332. public function testQueryWhereIn()
  333. {
  334. $qb = $this->dm->createQueryBuilder(User::class);
  335. $choices = ['a', 'b'];
  336. $qb->field('username')->in($choices);
  337. $expected = [
  338. 'username' => ['$in' => $choices],
  339. ];
  340. $this->assertSame($expected, $qb->getQueryArray());
  341. }
  342. public function testQueryWhereInReferenceId()
  343. {
  344. $qb = $this->dm->createQueryBuilder(User::class);
  345. $choices = [new ObjectId(), new ObjectId()];
  346. $qb->field('account.$id')->in($choices);
  347. $expected = [
  348. 'account.$id' => ['$in' => $choices],
  349. ];
  350. $this->assertSame($expected, $qb->getQueryArray());
  351. $this->assertSame($expected, $qb->getQuery()->debug('query'));
  352. }
  353. public function testQueryWhereOneValueOfCollection()
  354. {
  355. $qb = $this->dm->createQueryBuilder(Article::class);
  356. $qb->field('tags')->equals('pet');
  357. $expected = ['tags' => 'pet'];
  358. $this->assertSame($expected, $qb->getQueryArray());
  359. $this->assertSame($expected, $qb->getQuery()->debug('query'));
  360. }
  361. /** search for articles where tags exactly equal [pet, blue] */
  362. public function testQueryWhereAllValuesOfCollection()
  363. {
  364. $qb = $this->dm->createQueryBuilder(Article::class);
  365. $qb->field('tags')->equals(['pet', 'blue']);
  366. $expected = [
  367. 'tags' => ['pet', 'blue'],
  368. ];
  369. $this->assertSame($expected, $qb->getQueryArray());
  370. $this->assertSame($expected, $qb->getQuery()->debug('query'));
  371. }
  372. }