Skip to content

PHPLIB-547: Add helpers to list database and collection names #758

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

Merged
merged 2 commits into from
Jul 7, 2020

Conversation

alcaeus
Copy link
Member

@alcaeus alcaeus commented Jun 29, 2020

@alcaeus alcaeus requested a review from jmikola June 29, 2020 12:05
@alcaeus alcaeus self-assigned this Jun 29, 2020
Return Values
-------------

A generator containing the name of each database on the server.
Copy link
Member

Choose a reason for hiding this comment

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

Can we link to the PHP class with:

:php:`Generator <class.generator.php>`

Also, would it be more correct to write "a generator that yields that name of each..." or "a generator, which yields...", rather than "containing"?

Copy link
Member

Choose a reason for hiding this comment

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

Since this hasn't been changed yet, please see my other comment about only documenting a Traversable or Iterator. There may not be any reason to inform users that we're using Generators internally.

src/Client.php Outdated
* @throws InvalidArgumentException for parameter/option parsing errors
* @throws DriverRuntimeException for other driver errors (e.g. connection errors)
*/
public function listDatabaseNames(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.

Do we want to use : Generator as a return type hint here, or are we putting off adding those to our public API until we do so across the board?

Copy link
Member Author

Choose a reason for hiding this comment

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

I've started adding them to new methods, but forgot them in this case. I added type hints now.

Copy link
Member

Choose a reason for hiding this comment

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

Just left a related comment about this on the Database::listCollectionNames method. Perhaps it makes sense to only document that we return a Traversable or Iterator.

throw new UnexpectedValueException('listDatabases command did not return a "databases" array');
}

// Using array_column here emulates nameOnly behavior for servers that don't support it and ensures a consistent return type
Copy link
Member

Choose a reason for hiding this comment

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

This is what I'd suggest moving to ListDatabaseNames, which currently just yields from this result directly. I suppose doing yield from array_column($result['databases'], 'name') would be cheaper than using the CallbackIterator, especially since the result is already an array (unlike a potentially large listCollections response, where iterators may conserve memory).

Copy link
Member Author

Choose a reason for hiding this comment

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

array_column won't work here since the ListCollections command returns a CachingIterator over the result cursor, which is why I added the iterator on top of that.

Copy link
Member

Choose a reason for hiding this comment

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

We're talking about ListDatabases here, though, which always returns an array. Am I misunderstanding?

Copy link
Member Author

Choose a reason for hiding this comment

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

Apologies, I got confused. ListDatabaseNames uses array_column since we're already dealing with an array.

src/Database.php Outdated
*
* @see ListCollectionNames::__construct() for supported options
* @param array $options
* @return Generator
Copy link
Member

Choose a reason for hiding this comment

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

In the interest of a conservative public API, I wonder if we should just document that we return a Traversable or Iterator. This would be similar to how I only documented a generic CollectionInfoIterator return type for the listCollections method. Granted, that was the abstract the user from thinking about legacy and cursor-based responses, but it was also suggesting that the only thing they need care about was that the current element is a CollectionInfo object.

Generator has additional methods like send() that I expect would have no use, so the fact that we happen to use a generator here seems like an implementation detail best not revealed.

Copy link
Member Author

Choose a reason for hiding this comment

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

Generators can only be iterated once and can't be rewound, so I think the distinction is important to make sure people don't expect to repeatedly iterate over the same list of names.

Copy link
Member

@jmikola jmikola Jul 2, 2020

Choose a reason for hiding this comment

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

Ah, good point. That sounds like a possible deviation from the rewindable iterators returned by listDatabases and listCollections, though. Is it possible to wrap the generator with our CachingIterator. That would save users from having to ever care about this.

If we do make this change, I would then suggest we document an Iterator return value, since Traversable is not inherently rewindable.

Two side notes:

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point. ListCollectionNames now returns the CallbackIterator directly since we already have a CachingIterator below. ListDatabaseNames returns an ArrayIterator to iterate over the array of names. This can then always be changed to return a CachingIterator or other iterator should the listDatabases command ever be changed to returning a cursor.

src/Client.php Outdated
* @throws InvalidArgumentException for parameter/option parsing errors
* @throws DriverRuntimeException for other driver errors (e.g. connection errors)
*/
public function listDatabaseNames(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.

Just left a related comment about this on the Database::listCollectionNames method. Perhaps it makes sense to only document that we return a Traversable or Iterator.

Return Values
-------------

A generator containing the name of each database on the server.
Copy link
Member

Choose a reason for hiding this comment

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

Since this hasn't been changed yet, please see my other comment about only documenting a Traversable or Iterator. There may not be any reason to inform users that we're using Generators internally.

@alcaeus alcaeus merged commit de6950b into mongodb:v1.7 Jul 7, 2020
@alcaeus alcaeus deleted the phplib-547 branch July 7, 2020 07:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants