3.4 Remote Collections
Another feature introduced in ReStore 1.20 is Remote Collections. These are an efficiency mechanism which can be used to improve the performance of your application.
As already mentioned, ReStore fetches data from the database and creates objects as and when they are referenced (sent a message). This includes collections owned by persistent objects. A potential problem with this is that collection objects can be very large - for example, sending
selectedCustomer orders size
...could result in hundreds of Order records being fetched from the database (for a very good customer!) just to evaluate the message size. Since interaction with the database is likely to be the slowest part of your application (particularly with a remote database), reducing such performance hits is important.
Fortunately, ReStore provides a mechanism that allows you to treat collections owned by persistent objects in the same way as an instancesOf: collection. This is done by sending the message remote to the collection. Thus, the above example becomes:
selectedCustomer orders remote size
When expressed in this way, the message size is translated to an SQL 'count' query, in exactly the same way as with an instancesOf: collection. In this way, the size of the collection is determined without the penalty of fetching every member of the collection from the database. Other examples:
"Look for a customer's specific order without bringing every order into memory"
selectedCustomer orders remote detect: [ :each | each orderRef = 'OR123']
"Has the customer placed an order recently?"
selectedCustomer orders remote anySatisfy:
[ :each | each date >= (Date today subtractMonths: 1)]
The remote message is useful in circumstances when you are certain that a particular collection has not already been referenced (e.g. on a summary screen). However, there is little point in addressing the collection remotely if the 'hit' of fetching it from the database has already been incurred.
For circumstances where you are not certain whether the real collection has already been referenced (or not), ReStore allows your application to either address the collection remotely, or use the available in-memory copy, as appropriate. This is done by using the message orRemote in place of remote. If the collection is already in memory, orRemote returns the actual collection; if not, then an equivalent instancesOf: collection is returned.
Since an actual Smalltalk collection responds to the majority of the same messages as an instancesOf: collection, the two can usually be used interchangeably.
When using remote collections, it is worth bearing in mind that any messages are evaluated against the collection as it appears in the database. Thus if you have changed the collection in memory (but not committed those changes to the database) you may obtain different results depending on whether you address the remote collection or the in-memory copy.
3.4 Remote Collections