Result counts and dynamic queries

A query is always dynamic and returns results that may change if you use the object again. Some rows may have been added, changed, or removed from the database from one use of the query object to another use of the query, even within the same function.

The Count property of a query gets the current count of items. Do not rely on the count number remaining constant. That number might be useful in some contexts such as simple user interface messages such as “Displaying items 1-10 out of 236 results”. However, that count might be different from the number of items returned from a query even if you iterate across the result set immediately after retrieving the count. Other actions may add, change, or remove rows from the database between the time you access the Count property and when you iterate across the results.

Unsafe usage:

// Bad example. Do NOT follow this example. Do NOT rely on the result count staying constant! 

uses gw.api.database.Query

// create a query
var query = Query.make(User)

// THE FOLLOWING LINE IS UNSAFE
var myArray = new User[ query.select().Count ]

for (user in query.select() index y) {
  // This line throws an out-of-bounds exception if more results appear after the count calculation
   myArray[y] = user
}

Code like the previous example risks throwing array-out-of-bounds errors at run time. Adding a test to avoid the exception risks losing records from the result.

Instead, iterate across the set and count upward, appending query result entities to an ArrayList.

Safe usage:

uses gw.api.database.Query
uses java.util.ArrayList

var query = Query.make(User)

// Create a new list, and use generics to parameterize it
var myList = new ArrayList<User>()

for (user in query.select()) {
  // Add a row to the list
  myList.add(user) 
}

Calling query.select() does not snapshot the current value of the result set forever. When you access the query.select().Count property, PolicyCenter runs the query but the query results can change quickly. Database changes could happen in another thread on the current server or on another server in the cluster.