Querying Database Objects
You can read data values for multiple database objects using query methods in the Model Manager API. You have already seen examples of this for database configurations and repositories earlier in the section. As the number of objects in a database can potentially be large, these query methods return so-called result streams from which individual elements can be retrieved on demand. You may, for example, build an application in the Application Builder that shows the latest couple of versions of a model in a suitable form object. In that case, it would typically be wasteful to first fetch data for all versions from the database in the app and then immediately discard all but a few to show in the form object.
All result streams in the Model Manager API extend DatabaseApiResultStream. You can read the first element from the result stream, read a fixed number of elements from the result stream as a list or an array, or you can traverse the elements in the result stream using loop constructs.
The elements in the result stream only contain data values — they are not a representation of the database objects themselves. You may, for example, obtain a result stream whose elements correspond to a mix of model versions and file versions when querying items in the database. You can always obtain the corresponding database object from an element using its identifying key — see also Navigating a Model Manager Database.
Examples
Get the first branch created in a repository by querying all branches sorted on created date and then using the firstOrNull method on the result stream.
QueryBranchesParamGenerator p = DatabaseApiUtil.param()
  .forQueryBranches()
  .withSortByCreated();
QueryBranchResultStream resultStream = repository
  .queryBranches(p);
QueryBranchResult result = resultStream.firstOrNull();
Branch branch = repository.branchByKey(result.branchKey());
When you expect that a query should only return a single element — anything else to be considered an error — you can use the single method on the result stream. Find the latest version of a model with a specific filename, with the filename expected to be unique for models on the branch.
Branch branch = database.defaultRepository().defaultBranch();
 
// Filters can be specified using the Model Manager search syntax.
SearchBranchItemResultStream resultStream = branch
  .searchItems("@filename:my_model.mph");
 
// The single-method throws if the result stream does not contain
// exactly one element.
SearchBranchItemResult r = resultStream.single();
BranchModelItem branchModelItem = branch.modelByKey(r.itemKey());
You can read any number of elements from the stream into a list or an array. Read data values for the ten most recently saved versions of a file item in a branch.
// The itemKey variable is assumed to be initialized elsewhere.
BranchFileItem branchFileItem = branch.fileByKey(itemKey);
QueryItemVersionHistoryResultStream resultStream = branchFileItem
  .queryVersionHistory();
 
// You can use either a list or an array depending on preference.
java.util.List<QueryItemVersionHistoryResult> list = resultStream
  .toList(10);
QueryItemVersionHistoryResult[] array = resultStream
  .toArray(10);
When you need to traverse a large number of database objects from a result stream, it is better to use a for-each loop statement. Save the latest versions of all models from one source database to another target database.
SearchBranchItemResultStream resultStream = sourceDatabase
  .defaultRepository()
  .defaultBranch()
  .searchItems("@itemType:model");
 
for (SearchBranchItemResult r : resultStream) {
  SaveModelItemParamGenerator p = DatabaseApiUtil.param()
    .forSaveModel()
    .withSourceDatabaseKey(database1.databaseKey())
    .withSourceItemVersionKey(r.itemVersionKey());
 
  ModelItemVersion version = targetDatabase
    .defaultRepository()
    .defaultBranch()
    .saveModel(p, null);
}
You can also use the iterator method on DatabaseApiResultStream to take explicit control of the element traversal. With an iterator, you can, for example, fetch the next 100 versions when building an application user interface that shows a version history with show more functionality.
// The branch and itemKey variables are initialized elsewhere.
QueryItemVersionHistoryResultStream resultStream = branch
  .modelByKey(itemKey)
  .queryVersionHistory();
 
// An iterator obtained when initializing some form object that
// will show the version history.
java.util.Iterator<QueryItemVersionHistoryResult> iterator =
  resultStream.iterator();
The iterator may be used in method code that runs when, for example, clicking a Show More button in the application user interface.
int i = 0;
while (iterator.hasNext() && i < 100) {
  QueryItemVersionHistoryResult result = iterator.next();
  i++;
  // Add data to the form object...
}
When using the Model Manager API from a standalone Java® application, you can also use the stream method on a result stream to work directly with the Java® Stream API. Working with that API typically involves making use of lambda expressions — such expressions are not supported in the Application Builder’s Method Editor.