Better inspection — GT-Tools to the rescue

Is’nt there a better way to navigate and inspect these objects? Especially as we now know that we can navigate already by using Smalltalk expresssions:

from Mongo to the database

from a database to included collections

and from a collection to its persisted documents

Lets get deeper into GT-Tools. If you havent already done I would recommend the reader to checkout some web infos/documentation on GT-Tools first, there are various source like the official webpage or blog posts on extending the inspector itself.

Basically all GT-Tools (like Spotter or the GT Inspector) can be extended and customized easily. For our need here we have to know that we can extend the inspector representation of an object by providing a method annotated with specific pragmas.

With this knowledge the first step done is to create a new package “Mongo-Pharo-Tools” and implement the following instance side method in the Mongo class:

gtInspectorDatabasesIn: composite

<gtInspectorPresentationOrder: 40>

<gtInspectorTag: #basic>



composite list

title: 'Databases';

display: [ self databases ];

when: [ self isOpen ]

As we see this method includes some GT-Tools pragmas defining that we want to have an own inspector representation.

Lets see the effect by inspecting our Mongo instance again:

Mongo default open inspect

and magically we have a new tab called “Databases” listing all the databases:

By using the <gtInspectorPresentationOrder: x> pragma the inspector will find your custom inspector extension, the provided number x (here 40) is some kind of weight to specify the tab order compared to existing tabs.

The <gtInspectTag: aSymbol> is for grouping the extensions and will be explained later.

As you see the method has one argument that is provided from the outside: a composite view that we can ask to provide a list view. We have to provide the title and contents of the list —in this case our collection of databases.

The additional #when: in the method makes sure that this new tab is only displayed when the mongo connection is open. That means the tab will not be there when you just inspect Mongo without opening it first:

Mongo default inspect

But lets move on and inspect the Mongo DB instance again with our new “Database” tab:

Mongo default open inspect

Now when we click on one of the items in the database list the inspector shows a new pane to the right inspecting the selected Mongo database object:

Cool — with this we have our first navigation step and can already navigate from a Mongo object to an included database like “MyDB”.

That’s not enough. For the new MongoDatabase instance that is shown on the right inspector pane we now want to have a new additional tab again showing the collections of the database. Therefore we need to add another instance side method extending our inspector toolset. This time we provide a method on the MongoDatabase class:

gtInspectorCollectionsIn: composite

<gtInspectorPresentationOrder: 40>

<gtInspectorTag: #basic>



composite list

title: 'Collections';

display: [ self collections ];

when: [ self collections notEmpty ]

This tab should only be shown when we have collections in the database, therefore we check if the collection is empty or not.

Inspecting

Mongo default open

again we can now navigate:

from Mongo to the database

from a database to included collections

To implement our third and last navigation step (from a collection to its persisted documents) we again need to add another instance side method, this time it has to be on class MongoCollection:

gtInspectorDictionariesIn: composite

<gtInspectorPresentationOrder: 40>

<gtInspectorTag: #basic>



composite list

title: 'Documents';

display: [ self select: Dictionary new ];

when: [ (self select: Dictionary new) notEmpty ]

Again we get a new tab and we can now see the three documents stored in the Persons collection.

But the default representation of the three document items is not what we expect as we can not distinguish the items in the list. Robomongo is still better and displays the document id for each document — can we have that in our new Pharo tool as well? Yes!

One hast know that in Mongo databases each document has a unique object id, typically represented by the value of the “_id” key in the JSON representation.

So the only thing we have to do is to use the #format: method to provide a better string representation of the document objects when displayed as a list items:

gtInspectorDictionariesIn: composite

<gtInspectorPresentationOrder: 40>

<gtInspectorTag: #basic>



composite list

title: 'Documents';

display: [ self select: Dictionary new ];

format: [:each | (each at: #_id) asString ];

when: [ (self select: Dictionary new) notEmpty ]

Much better! Did you see the small bullets at the bottom of the window? You can use them to navigate back and forward.

So with three simple extension methods we are now able to navigate through our virtual object graph with our customized inspect. Amazing!