The QueryResult class provides a convenient way to process SQL result set rows. The
records()
method returns a Cursor object that provides methodhasNext()
to iterate over the result set rows and a number of methods for extracting the data or column information from these rows. For example the following code snippet demonstrates how to extract and print out the values from the result set of query "select * from Person" (see here for the definition of database classPerson
):void show_results(McoSqlEngine& engine) { QueryResult result(engine.executeQuery("select * from Person")); Cursor * cursor = result->records(); while (cursor->hasNext()) { Record * rec = cursor->next(); // Extract the _Person record to the corresponding struct _Person p; result->extract(rec, &p, sizeof(p)); printf("\tName=%s, Ordinal=%u\n", p.name, p.ordinal ); } }Note that the
struct
_Person
is:// Define the structure correponding to database table Person struct _Person { char const* name; uint4 ordinal; };QueryResult usage
The main purpose of the C++ QueryResult is to control the scope of the query and automatically release all allocated resources if the query is terminated abnormally. If the scope of the query (the lifetime of the QueryResult object instance) is incorrect it will lead to a runtime error. This can happen when the instance is used beyond the transaction it has been created in or still exists at the time the database instance is closed. The following code snippet demonstrates how this kind of incorrect usage may occur:
main (void) { McoSqlEngine engine; engine.open( ... ); ... QueryResult result(engine.executeQuery("select * from aRecord")); Cursor* cursor = result->records(); while (cursor->hasNext()) { ... } /* end of while loop */ engine.close(); /* database instance is destroyed here */ return 0; /* object of class QueryResult represented by local variable 'result' will be deleted here. Since the database no longer exists, the QueryResult destructor crashes the application */ }Because the transaction context that created the object is kept within the object, if the transaction is no longer valid, any operation over its handle leads to an error. In the code above, the QueryResult destructor is called as the object
result
goes out of scope. But the transaction handle in result is no longer valid because the database has been closed. So the attempt to close the transaction causes the application to crash!To avoid this, any instance of the QueryResult class must be deleted as soon as it is no longer required. This can be done by explicitly calling the
delete
operator on the object if it was created bynew
, or by using enclosing braces if the object is instantiated as a local variable.