Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion .github/workflows/build-ci.yml
Original file line number Diff line number Diff line change
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
67 changes: 65 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ services:
- .:/code
working_dir: /code
depends_on:
- mongodb
- mysql
- mongodb
- mongodb_repl
- mongodb_repl_2
- mongodb_repl_3
- mongo_repl_init
- mysql

mysql:
container_name: mysql
Expand All @@ -30,3 +34,62 @@ services:
- 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
links:
- mongodb_repl_2:mongodb_repl_2
- mongodb_repl_3: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" ]
logging:
driver: none

mongo_repl_init:
image: mongo:4.2.5
depends_on:
- 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
39 changes: 39 additions & 0 deletions mongo-repl-init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash
mongodb1=`getent hosts ${MONGO1} | awk '{ print $1 }'`

port=${PORT:-27018}

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

echo "Started.."

echo setup.sh time now: `date +"%T" `
mongo --host ${mongodb1}:${port} <<EOF
var cfg = {
"_id": "${RS}",
"protocolVersion": 1,
"members": [
{
"_id": 0,
"host": "${MONGO1}:${port}",
"priority": 2
},
{
"_id": 1,
"host": "${MONGO2}:${port}",
"priority": 0
},
{
"_id": 2,
"host": "${MONGO3}:${port}",
"priority": 0
}
]
};
rs.initiate(cfg, { force: true });
rs.reconfig(cfg, { force: true });
EOF
5 changes: 5 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
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_REPL_HOST" value="mongodb_repl"/>
<env name="MONGO_VERSION" value="4"/>
<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
Original file line number Diff line number Diff line change
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 = [])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the expected behaviour if a transaction is already in progress?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @alcaeus , there is another PR which looks promising. If you'd like and have a time, please take a look #1904

Thanks!

{
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
40 changes: 32 additions & 8 deletions src/Jenssegers/Mongodb/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -562,8 +562,20 @@ public function insert(array $values)
$values = [$values];
}

$options = $this->session();

// Check if table exists for multi-document transaction, otherwise create table.
if (!empty($options)) {
$schemaBuilder = $this->connection->getSchemaBuilder();
$tableName = $this->collection->getCollectionName();

if (!$schemaBuilder->hasTable($tableName)) {
$schemaBuilder->create($tableName);
}
}

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

return (1 == (int) $result->isAcknowledged());
}
Expand All @@ -573,7 +585,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 +609,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 +630,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 +688,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 +719,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 +848,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()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per signature below:

Suggested change
$result = $this->collection->UpdateMany($wheres, $query, array_merge($options, $this->session()));
$result = $this->collection->UpdateMany($wheres, $query, $this->session($options));

There are a few more instances of this in the class.

if (1 == (int) $result->isAcknowledged()) {
return $result->getModifiedCount() ? $result->getModifiedCount() : $result->getUpsertedCount();
}
Expand Down Expand Up @@ -1153,6 +1168,15 @@ public function options(array $options)
return $this;
}

protected function session(array $options = [])
{
if ($session = $this->connection->getSession()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion to not override an existing session:

Suggested change
if ($session = $this->connection->getSession()) {
if (!isset($options['session']) && $session = $this->connection->getSession()) {

$options['session'] = $this->connection->getSession();
}

return $options;
}

/**
* @inheritdoc
*/
Expand Down
1 change: 1 addition & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
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
Loading