From e54408a1e8f75bf21d362a2201283e6152897f70 Mon Sep 17 00:00:00 2001 From: klinson Date: Wed, 8 Jan 2020 17:20:19 +0800 Subject: [PATCH 01/87] add transaction support, requires mongodb version V4.0 or more and deployment replica sets or sharded clusters transaction support create/insert,update,delete,etc operation Supports infinite-level nested transactions, but outside transaction rollbacks do not affect the commit of inside transactions ``` DB::beginTransaction(); DB::collection('users')->where('name', 'klinson')->update(['age' => 18]); DB::transaction(function () { DB::collection('users')->where('name', 'mongodb')->update(['age' => 30]); }); DB::rollBack(); ``` --- src/Jenssegers/Mongodb/Connection.php | 83 +++++++++ src/Jenssegers/Mongodb/Query/Builder.php | 68 ++++++-- tests/TransactionBuilderTest.php | 201 +++++++++++++++++++++ tests/TransactionTest.php | 211 +++++++++++++++++++++++ 4 files changed, 553 insertions(+), 10 deletions(-) create mode 100644 tests/TransactionBuilderTest.php create mode 100644 tests/TransactionTest.php diff --git a/src/Jenssegers/Mongodb/Connection.php b/src/Jenssegers/Mongodb/Connection.php index 7920ec9f6..03d2ef832 100644 --- a/src/Jenssegers/Mongodb/Connection.php +++ b/src/Jenssegers/Mongodb/Connection.php @@ -5,6 +5,9 @@ use Illuminate\Database\Connection as BaseConnection; use Illuminate\Support\Arr; use MongoDB\Client; +use MongoDB\Driver\ReadConcern; +use MongoDB\Driver\ReadPreference; +use MongoDB\Driver\WriteConcern; class Connection extends BaseConnection { @@ -20,6 +23,9 @@ class Connection extends BaseConnection */ protected $connection; + protected $session_key; // sessions会话列表当前会话数组key 随机生成 + protected $sessions = []; // 会话列表 + /** * Create a new database connection instance. * @param array $config @@ -254,4 +260,81 @@ public function __call($method, $parameters) { return call_user_func_array([$this->db, $method], $parameters); } + + /** + * create a session and start a transaction in session + * + * In version 4.0, MongoDB supports multi-document transactions on replica sets. + * In version 4.2, MongoDB introduces distributed transactions, which adds support for multi-document transactions on sharded clusters and incorporates the existing support for multi-document transactions on replica sets. + * To use transactions on MongoDB 4.2 deployments(replica sets and sharded clusters), clients must use MongoDB drivers updated for MongoDB 4.2. + * + * @see https://docs.mongodb.com/manual/core/transactions/ + * @author klinson + */ + public function beginTransaction() + { + $this->session_key = uniqid(); + $this->sessions[$this->session_key] = $this->connection->startSession(); + + $this->sessions[$this->session_key]->startTransaction([ + 'readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY), + 'writeConcern' => new WriteConcern(1), + 'readConcern' => new ReadConcern(ReadConcern::LOCAL) + ]); + } + + /** + * commit transaction in this session and close this session + * @author klinson + */ + public function commit() + { + if ($session = $this->getSession()) { + $session->commitTransaction(); + $this->setLastSession(); + } + } + + /** + * rollback transaction in this session and close this session + * @author klinson + */ + public function rollBack() + { + if ($session = $this->getSession()) { + $session->abortTransaction(); + $this->setLastSession(); + } + } + + /** + * close this session and get last session key to session_key + * Why do it ? Because nested transactions + * @author klinson + */ + protected function setLastSession() + { + if ($session = $this->getSession()) { + $session->endSession(); + unset($this->sessions[$this->session_key]); + if (empty($this->sessions)) { + $this->session_key = null; + } else { + end($this->sessions); + $this->session_key = key($this->sessions); + } + } + } + + /** + * get now session if it has session + * @return \MongoDB\Driver\Session|null + * @author klinson + */ + public function getSession() + { + return ($this->session_key && isset($this->sessions[$this->session_key])) + ? $this->sessions[$this->session_key] + : null; + } } diff --git a/src/Jenssegers/Mongodb/Query/Builder.php b/src/Jenssegers/Mongodb/Query/Builder.php index 28d781a66..27d6c73d8 100644 --- a/src/Jenssegers/Mongodb/Query/Builder.php +++ b/src/Jenssegers/Mongodb/Query/Builder.php @@ -294,7 +294,7 @@ public function getFresh($columns = []) } } } - + // The _id field is mandatory when using grouping. if ($group && empty($group['_id'])) { $group['_id'] = null; @@ -338,6 +338,11 @@ public function getFresh($columns = []) $options = array_merge($options, $this->options); } + // if transaction in session + if ($session = $this->connection->getSession()) { + $options['session'] = $session; + } + // Execute aggregation $results = iterator_to_array($this->collection->aggregate($pipeline, $options)); @@ -348,13 +353,15 @@ public function getFresh($columns = []) // Return distinct results directly $column = isset($this->columns[0]) ? $this->columns[0] : '_id'; - // Execute distinct - if ($wheres) { - $result = $this->collection->distinct($column, $wheres); - } else { - $result = $this->collection->distinct($column); + $options = []; + // if transaction in session + if ($session = $this->connection->getSession()) { + $options['session'] = $session; } + // Execute distinct + $result = $this->collection->distinct($column, $wheres ?: [], $options); + return $this->useCollections ? new Collection($result) : $result; } // Normal query else { @@ -397,6 +404,11 @@ public function getFresh($columns = []) $options = array_merge($options, $this->options); } + // if transaction in session + if ($session = $this->connection->getSession()) { + $options['session'] = $session; + } + // Execute query and get MongoCursor $cursor = $this->collection->find($wheres, $options); @@ -561,7 +573,12 @@ public function insert(array $values) } // Batch insert - $result = $this->collection->insertMany($values); + $options = []; + // if transaction in session + if ($session = $this->connection->getSession()) { + $options['session'] = $session; + } + $result = $this->collection->insertMany($values, $options); return (1 == (int) $result->isAcknowledged()); } @@ -571,7 +588,12 @@ public function insert(array $values) */ public function insertGetId(array $values, $sequence = null) { - $result = $this->collection->insertOne($values); + $options = []; + // if transaction in session + if ($session = $this->connection->getSession()) { + $options['session'] = $session; + } + $result = $this->collection->insertOne($values, $options); if (1 == (int) $result->isAcknowledged()) { if ($sequence === null) { @@ -592,6 +614,10 @@ public function update(array $values, array $options = []) if (!Str::startsWith(key($values), '$')) { $values = ['$set' => $values]; } + // if transaction in session + if ($session = $this->connection->getSession()) { + $options['session'] = $session; + } return $this->performUpdate($values, $options); } @@ -614,6 +640,11 @@ public function increment($column, $amount = 1, array $extra = [], array $option $query->orWhereNotNull($column); }); + // if transaction in session + if ($session = $this->connection->getSession()) { + $options['session'] = $session; + } + return $this->performUpdate($query, $options); } @@ -673,7 +704,14 @@ public function delete($id = null) } $wheres = $this->compileWheres(); - $result = $this->collection->DeleteMany($wheres); + + $options = []; + // if transaction in session + if ($session = $this->connection->getSession()) { + $options['session'] = $session; + } + + $result = $this->collection->DeleteMany($wheres, $options); if (1 == (int) $result->isAcknowledged()) { return $result->getDeletedCount(); } @@ -698,7 +736,12 @@ public function from($collection, $as = null) */ public function truncate() { - $result = $this->collection->drop(); + $options = []; + // if transaction in session + if ($session = $this->connection->getSession()) { + $options['session'] = $session; + } + $result = $this->collection->drop($options); return (1 == (int) $result->ok); } @@ -826,6 +869,11 @@ protected function performUpdate($query, array $options = []) $options['multiple'] = true; } + // if transaction in session + if ($session = $this->connection->getSession()) { + $options['session'] = $session; + } + $wheres = $this->compileWheres(); $result = $this->collection->UpdateMany($wheres, $query, $options); if (1 == (int) $result->isAcknowledged()) { diff --git a/tests/TransactionBuilderTest.php b/tests/TransactionBuilderTest.php new file mode 100644 index 000000000..1dc645c4e --- /dev/null +++ b/tests/TransactionBuilderTest.php @@ -0,0 +1,201 @@ + 'klinson', 'age' => 20, 'title' => 'admin']; + protected $originData = ['name' => 'users', 'age' => 20, 'title' => 'user']; + + public function setUp(): void + { + parent::setUp(); + + DB::collection('users')->truncate(); + DB::collection('users')->insert($this->originData); + } + + public function tearDown(): void + { + DB::collection('users')->truncate(); + parent::tearDown(); + } + + public function testInsert() + { + /** rollback test */ + DB::beginTransaction(); + DB::collection('users')->insert($this->insertData); + DB::rollBack(); + $users = DB::collection('users')->where('name', $this->insertData['name'])->get(); + $this->assertCount(0, $users); + + /** commit test */ + DB::beginTransaction(); + DB::collection('users')->insert($this->insertData); + DB::commit(); + $users = DB::collection('users')->where('name', $this->insertData['name'])->get(); + $this->assertCount(1, $users); + } + + public function testInsertGetId() + { + /** rollback test */ + DB::beginTransaction(); + $user_id = DB::collection('users')->insertGetId($this->insertData); + DB::rollBack(); + $user_id = (string) $user_id; + $user = DB::collection('users')->find($user_id); + $this->assertNull($user); + + /** commit test */ + DB::beginTransaction(); + $user_id = DB::collection('users')->insertGetId($this->insertData); + DB::commit(); + $user_id = (string) $user_id; + $user = DB::collection('users')->find($user_id); + $this->assertEquals($this->insertData['name'], $user['name']); + } + + public function testUpdate() + { + /** rollback test */ + $new_age = $this->originData['age']+1; + DB::beginTransaction(); + DB::collection('users')->where('name', $this->originData['name'])->update(['age' => $new_age]); + DB::rollBack(); + $users = DB::collection('users')->where('name', $this->originData['name'])->where('age', $new_age)->get(); + $this->assertCount(0, $users); + + /** commit test */ + DB::beginTransaction(); + DB::collection('users')->where('name', $this->originData['name'])->update(['age' => $new_age]); + DB::commit(); + $users = DB::collection('users')->where('name', $this->originData['name'])->where('age', $new_age)->get(); + $this->assertCount(1, $users); + } + + public function testDelete() + { + /** rollback test */ + DB::beginTransaction(); + DB::collection('users')->where('name', $this->originData['name'])->delete(); + DB::rollBack(); + $users = DB::collection('users')->where('name', $this->originData['name'])->get(); + $this->assertCount(1, $users); + + /** commit test */ + DB::beginTransaction(); + DB::collection('users')->where('name', $this->originData['name'])->delete(); + DB::commit(); + $users = DB::collection('users')->where('name', $this->originData['name'])->get(); + $this->assertCount(0, $users); + } + + public function testIncrement() + { + /** rollback test */ + DB::beginTransaction(); + DB::collection('users')->where('name', $this->originData['name'])->increment('age'); + DB::rollBack(); + $user = DB::collection('users')->where('name', $this->originData['name'])->first(); + $this->assertEquals($this->originData['age'], $user['age']); + + /** commit test */ + DB::beginTransaction(); + DB::collection('users')->where('name', $this->originData['name'])->increment('age'); + DB::commit(); + $user = DB::collection('users')->where('name', $this->originData['name'])->first(); + $this->assertEquals($this->originData['age']+1, $user['age']); + } + + public function testDecrement() + { + /** rollback test */ + DB::beginTransaction(); + DB::collection('users')->where('name', $this->originData['name'])->decrement('age'); + DB::rollBack(); + $user = DB::collection('users')->where('name', $this->originData['name'])->first(); + $this->assertEquals($this->originData['age'], $user['age']); + + /** commit test */ + DB::beginTransaction(); + DB::collection('users')->where('name', $this->originData['name'])->decrement('age'); + DB::commit(); + $user = DB::collection('users')->where('name', $this->originData['name'])->first(); + $this->assertEquals($this->originData['age']-1, $user['age']); + } + + public function testQuery() + { + /** rollback test */ + DB::beginTransaction(); + $count = DB::collection('users')->count(); + $this->assertEquals(1, $count); + DB::collection('users')->insert($this->insertData); + $count = DB::collection('users')->count(); + $this->assertEquals(2, $count); + DB::rollBack(); + $count = DB::collection('users')->count(); + $this->assertEquals(1, $count); + + /** commit test */ + DB::beginTransaction(); + $count = DB::collection('users')->count(); + $this->assertEquals(1, $count); + DB::collection('users')->insert($this->insertData); + $count = DB::collection('users')->count(); + $this->assertEquals(2, $count); + DB::commit(); + $count = DB::collection('users')->count(); + $this->assertEquals(2, $count); + } + + public function testTransaction() + { + $count = DB::collection('users')->count(); + $this->assertEquals(1, $count); + + $new_age = $this->originData['age'] + 1; + DB::transaction(function () use ($new_age) { + DB::collection('users')->insert($this->insertData); + DB::collection('users')->where('name', $this->originData['name'])->update(['age' => $new_age]); + }); + $count = DB::collection('users')->count(); + $this->assertEquals(2, $count); + + $checkInsert = DB::collection('users')->where('name', $this->insertData['name'])->first(); + $this->assertNotNull($checkInsert); + $this->assertEquals($this->insertData['age'], $checkInsert['age']); + + $checkUpdate = DB::collection('users')->where('name', $this->originData['name'])->first(); + $this->assertEquals($new_age, $checkUpdate['age']); + } + + /** + * Supports infinite-level nested transactions, but outside transaction rollbacks do not affect the commit of inside transactions + */ + public function TestNestingTransaction() + { + DB::collection('users')->insert($this->insertData); + $new_age1 = $this->originData['age'] + 1; + $new_age2 = $this->insertData['age'] + 1; + /** outside transaction */ + DB::beginTransaction(); + + DB::collection('users')->where('name', $this->originData['name'])->update(['age' => $new_age1]); + + /** inside transaction */ + DB::transaction(function () use ($new_age2) { + DB::collection('users')->where('name', $this->insertData['name'])->update(['age' => $new_age2]); + }); + + DB::rollBack(); + + $check1 = DB::collection('users')->where('name', $this->originData['name'])->first(); + $check2 = DB::collection('users')->where('name', $this->insertData['name'])->first(); + $this->assertNotEquals($new_age1, $check1['age']); + $this->assertEquals($new_age2, $check2['age']); + } +} diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php new file mode 100644 index 000000000..d64fcd170 --- /dev/null +++ b/tests/TransactionTest.php @@ -0,0 +1,211 @@ + 'klinson', 'age' => 20, 'title' => 'admin']; + protected $originData = ['name' => 'users', 'age' => 20, 'title' => 'user']; + + public function setUp(): void + { + parent::setUp(); + User::truncate(); + User::create($this->originData); + } + + public function tearDown(): void + { + User::truncate(); + parent::tearDown(); + } + + public function testCreate() + { + /** rollback test */ + DB::beginTransaction(); + $user = User::create($this->insertData); + DB::rollBack(); + $this->assertInstanceOf(\Jenssegers\Mongodb\Eloquent\Model::class, $user); + $this->assertTrue($user->exists); + $this->assertEquals($this->insertData['name'], $user->name); + + $check = User::find($user->_id); + $this->assertNull($check); + + /** commit test */ + DB::beginTransaction(); + $user = User::create($this->insertData); + DB::commit(); + $this->assertInstanceOf(\Jenssegers\Mongodb\Eloquent\Model::class, $user); + $this->assertTrue($user->exists); + $this->assertEquals($this->insertData['name'], $user->name); + + $check = User::find($user->_id); + $this->assertNotNull($check); + $this->assertEquals($user->name, $check->name); + } + + public function testInsert() + { + /** rollback test */ + DB::beginTransaction(); + $user = new User; + $user->name = $this->insertData['name']; + $user->title = $this->insertData['title']; + $user->age = $this->insertData['age']; + $user->save(); + DB::rollBack(); + + $this->assertTrue($user->exists); + $this->assertTrue(isset($user->_id)); + $this->assertIsString($user->_id); + + $check = User::find($user->_id); + $this->assertNull($check); + + /** commit test */ + DB::beginTransaction(); + $user = new User; + $user->name = $this->insertData['name']; + $user->title = $this->insertData['title']; + $user->age = $this->insertData['age']; + $user->save(); + DB::commit(); + + $this->assertTrue($user->exists); + $this->assertTrue(isset($user->_id)); + $this->assertIsString($user->_id); + + $check = User::find($user->_id); + $this->assertNotNull($check); + $this->assertEquals($check->name, $user->name); + $this->assertEquals($check->age, $user->age); + $this->assertEquals($check->title, $user->title); + } + + public function testInsertWithId(): void + { + $id = 1; + $check = User::find($id); + $this->assertNull($check); + + /** rollback test */ + DB::beginTransaction(); + $user = new User; + $user->_id = $id; + $user->name = $this->insertData['name']; + $user->title = $this->insertData['title']; + $user->age = $this->insertData['age']; + $user->save(); + DB::rollBack(); + + $this->assertTrue($user->exists); + $this->assertEquals($id, $user->_id); + $check = User::find($id); + $this->assertNull($check); + + /** commit test */ + DB::beginTransaction(); + $user = new User; + $user->_id = $id; + $user->name = $this->insertData['name']; + $user->title = $this->insertData['title']; + $user->age = $this->insertData['age']; + $user->save(); + DB::commit(); + + $this->assertTrue($user->exists); + $this->assertEquals($id, $user->_id); + $check = User::find($id); + $this->assertNotNull($check); + $this->assertEquals($check->name, $user->name); + $this->assertEquals($check->age, $user->age); + $this->assertEquals($check->title, $user->title); + } + + public function testUpdate() + { + /** rollback test */ + $new_age = $this->insertData['age'] + 1; + $user1 = User::create($this->insertData); + $user2 = User::create($this->insertData); + DB::beginTransaction(); + $user1->age = $new_age; + $user1->save(); + $user2->update(['age' => $new_age]); + DB::rollBack(); + $this->assertEquals($new_age, $user1->age); + $this->assertEquals($new_age, $user2->age); + + $check1 = User::find($user1->_id); + $check2 = User::find($user2->_id); + $this->assertEquals($this->insertData['age'], $check1->age); + $this->assertEquals($this->insertData['age'], $check2->age); + + /** commit test */ + User::truncate(); + $user1 = User::create($this->insertData); + $user2 = User::create($this->insertData); + DB::beginTransaction(); + $user1->age = $new_age; + $user1->save(); + $user2->update(['age' => $new_age]); + DB::commit(); + $this->assertEquals($new_age, $user1->age); + $this->assertEquals($new_age, $user2->age); + + $check1 = User::find($user1->_id); + $check2 = User::find($user2->_id); + $this->assertEquals($new_age, $check1->age); + $this->assertEquals($new_age, $check2->age); + } + + public function testDelete() + { + /** rollback test */ + $user1 = User::create($this->insertData); + $user2 = User::create($this->insertData); + DB::beginTransaction(); + $user1->delete(); + User::destroy((string) $user2->_id); + DB::rollBack(); + $check1 = User::find($user1->_id); + $check2 = User::find($user2->_id); + $this->assertNotNull($check1); + $this->assertNotNull($check2); + + /** commit test */ + User::truncate(); + $user1 = User::create($this->insertData); + $user2 = User::create($this->insertData); + DB::beginTransaction(); + $user1->delete(); + User::destroy((string) $user2->_id); + DB::commit(); + $check1 = User::find($user1->_id); + $check2 = User::find($user2->_id); + $this->assertNull($check1); + $this->assertNull($check2); + } + + public function testTransaction() + { + $count = User::count(); + $this->assertEquals(1, $count); + $new_age = $this->originData['age'] + 1; + DB::transaction(function () use ($new_age) { + User::create($this->insertData); + User::where($this->originData['name'])->update(['age' => $new_age]); + }); + $count = User::count(); + $this->assertEquals(2, $count); + + $checkInsert = User::where($this->insertData['name'])->first(); + $this->assertNotNull($checkInsert); + + $checkUpdate = User::where($this->originData['name'])->first(); + $this->assertEquals($new_age, $checkUpdate->age); + } +} From 9a01d2325d6eaf510ea5be62daf53872813986d7 Mon Sep 17 00:00:00 2001 From: klinson Date: Wed, 8 Jan 2020 18:55:55 +0800 Subject: [PATCH 02/87] format code --- tests/TransactionBuilderTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/TransactionBuilderTest.php b/tests/TransactionBuilderTest.php index 1dc645c4e..77f3b8ba5 100644 --- a/tests/TransactionBuilderTest.php +++ b/tests/TransactionBuilderTest.php @@ -61,7 +61,7 @@ public function testInsertGetId() public function testUpdate() { /** rollback test */ - $new_age = $this->originData['age']+1; + $new_age = $this->originData['age'] + 1; DB::beginTransaction(); DB::collection('users')->where('name', $this->originData['name'])->update(['age' => $new_age]); DB::rollBack(); @@ -107,7 +107,7 @@ public function testIncrement() DB::collection('users')->where('name', $this->originData['name'])->increment('age'); DB::commit(); $user = DB::collection('users')->where('name', $this->originData['name'])->first(); - $this->assertEquals($this->originData['age']+1, $user['age']); + $this->assertEquals($this->originData['age'] + 1, $user['age']); } public function testDecrement() @@ -124,7 +124,7 @@ public function testDecrement() DB::collection('users')->where('name', $this->originData['name'])->decrement('age'); DB::commit(); $user = DB::collection('users')->where('name', $this->originData['name'])->first(); - $this->assertEquals($this->originData['age']-1, $user['age']); + $this->assertEquals($this->originData['age'] - 1, $user['age']); } public function testQuery() From 64b415611a41c1531c5fdf2773224bc75268fab6 Mon Sep 17 00:00:00 2001 From: klinson Date: Thu, 9 Jan 2020 18:39:18 +0800 Subject: [PATCH 03/87] add mongodb(replica set) environment into docker configuration --- MongoReplsetDockerFile | 5 ++++ docker-compose.yml | 46 ++++++++++++++++++++++++++++++++ mongo-replset-init.sh | 23 ++++++++++++++++ tests/TestCase.php | 1 + tests/TransactionBuilderTest.php | 7 +++++ tests/TransactionTest.php | 9 +++++++ tests/config/database.php | 13 +++++++++ tests/models/User.php | 2 +- 8 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 MongoReplsetDockerFile create mode 100644 mongo-replset-init.sh diff --git a/MongoReplsetDockerFile b/MongoReplsetDockerFile new file mode 100644 index 000000000..652d9bb96 --- /dev/null +++ b/MongoReplsetDockerFile @@ -0,0 +1,5 @@ +FROM mongo + +ADD mongo-replset-init.sh /usr/local/bin/ + +RUN chmod +x /usr/local/bin/mongo-replset-init.sh diff --git a/docker-compose.yml b/docker-compose.yml index c6f20163e..c3f2b9ce3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,6 +12,9 @@ services: depends_on: - mongodb - mysql + - mongo1 + - mongo2 + - mongo3 mysql: container_name: mysql @@ -30,3 +33,46 @@ services: - 27017:27017 logging: driver: none + + mongo1: + hostname: mongo1 + container_name: mongo1 + image: mongo + restart: always + expose: + - 27017 + ports: + - 27018:27017 + command: '--quiet --bind_ip_all --replSet rs0' + + mongo2: + hostname: mongo2 + container_name: mongo2 + image: mongo + restart: always + expose: + - 27017 + ports: + - 27019:27017 + command: '--quiet --bind_ip_all --replSet rs0' + + mongo3: + hostname: mongo3 + container_name: mongo3 + image: mongo + restart: always + expose: + - 27017 + ports: + - 27020:27017 + command: '--quiet --bind_ip_all --replSet rs0' + + mongoreplret: + build: + context: . + dockerfile: MongoReplsetDockerFile + depends_on: + - mongo1 + - mongo2 + - mongo3 + entrypoint: ["sh", "-c", "mongo-replset-init.sh"] diff --git a/mongo-replset-init.sh b/mongo-replset-init.sh new file mode 100644 index 000000000..d5a95b555 --- /dev/null +++ b/mongo-replset-init.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +echo "prepare rs initiating" + +check_db_status() { + mongo1=$(mongo --host mongo1 --port 27017 --eval "db.stats().ok" | tail -n1 | grep -E '(^|\s)1($|\s)') + mongo2=$(mongo --host mongo2 --port 27017 --eval "db.stats().ok" | tail -n1 | grep -E '(^|\s)1($|\s)') + mongo3=$(mongo --host mongo3 --port 27017 --eval "db.stats().ok" | tail -n1 | grep -E '(^|\s)1($|\s)') + if [[ $mongo1 == 1 ]] && [[ $mongo2 == 1 ]] && [[ $mongo3 == 1 ]]; then + init_rs + else + check_db_status + fi +} + +init_rs() { + ret=$(mongo --host mongo1 --port 27017 --eval "rs.initiate({ _id: 'rs0', members: [{ _id: 0, host: 'mongo1:27017' }, { _id: 1, host: 'mongo2:27017' }, { _id: 2, host: 'mongo3:27017' } ] })" > /dev/null 2>&1) +} + +check_db_status > /dev/null 2>&1 + +echo "rs initiating finished" +exit 0 diff --git a/tests/TestCase.php b/tests/TestCase.php index a455b8576..fb7cb9a2f 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -53,6 +53,7 @@ protected function getEnvironmentSetUp($app) $app['config']->set('database.connections.mongodb', $config['connections']['mongodb']); $app['config']->set('database.connections.mongodb2', $config['connections']['mongodb']); $app['config']->set('database.connections.dsn_mongodb', $config['connections']['dsn_mongodb']); + $app['config']->set('database.connections.mongodb_replset', $config['connections']['mongodb_replset']); $app['config']->set('auth.model', 'User'); $app['config']->set('auth.providers.users.model', 'User'); diff --git a/tests/TransactionBuilderTest.php b/tests/TransactionBuilderTest.php index 77f3b8ba5..7b5a31ff4 100644 --- a/tests/TransactionBuilderTest.php +++ b/tests/TransactionBuilderTest.php @@ -7,11 +7,17 @@ class TransactionBuilderTest extends TestCase { protected $insertData = ['name' => 'klinson', 'age' => 20, 'title' => 'admin']; protected $originData = ['name' => 'users', 'age' => 20, 'title' => 'user']; + protected $connection = 'mongodb_replset'; + protected $originConnection = 'mongodb'; public function setUp(): void { parent::setUp(); + /** change connection to seplset? because the transaction needs */ + $this->originConnection = DB::getDefaultConnection(); + DB::setDefaultConnection($this->connection); + DB::collection('users')->truncate(); DB::collection('users')->insert($this->originData); } @@ -19,6 +25,7 @@ public function setUp(): void public function tearDown(): void { DB::collection('users')->truncate(); + DB::setDefaultConnection($this->originConnection); parent::tearDown(); } diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index d64fcd170..6fa615aca 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -7,10 +7,17 @@ class TransactionTest extends TestCase { protected $insertData = ['name' => 'klinson', 'age' => 20, 'title' => 'admin']; protected $originData = ['name' => 'users', 'age' => 20, 'title' => 'user']; + protected $connection = 'mongodb_replset'; + protected $originConnection = 'mongodb'; public function setUp(): void { parent::setUp(); + + /** change connection to seplset? because the transaction needs */ + $this->originConnection = DB::getDefaultConnection(); + DB::setDefaultConnection($this->connection); + User::truncate(); User::create($this->originData); } @@ -18,6 +25,8 @@ public function setUp(): void public function tearDown(): void { User::truncate(); + DB::setDefaultConnection($this->originConnection); + parent::tearDown(); } diff --git a/tests/config/database.php b/tests/config/database.php index 23f8ca990..7bc3d4d04 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -14,6 +14,19 @@ 'database' => env('MONGO_DATABASE', 'unittest'), ], + 'mongodb_replset' => [ + 'driver' => 'mongodb', + 'host' => [ + 'mongo1:27017', + 'mongo2:27017', + 'mongo3:27017', + ], + 'database' => env('MONGO_DATABASE', 'unittest'), + 'options' => [ + 'replicaSet' => 'rs0' + ] + ], + 'dsn_mongodb' => [ 'driver' => 'mongodb', 'dsn' => "mongodb://$mongoHost:$mongoPort", diff --git a/tests/models/User.php b/tests/models/User.php index 1217af762..56cee1636 100644 --- a/tests/models/User.php +++ b/tests/models/User.php @@ -23,7 +23,7 @@ class User extends Eloquent implements AuthenticatableContract, CanResetPassword { use Authenticatable, CanResetPassword, HybridRelations, Notifiable; - protected $connection = 'mongodb'; +// protected $connection = 'mongodb'; protected $dates = ['birthday', 'entry.date']; protected static $unguarded = true; From 34b1a98ea53cac949c1beb1206106f500a304506 Mon Sep 17 00:00:00 2001 From: klinson Date: Thu, 9 Jan 2020 18:41:25 +0800 Subject: [PATCH 04/87] must be compatible with Illuminate\Database\Connection::rollBack($toLevel = NULL) --- src/Jenssegers/Mongodb/Connection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Jenssegers/Mongodb/Connection.php b/src/Jenssegers/Mongodb/Connection.php index 03d2ef832..82914a713 100644 --- a/src/Jenssegers/Mongodb/Connection.php +++ b/src/Jenssegers/Mongodb/Connection.php @@ -299,7 +299,7 @@ public function commit() * rollback transaction in this session and close this session * @author klinson */ - public function rollBack() + public function rollBack($toLevel = null) { if ($session = $this->getSession()) { $session->abortTransaction(); From 84850a9b85cc4f8eaf6edbfde54f432628311abd Mon Sep 17 00:00:00 2001 From: klinson Date: Thu, 9 Jan 2020 18:54:20 +0800 Subject: [PATCH 05/87] add transaction usage into readme.md --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index a6fc96e39..1a7f2d440 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Table of contents * [Eloquent](#eloquent) * [Optional: Alias](#optional-alias) * [Query Builder](#query-builder) +* [Transaction](#transaction) * [Schema](#schema) * [Extensions](#extensions) * [Troubleshooting](#troubleshooting) @@ -241,6 +242,26 @@ $user = DB::connection('mongodb')->collection('users')->get(); Read more about the query builder on http://laravel.com/docs/queries +Transaction +------------- +Transaction requires mongodb version V4.0 or more and deployment replica sets or sharded clusters. + +Transaction supports create/insert,update,delete,etc operation. + +Transaction supports infinite-level nested transactions, but outside transaction rollbacks do not affect the commit of inside transactions. +```php +DB::beginTransaction(); + +User::create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); + +DB::transaction(function () { +    DB::collection('users')->where('name', 'klinson')->update(['age' => 20]); +}); + +DB::rollBack(); +//DB::commit(); +``` + Schema ------ From bedaaa85733e201cb267850a7f3c71604a80b9c6 Mon Sep 17 00:00:00 2001 From: klinson Date: Fri, 10 Jan 2020 11:16:16 +0800 Subject: [PATCH 06/87] update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 736c4c86e..7d91a14b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ cache: install: - docker version - - sudo pip install docker-compose + - sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose - docker-compose version - docker-compose build --build-arg PHP_VERSION=${PHP_VERSION} - docker-compose run --rm tests composer install --no-interaction From b03091402652eebfeb2b3a09a70a969f3410b902 Mon Sep 17 00:00:00 2001 From: klinson Date: Mon, 13 Jan 2020 17:17:10 +0800 Subject: [PATCH 07/87] update database.conf --- tests/config/database.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/config/database.php b/tests/config/database.php index 7bc3d4d04..63ec1d37a 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -23,7 +23,8 @@ ], 'database' => env('MONGO_DATABASE', 'unittest'), 'options' => [ - 'replicaSet' => 'rs0' + 'replicaSet' => 'rs0', + 'serverSelectionTryOnce' => false, ] ], From 163b41dfdc2a93a291ab67485f8c76b27f4b6484 Mon Sep 17 00:00:00 2001 From: klinson Date: Mon, 13 Jan 2020 17:17:31 +0800 Subject: [PATCH 08/87] update .travis.yml --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7d91a14b0..82bb0836b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,4 +24,5 @@ install: - docker-compose run --rm tests composer install --no-interaction script: - - docker-compose run --rm tests ./vendor/bin/phpunit --coverage-clover ./clover.xml + - docker-compose up -d + - docker-compose exec tests ./vendor/bin/phpunit From 92c1e0780a646607a7a121fa48f60eb205a3ac5a Mon Sep 17 00:00:00 2001 From: klinson Date: Mon, 13 Jan 2020 17:17:56 +0800 Subject: [PATCH 09/87] update docker-compose.yml --- docker-compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index c3f2b9ce3..db4e52271 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,6 +15,8 @@ services: - mongo1 - mongo2 - mongo3 + stdin_open: true + tty: true mysql: container_name: mysql From caa61ea184796f1d7fb6f12aa48b771bf610e196 Mon Sep 17 00:00:00 2001 From: klinson Date: Fri, 17 Jan 2020 18:32:22 +0800 Subject: [PATCH 10/87] Update src/Jenssegers/Mongodb/Connection.php Co-Authored-By: Stas --- src/Jenssegers/Mongodb/Connection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Jenssegers/Mongodb/Connection.php b/src/Jenssegers/Mongodb/Connection.php index 82914a713..664d5d74d 100644 --- a/src/Jenssegers/Mongodb/Connection.php +++ b/src/Jenssegers/Mongodb/Connection.php @@ -333,7 +333,7 @@ protected function setLastSession() */ public function getSession() { - return ($this->session_key && isset($this->sessions[$this->session_key])) + return $this->sessions[$this->session_key] ?? null; ? $this->sessions[$this->session_key] : null; } From 7d96c3e7b9fe1611e28015a31d5f9ece52ca0561 Mon Sep 17 00:00:00 2001 From: klinson Date: Fri, 7 Feb 2020 21:05:20 +0800 Subject: [PATCH 11/87] fixbug Connection.php --- src/Jenssegers/Mongodb/Connection.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Jenssegers/Mongodb/Connection.php b/src/Jenssegers/Mongodb/Connection.php index 664d5d74d..815c8c6eb 100644 --- a/src/Jenssegers/Mongodb/Connection.php +++ b/src/Jenssegers/Mongodb/Connection.php @@ -334,7 +334,5 @@ protected function setLastSession() public function getSession() { return $this->sessions[$this->session_key] ?? null; - ? $this->sessions[$this->session_key] - : null; } } From 10bda056f878497d1e6869371b5e3f4bb11e68f2 Mon Sep 17 00:00:00 2001 From: klinson Date: Fri, 7 Feb 2020 22:01:56 +0800 Subject: [PATCH 12/87] add transaction into README.md --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 1f13ea261..3c0f88a89 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ This package adds functionalities to the Eloquent model and Query builder for Mo - [Query Builder](#query-builder) - [Basic Usage](#basic-usage-2) - [Available operations](#available-operations) + - [Transaction](#transaction) - [Schema](#schema) - [Basic Usage](#basic-usage-3) - [Geospatial indexes](#geospatial-indexes) @@ -936,6 +937,23 @@ If you are familiar with [Eloquent Queries](http://laravel.com/docs/queries), th ### Available operations To see the available operations, check the [Eloquent](#eloquent) section. +Transaction +------------- +Transaction requires mongodb version V4.0 or more and deployment replica sets or sharded clusters. + +Transaction supports create/insert,update,delete,etc operation. + +Transaction supports infinite-level nested transactions, but outside transaction rollbacks do not affect the commit of inside transactions. +```php +DB::beginTransaction(); +User::create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); +DB::transaction(function () { + DB::collection('users')->where('name', 'klinson')->update(['age' => 20]); +}); +DB::rollBack(); +//DB::commit(); +``` + Schema ------ The database driver also has (limited) schema builder support. You can easily manipulate collections and set indexes. From 85a0be86306ef428b6738176e187ebb65835b3c3 Mon Sep 17 00:00:00 2001 From: klinson Date: Fri, 7 Feb 2020 22:29:34 +0800 Subject: [PATCH 13/87] add replset mongodb tag --- MongoReplsetDockerFile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MongoReplsetDockerFile b/MongoReplsetDockerFile index 652d9bb96..fa5a16e84 100644 --- a/MongoReplsetDockerFile +++ b/MongoReplsetDockerFile @@ -1,4 +1,4 @@ -FROM mongo +FROM mongo:4.2 ADD mongo-replset-init.sh /usr/local/bin/ From b39251c16f2925ce92965c8beda4e41addbe316a Mon Sep 17 00:00:00 2001 From: klinson Date: Sun, 9 Feb 2020 16:05:51 +0800 Subject: [PATCH 14/87] Remove travis from PR please --- .travis.yml | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 82bb0836b..000000000 --- a/.travis.yml +++ /dev/null @@ -1,28 +0,0 @@ -language: minimal - -matrix: - include: - - name: "7.1" - env: PHP_VERSION=7.1 - - name: "7.2" - env: PHP_VERSION=7.2 - - name: "7.3" - env: PHP_VERSION=7.3 - -services: - - docker - -cache: - directories: - - $HOME/.composer/cache - -install: - - docker version - - sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose - - docker-compose version - - docker-compose build --build-arg PHP_VERSION=${PHP_VERSION} - - docker-compose run --rm tests composer install --no-interaction - -script: - - docker-compose up -d - - docker-compose exec tests ./vendor/bin/phpunit From fe610562d887d504468358e5088f58be55d7cd10 Mon Sep 17 00:00:00 2001 From: klinson Date: Fri, 14 Feb 2020 02:28:52 +0800 Subject: [PATCH 15/87] remove author tag and comments in Chinese language --- src/Jenssegers/Mongodb/Connection.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Jenssegers/Mongodb/Connection.php b/src/Jenssegers/Mongodb/Connection.php index 815c8c6eb..1893c1c4a 100644 --- a/src/Jenssegers/Mongodb/Connection.php +++ b/src/Jenssegers/Mongodb/Connection.php @@ -23,8 +23,8 @@ class Connection extends BaseConnection */ protected $connection; - protected $session_key; // sessions会话列表当前会话数组key 随机生成 - protected $sessions = []; // 会话列表 + protected $session_key; + protected $sessions = []; /** * Create a new database connection instance. @@ -269,7 +269,6 @@ public function __call($method, $parameters) * To use transactions on MongoDB 4.2 deployments(replica sets and sharded clusters), clients must use MongoDB drivers updated for MongoDB 4.2. * * @see https://docs.mongodb.com/manual/core/transactions/ - * @author klinson */ public function beginTransaction() { @@ -285,7 +284,6 @@ public function beginTransaction() /** * commit transaction in this session and close this session - * @author klinson */ public function commit() { @@ -297,7 +295,6 @@ public function commit() /** * rollback transaction in this session and close this session - * @author klinson */ public function rollBack($toLevel = null) { @@ -310,7 +307,6 @@ public function rollBack($toLevel = null) /** * close this session and get last session key to session_key * Why do it ? Because nested transactions - * @author klinson */ protected function setLastSession() { @@ -329,7 +325,6 @@ protected function setLastSession() /** * get now session if it has session * @return \MongoDB\Driver\Session|null - * @author klinson */ public function getSession() { From 3029e36592ce9738278cee3580520a22227b3551 Mon Sep 17 00:00:00 2001 From: klinson Date: Fri, 14 Feb 2020 02:45:29 +0800 Subject: [PATCH 16/87] improved function docblocks of transaction --- README.md | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3c0f88a89..a2bee0b14 100644 --- a/README.md +++ b/README.md @@ -938,11 +938,35 @@ If you are familiar with [Eloquent Queries](http://laravel.com/docs/queries), th To see the available operations, check the [Eloquent](#eloquent) section. Transaction -------------- -Transaction requires mongodb version V4.0 or more and deployment replica sets or sharded clusters. +------- +Transaction requires mongodb version V4.0 or more and deployment replica sets or sharded clusters.You can look at its speciality [in the MongoDB docs](https://docs.mongodb.com/manual/core/transactions/) + +### Basic Usage Transaction supports create/insert,update,delete,etc operation. +```php +DB::transaction(function () { + User::create(['name' => 'klinson', 'age' => 19, 'title' => 'admin', 'email' => 'klinsonup@gmail.com']); + DB::collection('users')->where('name', 'klinson')->update(['age' => 20]); + DB::collection('users')->where('name', 'klinson')->delete(); +}); +``` + +```php +// begin a transaction +DB::beginTransaction(); +User::create(['name' => 'klinson', 'age' => 19, 'title' => 'admin', 'email' => 'klinsonup@gmail.com']); +DB::collection('users')->where('name', 'klinson')->update(['age' => 20]); +DB::collection('users')->where('name', 'klinson')->delete(); + +// you can commit your changes +DB::commit(); + +// you can also rollback them +//DB::rollBack(); +``` + Transaction supports infinite-level nested transactions, but outside transaction rollbacks do not affect the commit of inside transactions. ```php DB::beginTransaction(); @@ -951,7 +975,6 @@ DB::transaction(function () { DB::collection('users')->where('name', 'klinson')->update(['age' => 20]); }); DB::rollBack(); -//DB::commit(); ``` Schema From 722141758637e2191df1a60c78636bf2e7c0e98f Mon Sep 17 00:00:00 2001 From: klinson Date: Sun, 28 Jun 2020 18:38:57 +0800 Subject: [PATCH 17/87] add another testsuite for transactional tests in phpunit.xml --- phpunit.xml.dist | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 4da34b41d..51f570dfb 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -25,6 +25,10 @@ tests/QueryBuilderTest.php tests/QueryTest.php + + tests/TransactionBuilderTest.php + tests/TransactionTest.php + tests/ModelTest.php tests/RelationsTest.php From 1b90047282b1039a08eb7e1b2050eb6e94a41bf6 Mon Sep 17 00:00:00 2001 From: klinson Date: Wed, 1 Jul 2020 20:49:56 +0800 Subject: [PATCH 18/87] optimized code --- src/Jenssegers/Mongodb/Query/Builder.php | 55 +++++++++++------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/src/Jenssegers/Mongodb/Query/Builder.php b/src/Jenssegers/Mongodb/Query/Builder.php index 101171452..5fd02f6f2 100644 --- a/src/Jenssegers/Mongodb/Query/Builder.php +++ b/src/Jenssegers/Mongodb/Query/Builder.php @@ -358,9 +358,7 @@ public function getFresh($columns = [], $returnLazy = false) } // if transaction in session - if ($session = $this->connection->getSession()) { - $options['session'] = $session; - } + $options = $this->setSession($options); // Execute aggregation $results = iterator_to_array($this->collection->aggregate($pipeline, $options)); @@ -374,9 +372,7 @@ public function getFresh($columns = [], $returnLazy = false) $options = []; // if transaction in session - if ($session = $this->connection->getSession()) { - $options['session'] = $session; - } + $options = $this->setSession($options); // Execute distinct $result = $this->collection->distinct($column, $wheres ?: [], $options); @@ -426,9 +422,7 @@ public function getFresh($columns = [], $returnLazy = false) } // if transaction in session - if ($session = $this->connection->getSession()) { - $options['session'] = $session; - } + $options = $this->setSession($options); // Execute query and get MongoCursor $cursor = $this->collection->find($wheres, $options); @@ -604,9 +598,8 @@ public function insert(array $values) // Batch insert $options = []; // if transaction in session - if ($session = $this->connection->getSession()) { - $options['session'] = $session; - } + $options = $this->setSession($options); + $result = $this->collection->insertMany($values, $options); return (1 == (int) $result->isAcknowledged()); @@ -619,9 +612,8 @@ public function insertGetId(array $values, $sequence = null) { $options = []; // if transaction in session - if ($session = $this->connection->getSession()) { - $options['session'] = $session; - } + $options = $this->setSession($options); + $result = $this->collection->insertOne($values, $options); if (1 == (int) $result->isAcknowledged()) { @@ -644,9 +636,7 @@ public function update(array $values, array $options = []) $values = ['$set' => $values]; } // if transaction in session - if ($session = $this->connection->getSession()) { - $options['session'] = $session; - } + $options = $this->setSession($options); return $this->performUpdate($values, $options); } @@ -670,9 +660,7 @@ public function increment($column, $amount = 1, array $extra = [], array $option }); // if transaction in session - if ($session = $this->connection->getSession()) { - $options['session'] = $session; - } + $options = $this->setSession($options); return $this->performUpdate($query, $options); } @@ -736,9 +724,7 @@ public function delete($id = null) $options = []; // if transaction in session - if ($session = $this->connection->getSession()) { - $options['session'] = $session; - } + $options = $this->setSession($options); $result = $this->collection->DeleteMany($wheres, $options); if (1 == (int) $result->isAcknowledged()) { @@ -769,9 +755,7 @@ public function truncate() 'typeMap' => ['root' => 'object', 'document' => 'object'], ]; // if transaction in session - if ($session = $this->connection->getSession()) { - $options['session'] = $session; - } + $options = $this->setSession($options); $result = $this->collection->drop($options); @@ -902,9 +886,7 @@ protected function performUpdate($query, array $options = []) } // if transaction in session - if ($session = $this->connection->getSession()) { - $options['session'] = $session; - } + $options = $this->setSession($options); $wheres = $this->compileWheres(); $result = $this->collection->UpdateMany($wheres, $query, $options); @@ -1238,6 +1220,19 @@ public function options(array $options) return $this; } + /** + * set session for the transaction + * @param $session + * @return mixed + */ + protected function setSession($options) + { + if ($session = $this->connection->getSession()) { + $options['session'] = $session; + } + return $options; + } + /** * @inheritdoc */ From a5d0858fce33219b714c0410b70dfb694e8201d1 Mon Sep 17 00:00:00 2001 From: klinson Date: Tue, 21 Jul 2020 15:05:01 +0800 Subject: [PATCH 19/87] update ci and tests configs --- MongoReplsetDockerFile | 5 -- docker-compose.yml | 91 ++++++++++++++++++------------- mongo-replset-init.sh | 52 +++++++++++------- tests/TestCase.php | 2 +- tests/TransactionBuilderTest.php | 14 ++++- tests/TransactionTest.php | 93 ++++++++++++++++++-------------- tests/config/database.php | 22 ++++---- tests/models/User.php | 2 +- 8 files changed, 166 insertions(+), 115 deletions(-) delete mode 100644 MongoReplsetDockerFile diff --git a/MongoReplsetDockerFile b/MongoReplsetDockerFile deleted file mode 100644 index fa5a16e84..000000000 --- a/MongoReplsetDockerFile +++ /dev/null @@ -1,5 +0,0 @@ -FROM mongo:4.2 - -ADD mongo-replset-init.sh /usr/local/bin/ - -RUN chmod +x /usr/local/bin/mongo-replset-init.sh diff --git a/docker-compose.yml b/docker-compose.yml index db4e52271..0057eea30 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,11 +10,12 @@ services: - .:/code working_dir: /code depends_on: - - mongodb - - mysql - - mongo1 - - mongo2 - - mongo3 + - mongodb + - mongodb_repl + - mongodb_repl_2 + - mongodb_repl_3 + - mongo_repl_init + - mysql stdin_open: true tty: true @@ -36,45 +37,61 @@ services: logging: driver: none - mongo1: - hostname: mongo1 - container_name: mongo1 - image: mongo + mongodb_repl: + container_name: mongodb_repl + image: mongo:4.2.5 restart: always - expose: - - 27017 ports: - - 27018:27017 - command: '--quiet --bind_ip_all --replSet rs0' + - "27018:27018" + entrypoint: [ "/usr/bin/mongod", "--quiet", "--bind_ip_all", "--port", "27018", "--replSet", "rs" ] + depends_on: + - mongodb_repl_2 + - mongodb_repl_3 + links: + - mongodb_repl_2:mongodb_repl_2 + - mongodb_repl_3:mongodb_repl_3 + logging: + driver: none - mongo2: - hostname: mongo2 - container_name: mongo2 - image: mongo + mongodb_repl_2: + container_name: mongodb_repl_2 + image: mongo:4.2.5 restart: always - expose: - - 27017 ports: - - 27019:27017 - command: '--quiet --bind_ip_all --replSet rs0' + - "27019:27018" + entrypoint: [ "/usr/bin/mongod", "--quiet", "--bind_ip_all", "--port", "27018", "--replSet", "rs" ] + depends_on: + - mongodb_repl_3 + logging: + driver: none - mongo3: - hostname: mongo3 - container_name: mongo3 - image: mongo + mongodb_repl_3: + container_name: mongodb_repl_3 + image: mongo:4.2.5 restart: always - expose: - - 27017 ports: - - 27020:27017 - command: '--quiet --bind_ip_all --replSet rs0' + - "27020:27018" + entrypoint: [ "/usr/bin/mongod", "--quiet", "--bind_ip_all", "--port", "27018", "--replSet", "rs" ] + logging: + driver: none - mongoreplret: - build: - context: . - dockerfile: MongoReplsetDockerFile + mongo_repl_init: + image: mongo:4.2.5 depends_on: - - mongo1 - - mongo2 - - mongo3 - entrypoint: ["sh", "-c", "mongo-replset-init.sh"] + - mongodb_repl + - mongodb_repl_2 + - mongodb_repl_3 + links: + - mongodb_repl:mongodb_repl + - mongodb_repl_2:mongodb_repl_2 + - mongodb_repl_3:mongodb_repl_3 + environment: + - MONGO1=mongodb_repl + - MONGO2=mongodb_repl_2 + - MONGO3=mongodb_repl_3 + - RS=rs + volumes: + - ./:/scripts + entrypoint: [ "sh", "-c", "/scripts/mongo-repl-init.sh" ] + logging: + driver: none diff --git a/mongo-replset-init.sh b/mongo-replset-init.sh index d5a95b555..9c184d51a 100644 --- a/mongo-replset-init.sh +++ b/mongo-replset-init.sh @@ -1,23 +1,39 @@ #!/bin/bash +mongodb1=`getent hosts ${MONGO1} | awk '{ print $1 }'` -echo "prepare rs initiating" +port=${PORT:-27018} -check_db_status() { - mongo1=$(mongo --host mongo1 --port 27017 --eval "db.stats().ok" | tail -n1 | grep -E '(^|\s)1($|\s)') - mongo2=$(mongo --host mongo2 --port 27017 --eval "db.stats().ok" | tail -n1 | grep -E '(^|\s)1($|\s)') - mongo3=$(mongo --host mongo3 --port 27017 --eval "db.stats().ok" | tail -n1 | grep -E '(^|\s)1($|\s)') - if [[ $mongo1 == 1 ]] && [[ $mongo2 == 1 ]] && [[ $mongo3 == 1 ]]; then - init_rs - else - check_db_status - fi -} +echo "Waiting for startup.." +until mongo --host ${mongodb1}:${port} --eval 'quit(db.runCommand({ ping: 1 }).ok ? 0 : 2)' &>/dev/null; do + printf '.' + sleep 1 +done -init_rs() { - ret=$(mongo --host mongo1 --port 27017 --eval "rs.initiate({ _id: 'rs0', members: [{ _id: 0, host: 'mongo1:27017' }, { _id: 1, host: 'mongo2:27017' }, { _id: 2, host: 'mongo3:27017' } ] })" > /dev/null 2>&1) -} +echo "Started.." -check_db_status > /dev/null 2>&1 - -echo "rs initiating finished" -exit 0 +echo setup.sh time now: `date +"%T" ` +mongo --host ${mongodb1}:${port} <set('database.connections.mongodb2', $config['connections']['mongodb']); $app['config']->set('database.connections.dsn_mongodb', $config['connections']['dsn_mongodb']); $app['config']->set('database.connections.dsn_mongodb_db', $config['connections']['dsn_mongodb_db']); - $app['config']->set('database.connections.mongodb_replset', $config['connections']['mongodb_replset']); + $app['config']->set('database.connections.mongodb_repl', $config['connections']['mongodb_repl']); $app['config']->set('auth.model', 'User'); $app['config']->set('auth.providers.users.model', 'User'); diff --git a/tests/TransactionBuilderTest.php b/tests/TransactionBuilderTest.php index 7b5a31ff4..03b2e6450 100644 --- a/tests/TransactionBuilderTest.php +++ b/tests/TransactionBuilderTest.php @@ -7,7 +7,7 @@ class TransactionBuilderTest extends TestCase { protected $insertData = ['name' => 'klinson', 'age' => 20, 'title' => 'admin']; protected $originData = ['name' => 'users', 'age' => 20, 'title' => 'user']; - protected $connection = 'mongodb_replset'; + protected $connection = 'mongodb_repl'; protected $originConnection = 'mongodb'; public function setUp(): void @@ -22,6 +22,18 @@ public function setUp(): void DB::collection('users')->insert($this->originData); } + protected function getEnvironmentSetUp($app) + { +// if (version_compare(env('MONGO_VERSION'), '4', '<')) { +// $this->markTestSkipped('MongoDB with version below 4 is not supported for transactions'); +// } + + $config = require 'config/database.php'; + + $app['config']->set('database.connections.'.$this->connection, $config['connections'][$this->connection]); + $app['config']->set('database.default', $this->connection); + } + public function tearDown(): void { DB::collection('users')->truncate(); diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 6fa615aca..e286016e7 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -7,25 +7,32 @@ class TransactionTest extends TestCase { protected $insertData = ['name' => 'klinson', 'age' => 20, 'title' => 'admin']; protected $originData = ['name' => 'users', 'age' => 20, 'title' => 'user']; - protected $connection = 'mongodb_replset'; + protected $connection = 'mongodb_repl'; protected $originConnection = 'mongodb'; public function setUp(): void { parent::setUp(); - /** change connection to seplset? because the transaction needs */ - $this->originConnection = DB::getDefaultConnection(); - DB::setDefaultConnection($this->connection); + User::on($this->connection)->truncate(); + User::on($this->connection)->create($this->originData); + } - User::truncate(); - User::create($this->originData); + protected function getEnvironmentSetUp($app) + { +// if (version_compare(env('MONGO_VERSION'), '4', '<')) { +// $this->markTestSkipped('MongoDB with version below 4 is not supported for transactions'); +// } + + $config = require 'config/database.php'; + + $app['config']->set('database.connections.'.$this->connection, $config['connections'][$this->connection]); + $app['config']->set('database.default', $this->connection); } public function tearDown(): void { - User::truncate(); - DB::setDefaultConnection($this->originConnection); + User::on($this->connection)->truncate(); parent::tearDown(); } @@ -34,24 +41,24 @@ public function testCreate() { /** rollback test */ DB::beginTransaction(); - $user = User::create($this->insertData); + $user = User::on($this->connection)->create($this->insertData); DB::rollBack(); $this->assertInstanceOf(\Jenssegers\Mongodb\Eloquent\Model::class, $user); $this->assertTrue($user->exists); $this->assertEquals($this->insertData['name'], $user->name); - $check = User::find($user->_id); + $check = User::on($this->connection)->find($user->_id); $this->assertNull($check); /** commit test */ DB::beginTransaction(); - $user = User::create($this->insertData); + $user = User::on($this->connection)->create($this->insertData); DB::commit(); $this->assertInstanceOf(\Jenssegers\Mongodb\Eloquent\Model::class, $user); $this->assertTrue($user->exists); $this->assertEquals($this->insertData['name'], $user->name); - $check = User::find($user->_id); + $check = User::on($this->connection)->find($user->_id); $this->assertNotNull($check); $this->assertEquals($user->name, $check->name); } @@ -61,6 +68,7 @@ public function testInsert() /** rollback test */ DB::beginTransaction(); $user = new User; + $user->on($this->connection); $user->name = $this->insertData['name']; $user->title = $this->insertData['title']; $user->age = $this->insertData['age']; @@ -71,12 +79,13 @@ public function testInsert() $this->assertTrue(isset($user->_id)); $this->assertIsString($user->_id); - $check = User::find($user->_id); + $check = User::on($this->connection)->find($user->_id); $this->assertNull($check); /** commit test */ DB::beginTransaction(); $user = new User; + $user->on($this->connection); $user->name = $this->insertData['name']; $user->title = $this->insertData['title']; $user->age = $this->insertData['age']; @@ -87,7 +96,7 @@ public function testInsert() $this->assertTrue(isset($user->_id)); $this->assertIsString($user->_id); - $check = User::find($user->_id); + $check = User::on($this->connection)->find($user->_id); $this->assertNotNull($check); $this->assertEquals($check->name, $user->name); $this->assertEquals($check->age, $user->age); @@ -97,12 +106,13 @@ public function testInsert() public function testInsertWithId(): void { $id = 1; - $check = User::find($id); + $check = User::on($this->connection)->find($id); $this->assertNull($check); /** rollback test */ DB::beginTransaction(); $user = new User; + $user->on($this->connection); $user->_id = $id; $user->name = $this->insertData['name']; $user->title = $this->insertData['title']; @@ -112,12 +122,13 @@ public function testInsertWithId(): void $this->assertTrue($user->exists); $this->assertEquals($id, $user->_id); - $check = User::find($id); + $check = User::on($this->connection)->find($id); $this->assertNull($check); /** commit test */ DB::beginTransaction(); $user = new User; + $user->on($this->connection); $user->_id = $id; $user->name = $this->insertData['name']; $user->title = $this->insertData['title']; @@ -127,7 +138,7 @@ public function testInsertWithId(): void $this->assertTrue($user->exists); $this->assertEquals($id, $user->_id); - $check = User::find($id); + $check = User::on($this->connection)->find($id); $this->assertNotNull($check); $this->assertEquals($check->name, $user->name); $this->assertEquals($check->age, $user->age); @@ -138,8 +149,8 @@ public function testUpdate() { /** rollback test */ $new_age = $this->insertData['age'] + 1; - $user1 = User::create($this->insertData); - $user2 = User::create($this->insertData); + $user1 = User::on($this->connection)->create($this->insertData); + $user2 = User::on($this->connection)->create($this->insertData); DB::beginTransaction(); $user1->age = $new_age; $user1->save(); @@ -148,15 +159,15 @@ public function testUpdate() $this->assertEquals($new_age, $user1->age); $this->assertEquals($new_age, $user2->age); - $check1 = User::find($user1->_id); - $check2 = User::find($user2->_id); + $check1 = User::on($this->connection)->find($user1->_id); + $check2 = User::on($this->connection)->find($user2->_id); $this->assertEquals($this->insertData['age'], $check1->age); $this->assertEquals($this->insertData['age'], $check2->age); /** commit test */ User::truncate(); - $user1 = User::create($this->insertData); - $user2 = User::create($this->insertData); + $user1 = User::on($this->connection)->create($this->insertData); + $user2 = User::on($this->connection)->create($this->insertData); DB::beginTransaction(); $user1->age = $new_age; $user1->save(); @@ -165,8 +176,8 @@ public function testUpdate() $this->assertEquals($new_age, $user1->age); $this->assertEquals($new_age, $user2->age); - $check1 = User::find($user1->_id); - $check2 = User::find($user2->_id); + $check1 = User::on($this->connection)->find($user1->_id); + $check2 = User::on($this->connection)->find($user2->_id); $this->assertEquals($new_age, $check1->age); $this->assertEquals($new_age, $check2->age); } @@ -174,47 +185,47 @@ public function testUpdate() public function testDelete() { /** rollback test */ - $user1 = User::create($this->insertData); - $user2 = User::create($this->insertData); + $user1 = User::on($this->connection)->create($this->insertData); + $user2 = User::on($this->connection)->create($this->insertData); DB::beginTransaction(); $user1->delete(); - User::destroy((string) $user2->_id); + User::on($this->connection)->destroy((string) $user2->_id); DB::rollBack(); - $check1 = User::find($user1->_id); - $check2 = User::find($user2->_id); + $check1 = User::on($this->connection)->find($user1->_id); + $check2 = User::on($this->connection)->find($user2->_id); $this->assertNotNull($check1); $this->assertNotNull($check2); /** commit test */ User::truncate(); - $user1 = User::create($this->insertData); - $user2 = User::create($this->insertData); + $user1 = User::on($this->connection)->create($this->insertData); + $user2 = User::on($this->connection)->create($this->insertData); DB::beginTransaction(); $user1->delete(); - User::destroy((string) $user2->_id); + User::on($this->connection)->destroy((string) $user2->_id); DB::commit(); - $check1 = User::find($user1->_id); - $check2 = User::find($user2->_id); + $check1 = User::on($this->connection)->find($user1->_id); + $check2 = User::on($this->connection)->find($user2->_id); $this->assertNull($check1); $this->assertNull($check2); } public function testTransaction() { - $count = User::count(); + $count = User::on($this->connection)->count(); $this->assertEquals(1, $count); $new_age = $this->originData['age'] + 1; DB::transaction(function () use ($new_age) { - User::create($this->insertData); - User::where($this->originData['name'])->update(['age' => $new_age]); + User::on($this->connection)->create($this->insertData); + User::on($this->connection)->where($this->originData['name'])->update(['age' => $new_age]); }); - $count = User::count(); + $count = User::on($this->connection)->count(); $this->assertEquals(2, $count); - $checkInsert = User::where($this->insertData['name'])->first(); + $checkInsert = User::on($this->connection)->where($this->insertData['name'])->first(); $this->assertNotNull($checkInsert); - $checkUpdate = User::where($this->originData['name'])->first(); + $checkUpdate = User::on($this->connection)->where($this->originData['name'])->first(); $this->assertEquals($new_age, $checkUpdate->age); } } diff --git a/tests/config/database.php b/tests/config/database.php index 1fdff2880..1a61d855c 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -1,7 +1,9 @@ env('MONGO_DATABASE', 'unittest'), ], - 'mongodb_replset' => [ - 'driver' => 'mongodb', - 'host' => [ - 'mongo1:27017', - 'mongo2:27017', - 'mongo3:27017', + 'mongodb_repl' => [ + 'name' => 'mongodb_repl', + 'driver' => 'mongodb', + 'host' => $mongoReplHost, + 'port' => $mongoReplPort, + 'database' => env('MONGO_DATABASE', 'unittest'), + 'options' => [ + 'replicaSet' => 'rs', + 'serverSelectionTryOnce' => false, ], - 'database' => env('MONGO_DATABASE', 'unittest'), - 'options' => [ - 'replicaSet' => 'rs0', - 'serverSelectionTryOnce' => false, - ] ], 'dsn_mongodb' => [ diff --git a/tests/models/User.php b/tests/models/User.php index 56cee1636..1217af762 100644 --- a/tests/models/User.php +++ b/tests/models/User.php @@ -23,7 +23,7 @@ class User extends Eloquent implements AuthenticatableContract, CanResetPassword { use Authenticatable, CanResetPassword, HybridRelations, Notifiable; -// protected $connection = 'mongodb'; + protected $connection = 'mongodb'; protected $dates = ['birthday', 'entry.date']; protected static $unguarded = true; From add9516d69a7619eaf241d5b81f5a202a0dd8be9 Mon Sep 17 00:00:00 2001 From: klinson Date: Tue, 21 Jul 2020 15:05:36 +0800 Subject: [PATCH 20/87] update tests configs --- tests/TransactionBuilderTest.php | 6 +++--- tests/TransactionTest.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/TransactionBuilderTest.php b/tests/TransactionBuilderTest.php index 03b2e6450..eba7a5a93 100644 --- a/tests/TransactionBuilderTest.php +++ b/tests/TransactionBuilderTest.php @@ -24,9 +24,9 @@ public function setUp(): void protected function getEnvironmentSetUp($app) { -// if (version_compare(env('MONGO_VERSION'), '4', '<')) { -// $this->markTestSkipped('MongoDB with version below 4 is not supported for transactions'); -// } + if (version_compare(env('MONGO_VERSION'), '4', '<')) { + $this->markTestSkipped('MongoDB with version below 4 is not supported for transactions'); + } $config = require 'config/database.php'; diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index e286016e7..7f6c83b90 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -20,9 +20,9 @@ public function setUp(): void protected function getEnvironmentSetUp($app) { -// if (version_compare(env('MONGO_VERSION'), '4', '<')) { -// $this->markTestSkipped('MongoDB with version below 4 is not supported for transactions'); -// } + if (version_compare(env('MONGO_VERSION'), '4', '<')) { + $this->markTestSkipped('MongoDB with version below 4 is not supported for transactions'); + } $config = require 'config/database.php'; From 14b3ad7534f3cd4dd8d64e55f8cebfa56a2e5414 Mon Sep 17 00:00:00 2001 From: klinson Date: Tue, 21 Jul 2020 15:18:13 +0800 Subject: [PATCH 21/87] update tests configs --- tests/TransactionBuilderTest.php | 4 ---- tests/TransactionTest.php | 4 ---- 2 files changed, 8 deletions(-) diff --git a/tests/TransactionBuilderTest.php b/tests/TransactionBuilderTest.php index eba7a5a93..609bef72d 100644 --- a/tests/TransactionBuilderTest.php +++ b/tests/TransactionBuilderTest.php @@ -24,10 +24,6 @@ public function setUp(): void protected function getEnvironmentSetUp($app) { - if (version_compare(env('MONGO_VERSION'), '4', '<')) { - $this->markTestSkipped('MongoDB with version below 4 is not supported for transactions'); - } - $config = require 'config/database.php'; $app['config']->set('database.connections.'.$this->connection, $config['connections'][$this->connection]); diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 7f6c83b90..69af2c3cd 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -20,10 +20,6 @@ public function setUp(): void protected function getEnvironmentSetUp($app) { - if (version_compare(env('MONGO_VERSION'), '4', '<')) { - $this->markTestSkipped('MongoDB with version below 4 is not supported for transactions'); - } - $config = require 'config/database.php'; $app['config']->set('database.connections.'.$this->connection, $config['connections'][$this->connection]); From 0c22e4a34e8fd61397533af239fddf789b3ec82f Mon Sep 17 00:00:00 2001 From: klinson Date: Tue, 21 Jul 2020 15:45:19 +0800 Subject: [PATCH 22/87] update ci.yml --- .github/workflows/build-ci.yml | 27 ++++++++++++++++----------- phpunit.xml.dist | 1 + 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index e830b6569..e2ff26b47 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -11,7 +11,7 @@ jobs: runs-on: ${{matrix.os}} strategy: matrix: - php: ['7.2', '7.3', '7.4'] + php: ['7.1', '7.2', '7.3', '7.4'] os: ['ubuntu-latest'] mongodb: ['3.6', '4.0', '4.2'] services: @@ -28,18 +28,21 @@ jobs: MYSQL_DATABASE: 'unittest' MYSQL_ROOT_PASSWORD: name: PHP v${{ matrix.php }} with Mongo v${{ matrix.mongodb }} - steps: - - uses: actions/checkout@v2 - - name: "Installing php" - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: curl,mbstring,xdebug - coverage: xdebug - tools: composer + - uses: actions/checkout@v1 + - name: Creating MongoDB replica + if: matrix.mongodb == '4.0' || matrix.mongodb == '4.2' + run: | + docker run --name mongodb_repl -e MONGO_INITDB_DATABASE=unittest --publish 27018:27018 --detach mongo:${{ matrix.mongodb }} mongod --port 27018 --replSet rs + until docker exec --tty mongodb_repl mongo 127.0.0.1:27018 --eval "db.serverStatus()"; do + sleep 1 + done + sudo docker exec --tty mongodb_repl mongo 127.0.0.1:27018 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"127.0.0.1:27018\" }]})" + env: + MONGO_HOST: 0.0.0.0 + MONGO_REPL_HOST: 0.0.0.0 - name: Show PHP version - run: php -v && composer -V + run: php${{ matrix.php }} -v && composer -V - name: Show Docker version run: if [[ "$DEBUG" == "true" ]]; then docker version && env; fi env: @@ -60,7 +63,9 @@ jobs: run: | ./vendor/bin/phpunit --coverage-clover coverage.xml env: + MONGO_VERSION: ${{ matrix.mongodb }}) MONGO_HOST: 0.0.0.0 + MONGO_REPL_HOST: 0.0.0.0 MYSQL_HOST: 0.0.0.0 MYSQL_PORT: 3307 - name: Send coveralls diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 51f570dfb..4174328b5 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -51,6 +51,7 @@ + From 0b840db9e45e85f827cd79e0684b80585a75f647 Mon Sep 17 00:00:00 2001 From: klinson Date: Tue, 21 Jul 2020 16:03:17 +0800 Subject: [PATCH 23/87] update tests --- tests/TransactionTest.php | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 69af2c3cd..8726fc623 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -8,7 +8,6 @@ class TransactionTest extends TestCase protected $insertData = ['name' => 'klinson', 'age' => 20, 'title' => 'admin']; protected $originData = ['name' => 'users', 'age' => 20, 'title' => 'user']; protected $connection = 'mongodb_repl'; - protected $originConnection = 'mongodb'; public function setUp(): void { @@ -63,8 +62,7 @@ public function testInsert() { /** rollback test */ DB::beginTransaction(); - $user = new User; - $user->on($this->connection); + $user = User::on($this->connection)->getModel(); $user->name = $this->insertData['name']; $user->title = $this->insertData['title']; $user->age = $this->insertData['age']; @@ -80,8 +78,7 @@ public function testInsert() /** commit test */ DB::beginTransaction(); - $user = new User; - $user->on($this->connection); + $user = User::on($this->connection)->getModel(); $user->name = $this->insertData['name']; $user->title = $this->insertData['title']; $user->age = $this->insertData['age']; @@ -107,8 +104,7 @@ public function testInsertWithId(): void /** rollback test */ DB::beginTransaction(); - $user = new User; - $user->on($this->connection); + $user = User::on($this->connection)->getModel(); $user->_id = $id; $user->name = $this->insertData['name']; $user->title = $this->insertData['title']; @@ -123,8 +119,7 @@ public function testInsertWithId(): void /** commit test */ DB::beginTransaction(); - $user = new User; - $user->on($this->connection); + $user = User::on($this->connection)->getModel(); $user->_id = $id; $user->name = $this->insertData['name']; $user->title = $this->insertData['title']; From cf88a035b52088dab61a6f352bcdcdee3e11c6f6 Mon Sep 17 00:00:00 2001 From: klinson Date: Tue, 21 Jul 2020 16:11:39 +0800 Subject: [PATCH 24/87] update tests --- tests/TransactionTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 8726fc623..f2b38809b 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -156,7 +156,7 @@ public function testUpdate() $this->assertEquals($this->insertData['age'], $check2->age); /** commit test */ - User::truncate(); + User::on($this->connection)->truncate(); $user1 = User::on($this->connection)->create($this->insertData); $user2 = User::on($this->connection)->create($this->insertData); DB::beginTransaction(); @@ -188,7 +188,7 @@ public function testDelete() $this->assertNotNull($check2); /** commit test */ - User::truncate(); + User::on($this->connection)->truncate(); $user1 = User::on($this->connection)->create($this->insertData); $user2 = User::on($this->connection)->create($this->insertData); DB::beginTransaction(); From 2664bd5a879073c6cd45f64919265ba3c604339a Mon Sep 17 00:00:00 2001 From: klinson Date: Tue, 21 Jul 2020 16:46:16 +0800 Subject: [PATCH 25/87] update tests --- tests/TransactionTest.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index f2b38809b..cacf3c2ef 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -177,28 +177,20 @@ public function testDelete() { /** rollback test */ $user1 = User::on($this->connection)->create($this->insertData); - $user2 = User::on($this->connection)->create($this->insertData); DB::beginTransaction(); $user1->delete(); - User::on($this->connection)->destroy((string) $user2->_id); DB::rollBack(); $check1 = User::on($this->connection)->find($user1->_id); - $check2 = User::on($this->connection)->find($user2->_id); $this->assertNotNull($check1); - $this->assertNotNull($check2); /** commit test */ User::on($this->connection)->truncate(); $user1 = User::on($this->connection)->create($this->insertData); - $user2 = User::on($this->connection)->create($this->insertData); DB::beginTransaction(); $user1->delete(); - User::on($this->connection)->destroy((string) $user2->_id); DB::commit(); $check1 = User::on($this->connection)->find($user1->_id); - $check2 = User::on($this->connection)->find($user2->_id); $this->assertNull($check1); - $this->assertNull($check2); } public function testTransaction() From 44bd0817bc3b9da7a9c7de25ab0b4530a84b4de9 Mon Sep 17 00:00:00 2001 From: klinson Date: Tue, 21 Jul 2020 17:31:07 +0800 Subject: [PATCH 26/87] update tests --- tests/TransactionBuilderTest.php | 4 ++++ tests/TransactionTest.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/tests/TransactionBuilderTest.php b/tests/TransactionBuilderTest.php index 609bef72d..eba7a5a93 100644 --- a/tests/TransactionBuilderTest.php +++ b/tests/TransactionBuilderTest.php @@ -24,6 +24,10 @@ public function setUp(): void protected function getEnvironmentSetUp($app) { + if (version_compare(env('MONGO_VERSION'), '4', '<')) { + $this->markTestSkipped('MongoDB with version below 4 is not supported for transactions'); + } + $config = require 'config/database.php'; $app['config']->set('database.connections.'.$this->connection, $config['connections'][$this->connection]); diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index cacf3c2ef..0cb95ddaf 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -19,6 +19,10 @@ public function setUp(): void protected function getEnvironmentSetUp($app) { + if (version_compare(env('MONGO_VERSION'), '4', '<')) { + $this->markTestSkipped('MongoDB with version below 4 is not supported for transactions'); + } + $config = require 'config/database.php'; $app['config']->set('database.connections.'.$this->connection, $config['connections'][$this->connection]); From 83f45c991970fc679c97862a7261fdef607c8312 Mon Sep 17 00:00:00 2001 From: klinson Date: Thu, 23 Jul 2020 09:58:01 +0800 Subject: [PATCH 27/87] delete links of docker-compose.yaml remove support for php 7.1 --- .github/workflows/build-ci.yml | 2 +- docker-compose.yml | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index e2ff26b47..849243b1b 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -11,7 +11,7 @@ jobs: runs-on: ${{matrix.os}} strategy: matrix: - php: ['7.1', '7.2', '7.3', '7.4'] + php: ['7.2', '7.3', '7.4'] os: ['ubuntu-latest'] mongodb: ['3.6', '4.0', '4.2'] services: diff --git a/docker-compose.yml b/docker-compose.yml index 0057eea30..51c21e948 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -47,9 +47,6 @@ services: depends_on: - mongodb_repl_2 - mongodb_repl_3 - links: - - mongodb_repl_2:mongodb_repl_2 - - mongodb_repl_3:mongodb_repl_3 logging: driver: none @@ -81,10 +78,6 @@ services: - mongodb_repl - mongodb_repl_2 - mongodb_repl_3 - links: - - mongodb_repl:mongodb_repl - - mongodb_repl_2:mongodb_repl_2 - - mongodb_repl_3:mongodb_repl_3 environment: - MONGO1=mongodb_repl - MONGO2=mongodb_repl_2 From 7741acbefde675224e0416eea25f717b59623212 Mon Sep 17 00:00:00 2001 From: klinson Date: Thu, 23 Jul 2020 14:47:49 +0800 Subject: [PATCH 28/87] optimize code --- src/Jenssegers/Mongodb/Query/Builder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Jenssegers/Mongodb/Query/Builder.php b/src/Jenssegers/Mongodb/Query/Builder.php index 5fd02f6f2..db7e6786e 100644 --- a/src/Jenssegers/Mongodb/Query/Builder.php +++ b/src/Jenssegers/Mongodb/Query/Builder.php @@ -1227,7 +1227,7 @@ public function options(array $options) */ protected function setSession($options) { - if ($session = $this->connection->getSession()) { + if (!isset($options['session']) && ($session = $this->connection->getSession())) { $options['session'] = $session; } return $options; From dafee61858c0c3e05e81784ef76fab987d8c5b9e Mon Sep 17 00:00:00 2001 From: klinson Date: Fri, 20 Nov 2020 17:49:29 +0800 Subject: [PATCH 29/87] remove testInsertWithId --- tests/TransactionTest.php | 40 --------------------------------------- 1 file changed, 40 deletions(-) diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 0cb95ddaf..597c6032d 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -100,46 +100,6 @@ public function testInsert() $this->assertEquals($check->title, $user->title); } - public function testInsertWithId(): void - { - $id = 1; - $check = User::on($this->connection)->find($id); - $this->assertNull($check); - - /** rollback test */ - DB::beginTransaction(); - $user = User::on($this->connection)->getModel(); - $user->_id = $id; - $user->name = $this->insertData['name']; - $user->title = $this->insertData['title']; - $user->age = $this->insertData['age']; - $user->save(); - DB::rollBack(); - - $this->assertTrue($user->exists); - $this->assertEquals($id, $user->_id); - $check = User::on($this->connection)->find($id); - $this->assertNull($check); - - /** commit test */ - DB::beginTransaction(); - $user = User::on($this->connection)->getModel(); - $user->_id = $id; - $user->name = $this->insertData['name']; - $user->title = $this->insertData['title']; - $user->age = $this->insertData['age']; - $user->save(); - DB::commit(); - - $this->assertTrue($user->exists); - $this->assertEquals($id, $user->_id); - $check = User::on($this->connection)->find($id); - $this->assertNotNull($check); - $this->assertEquals($check->name, $user->name); - $this->assertEquals($check->age, $user->age); - $this->assertEquals($check->title, $user->title); - } - public function testUpdate() { /** rollback test */ From 0fd27bac4a92aa6e329b148e6204aee540134bda Mon Sep 17 00:00:00 2001 From: klinson Date: Mon, 23 Nov 2020 10:07:33 +0800 Subject: [PATCH 30/87] update build-ci.yml --- .github/workflows/build-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 180ed7cde..7a49a35dd 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -42,7 +42,7 @@ jobs: steps: - uses: actions/checkout@v1 - name: Creating MongoDB replica - if: matrix.mongodb == '4.0' || matrix.mongodb == '4.2' + if: matrix.mongodb == '4.0' || matrix.mongodb == '4.2' || matrix.mongodb == '4.4' run: | docker run --name mongodb_repl -e MONGO_INITDB_DATABASE=unittest --publish 27018:27018 --detach mongo:${{ matrix.mongodb }} mongod --port 27018 --replSet rs until docker exec --tty mongodb_repl mongo 127.0.0.1:27018 --eval "db.serverStatus()"; do From 6e89c8b0dbfad661325a7eedd7575e4884771259 Mon Sep 17 00:00:00 2001 From: klinson Date: Mon, 23 Nov 2020 11:12:04 +0800 Subject: [PATCH 31/87] add return info to phpdoc --- src/Jenssegers/Mongodb/Connection.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Jenssegers/Mongodb/Connection.php b/src/Jenssegers/Mongodb/Connection.php index e9551935a..c3764e657 100644 --- a/src/Jenssegers/Mongodb/Connection.php +++ b/src/Jenssegers/Mongodb/Connection.php @@ -292,6 +292,7 @@ public function __call($method, $parameters) * To use transactions on MongoDB 4.2 deployments(replica sets and sharded clusters), clients must use MongoDB drivers updated for MongoDB 4.2. * * @see https://docs.mongodb.com/manual/core/transactions/ + * @return void */ public function beginTransaction() { @@ -307,6 +308,7 @@ public function beginTransaction() /** * commit transaction in this session and close this session + * @return void */ public function commit() { @@ -318,6 +320,7 @@ public function commit() /** * rollback transaction in this session and close this session + * @return void */ public function rollBack($toLevel = null) { @@ -330,6 +333,7 @@ public function rollBack($toLevel = null) /** * close this session and get last session key to session_key * Why do it ? Because nested transactions + * @return void */ protected function setLastSession() { From 5645fc7f202050a95d9c3a60acb340d781280907 Mon Sep 17 00:00:00 2001 From: klinson Date: Fri, 19 Feb 2021 17:37:19 +0800 Subject: [PATCH 32/87] format code --- src/Jenssegers/Mongodb/Connection.php | 8 ++++++++ src/Jenssegers/Mongodb/Query/Builder.php | 13 ++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/Jenssegers/Mongodb/Connection.php b/src/Jenssegers/Mongodb/Connection.php index c3764e657..641eb80c2 100644 --- a/src/Jenssegers/Mongodb/Connection.php +++ b/src/Jenssegers/Mongodb/Connection.php @@ -24,7 +24,15 @@ class Connection extends BaseConnection */ protected $connection; + /** + * A random unique id for identification of transaction. + * @var string + */ protected $session_key; + /** + * A list of transaction sessions. + * @var array + */ protected $sessions = []; /** diff --git a/src/Jenssegers/Mongodb/Query/Builder.php b/src/Jenssegers/Mongodb/Query/Builder.php index 0f83568f8..4e22620bd 100644 --- a/src/Jenssegers/Mongodb/Query/Builder.php +++ b/src/Jenssegers/Mongodb/Query/Builder.php @@ -728,9 +728,8 @@ public function from($collection, $as = null) */ public function truncate(): bool { - $options = []; - // if transaction in session - $options = $this->setSession($options); + // Check if transaction exist in session + $options = $this->setSession(); $result = $this->collection->deleteMany($options); @@ -860,7 +859,7 @@ protected function performUpdate($query, array $options = []) $options['multiple'] = true; } - // if transaction in session + // Check if transaction exist in session $options = $this->setSession($options); $wheres = $this->compileWheres(); @@ -1196,14 +1195,14 @@ public function options(array $options) } /** - * set session for the transaction + * Set session for the transaction * @param $session * @return mixed */ - protected function setSession($options) + protected function setSession($options = []) { if (!isset($options['session']) && ($session = $this->connection->getSession())) { - $options['session'] = $session; + $options['session'] = $session; } return $options; } From 9cd8bb2708d5de3acfaf4933aa035aeec8691135 Mon Sep 17 00:00:00 2001 From: klinson Date: Fri, 19 Feb 2021 17:37:34 +0800 Subject: [PATCH 33/87] update README.md --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index d5cb58b07..e48daa4c8 100644 --- a/README.md +++ b/README.md @@ -963,26 +963,26 @@ To see the available operations, check the [Eloquent](#eloquent) section. Transaction ------- -Transaction requires mongodb version V4.0 or more and deployment replica sets or sharded clusters.You can look at its speciality [in the MongoDB docs](https://docs.mongodb.com/manual/core/transactions/) +Transaction requires MongoDB version ^4.0 as well as deployment of replica set or sharded clusters. You can find more information [in the MongoDB docs](https://docs.mongodb.com/manual/core/transactions/) ### Basic Usage -Transaction supports create/insert,update,delete,etc operation. +Transaction supports CREATE/INSERT/UPDATE/DELETE operations. ```php DB::transaction(function () { - User::create(['name' => 'klinson', 'age' => 19, 'title' => 'admin', 'email' => 'klinsonup@gmail.com']); - DB::collection('users')->where('name', 'klinson')->update(['age' => 20]); - DB::collection('users')->where('name', 'klinson')->delete(); + User::create(['name' => 'john', 'age' => 19, 'title' => 'admin', 'email' => 'klinsonup@gmail.com']); + DB::collection('users')->where('name', 'john')->update(['age' => 20]); + DB::collection('users')->where('name', 'john')->delete(); }); ``` ```php // begin a transaction DB::beginTransaction(); -User::create(['name' => 'klinson', 'age' => 19, 'title' => 'admin', 'email' => 'klinsonup@gmail.com']); -DB::collection('users')->where('name', 'klinson')->update(['age' => 20]); -DB::collection('users')->where('name', 'klinson')->delete(); +User::create(['name' => 'john', 'age' => 19, 'title' => 'admin', 'email' => 'klinsonup@gmail.com']); +DB::collection('users')->where('name', 'john')->update(['age' => 20]); +DB::collection('users')->where('name', 'john')->delete(); // you can commit your changes DB::commit(); @@ -991,12 +991,12 @@ DB::commit(); //DB::rollBack(); ``` -Transaction supports infinite-level nested transactions, but outside transaction rollbacks do not affect the commit of inside transactions. +**NOTE:** Transaction supports infinite-level of nested transactions, but outside transaction rollbacks do not affect the commits of inside transactions. ```php DB::beginTransaction(); -User::create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); +User::create(['name' => 'john', 'age' => 20, 'title' => 'admin']); DB::transaction(function () { - DB::collection('users')->where('name', 'klinson')->update(['age' => 20]); + DB::collection('users')->where('name', 'john')->update(['age' => 20]); }); DB::rollBack(); ``` From 49307e217fba64f7d1b82408097aedc4bbeb4948 Mon Sep 17 00:00:00 2001 From: klinson Date: Sat, 27 Mar 2021 10:42:53 +0800 Subject: [PATCH 34/87] remove excess $option --- src/Jenssegers/Mongodb/Query/Builder.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Jenssegers/Mongodb/Query/Builder.php b/src/Jenssegers/Mongodb/Query/Builder.php index 4e22620bd..0f7cce2ce 100644 --- a/src/Jenssegers/Mongodb/Query/Builder.php +++ b/src/Jenssegers/Mongodb/Query/Builder.php @@ -572,10 +572,8 @@ public function insert(array $values) $values = [$values]; } - // Batch insert - $options = []; // if transaction in session - $options = $this->setSession($options); + $options = $this->setSession(); $result = $this->collection->insertMany($values, $options); @@ -587,9 +585,8 @@ public function insert(array $values) */ public function insertGetId(array $values, $sequence = null) { - $options = []; // if transaction in session - $options = $this->setSession($options); + $options = $this->setSession(); $result = $this->collection->insertOne($values, $options); @@ -699,9 +696,8 @@ public function delete($id = null) $wheres = $this->compileWheres(); - $options = []; // if transaction in session - $options = $this->setSession($options); + $options = $this->setSession(); $result = $this->collection->DeleteMany($wheres, $options); if (1 == (int) $result->isAcknowledged()) { From 59020fbe88100f2f0d42e61216b3447d5d212f9d Mon Sep 17 00:00:00 2001 From: klinson Date: Sat, 27 Mar 2021 12:54:10 +0800 Subject: [PATCH 35/87] divide testUpdate on two methods testUpdateWithRollback and testUpdateWithCommit --- tests/TransactionTest.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 597c6032d..b9ad78bf2 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -100,7 +100,7 @@ public function testInsert() $this->assertEquals($check->title, $user->title); } - public function testUpdate() + public function testUpdateWithRollback () { /** rollback test */ $new_age = $this->insertData['age'] + 1; @@ -108,7 +108,7 @@ public function testUpdate() $user2 = User::on($this->connection)->create($this->insertData); DB::beginTransaction(); $user1->age = $new_age; - $user1->save(); + $user1->update(); $user2->update(['age' => $new_age]); DB::rollBack(); $this->assertEquals($new_age, $user1->age); @@ -118,6 +118,11 @@ public function testUpdate() $check2 = User::on($this->connection)->find($user2->_id); $this->assertEquals($this->insertData['age'], $check1->age); $this->assertEquals($this->insertData['age'], $check2->age); + } + + public function testUpdateWithCommit() + { + $new_age = $this->insertData['age'] + 1; /** commit test */ User::on($this->connection)->truncate(); @@ -125,7 +130,7 @@ public function testUpdate() $user2 = User::on($this->connection)->create($this->insertData); DB::beginTransaction(); $user1->age = $new_age; - $user1->save(); + $user1->update(); $user2->update(['age' => $new_age]); DB::commit(); $this->assertEquals($new_age, $user1->age); From 97f9b4bf24b3dfc870934c37f6950ea1835136a5 Mon Sep 17 00:00:00 2001 From: klinson Date: Sat, 27 Mar 2021 13:01:48 +0800 Subject: [PATCH 36/87] update ci part --- .github/workflows/build-ci.yml | 126 +++++++++++++++++---------------- 1 file changed, 66 insertions(+), 60 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index fb4472ce7..12257f48d 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -14,19 +14,19 @@ jobs: strategy: matrix: include: - - { os: ubuntu-latest, php: 7.2, mongodb: 3.6, experimental: true} - - { os: ubuntu-latest, php: 7.2, mongodb: '4.0', experimental: true} - - { os: ubuntu-latest, php: 7.2, mongodb: 4.2, experimental: true} - - { os: ubuntu-latest, php: 7.2, mongodb: 4.4, experimental: true} - - { os: ubuntu-latest, php: 7.3, mongodb: 3.6, experimental: false} - - { os: ubuntu-latest, php: 7.3, mongodb: '4.0', experimental: false} - - { os: ubuntu-latest, php: 7.3, mongodb: 4.2, experimental: false} - - { os: ubuntu-latest, php: 7.3, mongodb: 4.4, experimental: false} - - { os: ubuntu-latest, php: 7.4, mongodb: 3.6, experimental: false} - - { os: ubuntu-latest, php: 7.4, mongodb: '4.0', experimental: false} - - { os: ubuntu-latest, php: 7.4, mongodb: 4.2, experimental: false} - - { os: ubuntu-latest, php: 7.4, mongodb: 4.4, experimental: false} - - { os: ubuntu-latest, php: 8.0, mongodb: 4.4, experimental: false} + - { os: ubuntu-latest, php: 7.2, mongodb: 3.6, experimental: true} + - { os: ubuntu-latest, php: 7.2, mongodb: '4.0', experimental: true} + - { os: ubuntu-latest, php: 7.2, mongodb: 4.2, experimental: true} + - { os: ubuntu-latest, php: 7.2, mongodb: 4.4, experimental: true} + - { os: ubuntu-latest, php: 7.3, mongodb: 3.6, experimental: false} + - { os: ubuntu-latest, php: 7.3, mongodb: '4.0', experimental: false} + - { os: ubuntu-latest, php: 7.3, mongodb: 4.2, experimental: false} + - { os: ubuntu-latest, php: 7.3, mongodb: 4.4, experimental: false} + - { os: ubuntu-latest, php: 7.4, mongodb: 3.6, experimental: false} + - { os: ubuntu-latest, php: 7.4, mongodb: '4.0', experimental: false} + - { os: ubuntu-latest, php: 7.4, mongodb: 4.2, experimental: false} + - { os: ubuntu-latest, php: 7.4, mongodb: 4.4, experimental: false} + - { os: ubuntu-latest, php: 8.0, mongodb: 4.4, experimental: false} services: mongo: image: mongo:${{ matrix.mongodb }} @@ -40,51 +40,57 @@ jobs: MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' MYSQL_DATABASE: 'unittest' MYSQL_ROOT_PASSWORD: + steps: - - uses: actions/checkout@v1 - - name: Creating MongoDB replica - if: matrix.mongodb == '4.0' || matrix.mongodb == '4.2' || matrix.mongodb == '4.4' - run: | - docker run --name mongodb_repl -e MONGO_INITDB_DATABASE=unittest --publish 27018:27018 --detach mongo:${{ matrix.mongodb }} mongod --port 27018 --replSet rs - until docker exec --tty mongodb_repl mongo 127.0.0.1:27018 --eval "db.serverStatus()"; do - sleep 1 - done - sudo docker exec --tty mongodb_repl mongo 127.0.0.1:27018 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"127.0.0.1:27018\" }]})" - env: - MONGO_HOST: 0.0.0.0 - MONGO_REPL_HOST: 0.0.0.0 - - name: Show PHP version - run: php${{ matrix.php }} -v && composer -V - - name: Show Docker version - run: if [[ "$DEBUG" == "true" ]]; then docker version && env; fi - env: - DEBUG: ${{secrets.DEBUG}} - - name: Download Composer cache dependencies from cache - if: (!startsWith(matrix.php, '7.2')) - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Cache Composer dependencies - if: (!startsWith(matrix.php, '7.2')) - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ matrix.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ matrix.os }}-composer- - - name: Install dependencies - if: (!startsWith(matrix.php, '7.2')) - run: | - composer install --no-interaction - - name: Run tests - if: (!startsWith(matrix.php, '7.2')) - run: | - ./vendor/bin/phpunit --coverage-clover coverage.xml - env: - MONGO_VERSION: ${{ matrix.mongodb }}) - MONGO_HOST: 0.0.0.0 - MONGO_REPL_HOST: 0.0.0.0 - MYSQL_HOST: 0.0.0.0 - MYSQL_PORT: 3307 - - uses: codecov/codecov-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: false + - uses: actions/checkout@v2 + - name: Creating MongoDB replica + if: matrix.mongodb == '4.0' || matrix.mongodb == '4.2' || matrix.mongodb == '4.4' + run: | + docker run --name mongodb_repl -e MONGO_INITDB_DATABASE=unittest --publish 27018:27018 --detach mongo:${{ matrix.mongodb }} mongod --port 27018 --replSet rs + until docker exec --tty mongodb_repl mongo 127.0.0.1:27018 --eval "db.serverStatus()"; do + sleep 1 + done + sudo docker exec --tty mongodb_repl mongo 127.0.0.1:27018 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"127.0.0.1:27018\" }]})" + env: + MONGO_HOST: 0.0.0.0 + MONGO_REPL_HOST: 0.0.0.0 + - name: "Installing php" + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: curl,mbstring,xdebug + coverage: xdebug + tools: composer + - name: Show PHP version + run: php -v && composer -V + - name: Show Docker version + run: if [[ "$DEBUG" == "true" ]]; then docker version && env; fi + env: + DEBUG: ${{secrets.DEBUG}} + - name: Download Composer cache dependencies from cache + if: (!startsWith(matrix.php, '7.2')) + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: Cache Composer dependencies + if: (!startsWith(matrix.php, '7.2')) + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ matrix.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ matrix.os }}-composer- + - name: Install dependencies + if: (!startsWith(matrix.php, '7.2')) + run: | + composer install --no-interaction + - name: Run tests + if: (!startsWith(matrix.php, '7.2')) + run: | + ./vendor/bin/phpunit --coverage-clover coverage.xml + env: + MONGO_HOST: 0.0.0.0 + MYSQL_HOST: 0.0.0.0 + MYSQL_PORT: 3307 + - uses: codecov/codecov-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: false From 9c90125860a085eaac6487a7bd65556a9bcf363a Mon Sep 17 00:00:00 2001 From: klinson Date: Sat, 27 Mar 2021 13:11:18 +0800 Subject: [PATCH 37/87] update ci part --- .github/workflows/build-ci.yml | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 12257f48d..a68c051ca 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -14,19 +14,19 @@ jobs: strategy: matrix: include: - - { os: ubuntu-latest, php: 7.2, mongodb: 3.6, experimental: true} - - { os: ubuntu-latest, php: 7.2, mongodb: '4.0', experimental: true} - - { os: ubuntu-latest, php: 7.2, mongodb: 4.2, experimental: true} - - { os: ubuntu-latest, php: 7.2, mongodb: 4.4, experimental: true} - - { os: ubuntu-latest, php: 7.3, mongodb: 3.6, experimental: false} - - { os: ubuntu-latest, php: 7.3, mongodb: '4.0', experimental: false} - - { os: ubuntu-latest, php: 7.3, mongodb: 4.2, experimental: false} - - { os: ubuntu-latest, php: 7.3, mongodb: 4.4, experimental: false} - - { os: ubuntu-latest, php: 7.4, mongodb: 3.6, experimental: false} - - { os: ubuntu-latest, php: 7.4, mongodb: '4.0', experimental: false} - - { os: ubuntu-latest, php: 7.4, mongodb: 4.2, experimental: false} - - { os: ubuntu-latest, php: 7.4, mongodb: 4.4, experimental: false} - - { os: ubuntu-latest, php: 8.0, mongodb: 4.4, experimental: false} + - { os: ubuntu-latest, php: 7.2, mongodb: 3.6, experimental: true} + - { os: ubuntu-latest, php: 7.2, mongodb: '4.0', experimental: true} + - { os: ubuntu-latest, php: 7.2, mongodb: 4.2, experimental: true} + - { os: ubuntu-latest, php: 7.2, mongodb: 4.4, experimental: true} + - { os: ubuntu-latest, php: 7.3, mongodb: 3.6, experimental: false} + - { os: ubuntu-latest, php: 7.3, mongodb: '4.0', experimental: false} + - { os: ubuntu-latest, php: 7.3, mongodb: 4.2, experimental: false} + - { os: ubuntu-latest, php: 7.3, mongodb: 4.4, experimental: false} + - { os: ubuntu-latest, php: 7.4, mongodb: 3.6, experimental: false} + - { os: ubuntu-latest, php: 7.4, mongodb: '4.0', experimental: false} + - { os: ubuntu-latest, php: 7.4, mongodb: 4.2, experimental: false} + - { os: ubuntu-latest, php: 7.4, mongodb: 4.4, experimental: false} + - { os: ubuntu-latest, php: 8.0, mongodb: 4.4, experimental: false} services: mongo: image: mongo:${{ matrix.mongodb }} @@ -87,7 +87,9 @@ jobs: run: | ./vendor/bin/phpunit --coverage-clover coverage.xml env: + MONGO_VERSION: ${{ matrix.mongodb }}) MONGO_HOST: 0.0.0.0 + MONGO_REPL_HOST: 0.0.0.0 MYSQL_HOST: 0.0.0.0 MYSQL_PORT: 3307 - uses: codecov/codecov-action@v1 From 8ff2eec0904f413e169515cb117a926fd0874e22 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Fri, 7 Oct 2022 20:41:44 +0400 Subject: [PATCH 38/87] Add WithTransaction function --- composer.json | 3 +- .../Mongodb/Concerns/TransactionManager.php | 50 ++++++++++++++++++ src/Jenssegers/Mongodb/Connection.php | 26 ++++++---- tests/TransactionTest.php | 51 +++++++++++++++++-- 4 files changed, 114 insertions(+), 16 deletions(-) create mode 100644 src/Jenssegers/Mongodb/Concerns/TransactionManager.php diff --git a/composer.json b/composer.json index 35f7d26d8..dde4b01a8 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,8 @@ "illuminate/container": "^8.0", "illuminate/database": "^8.0", "illuminate/events": "^8.0", - "mongodb/mongodb": "^1.6" + "mongodb/mongodb": "^1.6", + "ext-mongodb": "*" }, "require-dev": { "phpunit/phpunit": "^9.0", diff --git a/src/Jenssegers/Mongodb/Concerns/TransactionManager.php b/src/Jenssegers/Mongodb/Concerns/TransactionManager.php new file mode 100644 index 000000000..12f88c0b9 --- /dev/null +++ b/src/Jenssegers/Mongodb/Concerns/TransactionManager.php @@ -0,0 +1,50 @@ +connection->startSession(); + $attemptsLeft = $attempts; + $callbackResult = null; + + try { + $callbackFunction = function(Session $session) use ($callback, &$attemptsLeft, &$callbackResult) { + $attemptsLeft--; + + if ($attemptsLeft < 0) { + $session->abortTransaction(); + return; + } + + $callbackResult = $callback(); + }; + + with_transaction($session, $callbackFunction, $options); + + return $callbackResult; + } catch (Exception $exception) { + throw new $exception; + } + } +} diff --git a/src/Jenssegers/Mongodb/Connection.php b/src/Jenssegers/Mongodb/Connection.php index 641eb80c2..bc756affd 100644 --- a/src/Jenssegers/Mongodb/Connection.php +++ b/src/Jenssegers/Mongodb/Connection.php @@ -5,22 +5,27 @@ use Illuminate\Database\Connection as BaseConnection; use Illuminate\Support\Arr; use InvalidArgumentException; +use Jenssegers\Mongodb\Concerns\TransactionManager; use MongoDB\Client; +use MongoDB\Database; use MongoDB\Driver\ReadConcern; use MongoDB\Driver\ReadPreference; +use MongoDB\Driver\Session; use MongoDB\Driver\WriteConcern; class Connection extends BaseConnection { + use TransactionManager; + /** * The MongoDB database handler. - * @var \MongoDB\Database + * @var Database */ protected $db; /** * The MongoDB connection handler. - * @var \MongoDB\Client + * @var Client */ protected $connection; @@ -29,6 +34,7 @@ class Connection extends BaseConnection * @var string */ protected $session_key; + /** * A list of transaction sessions. * @var array @@ -93,7 +99,7 @@ public function table($table, $as = null) * @param string $name * @return Collection */ - public function getCollection($name) + public function getCollection(string $name) { return new Collection($this, $this->db->selectCollection($name)); } @@ -108,7 +114,7 @@ public function getSchemaBuilder() /** * Get the MongoDB database object. - * @return \MongoDB\Database + * @return Database */ public function getMongoDB() { @@ -117,9 +123,9 @@ public function getMongoDB() /** * return MongoDB object. - * @return \MongoDB\Client + * @return Client */ - public function getMongoClient() + public function getMongoClient(): Client { return $this->connection; } @@ -127,7 +133,7 @@ public function getMongoClient() /** * {@inheritdoc} */ - public function getDatabaseName() + public function getDatabaseName(): string { return $this->getMongoDB()->getDatabaseName(); } @@ -157,7 +163,7 @@ protected function getDefaultDatabaseName($dsn, $config) * @param string $dsn * @param array $config * @param array $options - * @return \MongoDB\Client + * @return Client */ protected function createConnection($dsn, array $config, array $options) { @@ -359,9 +365,9 @@ protected function setLastSession() /** * get now session if it has session - * @return \MongoDB\Driver\Session|null + * @return Session|null */ - public function getSession() + public function getSession(): ?Session { return $this->sessions[$this->session_key] ?? null; } diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index b9ad78bf2..8847844e2 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -162,15 +162,17 @@ public function testDelete() $this->assertNull($check1); } - public function testTransaction() + public function testTransaction(): void { $count = User::on($this->connection)->count(); $this->assertEquals(1, $count); - $new_age = $this->originData['age'] + 1; - DB::transaction(function () use ($new_age) { + $newAge = $this->originData['age'] + 1; + + DB::transaction(function () use ($newAge) { User::on($this->connection)->create($this->insertData); - User::on($this->connection)->where($this->originData['name'])->update(['age' => $new_age]); + User::on($this->connection)->where($this->originData['name'])->update(['age' => $newAge]); }); + $count = User::on($this->connection)->count(); $this->assertEquals(2, $count); @@ -178,6 +180,45 @@ public function testTransaction() $this->assertNotNull($checkInsert); $checkUpdate = User::on($this->connection)->where($this->originData['name'])->first(); - $this->assertEquals($new_age, $checkUpdate->age); + $this->assertEquals($newAge, $checkUpdate->age); + } + + public function testIsTransactionSuccessfullyAbortedWhenAttemptsEnd(): void + { + $oldUsersCount = User::on($this->connection)->count(); + + $result = DB::transaction(function () { + User::on($this->connection)->create($this->insertData); + User::on($this->connection)->create($this->insertData); + }, 0); + + $newUsersCount = User::on($this->connection)->count(); + + $this->assertNull($result); + $this->assertEquals($newUsersCount, $oldUsersCount); + } + + public function testIsDataInTransactionReturnedWhenTransactionWasSuccess(): void + { + $oldUsersCount = User::on($this->connection)->count(); + + $result = DB::transaction(function () { + return User::on($this->connection)->create($this->insertData); + }); + + $newUsersCount = User::on($this->connection)->count(); + + $this->assertNotNull($result); + $this->assertEquals($result->title, $this->insertData['title']); + $this->assertNotEquals($newUsersCount, $oldUsersCount); + } + + public function testTransactionReturnsException(): void + { + $this->expectException(Exception::class); + + DB::transaction(function () { + throw new Exception('dsdssd'); + }); } } From a174832b5a233b77cbdef7d8eb81081d99dc5516 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Fri, 7 Oct 2022 20:49:44 +0400 Subject: [PATCH 39/87] remove unnecessary error handleing --- .../Mongodb/Concerns/TransactionManager.php | 24 ++++++++----------- tests/TransactionTest.php | 9 ------- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/src/Jenssegers/Mongodb/Concerns/TransactionManager.php b/src/Jenssegers/Mongodb/Concerns/TransactionManager.php index 12f88c0b9..ad9e16fa2 100644 --- a/src/Jenssegers/Mongodb/Concerns/TransactionManager.php +++ b/src/Jenssegers/Mongodb/Concerns/TransactionManager.php @@ -28,23 +28,19 @@ public function transaction(Closure $callback, $attempts = 1, array $options = [ $attemptsLeft = $attempts; $callbackResult = null; - try { - $callbackFunction = function(Session $session) use ($callback, &$attemptsLeft, &$callbackResult) { - $attemptsLeft--; + $callbackFunction = function(Session $session) use ($callback, &$attemptsLeft, &$callbackResult) { + $attemptsLeft--; - if ($attemptsLeft < 0) { - $session->abortTransaction(); - return; - } + if ($attemptsLeft < 0) { + $session->abortTransaction(); + return; + } - $callbackResult = $callback(); - }; + $callbackResult = $callback(); + }; - with_transaction($session, $callbackFunction, $options); + with_transaction($session, $callbackFunction, $options); - return $callbackResult; - } catch (Exception $exception) { - throw new $exception; - } + return $callbackResult; } } diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 8847844e2..034cf481d 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -212,13 +212,4 @@ public function testIsDataInTransactionReturnedWhenTransactionWasSuccess(): void $this->assertEquals($result->title, $this->insertData['title']); $this->assertNotEquals($newUsersCount, $oldUsersCount); } - - public function testTransactionReturnsException(): void - { - $this->expectException(Exception::class); - - DB::transaction(function () { - throw new Exception('dsdssd'); - }); - } } From a58919e704b8be574d82b739afecd77ccea8ffee Mon Sep 17 00:00:00 2001 From: levon80999 Date: Mon, 10 Oct 2022 15:47:08 +0400 Subject: [PATCH 40/87] Restrict user to create nested transactions --- src/Jenssegers/Mongodb/Connection.php | 22 ++++++++++------------ tests/TransactionTest.php | 17 ++++++++++++++--- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/Jenssegers/Mongodb/Connection.php b/src/Jenssegers/Mongodb/Connection.php index bc756affd..45f02363d 100644 --- a/src/Jenssegers/Mongodb/Connection.php +++ b/src/Jenssegers/Mongodb/Connection.php @@ -8,10 +8,7 @@ use Jenssegers\Mongodb\Concerns\TransactionManager; use MongoDB\Client; use MongoDB\Database; -use MongoDB\Driver\ReadConcern; -use MongoDB\Driver\ReadPreference; use MongoDB\Driver\Session; -use MongoDB\Driver\WriteConcern; class Connection extends BaseConnection { @@ -308,16 +305,17 @@ public function __call($method, $parameters) * @see https://docs.mongodb.com/manual/core/transactions/ * @return void */ - public function beginTransaction() + public function beginTransaction(?array $options = []) { - $this->session_key = uniqid(); - $this->sessions[$this->session_key] = $this->connection->startSession(); - - $this->sessions[$this->session_key]->startTransaction([ - 'readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY), - 'writeConcern' => new WriteConcern(1), - 'readConcern' => new ReadConcern(ReadConcern::LOCAL) - ]); + $session = $this->getSession(); + + if (!$session) { + $this->session_key = uniqid(); + $session = $this->connection->startSession(); + $this->sessions[$this->session_key] = $session; + } + + $session->startTransaction($options); } /** diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 034cf481d..98d980d72 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -5,9 +5,9 @@ class TransactionTest extends TestCase { - protected $insertData = ['name' => 'klinson', 'age' => 20, 'title' => 'admin']; - protected $originData = ['name' => 'users', 'age' => 20, 'title' => 'user']; - protected $connection = 'mongodb_repl'; + protected array $insertData = ['name' => 'klinson', 'age' => 20, 'title' => 'admin']; + protected array $originData = ['name' => 'users', 'age' => 20, 'title' => 'user']; + protected string $connection = 'dsn_mongodb'; public function setUp(): void { @@ -212,4 +212,15 @@ public function testIsDataInTransactionReturnedWhenTransactionWasSuccess(): void $this->assertEquals($result->title, $this->insertData['title']); $this->assertNotEquals($newUsersCount, $oldUsersCount); } + + public function testThrowExceptionForNestedTransactions(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionCode(53 /* InvalidIdField */); + + DB::beginTransaction(); + DB::beginTransaction(); + DB::commit(); + DB::rollBack(); + } } From 25e9d9247175e0c22bda23afd4617811d75ac186 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Mon, 10 Oct 2022 15:53:21 +0400 Subject: [PATCH 41/87] Move transaction related functions to TransactionManager trait --- .../Mongodb/Concerns/TransactionManager.php | 75 ++++++++++++++ src/Jenssegers/Mongodb/Connection.php | 97 +++---------------- tests/TransactionTest.php | 2 +- 3 files changed, 87 insertions(+), 87 deletions(-) diff --git a/src/Jenssegers/Mongodb/Concerns/TransactionManager.php b/src/Jenssegers/Mongodb/Concerns/TransactionManager.php index ad9e16fa2..0d09590c9 100644 --- a/src/Jenssegers/Mongodb/Concerns/TransactionManager.php +++ b/src/Jenssegers/Mongodb/Concerns/TransactionManager.php @@ -10,6 +10,81 @@ trait TransactionManager { + /** + * create a session and start a transaction in session + * + * In version 4.0, MongoDB supports multi-document transactions on replica sets. + * In version 4.2, MongoDB introduces distributed transactions, which adds support for multi-document transactions on sharded clusters and incorporates the existing support for multi-document transactions on replica sets. + * To use transactions on MongoDB 4.2 deployments(replica sets and sharded clusters), clients must use MongoDB drivers updated for MongoDB 4.2. + * + * @see https://docs.mongodb.com/manual/core/transactions/ + * @return void + */ + public function beginTransaction(?array $options = []) + { + $session = $this->getSession(); + + if (!$session) { + $this->session_key = uniqid(); + $session = $this->connection->startSession(); + $this->sessions[$this->session_key] = $session; + } + + $session->startTransaction($options); + } + + /** + * commit transaction in this session and close this session + * @return void + */ + public function commit() + { + if ($session = $this->getSession()) { + $session->commitTransaction(); + $this->setLastSession(); + } + } + + /** + * rollback transaction in this session and close this session + * @return void + */ + public function rollBack($toLevel = null) + { + if ($session = $this->getSession()) { + $session->abortTransaction(); + $this->setLastSession(); + } + } + + /** + * close this session and get last session key to session_key + * Why do it ? Because nested transactions + * @return void + */ + protected function setLastSession() + { + if ($session = $this->getSession()) { + $session->endSession(); + unset($this->sessions[$this->session_key]); + if (empty($this->sessions)) { + $this->session_key = null; + } else { + end($this->sessions); + $this->session_key = key($this->sessions); + } + } + } + + /** + * get now session if it has session + * @return Session|null + */ + public function getSession(): ?Session + { + return $this->sessions[$this->session_key] ?? null; + } + /** * Static transaction function realize the with_transaction functionality provided by MongoDB. * diff --git a/src/Jenssegers/Mongodb/Connection.php b/src/Jenssegers/Mongodb/Connection.php index 45f02363d..175f669a8 100644 --- a/src/Jenssegers/Mongodb/Connection.php +++ b/src/Jenssegers/Mongodb/Connection.php @@ -68,6 +68,17 @@ public function __construct(array $config) $this->useDefaultQueryGrammar(); } + /** + * Dynamically pass methods to the connection. + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + return call_user_func_array([$this->db, $method], $parameters); + } + /** * Begin a fluent query against a database collection. * @param string $collection @@ -283,90 +294,4 @@ protected function getDefaultSchemaGrammar() { return new Schema\Grammar(); } - - /** - * Dynamically pass methods to the connection. - * @param string $method - * @param array $parameters - * @return mixed - */ - public function __call($method, $parameters) - { - return call_user_func_array([$this->db, $method], $parameters); - } - - /** - * create a session and start a transaction in session - * - * In version 4.0, MongoDB supports multi-document transactions on replica sets. - * In version 4.2, MongoDB introduces distributed transactions, which adds support for multi-document transactions on sharded clusters and incorporates the existing support for multi-document transactions on replica sets. - * To use transactions on MongoDB 4.2 deployments(replica sets and sharded clusters), clients must use MongoDB drivers updated for MongoDB 4.2. - * - * @see https://docs.mongodb.com/manual/core/transactions/ - * @return void - */ - public function beginTransaction(?array $options = []) - { - $session = $this->getSession(); - - if (!$session) { - $this->session_key = uniqid(); - $session = $this->connection->startSession(); - $this->sessions[$this->session_key] = $session; - } - - $session->startTransaction($options); - } - - /** - * commit transaction in this session and close this session - * @return void - */ - public function commit() - { - if ($session = $this->getSession()) { - $session->commitTransaction(); - $this->setLastSession(); - } - } - - /** - * rollback transaction in this session and close this session - * @return void - */ - public function rollBack($toLevel = null) - { - if ($session = $this->getSession()) { - $session->abortTransaction(); - $this->setLastSession(); - } - } - - /** - * close this session and get last session key to session_key - * Why do it ? Because nested transactions - * @return void - */ - protected function setLastSession() - { - if ($session = $this->getSession()) { - $session->endSession(); - unset($this->sessions[$this->session_key]); - if (empty($this->sessions)) { - $this->session_key = null; - } else { - end($this->sessions); - $this->session_key = key($this->sessions); - } - } - } - - /** - * get now session if it has session - * @return Session|null - */ - public function getSession(): ?Session - { - return $this->sessions[$this->session_key] ?? null; - } } diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 98d980d72..72da149a7 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -7,7 +7,7 @@ class TransactionTest extends TestCase { protected array $insertData = ['name' => 'klinson', 'age' => 20, 'title' => 'admin']; protected array $originData = ['name' => 'users', 'age' => 20, 'title' => 'user']; - protected string $connection = 'dsn_mongodb'; + protected string $connection = 'mongodb_repl'; public function setUp(): void { From a3b1d822aa0e9f1eb2f964a0c3d8653b705da265 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Tue, 11 Oct 2022 16:16:34 +0400 Subject: [PATCH 42/87] fix PR comments --- .../Mongodb/Concerns/TransactionManager.php | 28 ++----------------- src/Jenssegers/Mongodb/Connection.php | 18 ++++-------- tests/TransactionTest.php | 6 ++-- 3 files changed, 12 insertions(+), 40 deletions(-) diff --git a/src/Jenssegers/Mongodb/Concerns/TransactionManager.php b/src/Jenssegers/Mongodb/Concerns/TransactionManager.php index 0d09590c9..7e308b5c3 100644 --- a/src/Jenssegers/Mongodb/Concerns/TransactionManager.php +++ b/src/Jenssegers/Mongodb/Concerns/TransactionManager.php @@ -20,14 +20,13 @@ trait TransactionManager * @see https://docs.mongodb.com/manual/core/transactions/ * @return void */ - public function beginTransaction(?array $options = []) + public function beginTransaction(array $options = []) { $session = $this->getSession(); if (!$session) { - $this->session_key = uniqid(); $session = $this->connection->startSession(); - $this->sessions[$this->session_key] = $session; + $this->session = $session; } $session->startTransaction($options); @@ -41,7 +40,6 @@ public function commit() { if ($session = $this->getSession()) { $session->commitTransaction(); - $this->setLastSession(); } } @@ -53,26 +51,6 @@ public function rollBack($toLevel = null) { if ($session = $this->getSession()) { $session->abortTransaction(); - $this->setLastSession(); - } - } - - /** - * close this session and get last session key to session_key - * Why do it ? Because nested transactions - * @return void - */ - protected function setLastSession() - { - if ($session = $this->getSession()) { - $session->endSession(); - unset($this->sessions[$this->session_key]); - if (empty($this->sessions)) { - $this->session_key = null; - } else { - end($this->sessions); - $this->session_key = key($this->sessions); - } } } @@ -82,7 +60,7 @@ protected function setLastSession() */ public function getSession(): ?Session { - return $this->sessions[$this->session_key] ?? null; + return $this->session ?? null; } /** diff --git a/src/Jenssegers/Mongodb/Connection.php b/src/Jenssegers/Mongodb/Connection.php index 175f669a8..e17a3126d 100644 --- a/src/Jenssegers/Mongodb/Connection.php +++ b/src/Jenssegers/Mongodb/Connection.php @@ -27,16 +27,10 @@ class Connection extends BaseConnection protected $connection; /** - * A random unique id for identification of transaction. - * @var string + * A list of transaction session. + * @var Session */ - protected $session_key; - - /** - * A list of transaction sessions. - * @var array - */ - protected $sessions = []; + protected $session; /** * Create a new database connection instance. @@ -107,7 +101,7 @@ public function table($table, $as = null) * @param string $name * @return Collection */ - public function getCollection(string $name) + public function getCollection($name) { return new Collection($this, $this->db->selectCollection($name)); } @@ -133,7 +127,7 @@ public function getMongoDB() * return MongoDB object. * @return Client */ - public function getMongoClient(): Client + public function getMongoClient() { return $this->connection; } @@ -141,7 +135,7 @@ public function getMongoClient(): Client /** * {@inheritdoc} */ - public function getDatabaseName(): string + public function getDatabaseName() { return $this->getMongoDB()->getDatabaseName(); } diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 72da149a7..5c195aa13 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -5,9 +5,9 @@ class TransactionTest extends TestCase { - protected array $insertData = ['name' => 'klinson', 'age' => 20, 'title' => 'admin']; - protected array $originData = ['name' => 'users', 'age' => 20, 'title' => 'user']; - protected string $connection = 'mongodb_repl'; + protected $insertData = ['name' => 'klinson', 'age' => 20, 'title' => 'admin']; + protected $originData = ['name' => 'users', 'age' => 20, 'title' => 'user']; + protected $connection = 'mongodb_repl'; public function setUp(): void { From 180bdf3a94bc86f1bc494347f987fb3575e936fa Mon Sep 17 00:00:00 2001 From: levon80999 Date: Tue, 11 Oct 2022 19:51:14 +0400 Subject: [PATCH 43/87] Change function description --- src/Concerns/TransactionManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Concerns/TransactionManager.php b/src/Concerns/TransactionManager.php index 7e308b5c3..bc0596d6b 100644 --- a/src/Concerns/TransactionManager.php +++ b/src/Concerns/TransactionManager.php @@ -11,7 +11,7 @@ trait TransactionManager { /** - * create a session and start a transaction in session + * Use the existing or create new session and start a transaction in session * * In version 4.0, MongoDB supports multi-document transactions on replica sets. * In version 4.2, MongoDB introduces distributed transactions, which adds support for multi-document transactions on sharded clusters and incorporates the existing support for multi-document transactions on replica sets. From 2a9e2d57babca714eaa89f4b08cfbed9b35fc955 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Mon, 17 Oct 2022 16:09:31 +0400 Subject: [PATCH 44/87] Fix comments --- .github/workflows/build-ci.yml | 9 +- README.md | 13 +- docker-compose.yml | 52 +--- src/Concerns/TransactionManager.php | 59 +++-- src/Connection.php | 40 +-- src/Query/Builder.php | 41 +-- tests/TransactionBuilderTest.php | 220 ---------------- tests/TransactionTest.php | 381 ++++++++++++++++++++-------- tests/config/database.php | 4 + 9 files changed, 366 insertions(+), 453 deletions(-) delete mode 100644 tests/TransactionBuilderTest.php diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 5000a49a5..062b82eaa 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -43,6 +43,7 @@ jobs: - { os: ubuntu-latest, php: 8.1, mongodb: 4.2, experimental: false } - { os: ubuntu-latest, php: 8.1, mongodb: 4.4, experimental: false } - { os: ubuntu-latest, php: 8.1, mongodb: '5.0', experimental: false } + - { os: ubuntu-latest, php: 8.1, mongodb: '6.0', experimental: false } services: mongo: image: mongo:${{ matrix.mongodb }} @@ -61,14 +62,13 @@ jobs: - uses: actions/checkout@v2 - name: Creating MongoDB replica run: | - docker run --name mongodb_repl -e MONGO_INITDB_DATABASE=unittest --publish 27018:27018 --detach mongo:${{ matrix.mongodb }} mongod --port 27018 --replSet rs - until docker exec --tty mongodb_repl mongo 127.0.0.1:27018 --eval "db.serverStatus()"; do + docker run --name mongodb -e MONGO_INITDB_DATABASE=unittest --detach mongo:${{ matrix.mongodb }} mongod --replSet rs + until docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "db.serverStatus()"; do sleep 1 done - sudo docker exec --tty mongodb_repl mongo 127.0.0.1:27018 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"127.0.0.1:27018\" }]})" + sudo docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"127.0.0.1:27017\" }]})" env: MONGO_HOST: 0.0.0.0 - MONGO_REPL_HOST: 0.0.0.0 - name: "Installing php" uses: shivammathur/setup-php@v2 with: @@ -100,7 +100,6 @@ jobs: env: MONGO_VERSION: ${{ matrix.mongodb }}) MONGO_HOST: 0.0.0.0 - MONGO_REPL_HOST: 0.0.0.0 MYSQL_HOST: 0.0.0.0 MYSQL_PORT: 3307 - uses: codecov/codecov-action@v1 diff --git a/README.md b/README.md index 73cb0212a..b45df1905 100644 --- a/README.md +++ b/README.md @@ -986,7 +986,7 @@ Transaction requires MongoDB version ^4.0 as well as deployment of replica set o ### Basic Usage -Transaction supports CREATE/INSERT/UPDATE/DELETE operations. +Transaction supports all operations. ```php DB::transaction(function () { @@ -1009,14 +1009,13 @@ DB::commit(); // you can also rollback them //DB::rollBack(); ``` - -**NOTE:** Transaction supports infinite-level of nested transactions, but outside transaction rollbacks do not affect the commits of inside transactions. +**NOTE:** Transaction does not support nested transactions. DB::beginTransaction() function will start new transactions in a new created or existing session and will raise the RuntimeException when transactions already exist. See more in MongoDB official docs [Transactions and Sessions](https://www.mongodb.com/docs/manual/core/transactions/#transactions-and-sessions) ```php DB::beginTransaction(); -User::create(['name' => 'john', 'age' => 20, 'title' => 'admin']); -DB::transaction(function () { - DB::collection('users')->where('name', 'john')->update(['age' => 20]); -}); + User::create(['name' => 'john', 'age' => 20, 'title' => 'admin']); + DB::beginTransaction() + DB::collection('users')->where('name', 'john')->update(['age' => 20]); + DB::commit() DB::rollBack(); ``` diff --git a/docker-compose.yml b/docker-compose.yml index 8f38d705d..5aca36a5d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,9 +11,6 @@ services: working_dir: /code depends_on: - mongodb - - mongodb_repl - - mongodb_repl_2 - - mongodb_repl_3 - mongo_repl_init - mysql stdin_open: true @@ -33,57 +30,18 @@ services: mongodb: container_name: mongodb - image: mongo + image: mongo:6.0 ports: - - 27017:27017 - logging: - driver: none - - mongodb_repl: - container_name: mongodb_repl - image: mongo:4.2.5 - restart: always - ports: - - "27018:27018" - entrypoint: [ "/usr/bin/mongod", "--quiet", "--bind_ip_all", "--port", "27018", "--replSet", "rs" ] - depends_on: - - mongodb_repl_2 - - mongodb_repl_3 - logging: - driver: none - - mongodb_repl_2: - container_name: mongodb_repl_2 - image: mongo:4.2.5 - restart: always - ports: - - "27019:27018" - entrypoint: [ "/usr/bin/mongod", "--quiet", "--bind_ip_all", "--port", "27018", "--replSet", "rs" ] - depends_on: - - mongodb_repl_3 - logging: - driver: none - - mongodb_repl_3: - container_name: mongodb_repl_3 - image: mongo:4.2.5 - restart: always - ports: - - "27020:27018" - entrypoint: [ "/usr/bin/mongod", "--quiet", "--bind_ip_all", "--port", "27018", "--replSet", "rs" ] + - "27017:27017" + entrypoint: [ "/usr/bin/mongod", "--quiet", "--bind_ip_all", "--replSet", "rs" ] logging: driver: none mongo_repl_init: - image: mongo:4.2.5 + image: mongo:6.0 depends_on: - - mongodb_repl - - mongodb_repl_2 - - mongodb_repl_3 + - mongodb environment: - - MONGO1=mongodb_repl - - MONGO2=mongodb_repl_2 - - MONGO3=mongodb_repl_3 - RS=rs volumes: - ./:/scripts diff --git a/src/Concerns/TransactionManager.php b/src/Concerns/TransactionManager.php index bc0596d6b..77e977b2f 100644 --- a/src/Concerns/TransactionManager.php +++ b/src/Concerns/TransactionManager.php @@ -3,28 +3,41 @@ namespace Jenssegers\Mongodb\Concerns; use Closure; -use Exception; use MongoDB\Driver\Session; use function MongoDB\with_transaction; trait TransactionManager { + /** + * A list of transaction session. + * @var Session|null + */ + protected ?Session $session; + + /** + * Get the existing session or null. + */ + public function getSession(): ?Session + { + return $this->session ?? null; + } + /** * Use the existing or create new session and start a transaction in session * * In version 4.0, MongoDB supports multi-document transactions on replica sets. * In version 4.2, MongoDB introduces distributed transactions, which adds support for multi-document transactions on sharded clusters and incorporates the existing support for multi-document transactions on replica sets. - * To use transactions on MongoDB 4.2 deployments(replica sets and sharded clusters), clients must use MongoDB drivers updated for MongoDB 4.2. * * @see https://docs.mongodb.com/manual/core/transactions/ + * @param array $options * @return void */ - public function beginTransaction(array $options = []) + public function beginTransaction(array $options = []): void { $session = $this->getSession(); - if (!$session) { + if ($session === null) { $session = $this->connection->startSession(); $this->session = $session; } @@ -36,50 +49,42 @@ public function beginTransaction(array $options = []) * commit transaction in this session and close this session * @return void */ - public function commit() + public function commit(): void { - if ($session = $this->getSession()) { - $session->commitTransaction(); - } + $session = $this->getSession(); + + $session?->commitTransaction(); } /** * rollback transaction in this session and close this session + * @param null $toLevel * @return void */ - public function rollBack($toLevel = null) + public function rollBack($toLevel = null): void { - if ($session = $this->getSession()) { - $session->abortTransaction(); - } - } + $session = $this->getSession(); - /** - * get now session if it has session - * @return Session|null - */ - public function getSession(): ?Session - { - return $this->session ?? null; + $session?->abortTransaction(); } /** * Static transaction function realize the with_transaction functionality provided by MongoDB. * - * @see https://www.mongodb.com/docs/manual/core/transactions/ - * * @param Closure $callback * @param int $attempts * @param array $options - * - * @return Exception|mixed|null - * @throws Exception */ - public function transaction(Closure $callback, $attempts = 1, array $options = []) + public function transaction(Closure $callback, $attempts = 1, array $options = []): mixed { - $session = $this->connection->startSession(); $attemptsLeft = $attempts; $callbackResult = null; + $session = $this->getSession(); + + if ($session === null) { + $session = $this->connection->startSession(); + $this->session = $session; + } $callbackFunction = function(Session $session) use ($callback, &$attemptsLeft, &$callbackResult) { $attemptsLeft--; diff --git a/src/Connection.php b/src/Connection.php index d1c0bd9f5..132cf9ff0 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -8,7 +8,6 @@ use Jenssegers\Mongodb\Concerns\TransactionManager; use MongoDB\Client; use MongoDB\Database; -use MongoDB\Driver\Session; class Connection extends BaseConnection { @@ -28,12 +27,6 @@ class Connection extends BaseConnection */ protected $connection; - /** - * A list of transaction session. - * @var Session - */ - protected $session; - /** * Create a new database connection instance. * @@ -65,17 +58,6 @@ public function __construct(array $config) $this->useDefaultQueryGrammar(); } - /** - * Dynamically pass methods to the connection. - * @param string $method - * @param array $parameters - * @return mixed - */ - public function __call($method, $parameters) - { - return call_user_func_array([$this->db, $method], $parameters); - } - /** * Begin a fluent query against a database collection. * @@ -303,4 +285,26 @@ protected function getDefaultSchemaGrammar() { return new Schema\Grammar(); } + + /** + * Set database. + * + * @param \MongoDB\Database $db + */ + public function setDatabase(\MongoDB\Database $db) + { + $this->db = $db; + } + + /** + * Dynamically pass methods to the connection. + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call(string $method, $parameters) + { + return $this->db->$method(...$parameters); +// return call_user_func_array([$this->db, $method], $parameters); + } } diff --git a/src/Query/Builder.php b/src/Query/Builder.php index fe5a742ec..61b06ab3d 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -345,8 +345,7 @@ public function getFresh($columns = [], $returnLazy = false) $options = array_merge($options, $this->options); } - // if transaction in session - $options = $this->setSession($options); + $options = $this->inheritConnectionOptions($options); // Execute aggregation $results = iterator_to_array($this->collection->aggregate($pipeline, $options)); @@ -358,9 +357,7 @@ public function getFresh($columns = [], $returnLazy = false) // Return distinct results directly $column = isset($this->columns[0]) ? $this->columns[0] : '_id'; - $options = []; - // if transaction in session - $options = $this->setSession($options); + $options = $this->inheritConnectionOptions(); // Execute distinct $result = $this->collection->distinct($column, $wheres ?: [], $options); @@ -409,8 +406,7 @@ public function getFresh($columns = [], $returnLazy = false) $options = array_merge($options, $this->options); } - // if transaction in session - $options = $this->setSession($options); + $options = $this->inheritConnectionOptions($options); // Execute query and get MongoCursor $cursor = $this->collection->find($wheres, $options); @@ -586,8 +582,7 @@ public function insert(array $values) $values = [$values]; } - // if transaction in session - $options = $this->setSession(); + $options = $this->inheritConnectionOptions(); $result = $this->collection->insertMany($values, $options); @@ -599,8 +594,7 @@ public function insert(array $values) */ public function insertGetId(array $values, $sequence = null) { - // if transaction in session - $options = $this->setSession(); + $options = $this->inheritConnectionOptions(); $result = $this->collection->insertOne($values, $options); @@ -623,8 +617,8 @@ public function update(array $values, array $options = []) if (! Str::startsWith(key($values), '$')) { $values = ['$set' => $values]; } - // if transaction in session - $options = $this->setSession($options); + + $options = $this->inheritConnectionOptions($options); return $this->performUpdate($values, $options); } @@ -647,8 +641,7 @@ public function increment($column, $amount = 1, array $extra = [], array $option $query->orWhereNotNull($column); }); - // if transaction in session - $options = $this->setSession($options); + $options = $this->inheritConnectionOptions($options); return $this->performUpdate($query, $options); } @@ -711,9 +704,7 @@ public function delete($id = null) } $wheres = $this->compileWheres(); - - // if transaction in session - $options = $this->setSession(); + $options = $this->inheritConnectionOptions(); $result = $this->collection->DeleteMany($wheres, $options); if (1 == (int) $result->isAcknowledged()) { @@ -740,9 +731,7 @@ public function from($collection, $as = null) */ public function truncate(): bool { - // Check if transaction exist in session - $options = $this->setSession(); - + $options = $this->inheritConnectionOptions(); $result = $this->collection->deleteMany($options); return 1 === (int) $result->isAcknowledged(); @@ -876,8 +865,7 @@ protected function performUpdate($query, array $options = []) $options['multiple'] = true; } - // Check if transaction exist in session - $options = $this->setSession($options); + $options = $this->inheritConnectionOptions($options); $wheres = $this->compileWheres(); $result = $this->collection->UpdateMany($wheres, $query, $options); @@ -1274,15 +1262,14 @@ public function options(array $options) } /** - * Set session for the transaction - * @param $session - * @return mixed + * Apply the connection's session to options if it's not already specified. */ - protected function setSession($options = []) + private function inheritConnectionOptions(array $options = []): array { if (!isset($options['session']) && ($session = $this->connection->getSession())) { $options['session'] = $session; } + return $options; } diff --git a/tests/TransactionBuilderTest.php b/tests/TransactionBuilderTest.php deleted file mode 100644 index eba7a5a93..000000000 --- a/tests/TransactionBuilderTest.php +++ /dev/null @@ -1,220 +0,0 @@ - 'klinson', 'age' => 20, 'title' => 'admin']; - protected $originData = ['name' => 'users', 'age' => 20, 'title' => 'user']; - protected $connection = 'mongodb_repl'; - protected $originConnection = 'mongodb'; - - public function setUp(): void - { - parent::setUp(); - - /** change connection to seplset? because the transaction needs */ - $this->originConnection = DB::getDefaultConnection(); - DB::setDefaultConnection($this->connection); - - DB::collection('users')->truncate(); - DB::collection('users')->insert($this->originData); - } - - protected function getEnvironmentSetUp($app) - { - if (version_compare(env('MONGO_VERSION'), '4', '<')) { - $this->markTestSkipped('MongoDB with version below 4 is not supported for transactions'); - } - - $config = require 'config/database.php'; - - $app['config']->set('database.connections.'.$this->connection, $config['connections'][$this->connection]); - $app['config']->set('database.default', $this->connection); - } - - public function tearDown(): void - { - DB::collection('users')->truncate(); - DB::setDefaultConnection($this->originConnection); - parent::tearDown(); - } - - public function testInsert() - { - /** rollback test */ - DB::beginTransaction(); - DB::collection('users')->insert($this->insertData); - DB::rollBack(); - $users = DB::collection('users')->where('name', $this->insertData['name'])->get(); - $this->assertCount(0, $users); - - /** commit test */ - DB::beginTransaction(); - DB::collection('users')->insert($this->insertData); - DB::commit(); - $users = DB::collection('users')->where('name', $this->insertData['name'])->get(); - $this->assertCount(1, $users); - } - - public function testInsertGetId() - { - /** rollback test */ - DB::beginTransaction(); - $user_id = DB::collection('users')->insertGetId($this->insertData); - DB::rollBack(); - $user_id = (string) $user_id; - $user = DB::collection('users')->find($user_id); - $this->assertNull($user); - - /** commit test */ - DB::beginTransaction(); - $user_id = DB::collection('users')->insertGetId($this->insertData); - DB::commit(); - $user_id = (string) $user_id; - $user = DB::collection('users')->find($user_id); - $this->assertEquals($this->insertData['name'], $user['name']); - } - - public function testUpdate() - { - /** rollback test */ - $new_age = $this->originData['age'] + 1; - DB::beginTransaction(); - DB::collection('users')->where('name', $this->originData['name'])->update(['age' => $new_age]); - DB::rollBack(); - $users = DB::collection('users')->where('name', $this->originData['name'])->where('age', $new_age)->get(); - $this->assertCount(0, $users); - - /** commit test */ - DB::beginTransaction(); - DB::collection('users')->where('name', $this->originData['name'])->update(['age' => $new_age]); - DB::commit(); - $users = DB::collection('users')->where('name', $this->originData['name'])->where('age', $new_age)->get(); - $this->assertCount(1, $users); - } - - public function testDelete() - { - /** rollback test */ - DB::beginTransaction(); - DB::collection('users')->where('name', $this->originData['name'])->delete(); - DB::rollBack(); - $users = DB::collection('users')->where('name', $this->originData['name'])->get(); - $this->assertCount(1, $users); - - /** commit test */ - DB::beginTransaction(); - DB::collection('users')->where('name', $this->originData['name'])->delete(); - DB::commit(); - $users = DB::collection('users')->where('name', $this->originData['name'])->get(); - $this->assertCount(0, $users); - } - - public function testIncrement() - { - /** rollback test */ - DB::beginTransaction(); - DB::collection('users')->where('name', $this->originData['name'])->increment('age'); - DB::rollBack(); - $user = DB::collection('users')->where('name', $this->originData['name'])->first(); - $this->assertEquals($this->originData['age'], $user['age']); - - /** commit test */ - DB::beginTransaction(); - DB::collection('users')->where('name', $this->originData['name'])->increment('age'); - DB::commit(); - $user = DB::collection('users')->where('name', $this->originData['name'])->first(); - $this->assertEquals($this->originData['age'] + 1, $user['age']); - } - - public function testDecrement() - { - /** rollback test */ - DB::beginTransaction(); - DB::collection('users')->where('name', $this->originData['name'])->decrement('age'); - DB::rollBack(); - $user = DB::collection('users')->where('name', $this->originData['name'])->first(); - $this->assertEquals($this->originData['age'], $user['age']); - - /** commit test */ - DB::beginTransaction(); - DB::collection('users')->where('name', $this->originData['name'])->decrement('age'); - DB::commit(); - $user = DB::collection('users')->where('name', $this->originData['name'])->first(); - $this->assertEquals($this->originData['age'] - 1, $user['age']); - } - - public function testQuery() - { - /** rollback test */ - DB::beginTransaction(); - $count = DB::collection('users')->count(); - $this->assertEquals(1, $count); - DB::collection('users')->insert($this->insertData); - $count = DB::collection('users')->count(); - $this->assertEquals(2, $count); - DB::rollBack(); - $count = DB::collection('users')->count(); - $this->assertEquals(1, $count); - - /** commit test */ - DB::beginTransaction(); - $count = DB::collection('users')->count(); - $this->assertEquals(1, $count); - DB::collection('users')->insert($this->insertData); - $count = DB::collection('users')->count(); - $this->assertEquals(2, $count); - DB::commit(); - $count = DB::collection('users')->count(); - $this->assertEquals(2, $count); - } - - public function testTransaction() - { - $count = DB::collection('users')->count(); - $this->assertEquals(1, $count); - - $new_age = $this->originData['age'] + 1; - DB::transaction(function () use ($new_age) { - DB::collection('users')->insert($this->insertData); - DB::collection('users')->where('name', $this->originData['name'])->update(['age' => $new_age]); - }); - $count = DB::collection('users')->count(); - $this->assertEquals(2, $count); - - $checkInsert = DB::collection('users')->where('name', $this->insertData['name'])->first(); - $this->assertNotNull($checkInsert); - $this->assertEquals($this->insertData['age'], $checkInsert['age']); - - $checkUpdate = DB::collection('users')->where('name', $this->originData['name'])->first(); - $this->assertEquals($new_age, $checkUpdate['age']); - } - - /** - * Supports infinite-level nested transactions, but outside transaction rollbacks do not affect the commit of inside transactions - */ - public function TestNestingTransaction() - { - DB::collection('users')->insert($this->insertData); - $new_age1 = $this->originData['age'] + 1; - $new_age2 = $this->insertData['age'] + 1; - /** outside transaction */ - DB::beginTransaction(); - - DB::collection('users')->where('name', $this->originData['name'])->update(['age' => $new_age1]); - - /** inside transaction */ - DB::transaction(function () use ($new_age2) { - DB::collection('users')->where('name', $this->insertData['name'])->update(['age' => $new_age2]); - }); - - DB::rollBack(); - - $check1 = DB::collection('users')->where('name', $this->originData['name'])->first(); - $check2 = DB::collection('users')->where('name', $this->insertData['name'])->first(); - $this->assertNotEquals($new_age1, $check1['age']); - $this->assertEquals($new_age2, $check2['age']); - } -} diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 5c195aa13..0458adc33 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -1,186 +1,352 @@ 'klinson', 'age' => 20, 'title' => 'admin']; - protected $originData = ['name' => 'users', 'age' => 20, 'title' => 'user']; - protected $connection = 'mongodb_repl'; + protected string $connection = 'dsn_mongodb'; public function setUp(): void { parent::setUp(); User::on($this->connection)->truncate(); - User::on($this->connection)->create($this->originData); } - protected function getEnvironmentSetUp($app) + public function tearDown(): void { - if (version_compare(env('MONGO_VERSION'), '4', '<')) { - $this->markTestSkipped('MongoDB with version below 4 is not supported for transactions'); - } + User::on($this->connection)->truncate(); + parent::tearDown(); + } + + protected function getEnvironmentSetUp($app) + { $config = require 'config/database.php'; $app['config']->set('database.connections.'.$this->connection, $config['connections'][$this->connection]); $app['config']->set('database.default', $this->connection); } - public function tearDown(): void + public function testCreateWhenTransactionCommitted(): void { - User::on($this->connection)->truncate(); + DB::beginTransaction(); + /** @var User $user */ + $user = User::on($this->connection)->create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); + DB::commit(); - parent::tearDown(); + $this->assertInstanceOf(Model::class, $user); + $this->assertTrue($user->exists); + $this->assertEquals('klinson', $user->name); + + /** @var User $check */ + $check = User::on($this->connection)->find($user->_id); + $this->assertNotNull($check); + $this->assertEquals($user->name, $check->name); } - public function testCreate() + public function testCreateWhenTransactionRollback(): void { - /** rollback test */ DB::beginTransaction(); - $user = User::on($this->connection)->create($this->insertData); + /** @var User $user */ + $user = User::on($this->connection)->create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); DB::rollBack(); - $this->assertInstanceOf(\Jenssegers\Mongodb\Eloquent\Model::class, $user); + + $this->assertInstanceOf(Model::class, $user); $this->assertTrue($user->exists); - $this->assertEquals($this->insertData['name'], $user->name); + $this->assertEquals('klinson', $user->name); - $check = User::on($this->connection)->find($user->_id); - $this->assertNull($check); + $check = User::on($this->connection)->where('_id', $user->_id)->exists(); + $this->assertFalse($check); + } - /** commit test */ + public function testInsertThroughQueryBuilderWhenTransactionCommitted(): void + { + DB::beginTransaction(); + DB::collection('users')->insert(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); + DB::commit(); + $existUser = DB::collection('users')->where('name', 'klinson')->where('age', 20)->where('title', 'admin')->exists(); + $this->assertTrue($existUser); + } + + public function testInsertThroughQueryBuilderWhenTransactionRollback(): void + { DB::beginTransaction(); - $user = User::on($this->connection)->create($this->insertData); + DB::collection('users')->insert(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); + DB::rollBack(); + $existUser = DB::collection('users')->where('name', 'klinson')->where('age', 20)->where('title', 'admin')->exists(); + $this->assertFalse($existUser); + } + + public function testInsertThroughEloquentSaveWhenTransactionCommitted(): void + { + DB::beginTransaction(); + /** @var User $user */ + $user = User::on($this->connection)->getModel(); + $user->name = 'klinson'; + $user->save(); DB::commit(); - $this->assertInstanceOf(\Jenssegers\Mongodb\Eloquent\Model::class, $user); + $this->assertTrue($user->exists); - $this->assertEquals($this->insertData['name'], $user->name); + $this->assertNotNull($user->getIdAttribute()); + /** @var User $check */ $check = User::on($this->connection)->find($user->_id); $this->assertNotNull($check); - $this->assertEquals($user->name, $check->name); + $this->assertEquals($check->name, $user->name); } - public function testInsert() + public function testInsertThroughEloquentSaveWhenTransactionRollback(): void { - /** rollback test */ DB::beginTransaction(); - $user = User::on($this->connection)->getModel(); - $user->name = $this->insertData['name']; - $user->title = $this->insertData['title']; - $user->age = $this->insertData['age']; - $user->save(); + /** @var User $user */ + $user = User::on($this->connection)->getModel(); + $user->name = 'klinson'; + $user->save(); DB::rollBack(); $this->assertTrue($user->exists); - $this->assertTrue(isset($user->_id)); - $this->assertIsString($user->_id); + $this->assertNotNull($user->getIdAttribute()); - $check = User::on($this->connection)->find($user->_id); - $this->assertNull($check); + $userExists = User::on($this->connection)->where('_id', $user->_id)->exists(); + $this->assertFalse($userExists); + } - /** commit test */ + public function testInsertGetIdWhenTransactionCommitted(): void + { DB::beginTransaction(); - $user = User::on($this->connection)->getModel(); - $user->name = $this->insertData['name']; - $user->title = $this->insertData['title']; - $user->age = $this->insertData['age']; - $user->save(); + $userId = DB::collection('users')->insertGetId(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); DB::commit(); - $this->assertTrue($user->exists); - $this->assertTrue(isset($user->_id)); - $this->assertIsString($user->_id); + $user = DB::collection('users')->find((string) $userId); + $this->assertEquals('klinson', $user['name']); + } - $check = User::on($this->connection)->find($user->_id); - $this->assertNotNull($check); - $this->assertEquals($check->name, $user->name); - $this->assertEquals($check->age, $user->age); - $this->assertEquals($check->title, $user->title); + public function testInsertGetIdWhenTransactionRollback(): void + { + DB::beginTransaction(); + $userId = DB::collection('users')->insertGetId(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); + DB::rollBack(); + + $userExists = DB::collection('users')->where('_id', (string) $userId)->exists(); + $this->assertFalse($userExists); } - public function testUpdateWithRollback () + public function testUpdateThroughQueryBuilderWhenTransactionCommitted(): void { - /** rollback test */ - $new_age = $this->insertData['age'] + 1; - $user1 = User::on($this->connection)->create($this->insertData); - $user2 = User::on($this->connection)->create($this->insertData); + User::on($this->connection)->create(['name' => 'users', 'age' => 20, 'title' => 'user']); + DB::beginTransaction(); - $user1->age = $new_age; - $user1->update(); - $user2->update(['age' => $new_age]); + $updated = DB::collection('users')->where('name', 'users')->update(['age' => 999]); + $this->assertEquals(1, $updated); + DB::commit(); + + $userExists = DB::collection('users')->where('name', 'users')->where('age', 999)->exists(); + $this->assertTrue($userExists); + } + + public function testUpdateThroughQueryBuilderWhenTransactionRollback(): void + { + User::on($this->connection)->create(['name' => 'users', 'age' => 20, 'title' => 'user']); + + DB::beginTransaction(); + $updated = DB::collection('users')->where('name', 'users')->update(['age' => 999]); + $this->assertEquals(1, $updated); DB::rollBack(); - $this->assertEquals($new_age, $user1->age); - $this->assertEquals($new_age, $user2->age); - $check1 = User::on($this->connection)->find($user1->_id); - $check2 = User::on($this->connection)->find($user2->_id); - $this->assertEquals($this->insertData['age'], $check1->age); - $this->assertEquals($this->insertData['age'], $check2->age); + $userExists = DB::collection('users')->where('name', 'users')->where('age', 999)->exists(); + $this->assertFalse($userExists); } - public function testUpdateWithCommit() + public function testUpdateThroughEloquentUpdateWhenTransactionCommitted(): void { - $new_age = $this->insertData['age'] + 1; + /** @var User $user1 */ + $user1 = User::on($this->connection)->create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); + /** @var User $user2 */ + $user2 = User::on($this->connection)->create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); - /** commit test */ - User::on($this->connection)->truncate(); - $user1 = User::on($this->connection)->create($this->insertData); - $user2 = User::on($this->connection)->create($this->insertData); DB::beginTransaction(); - $user1->age = $new_age; - $user1->update(); - $user2->update(['age' => $new_age]); + $user1->age = 999; + $user1->update(); + $user2->update(['age' => 1000]); DB::commit(); - $this->assertEquals($new_age, $user1->age); - $this->assertEquals($new_age, $user2->age); - $check1 = User::on($this->connection)->find($user1->_id); - $check2 = User::on($this->connection)->find($user2->_id); - $this->assertEquals($new_age, $check1->age); - $this->assertEquals($new_age, $check2->age); + $this->assertEquals(999, $user1->age); + $this->assertEquals(1000, $user2->age); + + $check1 = User::on($this->connection)->where('_id', $user1->_id)->where('age', 999)->exists(); + $check2 = User::on($this->connection)->where('_id', $user2->_id)->where('age', 1000)->exists(); + $this->assertTrue($check1); + $this->assertTrue($check2); + } + + public function testUpdateThroughEloquentUpdateWhenTransactionRollback(): void + { + /** @var User $user1 */ + $user1 = User::on($this->connection)->create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); + /** @var User $user2 */ + $user2 = User::on($this->connection)->create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); + + DB::beginTransaction(); + $user1->age = 999; + $user1->update(); + $user2->update(['age' => 1000]); + DB::rollBack(); + + $this->assertEquals(999, $user1->age); + $this->assertEquals(1000, $user2->age); + + $check1 = User::on($this->connection)->where('_id', $user1->_id)->where('age', 999)->exists(); + $check2 = User::on($this->connection)->where('_id', $user2->_id)->where('age', 1000)->exists(); + $this->assertFalse($check1); + $this->assertFalse($check2); } - public function testDelete() + public function testDeleteThroughQueryBuilderWhenTransactionCommitted(): void + { + User::on($this->connection)->create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); + + DB::beginTransaction(); + $deleted = User::on($this->connection)->where(['name' => 'klinson', 'age' => 20, 'title' => 'admin'])->delete(); + $this->assertEquals(1, $deleted); + DB::commit(); + + $userExists = User::on($this->connection)->where(['name' => 'klinson', 'age' => 20, 'title' => 'admin'])->exists(); + $this->assertFalse($userExists); + } + + public function testDeleteThroughQueryBuilderWhenTransactionRollback(): void + { + User::on($this->connection)->create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); + + DB::beginTransaction(); + $deleted = User::on($this->connection)->where(['name' => 'klinson', 'age' => 20, 'title' => 'admin'])->delete(); + $this->assertEquals(1, $deleted); + DB::rollBack(); + + $userExists = User::on($this->connection)->where(['name' => 'klinson', 'age' => 20, 'title' => 'admin'])->exists(); + $this->assertTrue($userExists); + } + + public function testDeleteThroughEloquentUpdateWhenTransactionCommitted(): void + { + /** @var User $user1 */ + $user1 = User::on($this->connection)->create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); + + DB::beginTransaction(); + $user1->delete(); + DB::commit(); + + $userExists = User::on($this->connection)->where('_id', $user1->_id)->exists(); + $this->assertFalse($userExists); + } + + public function testDeleteThroughEloquentUpdateWhenTransactionRollback(): void + { + /** @var User $user1 */ + $user1 = User::on($this->connection)->create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); + + DB::beginTransaction(); + $user1->delete(); + DB::rollBack(); + + $userExists = User::on($this->connection)->where('_id', $user1->_id)->exists(); + $this->assertTrue($userExists); + } + + public function testIncrementWhenTransactionCommitted(): void + { + User::on($this->connection)->create(['name' => 'users', 'age' => 20, 'title' => 'user']); + + DB::beginTransaction(); + DB::collection('users')->where('name', 'users')->increment('age'); + DB::commit(); + + $userExists = DB::collection('users')->where('name', 'users')->where('age', 21)->exists(); + $this->assertTrue($userExists); + } + + public function testIncrementWhenTransactionRollback(): void + { + User::on($this->connection)->create(['name' => 'users', 'age' => 20, 'title' => 'user']); + + DB::beginTransaction(); + DB::collection('users')->where('name', 'users')->increment('age'); + DB::rollBack(); + + $userExists = DB::collection('users')->where('name', 'users')->where('age', 20)->exists(); + $this->assertTrue($userExists); + } + + public function testDecrementWhenTransactionCommitted(): void + { + User::on($this->connection)->create(['name' => 'users', 'age' => 20, 'title' => 'user']); + + DB::beginTransaction(); + DB::collection('users')->where('name', 'users')->decrement('age'); + DB::commit(); + + $userExists = DB::collection('users')->where('name', 'users')->where('age', 19)->exists(); + $this->assertTrue($userExists); + } + + public function testDecrementWhenTransactionRollback(): void + { + User::on($this->connection)->create(['name' => 'users', 'age' => 20, 'title' => 'user']); + + DB::beginTransaction(); + DB::collection('users')->where('name', 'users')->decrement('age'); + DB::rollBack(); + + $userExists = DB::collection('users')->where('name', 'users')->where('age', 20)->exists(); + $this->assertTrue($userExists); + } + + public function testQuery() { /** rollback test */ - $user1 = User::on($this->connection)->create($this->insertData); DB::beginTransaction(); - $user1->delete(); + $count = DB::collection('users')->count(); + $this->assertEquals(0, $count); + DB::collection('users')->insert(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); + $count = DB::collection('users')->count(); + $this->assertEquals(1, $count); DB::rollBack(); - $check1 = User::on($this->connection)->find($user1->_id); - $this->assertNotNull($check1); + + $count = DB::collection('users')->count(); + $this->assertEquals(0, $count); /** commit test */ - User::on($this->connection)->truncate(); - $user1 = User::on($this->connection)->create($this->insertData); DB::beginTransaction(); - $user1->delete(); + $count = DB::collection('users')->count(); + $this->assertEquals(0, $count); + DB::collection('users')->insert(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); + $count = DB::collection('users')->count(); + $this->assertEquals(1, $count); DB::commit(); - $check1 = User::on($this->connection)->find($user1->_id); - $this->assertNull($check1); + + $count = DB::collection('users')->count(); + $this->assertEquals(1, $count); } public function testTransaction(): void { - $count = User::on($this->connection)->count(); - $this->assertEquals(1, $count); - $newAge = $this->originData['age'] + 1; + User::on($this->connection)->create(['name' => 'users', 'age' => 20, 'title' => 'user']); - DB::transaction(function () use ($newAge) { - User::on($this->connection)->create($this->insertData); - User::on($this->connection)->where($this->originData['name'])->update(['age' => $newAge]); + DB::transaction(function () { + User::on($this->connection)->create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); + User::on($this->connection)->where('users')->update(['age' => 999]); }); $count = User::on($this->connection)->count(); $this->assertEquals(2, $count); - $checkInsert = User::on($this->connection)->where($this->insertData['name'])->first(); - $this->assertNotNull($checkInsert); + $checkInsert = User::on($this->connection)->where('klinson')->exists(); + $this->assertTrue($checkInsert); - $checkUpdate = User::on($this->connection)->where($this->originData['name'])->first(); - $this->assertEquals($newAge, $checkUpdate->age); + $checkUpdate = User::on($this->connection)->where('users')->where('age', 999)->exists(); + $this->assertTrue($checkUpdate); } public function testIsTransactionSuccessfullyAbortedWhenAttemptsEnd(): void @@ -188,8 +354,8 @@ public function testIsTransactionSuccessfullyAbortedWhenAttemptsEnd(): void $oldUsersCount = User::on($this->connection)->count(); $result = DB::transaction(function () { - User::on($this->connection)->create($this->insertData); - User::on($this->connection)->create($this->insertData); + User::on($this->connection)->create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); + User::on($this->connection)->create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); }, 0); $newUsersCount = User::on($this->connection)->count(); @@ -203,13 +369,13 @@ public function testIsDataInTransactionReturnedWhenTransactionWasSuccess(): void $oldUsersCount = User::on($this->connection)->count(); $result = DB::transaction(function () { - return User::on($this->connection)->create($this->insertData); + return User::on($this->connection)->create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); }); $newUsersCount = User::on($this->connection)->count(); $this->assertNotNull($result); - $this->assertEquals($result->title, $this->insertData['title']); + $this->assertEquals($result->title, 'admin'); $this->assertNotEquals($newUsersCount, $oldUsersCount); } @@ -223,4 +389,15 @@ public function testThrowExceptionForNestedTransactions(): void DB::commit(); DB::rollBack(); } + + public function testThrowExceptionWhenNestingTransactionInManualTransaction() + { + $this->expectException(RuntimeException::class); + $this->expectExceptionCode(53 /* InvalidIdField */); + + DB::beginTransaction(); + DB::transaction(function () { + }); + DB::rollBack(); + } } diff --git a/tests/config/database.php b/tests/config/database.php index 1ac2ff941..2aabe9d48 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -33,6 +33,10 @@ 'driver' => 'mongodb', 'dsn' => "mongodb://$mongoHost:$mongoPort", 'database' => env('MONGO_DATABASE', 'unittest'), + 'options' => [ + 'replicaSet' => 'rs', + 'serverSelectionTryOnce' => false, + ], ], 'dsn_mongodb_db' => [ From fcb6a2c8f04c06c91ce11f3310f3223d07755eef Mon Sep 17 00:00:00 2001 From: levon80999 Date: Mon, 17 Oct 2022 16:10:20 +0400 Subject: [PATCH 45/87] fix comments --- mongo-replset-init.sh | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) mode change 100644 => 100755 mongo-replset-init.sh diff --git a/mongo-replset-init.sh b/mongo-replset-init.sh old mode 100644 new mode 100755 index 9c184d51a..0cbbb7b89 --- a/mongo-replset-init.sh +++ b/mongo-replset-init.sh @@ -1,10 +1,10 @@ #!/bin/bash -mongodb1=`getent hosts ${MONGO1} | awk '{ print $1 }'` +mongodbHost='127.0.0.1' -port=${PORT:-27018} +port=${PORT:-27017} echo "Waiting for startup.." -until mongo --host ${mongodb1}:${port} --eval 'quit(db.runCommand({ ping: 1 }).ok ? 0 : 2)' &>/dev/null; do +until mongo --host ${mongodbHost}:${port} --eval 'quit(db.runCommand({ ping: 1 }).ok ? 0 : 2)' &>/dev/null; do printf '.' sleep 1 done @@ -12,26 +12,15 @@ done echo "Started.." echo setup.sh time now: `date +"%T" ` -mongo --host ${mongodb1}:${port} < Date: Mon, 17 Oct 2022 16:14:18 +0400 Subject: [PATCH 46/87] Remove TransactionBuilderTest.php --- phpunit.xml.dist | 1 - 1 file changed, 1 deletion(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 439a90dac..c99dbecc0 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -20,7 +20,6 @@ tests/QueryTest.php - tests/TransactionBuilderTest.php tests/TransactionTest.php From b03614bc475f19e04fa96551b98a92955ce3c1af Mon Sep 17 00:00:00 2001 From: levon80999 Date: Mon, 17 Oct 2022 16:32:13 +0400 Subject: [PATCH 47/87] make __call method compatible with Illuminate\Database\Connection::__call --- src/Connection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Connection.php b/src/Connection.php index 132cf9ff0..4665b02c3 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -302,7 +302,7 @@ public function setDatabase(\MongoDB\Database $db) * @param array $parameters * @return mixed */ - public function __call(string $method, $parameters) + public function __call($method, $parameters) { return $this->db->$method(...$parameters); // return call_user_func_array([$this->db, $method], $parameters); From 87cb7e6c0bd2b691d57c5773435a3adfb68fcebb Mon Sep 17 00:00:00 2001 From: levon80999 Date: Mon, 17 Oct 2022 16:39:54 +0400 Subject: [PATCH 48/87] Fix cs fixer --- src/Concerns/TransactionManager.php | 9 ++++----- src/Query/Builder.php | 2 +- tests/config/database.php | 4 ++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Concerns/TransactionManager.php b/src/Concerns/TransactionManager.php index 77e977b2f..e26a76ddf 100644 --- a/src/Concerns/TransactionManager.php +++ b/src/Concerns/TransactionManager.php @@ -4,7 +4,6 @@ use Closure; use MongoDB\Driver\Session; - use function MongoDB\with_transaction; trait TransactionManager @@ -24,7 +23,7 @@ public function getSession(): ?Session } /** - * Use the existing or create new session and start a transaction in session + * Use the existing or create new session and start a transaction in session. * * In version 4.0, MongoDB supports multi-document transactions on replica sets. * In version 4.2, MongoDB introduces distributed transactions, which adds support for multi-document transactions on sharded clusters and incorporates the existing support for multi-document transactions on replica sets. @@ -46,7 +45,7 @@ public function beginTransaction(array $options = []): void } /** - * commit transaction in this session and close this session + * Commit transaction in this session and close this session. * @return void */ public function commit(): void @@ -57,7 +56,7 @@ public function commit(): void } /** - * rollback transaction in this session and close this session + * Rollback transaction in this session and close this session. * @param null $toLevel * @return void */ @@ -86,7 +85,7 @@ public function transaction(Closure $callback, $attempts = 1, array $options = [ $this->session = $session; } - $callbackFunction = function(Session $session) use ($callback, &$attemptsLeft, &$callbackResult) { + $callbackFunction = function (Session $session) use ($callback, &$attemptsLeft, &$callbackResult) { $attemptsLeft--; if ($attemptsLeft < 0) { diff --git a/src/Query/Builder.php b/src/Query/Builder.php index 61b06ab3d..d855df94e 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -1266,7 +1266,7 @@ public function options(array $options) */ private function inheritConnectionOptions(array $options = []): array { - if (!isset($options['session']) && ($session = $this->connection->getSession())) { + if (! isset($options['session']) && ($session = $this->connection->getSession())) { $options['session'] = $session; } diff --git a/tests/config/database.php b/tests/config/database.php index 2aabe9d48..d6cbe7ca5 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -1,9 +1,9 @@ Date: Tue, 18 Oct 2022 17:36:41 +0400 Subject: [PATCH 49/87] make correction in docker setup --- docker-compose.yml | 7 ++----- mongo-replset-init.sh | 5 ++--- src/Concerns/TransactionManager.php | 1 + 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 5aca36a5d..fd10d7459 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,6 +19,7 @@ services: mysql: container_name: mysql image: mysql:5.7 + platform: "linux/amd64" ports: - 3306:3306 environment: @@ -34,8 +35,6 @@ services: ports: - "27017:27017" entrypoint: [ "/usr/bin/mongod", "--quiet", "--bind_ip_all", "--replSet", "rs" ] - logging: - driver: none mongo_repl_init: image: mongo:6.0 @@ -45,6 +44,4 @@ services: - RS=rs volumes: - ./:/scripts - entrypoint: [ "sh", "-c", "/scripts/mongo-repl-init.sh" ] - logging: - driver: none + entrypoint: [ "sh", "-c", "./scripts/mongo-replset-init.sh" ] diff --git a/mongo-replset-init.sh b/mongo-replset-init.sh index 0cbbb7b89..2eb74c3bd 100755 --- a/mongo-replset-init.sh +++ b/mongo-replset-init.sh @@ -12,9 +12,9 @@ done echo "Started.." echo setup.sh time now: `date +"%T" ` -mongo --host ${mongodbHost}:${port} <abortTransaction(); + return; } From eb7b84a3029b92a61d29cd00906ee8628a43cb9b Mon Sep 17 00:00:00 2001 From: levon80999 Date: Tue, 18 Oct 2022 17:43:35 +0400 Subject: [PATCH 50/87] Change mongo to mongosh --- .github/workflows/build-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 062b82eaa..3e7feacd0 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -63,10 +63,10 @@ jobs: - name: Creating MongoDB replica run: | docker run --name mongodb -e MONGO_INITDB_DATABASE=unittest --detach mongo:${{ matrix.mongodb }} mongod --replSet rs - until docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "db.serverStatus()"; do + until docker exec --tty mongodb mongosh 127.0.0.1:27017 --eval "db.serverStatus()"; do sleep 1 done - sudo docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"127.0.0.1:27017\" }]})" + sudo docker exec --tty mongodb mongosh 127.0.0.1:27017 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"127.0.0.1:27017\" }]})" env: MONGO_HOST: 0.0.0.0 - name: "Installing php" From a1916675e09d9c1dec651977855ff113bd0fca91 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Tue, 18 Oct 2022 17:54:30 +0400 Subject: [PATCH 51/87] Remove Repl host --- phpunit.xml.dist | 1 - tests/TestCase.php | 1 - tests/config/database.php | 14 -------------- 3 files changed, 16 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c99dbecc0..f9f54f4c5 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -39,7 +39,6 @@ - diff --git a/tests/TestCase.php b/tests/TestCase.php index 62c5bc6b8..584ff82de 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -58,7 +58,6 @@ protected function getEnvironmentSetUp($app) $app['config']->set('database.connections.mongodb2', $config['connections']['mongodb']); $app['config']->set('database.connections.dsn_mongodb', $config['connections']['dsn_mongodb']); $app['config']->set('database.connections.dsn_mongodb_db', $config['connections']['dsn_mongodb_db']); - $app['config']->set('database.connections.mongodb_repl', $config['connections']['mongodb_repl']); $app['config']->set('auth.model', 'User'); $app['config']->set('auth.providers.users.model', 'User'); diff --git a/tests/config/database.php b/tests/config/database.php index d6cbe7ca5..c313859ca 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -1,9 +1,7 @@ env('MONGO_DATABASE', 'unittest'), ], - 'mongodb_repl' => [ - 'name' => 'mongodb_repl', - 'driver' => 'mongodb', - 'host' => $mongoReplHost, - 'port' => $mongoReplPort, - 'database' => env('MONGO_DATABASE', 'unittest'), - 'options' => [ - 'replicaSet' => 'rs', - 'serverSelectionTryOnce' => false, - ], - ], - 'dsn_mongodb' => [ 'driver' => 'mongodb', 'dsn' => "mongodb://$mongoHost:$mongoPort", From f31fb2aedd93549f0f77b2f2057c25901a5d6ad7 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Tue, 18 Oct 2022 18:07:25 +0400 Subject: [PATCH 52/87] Remove mongo 6.0 from jobs --- .github/workflows/build-ci.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 3e7feacd0..4c5ec127a 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -36,14 +36,13 @@ jobs: matrix: include: - { os: ubuntu-latest, php: 8.0, mongodb: '4.0', experimental: false } - - { os: ubuntu-latest, php: 8.0, mongodb: 4.2, experimental: false } - - { os: ubuntu-latest, php: 8.0, mongodb: 4.4, experimental: false } + - { os: ubuntu-latest, php: 8.0, mongodb: '4.2', experimental: false } + - { os: ubuntu-latest, php: 8.0, mongodb: '4.4', experimental: false } - { os: ubuntu-latest, php: 8.0, mongodb: '5.0', experimental: false } - { os: ubuntu-latest, php: 8.1, mongodb: '4.0', experimental: false } - - { os: ubuntu-latest, php: 8.1, mongodb: 4.2, experimental: false } - - { os: ubuntu-latest, php: 8.1, mongodb: 4.4, experimental: false } + - { os: ubuntu-latest, php: 8.1, mongodb: '4.2', experimental: false } + - { os: ubuntu-latest, php: 8.1, mongodb: '4.4', experimental: false } - { os: ubuntu-latest, php: 8.1, mongodb: '5.0', experimental: false } - - { os: ubuntu-latest, php: 8.1, mongodb: '6.0', experimental: false } services: mongo: image: mongo:${{ matrix.mongodb }} @@ -63,10 +62,10 @@ jobs: - name: Creating MongoDB replica run: | docker run --name mongodb -e MONGO_INITDB_DATABASE=unittest --detach mongo:${{ matrix.mongodb }} mongod --replSet rs - until docker exec --tty mongodb mongosh 127.0.0.1:27017 --eval "db.serverStatus()"; do + until docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "db.serverStatus()"; do sleep 1 done - sudo docker exec --tty mongodb mongosh 127.0.0.1:27017 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"127.0.0.1:27017\" }]})" + sudo docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"127.0.0.1:27017\" }]})" env: MONGO_HOST: 0.0.0.0 - name: "Installing php" From 298646faf68fa75f0974a38a227afbfecf5fecac Mon Sep 17 00:00:00 2001 From: levon80999 Date: Tue, 18 Oct 2022 18:23:13 +0400 Subject: [PATCH 53/87] Change MongoDB host in coverage xml file --- phpunit.xml.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index f9f54f4c5..ab52e9962 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -38,7 +38,7 @@ - + From 9ca9074384586800f8cdf73ad35b0e0b9272d7b2 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Tue, 18 Oct 2022 18:56:24 +0400 Subject: [PATCH 54/87] Change hard coded configurations --- docker-compose.yml | 1 + mongo-replset-init.sh | 6 +++--- phpunit.xml.dist | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index fd10d7459..762be9dcd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,6 +41,7 @@ services: depends_on: - mongodb environment: + - MONGO=mongodb - RS=rs volumes: - ./:/scripts diff --git a/mongo-replset-init.sh b/mongo-replset-init.sh index 2eb74c3bd..c93e034e9 100755 --- a/mongo-replset-init.sh +++ b/mongo-replset-init.sh @@ -1,6 +1,6 @@ #!/bin/bash -mongodbHost='127.0.0.1' - +mongodbHost="${MONGO}" +rs=${RS} port=${PORT:-27017} echo "Waiting for startup.." @@ -14,7 +14,7 @@ echo "Started.." echo setup.sh time now: `date +"%T" ` mongosh --host ${mongodbHost}:${port} < - + From 115ce15bd17d1549415011dfd93c76bdcb3b8a2f Mon Sep 17 00:00:00 2001 From: levon80999 Date: Tue, 18 Oct 2022 19:16:13 +0400 Subject: [PATCH 55/87] Change hard coded configurations --- mongo-replset-init.sh | 2 +- phpunit.xml.dist | 2 +- tests/TransactionTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mongo-replset-init.sh b/mongo-replset-init.sh index c93e034e9..11482f9d8 100755 --- a/mongo-replset-init.sh +++ b/mongo-replset-init.sh @@ -14,7 +14,7 @@ echo "Started.." echo setup.sh time now: `date +"%T" ` mongosh --host ${mongodbHost}:${port} < - + diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 0458adc33..fe37f68e0 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -5,7 +5,7 @@ class TransactionTest extends TestCase { - protected string $connection = 'dsn_mongodb'; + protected string $connection = 'mongodb'; public function setUp(): void { From f80f7bc2f7abf581aacda221e86fb934da28e65b Mon Sep 17 00:00:00 2001 From: levon80999 Date: Tue, 18 Oct 2022 19:21:02 +0400 Subject: [PATCH 56/87] Change hard coded configurations --- .github/workflows/build-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 4c5ec127a..8053643df 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -62,10 +62,10 @@ jobs: - name: Creating MongoDB replica run: | docker run --name mongodb -e MONGO_INITDB_DATABASE=unittest --detach mongo:${{ matrix.mongodb }} mongod --replSet rs - until docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "db.serverStatus()"; do + until docker exec --tty mongodb mongo mongodb:27017 --eval "db.serverStatus()"; do sleep 1 done - sudo docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"127.0.0.1:27017\" }]})" + sudo docker exec --tty mongodb mongo mongodb:27017 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"mongodb:27017\" }]})" env: MONGO_HOST: 0.0.0.0 - name: "Installing php" From ab0903e47740b92de57999b25b4b9b22c1b709c1 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Tue, 18 Oct 2022 19:29:50 +0400 Subject: [PATCH 57/87] Change hard coded configurations --- .github/workflows/build-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 8053643df..4c5ec127a 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -62,10 +62,10 @@ jobs: - name: Creating MongoDB replica run: | docker run --name mongodb -e MONGO_INITDB_DATABASE=unittest --detach mongo:${{ matrix.mongodb }} mongod --replSet rs - until docker exec --tty mongodb mongo mongodb:27017 --eval "db.serverStatus()"; do + until docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "db.serverStatus()"; do sleep 1 done - sudo docker exec --tty mongodb mongo mongodb:27017 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"mongodb:27017\" }]})" + sudo docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"127.0.0.1:27017\" }]})" env: MONGO_HOST: 0.0.0.0 - name: "Installing php" From a953e84985481014902cbf89f93313bc36639efe Mon Sep 17 00:00:00 2001 From: levon80999 Date: Tue, 18 Oct 2022 19:39:20 +0400 Subject: [PATCH 58/87] Change connection string --- phpunit.xml.dist | 2 +- tests/TransactionTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 73bac83b3..f9f54f4c5 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -38,7 +38,7 @@ - + diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index fe37f68e0..0458adc33 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -5,7 +5,7 @@ class TransactionTest extends TestCase { - protected string $connection = 'mongodb'; + protected string $connection = 'dsn_mongodb'; public function setUp(): void { From 318b30c62e0af05c87dc733122eaa4e107cab3c0 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Tue, 18 Oct 2022 19:46:35 +0400 Subject: [PATCH 59/87] set mongo host to local --- phpunit.xml.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index f9f54f4c5..73bac83b3 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -38,7 +38,7 @@ - + From 461589528eeaa984c6aac7c129e188ab1b059335 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Tue, 18 Oct 2022 19:52:10 +0400 Subject: [PATCH 60/87] set mongo host to local --- tests/TransactionTest.php | 2 +- tests/config/database.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 0458adc33..fe37f68e0 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -5,7 +5,7 @@ class TransactionTest extends TestCase { - protected string $connection = 'dsn_mongodb'; + protected string $connection = 'mongodb'; public function setUp(): void { diff --git a/tests/config/database.php b/tests/config/database.php index c313859ca..d4c2746aa 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -13,6 +13,10 @@ 'driver' => 'mongodb', 'host' => $mongoHost, 'database' => env('MONGO_DATABASE', 'unittest'), + 'options' => [ + 'replicaSet' => 'rs', + 'serverSelectionTryOnce' => false, + ], ], 'dsn_mongodb' => [ From a55878176a6cc5ba31a1394cbbe07d1be96f87b5 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 15:54:44 +0400 Subject: [PATCH 61/87] set mongo host to local --- phpunit.xml.dist | 2 +- tests/TransactionTest.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 73bac83b3..a87f4f3ea 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -38,7 +38,7 @@ - + diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index fe37f68e0..215e7a5fc 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -31,6 +31,8 @@ protected function getEnvironmentSetUp($app) public function testCreateWhenTransactionCommitted(): void { + $this->skipIfTransactionsAreNotSupported(); + DB::beginTransaction(); /** @var User $user */ $user = User::on($this->connection)->create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); From 3d4280e405832f85f28af9af469026a5daab1158 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 16:05:14 +0400 Subject: [PATCH 62/87] set mongo host to local --- phpunit.xml.dist | 2 +- tests/TransactionTest.php | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index a87f4f3ea..73bac83b3 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -38,7 +38,7 @@ - + diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 215e7a5fc..fe37f68e0 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -31,8 +31,6 @@ protected function getEnvironmentSetUp($app) public function testCreateWhenTransactionCommitted(): void { - $this->skipIfTransactionsAreNotSupported(); - DB::beginTransaction(); /** @var User $user */ $user = User::on($this->connection)->create(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); From a46b3ac8cce7999a5d79e6242545e89cfa7ba061 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 16:09:46 +0400 Subject: [PATCH 63/87] set mongo host to container name --- phpunit.xml.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 73bac83b3..f9f54f4c5 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -38,7 +38,7 @@ - + From 6aebb3451baa2ba626ac504b44aefaf6995f9db8 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 17:17:16 +0400 Subject: [PATCH 64/87] Change call to Attribute class in Model --- .github/workflows/build-ci.yml | 1 + tests/models/User.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 4c5ec127a..6c328457f 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -99,6 +99,7 @@ jobs: env: MONGO_VERSION: ${{ matrix.mongodb }}) MONGO_HOST: 0.0.0.0 + MONGO_PORT: 27017 MYSQL_HOST: 0.0.0.0 MYSQL_PORT: 3307 - uses: codecov/codecov-action@v1 diff --git a/tests/models/User.php b/tests/models/User.php index b394ea6e7..44b077faa 100644 --- a/tests/models/User.php +++ b/tests/models/User.php @@ -93,7 +93,7 @@ protected function serializeDate(DateTimeInterface $date) protected function username(): Attribute { - return Attribute::make( + return new Attribute( get: fn ($value) => $value, set: fn ($value) => Str::slug($value) ); From c24526144e0276f87fa123e14684e5de97fe1aaa Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 17:23:49 +0400 Subject: [PATCH 65/87] check port usage --- .github/workflows/build-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 6c328457f..ea4f25a55 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -77,6 +77,8 @@ jobs: tools: composer - name: Show PHP version run: php -v && composer -V + - name: Show MongoDB Port + run: lsof -i tcp:27017 - name: Show Docker version run: if [[ "$DEBUG" == "true" ]]; then docker version && env; fi env: From 880ad4c3793b5a4e4a37e87ee276d8628c383056 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 17:30:12 +0400 Subject: [PATCH 66/87] set env to default --- .github/workflows/build-ci.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index ea4f25a55..7896cd4e0 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -77,8 +77,6 @@ jobs: tools: composer - name: Show PHP version run: php -v && composer -V - - name: Show MongoDB Port - run: lsof -i tcp:27017 - name: Show Docker version run: if [[ "$DEBUG" == "true" ]]; then docker version && env; fi env: @@ -100,8 +98,6 @@ jobs: ./vendor/bin/phpunit --coverage-clover coverage.xml env: MONGO_VERSION: ${{ matrix.mongodb }}) - MONGO_HOST: 0.0.0.0 - MONGO_PORT: 27017 MYSQL_HOST: 0.0.0.0 MYSQL_PORT: 3307 - uses: codecov/codecov-action@v1 From 539f7a5cd4402e8e3dea309b2787310ddcc9ea06 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 17:40:44 +0400 Subject: [PATCH 67/87] revert test changes --- .github/workflows/build-ci.yml | 1 + phpunit.xml.dist | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 7896cd4e0..4c5ec127a 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -98,6 +98,7 @@ jobs: ./vendor/bin/phpunit --coverage-clover coverage.xml env: MONGO_VERSION: ${{ matrix.mongodb }}) + MONGO_HOST: 0.0.0.0 MYSQL_HOST: 0.0.0.0 MYSQL_PORT: 3307 - uses: codecov/codecov-action@v1 diff --git a/phpunit.xml.dist b/phpunit.xml.dist index f9f54f4c5..ab52e9962 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -38,7 +38,7 @@ - + From 67bd2e93028c9a4cbe7521e763d7611e9dc60c92 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 17:44:07 +0400 Subject: [PATCH 68/87] revert test changes --- .github/workflows/build-ci.yml | 2 +- phpunit.xml.dist | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 4c5ec127a..01994ebad 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -98,7 +98,7 @@ jobs: ./vendor/bin/phpunit --coverage-clover coverage.xml env: MONGO_VERSION: ${{ matrix.mongodb }}) - MONGO_HOST: 0.0.0.0 + MONGO_HOST: 127.0.0.1 MYSQL_HOST: 0.0.0.0 MYSQL_PORT: 3307 - uses: codecov/codecov-action@v1 diff --git a/phpunit.xml.dist b/phpunit.xml.dist index ab52e9962..73bac83b3 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -38,7 +38,7 @@ - + From 06a6d95084c03e7f832a4311c61304a3daf5e6b3 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 18:00:44 +0400 Subject: [PATCH 69/87] set all connections to local --- .github/workflows/build-ci.yml | 2 +- tests/TransactionTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 01994ebad..4c5ec127a 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -98,7 +98,7 @@ jobs: ./vendor/bin/phpunit --coverage-clover coverage.xml env: MONGO_VERSION: ${{ matrix.mongodb }}) - MONGO_HOST: 127.0.0.1 + MONGO_HOST: 0.0.0.0 MYSQL_HOST: 0.0.0.0 MYSQL_PORT: 3307 - uses: codecov/codecov-action@v1 diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index fe37f68e0..0458adc33 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -5,7 +5,7 @@ class TransactionTest extends TestCase { - protected string $connection = 'mongodb'; + protected string $connection = 'dsn_mongodb'; public function setUp(): void { From a0a8339093d3cc545f3a7bd42bcbcecf7af174d7 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 18:23:27 +0400 Subject: [PATCH 70/87] check connection --- tests/config/database.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/config/database.php b/tests/config/database.php index d4c2746aa..0b8b79f54 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -3,7 +3,7 @@ $mongoHost = env('MONGO_HOST', 'mongodb'); $mongoPort = env('MONGO_PORT') ? (int) env('MONGO_PORT') : 27017; $mysqlPort = env('MYSQL_PORT') ? (int) env('MYSQL_PORT') : 3306; - +echo "-".$mongoHost."-".$mongoPort."-"; return [ 'connections' => [ From 8505a2f148128effe59a9e2987c05ac89f3c53d3 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 18:26:18 +0400 Subject: [PATCH 71/87] check connection --- .github/workflows/build-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 4c5ec127a..3888fc074 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -98,7 +98,7 @@ jobs: ./vendor/bin/phpunit --coverage-clover coverage.xml env: MONGO_VERSION: ${{ matrix.mongodb }}) - MONGO_HOST: 0.0.0.0 + MONGO_HOST: mongodb MYSQL_HOST: 0.0.0.0 MYSQL_PORT: 3307 - uses: codecov/codecov-action@v1 From 788c4673ba19140affe281bcc0534a19f694787b Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 18:29:48 +0400 Subject: [PATCH 72/87] check connection --- .github/workflows/build-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 3888fc074..01994ebad 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -98,7 +98,7 @@ jobs: ./vendor/bin/phpunit --coverage-clover coverage.xml env: MONGO_VERSION: ${{ matrix.mongodb }}) - MONGO_HOST: mongodb + MONGO_HOST: 127.0.0.1 MYSQL_HOST: 0.0.0.0 MYSQL_PORT: 3307 - uses: codecov/codecov-action@v1 From 18b7a521b1ed6728040a2f0334cc992cfd3c9a77 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 18:32:44 +0400 Subject: [PATCH 73/87] check connection --- tests/config/database.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/config/database.php b/tests/config/database.php index 0b8b79f54..71bd44584 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -13,10 +13,6 @@ 'driver' => 'mongodb', 'host' => $mongoHost, 'database' => env('MONGO_DATABASE', 'unittest'), - 'options' => [ - 'replicaSet' => 'rs', - 'serverSelectionTryOnce' => false, - ], ], 'dsn_mongodb' => [ From 9eef2fe5d84318704a97f30dd64c120bd8cffdd6 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 19:06:35 +0400 Subject: [PATCH 74/87] check connection --- .github/workflows/build-ci.yml | 4 ++-- phpunit.xml.dist | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 01994ebad..50a9c6244 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -61,7 +61,7 @@ jobs: - uses: actions/checkout@v2 - name: Creating MongoDB replica run: | - docker run --name mongodb -e MONGO_INITDB_DATABASE=unittest --detach mongo:${{ matrix.mongodb }} mongod --replSet rs + docker run --name mongodb -e MONGO_INITDB_DATABASE=unittest --publish 27017:27017 --detach mongo:${{ matrix.mongodb }} mongod --replSet rs until docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "db.serverStatus()"; do sleep 1 done @@ -98,7 +98,7 @@ jobs: ./vendor/bin/phpunit --coverage-clover coverage.xml env: MONGO_VERSION: ${{ matrix.mongodb }}) - MONGO_HOST: 127.0.0.1 + MONGO_HOST: 0.0.0.0 MYSQL_HOST: 0.0.0.0 MYSQL_PORT: 3307 - uses: codecov/codecov-action@v1 diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 73bac83b3..f9f54f4c5 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -38,7 +38,7 @@ - + From 9361058080c8df35e766a8715005fbf273e95827 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 19:14:23 +0400 Subject: [PATCH 75/87] check connection --- .github/workflows/build-ci.yml | 2 +- phpunit.xml.dist | 2 +- tests/config/database.php | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 50a9c6244..4c5ec127a 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -61,7 +61,7 @@ jobs: - uses: actions/checkout@v2 - name: Creating MongoDB replica run: | - docker run --name mongodb -e MONGO_INITDB_DATABASE=unittest --publish 27017:27017 --detach mongo:${{ matrix.mongodb }} mongod --replSet rs + docker run --name mongodb -e MONGO_INITDB_DATABASE=unittest --detach mongo:${{ matrix.mongodb }} mongod --replSet rs until docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "db.serverStatus()"; do sleep 1 done diff --git a/phpunit.xml.dist b/phpunit.xml.dist index f9f54f4c5..73bac83b3 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -38,7 +38,7 @@ - + diff --git a/tests/config/database.php b/tests/config/database.php index 71bd44584..0b8b79f54 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -13,6 +13,10 @@ 'driver' => 'mongodb', 'host' => $mongoHost, 'database' => env('MONGO_DATABASE', 'unittest'), + 'options' => [ + 'replicaSet' => 'rs', + 'serverSelectionTryOnce' => false, + ], ], 'dsn_mongodb' => [ From b7c6e6f4700ab8e47dda7edf1d538a852287eec0 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 19:17:38 +0400 Subject: [PATCH 76/87] check connection --- .github/workflows/build-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 4c5ec127a..9c5e6f1de 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -98,7 +98,7 @@ jobs: ./vendor/bin/phpunit --coverage-clover coverage.xml env: MONGO_VERSION: ${{ matrix.mongodb }}) - MONGO_HOST: 0.0.0.0 + MONGO_HOST: localhost MYSQL_HOST: 0.0.0.0 MYSQL_PORT: 3307 - uses: codecov/codecov-action@v1 From 50c14cd4d52911f44fcb928f2c76eb0132a3fc3c Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 22:57:55 +0400 Subject: [PATCH 77/87] check connection --- .github/workflows/build-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 9c5e6f1de..4c5ec127a 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -98,7 +98,7 @@ jobs: ./vendor/bin/phpunit --coverage-clover coverage.xml env: MONGO_VERSION: ${{ matrix.mongodb }}) - MONGO_HOST: localhost + MONGO_HOST: 0.0.0.0 MYSQL_HOST: 0.0.0.0 MYSQL_PORT: 3307 - uses: codecov/codecov-action@v1 From ff01de7a5ef3df49b1fc27321febf6dfa8f17e0e Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 23:27:50 +0400 Subject: [PATCH 78/87] check connection --- .github/workflows/build-ci.yml | 130 ++++++++++++++------------------- tests/TransactionTest.php | 2 +- tests/config/database.php | 2 +- 3 files changed, 56 insertions(+), 78 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 4c5ec127a..dd154d789 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -7,27 +7,6 @@ on: pull_request: jobs: - php-cs-fixer: - runs-on: ubuntu-latest - env: - PHP_CS_FIXER_VERSION: v3.6.0 - strategy: - matrix: - php: - - '8.0' - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: curl,mbstring - tools: php-cs-fixer:${{ env.PHP_CS_FIXER_VERSION }} - coverage: none - - name: Run PHP-CS-Fixer Fix, version ${{ env.PHP_CS_FIXER_VERSION }} - run: php-cs-fixer fix --dry-run --diff --ansi - build: runs-on: ${{ matrix.os }} name: PHP v${{ matrix.php }} with Mongo v${{ matrix.mongodb }} @@ -35,14 +14,7 @@ jobs: strategy: matrix: include: - - { os: ubuntu-latest, php: 8.0, mongodb: '4.0', experimental: false } - - { os: ubuntu-latest, php: 8.0, mongodb: '4.2', experimental: false } - - { os: ubuntu-latest, php: 8.0, mongodb: '4.4', experimental: false } - - { os: ubuntu-latest, php: 8.0, mongodb: '5.0', experimental: false } - - { os: ubuntu-latest, php: 8.1, mongodb: '4.0', experimental: false } - - { os: ubuntu-latest, php: 8.1, mongodb: '4.2', experimental: false } - - { os: ubuntu-latest, php: 8.1, mongodb: '4.4', experimental: false } - - { os: ubuntu-latest, php: 8.1, mongodb: '5.0', experimental: false } + - { os: ubuntu-latest, php: 8.0, mongodb: 5.0, experimental: false} services: mongo: image: mongo:${{ matrix.mongodb }} @@ -58,50 +30,56 @@ jobs: MYSQL_ROOT_PASSWORD: steps: - - uses: actions/checkout@v2 - - name: Creating MongoDB replica - run: | - docker run --name mongodb -e MONGO_INITDB_DATABASE=unittest --detach mongo:${{ matrix.mongodb }} mongod --replSet rs - until docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "db.serverStatus()"; do - sleep 1 - done - sudo docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"127.0.0.1:27017\" }]})" - env: - MONGO_HOST: 0.0.0.0 - - name: "Installing php" - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: curl,mbstring,xdebug - coverage: xdebug - tools: composer - - name: Show PHP version - run: php -v && composer -V - - name: Show Docker version - run: if [[ "$DEBUG" == "true" ]]; then docker version && env; fi - env: - DEBUG: ${{secrets.DEBUG}} - - name: Download Composer cache dependencies from cache - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Cache Composer dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ matrix.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ matrix.os }}-composer- - - name: Install dependencies - run: | - composer install --no-interaction - - name: Run tests - run: | - ./vendor/bin/phpunit --coverage-clover coverage.xml - env: - MONGO_VERSION: ${{ matrix.mongodb }}) - MONGO_HOST: 0.0.0.0 - MYSQL_HOST: 0.0.0.0 - MYSQL_PORT: 3307 - - uses: codecov/codecov-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: false + - uses: actions/checkout@v2 + - name: Creating MongoDB replica + run: | + docker run --name mongodb_repl -e MONGO_INITDB_DATABASE=unittest --publish 27018:27018 --detach mongo:${{ matrix.mongodb }} mongod --port 27018 --replSet rs + until docker exec --tty mongodb_repl mongo 127.0.0.1:27018 --eval "db.serverStatus()"; do + sleep 1 + done + sudo docker exec --tty mongodb_repl mongo 127.0.0.1:27018 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"127.0.0.1:27018\" }]})" + env: + MONGO_HOST: 0.0.0.0 + MONGO_REPL_HOST: 0.0.0.0 + - name: "Installing php" + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: curl,mbstring,xdebug + coverage: xdebug + tools: composer + - name: Show PHP version + run: php -v && composer -V + - name: Show Docker version + run: if [[ "$DEBUG" == "true" ]]; then docker version && env; fi + env: + DEBUG: ${{secrets.DEBUG}} + - name: Download Composer cache dependencies from cache + if: (!startsWith(matrix.php, '7.2')) + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: Cache Composer dependencies + if: (!startsWith(matrix.php, '7.2')) + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ matrix.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ matrix.os }}-composer- + - name: Install dependencies + if: (!startsWith(matrix.php, '7.2')) + run: | + composer install --no-interaction + - name: Run tests + if: (!startsWith(matrix.php, '7.2')) + run: | + ./vendor/bin/phpunit --coverage-clover coverage.xml + env: + MONGO_VERSION: ${{ matrix.mongodb }}) + MONGO_HOST: 0.0.0.0 + MONGO_REPL_HOST: 0.0.0.0 + MYSQL_HOST: 0.0.0.0 + MYSQL_PORT: 3307 + - uses: codecov/codecov-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: false diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 0458adc33..fe37f68e0 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -5,7 +5,7 @@ class TransactionTest extends TestCase { - protected string $connection = 'dsn_mongodb'; + protected string $connection = 'mongodb'; public function setUp(): void { diff --git a/tests/config/database.php b/tests/config/database.php index 0b8b79f54..d4c2746aa 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -3,7 +3,7 @@ $mongoHost = env('MONGO_HOST', 'mongodb'); $mongoPort = env('MONGO_PORT') ? (int) env('MONGO_PORT') : 27017; $mysqlPort = env('MYSQL_PORT') ? (int) env('MYSQL_PORT') : 3306; -echo "-".$mongoHost."-".$mongoPort."-"; + return [ 'connections' => [ From f3d155353b254eb19ceeeb9b09eb3aff34116764 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Wed, 19 Oct 2022 23:31:15 +0400 Subject: [PATCH 79/87] check connection --- tests/TransactionTest.php | 2 +- tests/config/database.php | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index fe37f68e0..3e7471525 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -5,7 +5,7 @@ class TransactionTest extends TestCase { - protected string $connection = 'mongodb'; + protected string $connection = 'mongodb_repl'; public function setUp(): void { diff --git a/tests/config/database.php b/tests/config/database.php index d4c2746aa..2b2d0d651 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -1,7 +1,9 @@ [ + 'name' => 'mongodb_repl', + 'driver' => 'mongodb', + 'host' => $mongoReplHost, + 'port' => $mongoReplPort, + 'database' => env('MONGO_DATABASE', 'unittest'), + 'options' => [ + 'replicaSet' => 'rs', + 'serverSelectionTryOnce' => false, + ], + ], + 'dsn_mongodb' => [ 'driver' => 'mongodb', 'dsn' => "mongodb://$mongoHost:$mongoPort", From 16e95a71841bfd5efb7bb8898a82712f61f58815 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Thu, 20 Oct 2022 00:35:18 +0400 Subject: [PATCH 80/87] Update transaction documentation and deleted remaining comments --- README.md | 3 ++- src/Connection.php | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b45df1905..d0c8e9060 100644 --- a/README.md +++ b/README.md @@ -1009,8 +1009,9 @@ DB::commit(); // you can also rollback them //DB::rollBack(); ``` -**NOTE:** Transaction does not support nested transactions. DB::beginTransaction() function will start new transactions in a new created or existing session and will raise the RuntimeException when transactions already exist. See more in MongoDB official docs [Transactions and Sessions](https://www.mongodb.com/docs/manual/core/transactions/#transactions-and-sessions) +**NOTE:** The Transactions in MongoDb does not support nested transactions. DB::beginTransaction() function will start new transactions in a new created or existing session and will raise the RuntimeException when transactions already exist. See more in MongoDB official docs [Transactions and Sessions](https://www.mongodb.com/docs/manual/core/transactions/#transactions-and-sessions) ```php +// This code will rise RuntimeException DB::beginTransaction(); User::create(['name' => 'john', 'age' => 20, 'title' => 'admin']); DB::beginTransaction() diff --git a/src/Connection.php b/src/Connection.php index 4665b02c3..4939327a1 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -305,6 +305,5 @@ public function setDatabase(\MongoDB\Database $db) public function __call($method, $parameters) { return $this->db->$method(...$parameters); -// return call_user_func_array([$this->db, $method], $parameters); } } From f61fa07667ef40511e6c41a15a8f93daae57f7d4 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Thu, 20 Oct 2022 00:37:39 +0400 Subject: [PATCH 81/87] Revert test changes --- .github/workflows/build-ci.yml | 130 +++++++++++++++++++-------------- tests/config/database.php | 14 ---- 2 files changed, 76 insertions(+), 68 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index dd154d789..4c5ec127a 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -7,6 +7,27 @@ on: pull_request: jobs: + php-cs-fixer: + runs-on: ubuntu-latest + env: + PHP_CS_FIXER_VERSION: v3.6.0 + strategy: + matrix: + php: + - '8.0' + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: curl,mbstring + tools: php-cs-fixer:${{ env.PHP_CS_FIXER_VERSION }} + coverage: none + - name: Run PHP-CS-Fixer Fix, version ${{ env.PHP_CS_FIXER_VERSION }} + run: php-cs-fixer fix --dry-run --diff --ansi + build: runs-on: ${{ matrix.os }} name: PHP v${{ matrix.php }} with Mongo v${{ matrix.mongodb }} @@ -14,7 +35,14 @@ jobs: strategy: matrix: include: - - { os: ubuntu-latest, php: 8.0, mongodb: 5.0, experimental: false} + - { os: ubuntu-latest, php: 8.0, mongodb: '4.0', experimental: false } + - { os: ubuntu-latest, php: 8.0, mongodb: '4.2', experimental: false } + - { os: ubuntu-latest, php: 8.0, mongodb: '4.4', experimental: false } + - { os: ubuntu-latest, php: 8.0, mongodb: '5.0', experimental: false } + - { os: ubuntu-latest, php: 8.1, mongodb: '4.0', experimental: false } + - { os: ubuntu-latest, php: 8.1, mongodb: '4.2', experimental: false } + - { os: ubuntu-latest, php: 8.1, mongodb: '4.4', experimental: false } + - { os: ubuntu-latest, php: 8.1, mongodb: '5.0', experimental: false } services: mongo: image: mongo:${{ matrix.mongodb }} @@ -30,56 +58,50 @@ jobs: MYSQL_ROOT_PASSWORD: steps: - - uses: actions/checkout@v2 - - name: Creating MongoDB replica - run: | - docker run --name mongodb_repl -e MONGO_INITDB_DATABASE=unittest --publish 27018:27018 --detach mongo:${{ matrix.mongodb }} mongod --port 27018 --replSet rs - until docker exec --tty mongodb_repl mongo 127.0.0.1:27018 --eval "db.serverStatus()"; do - sleep 1 - done - sudo docker exec --tty mongodb_repl mongo 127.0.0.1:27018 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"127.0.0.1:27018\" }]})" - env: - MONGO_HOST: 0.0.0.0 - MONGO_REPL_HOST: 0.0.0.0 - - name: "Installing php" - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: curl,mbstring,xdebug - coverage: xdebug - tools: composer - - name: Show PHP version - run: php -v && composer -V - - name: Show Docker version - run: if [[ "$DEBUG" == "true" ]]; then docker version && env; fi - env: - DEBUG: ${{secrets.DEBUG}} - - name: Download Composer cache dependencies from cache - if: (!startsWith(matrix.php, '7.2')) - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Cache Composer dependencies - if: (!startsWith(matrix.php, '7.2')) - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ matrix.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ matrix.os }}-composer- - - name: Install dependencies - if: (!startsWith(matrix.php, '7.2')) - run: | - composer install --no-interaction - - name: Run tests - if: (!startsWith(matrix.php, '7.2')) - run: | - ./vendor/bin/phpunit --coverage-clover coverage.xml - env: - MONGO_VERSION: ${{ matrix.mongodb }}) - MONGO_HOST: 0.0.0.0 - MONGO_REPL_HOST: 0.0.0.0 - MYSQL_HOST: 0.0.0.0 - MYSQL_PORT: 3307 - - uses: codecov/codecov-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: false + - uses: actions/checkout@v2 + - name: Creating MongoDB replica + run: | + docker run --name mongodb -e MONGO_INITDB_DATABASE=unittest --detach mongo:${{ matrix.mongodb }} mongod --replSet rs + until docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "db.serverStatus()"; do + sleep 1 + done + sudo docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "rs.initiate({\"_id\":\"rs\",\"members\":[{\"_id\":0,\"host\":\"127.0.0.1:27017\" }]})" + env: + MONGO_HOST: 0.0.0.0 + - name: "Installing php" + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: curl,mbstring,xdebug + coverage: xdebug + tools: composer + - name: Show PHP version + run: php -v && composer -V + - name: Show Docker version + run: if [[ "$DEBUG" == "true" ]]; then docker version && env; fi + env: + DEBUG: ${{secrets.DEBUG}} + - name: Download Composer cache dependencies from cache + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: Cache Composer dependencies + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ matrix.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ matrix.os }}-composer- + - name: Install dependencies + run: | + composer install --no-interaction + - name: Run tests + run: | + ./vendor/bin/phpunit --coverage-clover coverage.xml + env: + MONGO_VERSION: ${{ matrix.mongodb }}) + MONGO_HOST: 0.0.0.0 + MYSQL_HOST: 0.0.0.0 + MYSQL_PORT: 3307 + - uses: codecov/codecov-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: false diff --git a/tests/config/database.php b/tests/config/database.php index 2b2d0d651..d4c2746aa 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -1,9 +1,7 @@ [ - 'name' => 'mongodb_repl', - 'driver' => 'mongodb', - 'host' => $mongoReplHost, - 'port' => $mongoReplPort, - 'database' => env('MONGO_DATABASE', 'unittest'), - 'options' => [ - 'replicaSet' => 'rs', - 'serverSelectionTryOnce' => false, - ], - ], - 'dsn_mongodb' => [ 'driver' => 'mongodb', 'dsn' => "mongodb://$mongoHost:$mongoPort", From 2316afd36a326f6a2113e97ca592bd68314c0da7 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Thu, 20 Oct 2022 01:01:46 +0400 Subject: [PATCH 82/87] Return exception if user call commit or rollback before start transaction --- src/Concerns/TransactionManager.php | 16 ++++++++++++++++ tests/TransactionTest.php | 28 +++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/Concerns/TransactionManager.php b/src/Concerns/TransactionManager.php index d3c3a8a60..bced945b6 100644 --- a/src/Concerns/TransactionManager.php +++ b/src/Concerns/TransactionManager.php @@ -3,6 +3,7 @@ namespace Jenssegers\Mongodb\Concerns; use Closure; +use MongoDB\Driver\Exception\RuntimeException; use MongoDB\Driver\Session; use function MongoDB\with_transaction; @@ -50,6 +51,7 @@ public function beginTransaction(array $options = []): void */ public function commit(): void { + $this->throwExceptionIfTransactionDoesNotStart(); $session = $this->getSession(); $session?->commitTransaction(); @@ -62,6 +64,7 @@ public function commit(): void */ public function rollBack($toLevel = null): void { + $this->throwExceptionIfTransactionDoesNotStart(); $session = $this->getSession(); $session?->abortTransaction(); @@ -101,4 +104,17 @@ public function transaction(Closure $callback, $attempts = 1, array $options = [ return $callbackResult; } + + private function throwExceptionIfTransactionDoesNotStart() : void + { + $session = $this->getSession(); + + if ($session === null) { + throw new RuntimeException('There is no active session.', 206 /* NoSuchSession */); + } + + if ($session->isInTransaction() === false) { + throw new RuntimeException('There is no active transaction.', 244 /* NOT_YET_AVAILABLE_TransactionAborted */); + } + } } diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 3e7471525..feb5319c2 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -5,7 +5,7 @@ class TransactionTest extends TestCase { - protected string $connection = 'mongodb_repl'; + protected string $connection = 'dsn_mongodb'; public function setUp(): void { @@ -400,4 +400,30 @@ public function testThrowExceptionWhenNestingTransactionInManualTransaction() }); DB::rollBack(); } + + public function testThrowExceptionWhenCallCommitBeforeStartTransaction(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionCode(206 /* NoSuchSession */); + + DB::commit(); + } + + public function testThrowExceptionWhenCallRollbackBeforeStartTransaction(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionCode(206 /* NoSuchSession */); + + DB::rollback(); + } + + public function testThrowExceptionWhenCallRollbackAfterCommit(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionCode(244 /* NOT_YET_AVAILABLE_TransactionAborted */); + DB::beginTransaction(); + DB::commit(); + + DB::rollback(); + } } From 5ac9b7a643eb8cb4884d83c4648da709f2e6e51c Mon Sep 17 00:00:00 2001 From: levon80999 Date: Thu, 20 Oct 2022 01:23:47 +0400 Subject: [PATCH 83/87] Add Return types --- src/Connection.php | 12 ++++++------ src/Query/Builder.php | 30 +++++++++++++++--------------- tests/TransactionTest.php | 2 ++ tests/config/database.php | 10 ++++++---- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/Connection.php b/src/Connection.php index 4939327a1..7a603cad9 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -138,7 +138,7 @@ public function getDatabaseName() * @return string * @throws InvalidArgumentException */ - protected function getDefaultDatabaseName($dsn, $config) + protected function getDefaultDatabaseName(string $dsn, array $config): string { if (empty($config['database'])) { if (preg_match('/^mongodb(?:[+]srv)?:\\/\\/.+\\/([^?&]+)/s', $dsn, $matches)) { @@ -159,7 +159,7 @@ protected function getDefaultDatabaseName($dsn, $config) * @param array $options * @return Client */ - protected function createConnection($dsn, array $config, array $options) + protected function createConnection($dsn, array $config, array $options): Client { // By default driver options is an empty array. $driverOptions = []; @@ -204,7 +204,7 @@ protected function hasDsnString(array $config) * @param array $config * @return string */ - protected function getDsnString(array $config) + protected function getDsnString(array $config): string { return $config['dsn']; } @@ -215,7 +215,7 @@ protected function getDsnString(array $config) * @param array $config * @return string */ - protected function getHostDsn(array $config) + protected function getHostDsn(array $config): string { // Treat host option as array of hosts $hosts = is_array($config['host']) ? $config['host'] : [$config['host']]; @@ -239,7 +239,7 @@ protected function getHostDsn(array $config) * @param array $config * @return string */ - protected function getDsn(array $config) + protected function getDsn(array $config): string { return $this->hasDsnString($config) ? $this->getDsnString($config) @@ -281,7 +281,7 @@ protected function getDefaultQueryGrammar() /** * @inheritdoc */ - protected function getDefaultSchemaGrammar() + protected function getDefaultSchemaGrammar(): Schema\Grammar { return new Schema\Grammar(); } diff --git a/src/Query/Builder.php b/src/Query/Builder.php index d855df94e..ddac6f4a6 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -919,7 +919,7 @@ public function where($column, $operator = null, $value = null, $boolean = 'and' * * @return array */ - protected function compileWheres() + protected function compileWheres(): array { // The wheres to compile. $wheres = $this->wheres ?: []; @@ -1016,7 +1016,7 @@ protected function compileWheres() * @param array $where * @return array */ - protected function compileWhereAll(array $where) + protected function compileWhereAll(array $where): array { extract($where); @@ -1027,7 +1027,7 @@ protected function compileWhereAll(array $where) * @param array $where * @return array */ - protected function compileWhereBasic(array $where) + protected function compileWhereBasic(array $where): array { extract($where); @@ -1083,7 +1083,7 @@ protected function compileWhereBasic(array $where) * @param array $where * @return mixed */ - protected function compileWhereNested(array $where) + protected function compileWhereNested(array $where): mixed { extract($where); @@ -1094,7 +1094,7 @@ protected function compileWhereNested(array $where) * @param array $where * @return array */ - protected function compileWhereIn(array $where) + protected function compileWhereIn(array $where): array { extract($where); @@ -1105,7 +1105,7 @@ protected function compileWhereIn(array $where) * @param array $where * @return array */ - protected function compileWhereNotIn(array $where) + protected function compileWhereNotIn(array $where): array { extract($where); @@ -1116,7 +1116,7 @@ protected function compileWhereNotIn(array $where) * @param array $where * @return array */ - protected function compileWhereNull(array $where) + protected function compileWhereNull(array $where): array { $where['operator'] = '='; $where['value'] = null; @@ -1128,7 +1128,7 @@ protected function compileWhereNull(array $where) * @param array $where * @return array */ - protected function compileWhereNotNull(array $where) + protected function compileWhereNotNull(array $where): array { $where['operator'] = '!='; $where['value'] = null; @@ -1140,7 +1140,7 @@ protected function compileWhereNotNull(array $where) * @param array $where * @return array */ - protected function compileWhereBetween(array $where) + protected function compileWhereBetween(array $where): array { extract($where); @@ -1173,7 +1173,7 @@ protected function compileWhereBetween(array $where) * @param array $where * @return array */ - protected function compileWhereDate(array $where) + protected function compileWhereDate(array $where): array { extract($where); @@ -1187,7 +1187,7 @@ protected function compileWhereDate(array $where) * @param array $where * @return array */ - protected function compileWhereMonth(array $where) + protected function compileWhereMonth(array $where): array { extract($where); @@ -1201,7 +1201,7 @@ protected function compileWhereMonth(array $where) * @param array $where * @return array */ - protected function compileWhereDay(array $where) + protected function compileWhereDay(array $where): array { extract($where); @@ -1215,7 +1215,7 @@ protected function compileWhereDay(array $where) * @param array $where * @return array */ - protected function compileWhereYear(array $where) + protected function compileWhereYear(array $where): array { extract($where); @@ -1229,7 +1229,7 @@ protected function compileWhereYear(array $where) * @param array $where * @return array */ - protected function compileWhereTime(array $where) + protected function compileWhereTime(array $where): array { extract($where); @@ -1243,7 +1243,7 @@ protected function compileWhereTime(array $where) * @param array $where * @return mixed */ - protected function compileWhereRaw(array $where) + protected function compileWhereRaw(array $where): mixed { return $where['sql']; } diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index feb5319c2..6839b77f3 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -66,6 +66,7 @@ public function testInsertThroughQueryBuilderWhenTransactionCommitted(): void DB::beginTransaction(); DB::collection('users')->insert(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); DB::commit(); + $existUser = DB::collection('users')->where('name', 'klinson')->where('age', 20)->where('title', 'admin')->exists(); $this->assertTrue($existUser); } @@ -75,6 +76,7 @@ public function testInsertThroughQueryBuilderWhenTransactionRollback(): void DB::beginTransaction(); DB::collection('users')->insert(['name' => 'klinson', 'age' => 20, 'title' => 'admin']); DB::rollBack(); + $existUser = DB::collection('users')->where('name', 'klinson')->where('age', 20)->where('title', 'admin')->exists(); $this->assertFalse($existUser); } diff --git a/tests/config/database.php b/tests/config/database.php index d4c2746aa..57bb61cea 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -14,8 +14,9 @@ 'host' => $mongoHost, 'database' => env('MONGO_DATABASE', 'unittest'), 'options' => [ - 'replicaSet' => 'rs', - 'serverSelectionTryOnce' => false, + 'replicaSet' => 'rs', + 'connectTimeoutMS' => 100, + 'serverSelectionTimeoutMS' => 250, ], ], @@ -24,8 +25,9 @@ 'dsn' => "mongodb://$mongoHost:$mongoPort", 'database' => env('MONGO_DATABASE', 'unittest'), 'options' => [ - 'replicaSet' => 'rs', - 'serverSelectionTryOnce' => false, + 'replicaSet' => 'rs', + 'connectTimeoutMS' => 100, + 'serverSelectionTimeoutMS' => 250, ], ], From 40a8ea7e221809f68bb395d3e922ad8a734f1243 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Thu, 20 Oct 2022 02:17:29 +0400 Subject: [PATCH 84/87] Add option to dsn conncetion --- tests/config/database.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/config/database.php b/tests/config/database.php index 57bb61cea..d5a96f519 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -34,6 +34,11 @@ 'dsn_mongodb_db' => [ 'driver' => 'mongodb', 'dsn' => "mongodb://$mongoHost:$mongoPort/".env('MONGO_DATABASE', 'unittest'), + 'options' => [ + 'replicaSet' => 'rs', + 'connectTimeoutMS' => 100, + 'serverSelectionTimeoutMS' => 250, + ], ], 'mysql' => [ From 301f9798f344a07712301cb30d57483ba778fbb8 Mon Sep 17 00:00:00 2001 From: levon80999 Date: Thu, 20 Oct 2022 15:57:15 +0400 Subject: [PATCH 85/87] Add option to dsn conncetion --- .github/workflows/build-ci.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 4c5ec127a..60791cd17 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -44,10 +44,6 @@ jobs: - { os: ubuntu-latest, php: 8.1, mongodb: '4.4', experimental: false } - { os: ubuntu-latest, php: 8.1, mongodb: '5.0', experimental: false } services: - mongo: - image: mongo:${{ matrix.mongodb }} - ports: - - 27017:27017 mysql: image: mysql:5.7 ports: @@ -61,7 +57,7 @@ jobs: - uses: actions/checkout@v2 - name: Creating MongoDB replica run: | - docker run --name mongodb -e MONGO_INITDB_DATABASE=unittest --detach mongo:${{ matrix.mongodb }} mongod --replSet rs + docker run --name mongodb -p 27017:27017 -e MONGO_INITDB_DATABASE=unittest --detach mongo:${{ matrix.mongodb }} mongod --replSet rs until docker exec --tty mongodb mongo 127.0.0.1:27017 --eval "db.serverStatus()"; do sleep 1 done From cf6612950f0781b5a6d52c89820b582a3d5d1b3d Mon Sep 17 00:00:00 2001 From: levon80999 Date: Thu, 20 Oct 2022 16:00:40 +0400 Subject: [PATCH 86/87] Cs fixer --- src/Concerns/TransactionManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Concerns/TransactionManager.php b/src/Concerns/TransactionManager.php index bced945b6..d84cd4ab4 100644 --- a/src/Concerns/TransactionManager.php +++ b/src/Concerns/TransactionManager.php @@ -105,7 +105,7 @@ public function transaction(Closure $callback, $attempts = 1, array $options = [ return $callbackResult; } - private function throwExceptionIfTransactionDoesNotStart() : void + private function throwExceptionIfTransactionDoesNotStart(): void { $session = $this->getSession(); From 5b1f3a40af637fe28bb1422ecffc80bdd55d43bb Mon Sep 17 00:00:00 2001 From: levon80999 Date: Fri, 21 Oct 2022 16:10:30 +0400 Subject: [PATCH 87/87] Fix comments --- src/Concerns/TransactionManager.php | 46 ++++++++++------------------- src/Connection.php | 2 +- src/Query/Builder.php | 3 +- tests/TransactionTest.php | 4 +-- tests/config/database.php | 29 +++++------------- 5 files changed, 27 insertions(+), 57 deletions(-) diff --git a/src/Concerns/TransactionManager.php b/src/Concerns/TransactionManager.php index d84cd4ab4..380072d8e 100644 --- a/src/Concerns/TransactionManager.php +++ b/src/Concerns/TransactionManager.php @@ -11,16 +11,26 @@ trait TransactionManager { /** * A list of transaction session. - * @var Session|null */ - protected ?Session $session; + protected ?Session $session = null; /** * Get the existing session or null. */ public function getSession(): ?Session { - return $this->session ?? null; + return $this->session; + } + + private function getSessionOrThrow(): Session + { + $session = $this->getSession(); + + if ($session === null) { + throw new RuntimeException('There is no active session.'); + } + + return $session; } /** @@ -30,8 +40,6 @@ public function getSession(): ?Session * In version 4.2, MongoDB introduces distributed transactions, which adds support for multi-document transactions on sharded clusters and incorporates the existing support for multi-document transactions on replica sets. * * @see https://docs.mongodb.com/manual/core/transactions/ - * @param array $options - * @return void */ public function beginTransaction(array $options = []): void { @@ -47,35 +55,24 @@ public function beginTransaction(array $options = []): void /** * Commit transaction in this session and close this session. - * @return void */ public function commit(): void { - $this->throwExceptionIfTransactionDoesNotStart(); - $session = $this->getSession(); - - $session?->commitTransaction(); + $this->getSessionOrThrow()->commitTransaction(); } /** * Rollback transaction in this session and close this session. - * @param null $toLevel - * @return void */ public function rollBack($toLevel = null): void { - $this->throwExceptionIfTransactionDoesNotStart(); - $session = $this->getSession(); - - $session?->abortTransaction(); + $this->getSessionOrThrow()->abortTransaction(); } /** * Static transaction function realize the with_transaction functionality provided by MongoDB. * - * @param Closure $callback * @param int $attempts - * @param array $options */ public function transaction(Closure $callback, $attempts = 1, array $options = []): mixed { @@ -104,17 +101,4 @@ public function transaction(Closure $callback, $attempts = 1, array $options = [ return $callbackResult; } - - private function throwExceptionIfTransactionDoesNotStart(): void - { - $session = $this->getSession(); - - if ($session === null) { - throw new RuntimeException('There is no active session.', 206 /* NoSuchSession */); - } - - if ($session->isInTransaction() === false) { - throw new RuntimeException('There is no active transaction.', 244 /* NOT_YET_AVAILABLE_TransactionAborted */); - } - } } diff --git a/src/Connection.php b/src/Connection.php index 7a603cad9..a2a3b1f89 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -281,7 +281,7 @@ protected function getDefaultQueryGrammar() /** * @inheritdoc */ - protected function getDefaultSchemaGrammar(): Schema\Grammar + protected function getDefaultSchemaGrammar() { return new Schema\Grammar(); } diff --git a/src/Query/Builder.php b/src/Query/Builder.php index ddac6f4a6..ab14734e0 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -706,7 +706,8 @@ public function delete($id = null) $wheres = $this->compileWheres(); $options = $this->inheritConnectionOptions(); - $result = $this->collection->DeleteMany($wheres, $options); + $result = $this->collection->deleteMany($wheres, $options); + if (1 == (int) $result->isAcknowledged()) { return $result->getDeletedCount(); } diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 6839b77f3..cb9d2072e 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -406,7 +406,6 @@ public function testThrowExceptionWhenNestingTransactionInManualTransaction() public function testThrowExceptionWhenCallCommitBeforeStartTransaction(): void { $this->expectException(RuntimeException::class); - $this->expectExceptionCode(206 /* NoSuchSession */); DB::commit(); } @@ -414,7 +413,6 @@ public function testThrowExceptionWhenCallCommitBeforeStartTransaction(): void public function testThrowExceptionWhenCallRollbackBeforeStartTransaction(): void { $this->expectException(RuntimeException::class); - $this->expectExceptionCode(206 /* NoSuchSession */); DB::rollback(); } @@ -422,7 +420,7 @@ public function testThrowExceptionWhenCallRollbackBeforeStartTransaction(): void public function testThrowExceptionWhenCallRollbackAfterCommit(): void { $this->expectException(RuntimeException::class); - $this->expectExceptionCode(244 /* NOT_YET_AVAILABLE_TransactionAborted */); + DB::beginTransaction(); DB::commit(); diff --git a/tests/config/database.php b/tests/config/database.php index d5a96f519..4ed6d6cac 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -3,44 +3,32 @@ $mongoHost = env('MONGO_HOST', 'mongodb'); $mongoPort = env('MONGO_PORT') ? (int) env('MONGO_PORT') : 27017; $mysqlPort = env('MYSQL_PORT') ? (int) env('MYSQL_PORT') : 3306; +$options = [ + 'replicaSet' => 'rs', + 'connectTimeoutMS' => 100, + 'serverSelectionTimeoutMS' => 250, +]; return [ - 'connections' => [ - 'mongodb' => [ 'name' => 'mongodb', 'driver' => 'mongodb', 'host' => $mongoHost, 'database' => env('MONGO_DATABASE', 'unittest'), - 'options' => [ - 'replicaSet' => 'rs', - 'connectTimeoutMS' => 100, - 'serverSelectionTimeoutMS' => 250, - ], + 'options' => $options, ], - 'dsn_mongodb' => [ 'driver' => 'mongodb', 'dsn' => "mongodb://$mongoHost:$mongoPort", 'database' => env('MONGO_DATABASE', 'unittest'), - 'options' => [ - 'replicaSet' => 'rs', - 'connectTimeoutMS' => 100, - 'serverSelectionTimeoutMS' => 250, - ], + 'options' => $options, ], - 'dsn_mongodb_db' => [ 'driver' => 'mongodb', 'dsn' => "mongodb://$mongoHost:$mongoPort/".env('MONGO_DATABASE', 'unittest'), - 'options' => [ - 'replicaSet' => 'rs', - 'connectTimeoutMS' => 100, - 'serverSelectionTimeoutMS' => 250, - ], + 'options' => $options, ], - 'mysql' => [ 'driver' => 'mysql', 'host' => env('MYSQL_HOST', 'mysql'), @@ -53,5 +41,4 @@ 'prefix' => '', ], ], - ];