Skip to content

Commit

Permalink
Merge cfb7aee into a7acac7
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyasokay committed Apr 9, 2020
2 parents a7acac7 + cfb7aee commit 65a3791
Show file tree
Hide file tree
Showing 7 changed files with 258 additions and 12 deletions.
14 changes: 13 additions & 1 deletion .github/workflows/build-ci.yml
Expand Up @@ -28,9 +28,19 @@ jobs:
MYSQL_DATABASE: 'unittest'
MYSQL_ROOT_PASSWORD:
name: PHP v${{ matrix.php }} with Mongo v${{ matrix.mongodb }}

steps:
- 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${{ matrix.php }} -v && composer -V
- name: Show Docker version
Expand All @@ -53,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
Expand Down
5 changes: 5 additions & 0 deletions phpunit.xml.dist
Expand Up @@ -36,6 +36,9 @@
<testsuite name="mysqlrelations">
<file>tests/RelationsTest.php</file>
</testsuite>
<testsuite name="transaction">
<file>tests/TransactionTest.php</file>
</testsuite>
<testsuite name="validation">
<file>tests/ValidationTest.php</file>
</testsuite>
Expand All @@ -47,6 +50,8 @@
</filter>
<php>
<env name="MONGO_HOST" value="mongodb"/>
<env name="MONGO_VERSION" value="4"/>
<env name="MONGO_REPL_HOST" value="mongodb_repl"/>
<env name="MONGO_DATABASE" value="unittest"/>
<env name="MONGO_PORT" value="27017"/>
<env name="MYSQL_HOST" value="mysql"/>
Expand Down
39 changes: 39 additions & 0 deletions src/Jenssegers/Mongodb/Connection.php
Expand Up @@ -9,6 +9,11 @@

