-
Notifications
You must be signed in to change notification settings - Fork 208
Split and modify CRUD examples #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?php | ||
|
||
$batch = new \MongoDB\Batch\InsertBatch(); | ||
$batch | ||
->add($hannes) | ||
->add($hayley); | ||
|
||
$writeOptions = array( | ||
"ordered" => true, | ||
"writeConcern" => array( | ||
"w" => 3, | ||
"wtimeout" => 42, | ||
), | ||
); | ||
|
||
$mm = new \MongoDB\Manager("mongodb://server1,server2/?replicaSet=FOOBAR"); | ||
|
||
$results = $mm->executeWrite("db.collection", $batch, $writeOptions); | ||
|
||
assert($results instanceof \MongoDB\WriteResults); | ||
|
||
printf( | ||
"Inserted %d documents %s in %d msec\n", | ||
$results->getOpCount(), | ||
$results->getServer()->getHostname(), | ||
$results->getTimer() | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
<?php | ||
|
||
class Person implements BsonSerializable { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Renamed Mongolizable to BsonSerializable. This mimics JsonSerializable and I don't see the harm in referring to BSON if we're already going to do it in the type mappings elsewhere. |
||
protected $name; | ||
protected $nick; | ||
protected $addresses = array(); | ||
|
||
function __construct($name, $nick, array $addresses) { | ||
$this->name = $name; | ||
$this->nick = $nick; | ||
foreach($addresses as $address) { | ||
if ($address instanceof Address) { | ||
$this->addresses[] = $address; | ||
} | ||
} | ||
} | ||
|
||
function getAddresses() { | ||
return $this->addresses; | ||
} | ||
} | ||
|
||
class Address implements BsonSerializable { | ||
protected $address; | ||
protected $country; | ||
|
||
function __construct($address, Country $country) { | ||
$this->address = $address; | ||
$this->country = $country; | ||
} | ||
|
||
function getCountry() { | ||
return $this->country; | ||
} | ||
} | ||
|
||
class Country implements BsonSerializable { | ||
protected $name; | ||
|
||
function __construct($name) { | ||
$this->name; | ||
} | ||
|
||
function getName() { | ||
return $name; | ||
} | ||
} | ||
|
||
$norway = new Country("Norway"); | ||
$iceland = new Country("Iceland"); | ||
$usa = new Country("USA"); | ||
|
||
$menlo = new Address("22 Coleman Pl", $usa); | ||
|
||
$addresses = array( | ||
new Address("Dynekilgata 15", $norway), | ||
new Address("Mánabraut 4", $iceland), | ||
$menlo, | ||
); | ||
|
||
$hannes = new Person("Hannes", "bjori", $addresses); | ||
$hayley = new Person("Hayley", "Ninja", array($menlo)); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?php | ||
|
||
$queryDocument = array( | ||
'$query' => array("name" => "Hannes"), | ||
'$orderBy' => array('name' => 1), | ||
'$comment' => 'More special stuff', | ||
); | ||
|
||
$queryFields = array( | ||
'fieldname' => 1, | ||
'fieldname.two' => 1, | ||
); | ||
|
||
$flags = EXHAUST | NO_CURSOR_TIMEOUT; | ||
$limit = -3; // Kill server cursor after 3 documents | ||
$skip = 0; // Don't skip any documents | ||
|
||
$query = new \MongoDB\Query($queryDocument, $queryFields, $flags, $limit, $skip); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alternatively, this could be a single argument with an array of our own concept query options:
I'm against the original design, which had the selector, flags, limit, and skip options within the query document, as that requires C code to pluck out options before we can send anything to libmongoc. Also, there is a hypothetical situation if the server added a All that said, I would support having Query's constructor take a single array of options instead of separate arguments, as I know having a constructors with many args (many of which are optional in their own right) is asking for trouble down the line if we need to change the API. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. $limit, $skip order will forever require quick documentation lookup. I think having these as separate arguments will is indeed asking for problems down the line. I don't understand the difference between your suggested alternative vs the original suggestion.. So refactor this into an array of our own query options as you suggested please :) |
||
|
||
$readPreference = array( | ||
"type" => 'secondaryPreferred', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Read preferences are strings, so I don't think the base driver needs to enforce constants. That is easily maintained in PHP userland, unless we need to throw exceptions for unrecognized read preferences? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I actually think it was a bad call to make it an array. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To that end, shouldn't WriteOptions and possible WriteConcern also have their own class? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes :) |
||
"tags" => array( | ||
array("dc:eu", "cpu:fast"), | ||
array("dc:eu", "cc:is"), | ||
array(""), | ||
), | ||
); | ||
|
||
$mm = new \MongoDB\Manager("mongodb://server1,server2/?replicaSet=FOOBAR"); | ||
|
||
$cursor = $mm->executeQuery("db.collection", $query, $readPreference); | ||
|
||
assert($cursor instanceof \MongoDB\Cursor); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previously, this was QueryResult. I'm not sure what the relation of that class would be to the result of a command, which would also be iterable (i.e. Traversable in PHP) and possibly a cursor. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking an intermediate step from query execution to the actual cursor. QueryResult would implement IteratorAggregate and return a Cursor which would only be that, a iterable cursor. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That makes sense and I believe we talked about that, too. It wasn't clear from the |
||
|
||
foreach($cursor as $person) { | ||
printf( | ||
"%s has lived in %s\n", | ||
$person->getName(), | ||
$person->getAddresses()[0]->getCountry()->getName() | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other than InsertBatch telling us that the operations are inserts (by its class name), I don't see why we shouldn't just pass in an array of operations. This would mean we'd have specific methods like
executeInsert()
, which I think is fine. In the C code, it means there's no need to check the class and then branch off internally to the appropriate write method in libmongoc. Also, being able to pass an array of operations (e.g. documents to insert or the update arguments) in one shot addresses @derickr's concern about having a simple interface.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having a classname makes it easier and cleaner to validate the actual operations.
Having to validate enormous array all the time is both complex and not something you want to have multiple branches of in one method.
Allow individual classes to provide their own validation and then simply be typehinted simplifies the entire chain of events and allows us to keep small pieces of selfcontained code.
Having an executeInsert(array($document1, $document2)); is begging for validation issues and "whops, I did executeInsert($document)"
Providing a \MongoDB\Manager\CRUD->insertOne($document); is a trivial wrapper though we could also provide as part of the extension as a simplified helper API....