CommandTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. <?php
  2. namespace yiiunit\extensions\mongodb;
  3. use MongoDB\BSON\ObjectID;
  4. use MongoDB\Driver\Cursor;
  5. use yii\helpers\ArrayHelper;
  6. class CommandTest extends TestCase
  7. {
  8. protected function tearDown()
  9. {
  10. $this->dropCollection('customer');
  11. parent::tearDown();
  12. }
  13. public function testCreateCollection()
  14. {
  15. $command = $this->getConnection()->createCommand();
  16. $this->assertTrue($command->createCollection('customer'));
  17. }
  18. /**
  19. * @depends testCreateCollection
  20. */
  21. public function testDropCollection()
  22. {
  23. $command = $this->getConnection()->createCommand();
  24. $command->createCollection('customer');
  25. $this->assertTrue($command->dropCollection('customer'));
  26. }
  27. public function testCount()
  28. {
  29. $command = $this->getConnection()->createCommand();
  30. $this->assertEquals(0, $command->count('customer'));
  31. }
  32. public function testCreateIndexes()
  33. {
  34. $command = $this->getConnection()->createCommand();
  35. $this->assertTrue($command->createIndexes('customer', [
  36. [
  37. 'key' => ['name' => +1],
  38. ],
  39. [
  40. 'key' => ['email'],
  41. ],
  42. [
  43. 'key' => 'address',
  44. ],
  45. ]));
  46. }
  47. /**
  48. * @depends testCreateIndexes
  49. */
  50. public function testListIndexes()
  51. {
  52. $command = $this->getConnection()->createCommand();
  53. $command->createIndexes('customer', [
  54. [
  55. 'key' => ['name' => +1],
  56. 'name' => 'asc_index'
  57. ],
  58. ]);
  59. $result = $command->listIndexes('customer');
  60. $this->assertEquals('_id_', $result[0]['name']);
  61. $this->assertEquals('asc_index', $result[1]['name']);
  62. }
  63. /**
  64. * @depends testCreateIndexes
  65. */
  66. public function testDropIndexes()
  67. {
  68. $command = $this->getConnection()->createCommand();
  69. $command->createIndexes('customer', [
  70. [
  71. 'key' => ['name' => +1],
  72. 'name' => 'asc_index'
  73. ],
  74. [
  75. 'key' => ['name' => -1],
  76. 'name' => 'desc_index'
  77. ],
  78. ]);
  79. $result = $command->dropIndexes('customer', 'asc_index');
  80. $this->assertEquals(3, $result['nIndexesWas']);
  81. $result = $command->dropIndexes('customer', '*');
  82. $this->assertEquals(2, $result['nIndexesWas']);
  83. $this->expectException('yii\mongodb\Exception');
  84. $this->expectExceptionMessage('index not found with name');
  85. $command->dropIndexes('customer', 'desc_index');
  86. }
  87. public function testInsert()
  88. {
  89. $command = $this->getConnection()->createCommand();
  90. $insertedId = $command->insert('customer', ['name' => 'John']);
  91. $this->assertTrue($insertedId instanceof ObjectID);
  92. }
  93. /**
  94. * @depends testInsert
  95. */
  96. public function testBatchInsert()
  97. {
  98. $command = $this->getConnection()->createCommand();
  99. $insertedIds = $command->batchInsert('customer', [
  100. ['name' => 'John'],
  101. ['name' => 'Sara'],
  102. ]);
  103. $this->assertTrue($insertedIds[0] instanceof ObjectID);
  104. $this->assertTrue($insertedIds[1] instanceof ObjectID);
  105. }
  106. /**
  107. * @depends testInsert
  108. */
  109. public function testUpdate()
  110. {
  111. $connection = $this->getConnection();
  112. $newRecordId = $connection->createCommand()->insert('customer', ['name' => 'John']);
  113. $result = $connection->createCommand()->update('customer', ['_id' => $newRecordId], ['name' => 'Mike']);
  114. $this->assertEquals(1, $result->getModifiedCount());
  115. }
  116. /**
  117. * @depends testInsert
  118. */
  119. public function testDelete()
  120. {
  121. $connection = $this->getConnection();
  122. $newRecordId = $connection->createCommand()->insert('customer', ['name' => 'John']);
  123. $result = $connection->createCommand()->delete('customer', ['_id' => $newRecordId]);
  124. $this->assertEquals(1, $result->getDeletedCount());
  125. }
  126. /**
  127. * @depends testInsert
  128. */
  129. public function testFind()
  130. {
  131. $connection = $this->getConnection();
  132. $connection->createCommand()->insert('customer', ['name' => 'John']);
  133. $cursor = $connection->createCommand()->find('customer', []);
  134. $rows = $cursor->toArray();
  135. $this->assertCount(1, $rows);
  136. $this->assertEquals('John', $rows[0]['name']);
  137. }
  138. /**
  139. * @depends testBatchInsert
  140. */
  141. public function testFindAndModify()
  142. {
  143. $connection = $this->getConnection();
  144. $rows = [
  145. [
  146. 'name' => 'customer 1',
  147. 'status' => 1,
  148. 'amount' => 100,
  149. ],
  150. [
  151. 'name' => 'customer 2',
  152. 'status' => 1,
  153. 'amount' => 200,
  154. ],
  155. ];
  156. $command = $connection->createCommand();
  157. $command->batchInsert('customer', $rows);
  158. // increment field
  159. $result = $connection->createCommand()->findAndModify('customer', ['name' => 'customer 1'], ['$inc' => ['status' => 1]]);
  160. $this->assertEquals('customer 1', $result['name']);
  161. $this->assertEquals(1, $result['status']);
  162. $cursor = $connection->createCommand()->find('customer', ['name' => 'customer 1']);
  163. $newResult = current($cursor->toArray());
  164. $this->assertEquals(2, $newResult['status']);
  165. // $set and return modified document
  166. $result = $connection->createCommand()->findAndModify(
  167. 'customer',
  168. ['name' => 'customer 2'],
  169. ['$set' => ['status' => 2]],
  170. ['new' => true]
  171. );
  172. $this->assertEquals('customer 2', $result['name']);
  173. $this->assertEquals(2, $result['status']);
  174. // Full update document
  175. $data = [
  176. 'name' => 'customer 3',
  177. 'city' => 'Minsk'
  178. ];
  179. $result = $connection->createCommand()->findAndModify(
  180. 'customer',
  181. ['name' => 'customer 2'],
  182. $data,
  183. ['new' => true]
  184. );
  185. $this->assertEquals('customer 3', $result['name']);
  186. $this->assertEquals('Minsk', $result['city']);
  187. $this->assertTrue(!isset($result['status']));
  188. // Test exceptions
  189. $this->expectException('\yii\mongodb\Exception');
  190. $connection->createCommand()->findAndModify('customer',['name' => 'customer 1'], ['$wrongOperator' => ['status' => 1]]);
  191. }
  192. /**
  193. * @depends testBatchInsert
  194. */
  195. public function testAggregate()
  196. {
  197. $connection = $this->getConnection();
  198. $rows = [
  199. [
  200. 'name' => 'customer 1',
  201. 'status' => 1,
  202. 'amount' => 100,
  203. ],
  204. [
  205. 'name' => 'customer 2',
  206. 'status' => 1,
  207. 'amount' => 200,
  208. ],
  209. ];
  210. $command = $connection->createCommand();
  211. $command->batchInsert('customer', $rows);
  212. $pipelines = [
  213. [
  214. '$match' => ['status' => 1]
  215. ],
  216. [
  217. '$group' => [
  218. '_id' => '1',
  219. 'total' => [
  220. '$sum' => '$amount'
  221. ],
  222. ]
  223. ]
  224. ];
  225. $result = $connection->createCommand()->aggregate('customer', $pipelines);
  226. $this->assertEquals(['_id' => '1', 'total' => 300], $result[0]);
  227. }
  228. /**
  229. * @depends testAggregate
  230. *
  231. * @see https://github.com/yiisoft/yii2-mongodb/issues/228
  232. */
  233. public function testAggregateCursor()
  234. {
  235. $connection = $this->getConnection();
  236. $rows = [
  237. [
  238. 'name' => 'customer 1',
  239. 'status' => 1,
  240. 'amount' => 100,
  241. ],
  242. [
  243. 'name' => 'customer 2',
  244. 'status' => 1,
  245. 'amount' => 200,
  246. ],
  247. [
  248. 'name' => 'customer 3',
  249. 'status' => 1,
  250. 'amount' => 100,
  251. ],
  252. [
  253. 'name' => 'customer 4',
  254. 'status' => 1,
  255. 'amount' => 200,
  256. ],
  257. ];
  258. $command = $connection->createCommand();
  259. $command->batchInsert('customer', $rows);
  260. $pipelines = [
  261. [
  262. '$match' => ['status' => 1]
  263. ],
  264. [
  265. '$group' => [
  266. '_id' => '1',
  267. 'total' => [
  268. '$sum' => '$amount'
  269. ],
  270. ]
  271. ]
  272. ];
  273. $result = $connection->createCommand()->aggregate('customer', $pipelines, ['cursor' => ['batchSize' => 2]]);
  274. $this->assertTrue($result instanceof Cursor);
  275. $this->assertEquals(['_id' => '1', 'total' => 600], $result->toArray()[0]);
  276. }
  277. /**
  278. * @depends testFind
  279. */
  280. public function testExplain()
  281. {
  282. $connection = $this->getConnection();
  283. $connection->createCommand()->insert('customer', ['name' => 'John']);
  284. $result = $connection->createCommand()->explain('customer', [
  285. 'filter' => [
  286. 'name' => 'John'
  287. ],
  288. ]);
  289. $this->assertArrayHasKey('queryPlanner', $result);
  290. $this->assertArrayHasKey('executionStats', $result);
  291. }
  292. /**
  293. * @depends testCreateCollection
  294. */
  295. public function testListCollections()
  296. {
  297. $connection = $this->getConnection();
  298. $connection->createCommand()->createCollection('customer');
  299. $collections = $connection->createCommand()->listCollections();
  300. $collectionNames = ArrayHelper::getColumn($collections, 'name');
  301. $this->assertContains('customer', $collectionNames);
  302. }
  303. /**
  304. * @depends testUpdate
  305. * @depends testCount
  306. *
  307. * @see https://github.com/yiisoft/yii2-mongodb/issues/168
  308. */
  309. public function testUpdateUpsert()
  310. {
  311. $connection = $this->getConnection();
  312. $connection->createCommand()->insert('customer', ['name' => 'John']);
  313. $result = $connection->createCommand()
  314. ->update('customer', ['name' => 'Mike'], ['name' => 'Jack']);
  315. $this->assertEquals(0, $result->getModifiedCount());
  316. $this->assertEquals(0, $result->getUpsertedCount());
  317. $this->assertEquals(1, $connection->createCommand()->count('customer'));
  318. $result = $connection->createCommand()
  319. ->update('customer', ['name' => 'Mike'], ['name' => 'Jack'], ['upsert' => true]);
  320. $this->assertEquals(0, $result->getModifiedCount());
  321. $this->assertEquals(1, $result->getUpsertedCount());
  322. $this->assertEquals(2, $connection->createCommand()->count('customer'));
  323. }
  324. }