class Connection extends BaseConnection
{
/**
* The MongoDB session handler.
*/
protected $session;

/**
* The MongoDB database handler.
* @var \MongoDB\Database
Expand Down Expand Up @@ -267,6 +272,40 @@ protected function getDefaultSchemaGrammar()
return new Schema\Grammar();
}

public function beginTransaction(array $options = [])
{
if (!$this->getSession()) {
$this->session = $this->getMongoClient()->startSession();
$this->session->startTransaction($options);
}
}

public function commit()
{
if ($this->getSession()) {
$this->session->commitTransaction();
$this->clearSession();
}
}

public function rollBack($toLevel = null)
{
if ($this->getSession()) {
$this->session->abortTransaction();
$this->clearSession();
}
}

protected function clearSession()
{
$this->session = null;
}

public function getSession()
{
return $this->session;
}

/**
* Dynamically pass methods to the connection.
* @param string $method
Expand Down
30 changes: 22 additions & 8 deletions src/Jenssegers/Mongodb/Query/Builder.php
Expand Up @@ -562,8 +562,10 @@ public function insert(array $values)
$values = [$values];
}

$options = $this->session();

// Batch insert
$result = $this->collection->insertMany($values);
$result = $this->collection->insertMany($values, $options);

return (1 == (int) $result->isAcknowledged());
}
Expand All @@ -573,7 +575,9 @@ public function insert(array $values)
*/
public function insertGetId(array $values, $sequence = null)
{
$result = $this->collection->insertOne($values);
$options = $this->session();

$result = $this->collection->insertOne($values, $options);

if (1 == (int) $result->isAcknowledged()) {
if ($sequence === null) {
Expand All @@ -595,7 +599,7 @@ public function update(array $values, array $options = [])
$values = ['$set' => $values];
}

return $this->performUpdate($values, $options);
return $this->performUpdate($values, array_merge($options, $this->session()));
}

/**
Expand All @@ -616,15 +620,15 @@ public function increment($column, $amount = 1, array $extra = [], array $option
$query->orWhereNotNull($column);
});

return $this->performUpdate($query, $options);
return $this->performUpdate($query, array_merge($options, $this->session()));
}

/**
* @inheritdoc
*/
public function decrement($column, $amount = 1, array $extra = [], array $options = [])
{
return $this->increment($column, -1 * $amount, $extra, $options);
return $this->increment($column, -1 * $amount, $extra, array_merge($options, $this->session()));
}

/**
Expand Down Expand Up @@ -674,8 +678,9 @@ public function delete($id = null)
$this->where('_id', '=', $id);
}

$options = $this->session();
$wheres = $this->compileWheres();
$result = $this->collection->DeleteMany($wheres);
$result = $this->collection->DeleteMany($wheres, $options);
if (1 == (int) $result->isAcknowledged()) {
return $result->getDeletedCount();
}
Expand Down Expand Up @@ -704,7 +709,7 @@ public function truncate()
'typeMap' => ['root' => 'object', 'document' => 'object'],
];

$result = $this->collection->drop($options);
$result = $this->collection->drop(array_merge($options, $this->session()));

return (1 == (int) $result->ok);
}
Expand Down Expand Up @@ -833,7 +838,7 @@ protected function performUpdate($query, array $options = [])
}

$wheres = $this->compileWheres();
$result = $this->collection->UpdateMany($wheres, $query, $options);
$result = $this->collection->UpdateMany($wheres, $query, array_merge($options, $this->session()));
if (1 == (int) $result->isAcknowledged()) {
return $result->getModifiedCount() ? $result->getModifiedCount() : $result->getUpsertedCount();
}
Expand Down Expand Up @@ -1153,6 +1158,15 @@ public function options(array $options)
return $this;
}

protected function session(array $options = [])
{
if ($session = $this->connection->getSession()) {
$options['session'] = $this->connection->getSession();
}

return $options;
}

/**
* @inheritdoc
*/
Expand Down
1 change: 1 addition & 0 deletions tests/TestCase.php
Expand Up @@ -51,6 +51,7 @@ protected function getEnvironmentSetUp($app)
$app['config']->set('database.default', 'mongodb');
$app['config']->set('database.connections.mysql', $config['connections']['mysql']);
$app['config']->set('database.connections.mongodb', $config['connections']['mongodb']);
$app['config']->set('database.connections.mongodb_repl', $config['connections']['mongodb_repl']);
$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']);
Expand Down
161 changes: 161 additions & 0 deletions tests/TransactionTest.php
@@ -0,0 +1,161 @@
<?php

declare(strict_types=1);

class TransactionTest extends TestCase
{
public $connection = 'mongodb_repl';

public function setUp(): void
{
parent::setUp();

Schema::create('users');
}

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
{
parent::setUp();

User::on($this->connection)->truncate();
DB::collection('users')->truncate();
Schema::drop('users');
}

public function testCommitTransaction(): void
{
/**
* Insert Commit
*/
try {
DB::beginTransaction();

User::on($this->connection)->insert([
'name' => 'John Doe'
]);

DB::commit();
} catch (Exception $e) {
DB::rollBack();

dd($e);

$this->assertTrue(false);
}

$this->assertTrue(User::on($this->connection)->where('name', 'John Doe')->exists());

/**
* Update Commit
*/
try {
DB::beginTransaction();

User::on($this->connection)->where('name', 'John Doe')->update([
'name' => 'Jane Doe'
]);

DB::commit();
} catch (Exception $e) {
DB::rollBack();

$this->assertTrue(false);
}

$this->assertTrue(User::on($this->connection)->where('name', 'Jane Doe')->exists());

/**
* Delete Commit
*/
try {
DB::beginTransaction();

User::on($this->connection)->where('name', 'Jane Doe')->delete();

DB::commit();
} catch (Exception $e) {
DB::rollBack();

$this->assertTrue(false);
}

$this->assertFalse(User::on($this->connection)->where('name', 'Jane Doe')->exists());
}

public function testRollbackTransaction(): void
{
try {
DB::beginTransaction();

User::on($this->connection)->insert([
'name' => 'John Doe'
]);

DB::rollBack();
} catch (Exception $e) {
DB::rollBack();

$this->assertTrue(false);
}

$this->assertFalse(User::on($this->connection)->where('name', 'John Doe')->exists());

try {
DB::beginTransaction();

User::on($this->connection)->insert([
'name' => 'John Doe'
]);

DB::commit();
} catch (Exception $e) {
DB::rollBack();

$this->assertTrue(false);
}

$this->assertTrue(User::on($this->connection)->where('name', 'John Doe')->exists());

try {
DB::beginTransaction();

User::on($this->connection)->where('name', 'John Doe')->update([
'name' => 'Jane Doe'
]);

DB::rollBack();
} catch (Exception $e) {
DB::rollBack();

$this->assertTrue(false);
}

$this->assertTrue(User::on($this->connection)->where('name', 'John Doe')->exists());

try {
DB::beginTransaction();

User::on($this->connection)->where('name', 'John Doe')->delete();

DB::rollBack();
} catch (Exception $e) {
DB::rollBack();

$this->assertTrue(false);
}

$this->assertTrue(User::on($this->connection)->where('name', 'John Doe')->exists());
}
}

0 comments on commit 65a3791

Please sign in to comment.