Skip to content

Commit

Permalink
Make this library compatible with xp-forge/mongodb 2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
thekid committed Aug 19, 2023
1 parent bbb7098 commit 2c38389
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 98 deletions.
3 changes: 3 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ MongoDB Sessions change log

## ?.?.? / ????-??-??

## 1.3.0 / 2023-08-19

* Made this library compatible with `xp-forge/mongodb` 2.0.0 - @thekid
* Merged PR #5: Migrate to new testing library - @thekid

## 1.2.0 / 2022-07-09
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"require" : {
"xp-framework/core": "^11.0 | ^10.0 | ^9.0 | ^8.0",
"xp-forge/sessions": "^3.0 | ^2.0 | ^1.0",
"xp-forge/mongodb": "^1.4",
"xp-forge/mongodb": "^2.0 | ^1.4",
"php" : ">=7.0.0"
},
"require-dev" : {
Expand Down
100 changes: 100 additions & 0 deletions src/test/php/web/session/mongo/unittest/CollectionV1.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php namespace web\session\mongo\unittest;

use com\mongodb\result\{Cursor, Delete, Insert, Run, Update};
use com\mongodb\{Collection, Document, Int64, ObjectId, Session};

class CollectionV1 extends Collection {
private $lookup= [];

public function __construct($documents) {
foreach ($documents as $document) {
$this->lookup[$document->id()->string()]= $document;
}
}

public function present($id) {
return isset($this->lookup[$id]);
}

public function find($query= [], Session $session= null): Cursor {

// Query will always be an ObjectId
$result= $this->lookup[$query->string()] ?? null;
return new Cursor(null, $session, [
'firstBatch' => [$result->properties()],
'id' => new Int64(0),
'ns' => 'test.sessions'
]);
}

public function insert($arg, Session $session= null): Insert {

// Argument will always be a Document
$arg['_id']= ObjectId::create();
$this->lookup[$arg['_id']->string()]= $arg;
return new Insert([], [$arg['_id']]);
}

public function run($name, array $params= [], $method= 'write', Session $session= null) {
switch ($name) {
case 'listIndexes':
return new Run(null, null, ['body' => [
'ok' => 1,
'cursor' => [
'id' => new Int64(0),
'ns' => 'test.sessions',
'firstBatch' => [[
'v' => 2,
'key' => ['_created' => 1],
'name' => '_created_1',
'expireAfterSeconds' => 1800,
]]
]
]]);

case 'findAndModify':

// Query will always be an ObjectId
$result= &$this->lookup[$params['query']['_id']->string()];
switch (key($params['update'])) {
case '$set':
foreach ($params['update']['$set'] as $name => $value) {
$result[$name]= $value;
}
break;

case '$unset':
foreach ($params['update']['$unset'] as $name => $_) {
unset($result[$name]);
}
break;
}

return new Run(null, null, ['body' => [
'lastErrorObject' => ['n' => 1, 'updatedExisting' => true],
'value' => $result->properties()
]]);

default:
throw new IllegalStateException('Unreachable code - command "'.$name.'"');
}
}

public function delete($query, Session $session= null): Delete {

// Query will either be an ObjectId or [_created => [$lt => time()]]
if ($query instanceof ObjectId) {
unset($this->lookup[$query->string()]);
$n= 1;
} else {
$n= 0;
foreach ($this->lookup as $id => $document) {
if ($document['_created']->isBefore($query['_created']['$lt'])) {
unset($this->lookup[$id]);
$n++;
}
}
}
return new Delete(['n' => $n], [$query]);
}
}
100 changes: 100 additions & 0 deletions src/test/php/web/session/mongo/unittest/CollectionV2.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php namespace web\session\mongo\unittest;

use com\mongodb\result\{Cursor, Delete, Insert, Run, Update};
use com\mongodb\{Collection, Document, Int64, ObjectId, Options};

class CollectionV2 extends Collection {
private $lookup= [];

public function __construct($documents) {
foreach ($documents as $document) {
$this->lookup[$document->id()->string()]= $document;
}
}

public function present($id) {
return isset($this->lookup[$id]);
}

public function find($query= [], Options... $options): Cursor {

// Query will always be an ObjectId
$result= $this->lookup[$query->string()] ?? null;
return new Cursor(null, $options, [
'firstBatch' => [$result->properties()],
'id' => new Int64(0),
'ns' => 'test.sessions'
]);
}

public function insert($arg, Options... $options): Insert {

// Argument will always be a Document
$arg['_id']= ObjectId::create();
$this->lookup[$arg['_id']->string()]= $arg;
return new Insert([], [$arg['_id']]);
}

public function run($name, array $params= [], $method= 'write', Options... $options) {
switch ($name) {
case 'listIndexes':
return new Run(null, null, ['body' => [
'ok' => 1,
'cursor' => [
'id' => new Int64(0),
'ns' => 'test.sessions',
'firstBatch' => [[
'v' => 2,
'key' => ['_created' => 1],
'name' => '_created_1',
'expireAfterSeconds' => 1800,
]]
]
]]);

case 'findAndModify':

// Query will always be an ObjectId
$result= &$this->lookup[$params['query']['_id']->string()];
switch (key($params['update'])) {
case '$set':
foreach ($params['update']['$set'] as $name => $value) {
$result[$name]= $value;
}
break;

case '$unset':
foreach ($params['update']['$unset'] as $name => $_) {
unset($result[$name]);
}
break;
}

return new Run(null, null, ['body' => [
'lastErrorObject' => ['n' => 1, 'updatedExisting' => true],
'value' => $result->properties()
]]);

default:
throw new IllegalStateException('Unreachable code - command "'.$name.'"');
}
}

public function delete($query, Options... $options): Delete {

// Query will either be an ObjectId or [_created => [$lt => time()]]
if ($query instanceof ObjectId) {
unset($this->lookup[$query->string()]);
$n= 1;
} else {
$n= 0;
foreach ($this->lookup as $id => $document) {
if ($document['_created']->isBefore($query['_created']['$lt'])) {
unset($this->lookup[$id]);
$n++;
}
}
}
return new Delete(['n' => $n], [$query]);
}
}
103 changes: 6 additions & 97 deletions src/test/php/web/session/mongo/unittest/MongoTest.class.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?php namespace web\session\mongo\unittest;

use com\mongodb\result\{Cursor, Delete, Insert, Run, Update};
use com\mongodb\{Collection, Document, Int64, ObjectId, Session};
use com\mongodb\{Collection, Document, ObjectId, Options};
use lang\IllegalStateException;
use test\{Assert, Expect, Test};
use util\{Date, Dates};
Expand All @@ -11,101 +10,11 @@ class MongoTest {

/** Returns a MongoDB collection with documents */
private function collection($documents) {
return new class($documents) extends Collection {
private $lookup= [];

public function __construct($documents) {
foreach ($documents as $document) {
$this->lookup[$document->id()->string()]= $document;
}
}

public function present($id) {
return isset($this->lookup[$id]);
}

public function find($query= [], Session $session= null): Cursor {

// Query will always be an ObjectId
$result= $this->lookup[$query->string()] ?? null;
return new Cursor(null, $session, [
'firstBatch' => [$result->properties()],
'id' => new Int64(0),
'ns' => 'test.sessions'
]);
}

public function insert($arg, Session $session= null): Insert {

// Argument will always be a Document
$arg['_id']= ObjectId::create();
$this->lookup[$arg['_id']->string()]= $arg;
return new Insert([], [$arg['_id']]);
}

public function run($name, array $params= [], $method= 'write', Session $session= null) {
switch ($name) {
case 'listIndexes':
return new Run(null, null, ['body' => [
'ok' => 1,
'cursor' => [
'id' => new Int64(0),
'ns' => 'test.sessions',
'firstBatch' => [[
'v' => 2,
'key' => ['_created' => 1],
'name' => '_created_1',
'expireAfterSeconds' => 1800,
]]
]
]]);

case 'findAndModify':

// Query will always be an ObjectId
$result= &$this->lookup[$params['query']['_id']->string()];
switch (key($params['update'])) {
case '$set':
foreach ($params['update']['$set'] as $name => $value) {
$result[$name]= $value;
}
break;

case '$unset':
foreach ($params['update']['$unset'] as $name => $_) {
unset($result[$name]);
}
break;
}

return new Run(null, null, ['body' => [
'lastErrorObject' => ['n' => 1, 'updatedExisting' => true],
'value' => $result->properties()
]]);

default:
throw new IllegalStateException('Unreachable code - command "'.$name.'"');
}
}

public function delete($query, Session $session= null): Delete {

// Query will either be an ObjectId or [_created => [$lt => time()]]
if ($query instanceof ObjectId) {
unset($this->lookup[$query->string()]);
$n= 1;
} else {
$n= 0;
foreach ($this->lookup as $id => $document) {
if ($document['_created']->isBefore($query['_created']['$lt'])) {
unset($this->lookup[$id]);
$n++;
}
}
}
return new Delete(['n' => $n], [$query]);
}
};
if (class_exists(Options::class)) {
return new CollectionV2($documents);
} else {
return new CollectionV1($documents);
}
}

#[Test]
Expand Down

0 comments on commit 2c38389

Please sign in to comment.