GnuCash  3.6-143-ge4de6a319+
Files | Data Structures | Macros | Typedefs | Enumerations
Query: Querying for Objects

BASIC QUERY API: With this API you can create arbitrary logical queries to find sets of arbitrary object. More...

Files

file  qofquery.h
 find objects that match a certain expression.
 
file  qofquerycore.h
 API for providing core Query data types.
 

Data Structures

struct  QofQueryPredData
 No extended comparisons for QOF_TYPE_INT32, QOF_TYPE_INT64, QOF_TYPE_DOUBLE, QOF_TYPE_BOOLEAN. More...
 

Macros

#define QOF_MOD_QUERY   "qof.query"
 
#define QOF_QUERY_FIRST_TERM   QOF_QUERY_AND
 First/only term is same as 'and'.
 
#define QUERY_DEFAULT_SORT   "QofQueryDefaultSort"
 Default sort object type.
 
#define QOF_PARAM_BOOK   "book"
 "Known" Object Parameters – all objects must support these
 
#define QOF_PARAM_GUID   "guid"
 
#define QOF_PARAM_KVP   "kvp"
 "Known" Object Parameters – some objects might support these
 
#define QOF_PARAM_ACTIVE   "active"
 
#define QOF_PARAM_VERSION   "version"
 

Typedefs

typedef GSList QofQueryParamList
 A list of parameters (QofIdType) used to describe a parameter to use in a predicate or when sorting.
 

Enumerations

enum  QofQueryOp {
  QOF_QUERY_AND = 1, QOF_QUERY_OR, QOF_QUERY_NAND, QOF_QUERY_NOR,
  QOF_QUERY_XOR
}
 Query Term Operators, for combining Query Terms.
 
enum  QofQueryCompare {
  QOF_COMPARE_LT = 1, QOF_COMPARE_LTE, QOF_COMPARE_EQUAL, QOF_COMPARE_GT,
  QOF_COMPARE_GTE, QOF_COMPARE_NEQ, QOF_COMPARE_CONTAINS, QOF_COMPARE_NCONTAINS
}
 Standard Query comparators, for how to compare objects in a predicate. More...
 
enum  QofStringMatch { QOF_STRING_MATCH_NORMAL = 1, QOF_STRING_MATCH_CASEINSENSITIVE }
 List of known core query data-types... More...
 
enum  QofDateMatch { QOF_DATE_MATCH_NORMAL = 1, QOF_DATE_MATCH_DAY }
 Comparisons for QOF_TYPE_DATE The QOF_DATE_MATCH_DAY comparison rounds the two time values to mid-day and then compares these rounded values. More...
 
enum  QofNumericMatch { QOF_NUMERIC_MATCH_DEBIT = 1, QOF_NUMERIC_MATCH_CREDIT, QOF_NUMERIC_MATCH_ANY }
 Comparisons for QOF_TYPE_NUMERIC, QOF_TYPE_DEBCRED. More...
 
enum  QofGuidMatch {
  QOF_GUID_MATCH_ANY = 1, QOF_GUID_MATCH_NONE, QOF_GUID_MATCH_NULL, QOF_GUID_MATCH_ALL,
  QOF_GUID_MATCH_LIST_ANY
}
 
enum  QofCharMatch { QOF_CHAR_MATCH_ANY = 1, QOF_CHAR_MATCH_NONE }
 A CHAR type is for a RECNCell, Comparisons for QOF_TYPE_CHAR 'ANY' will match any character in the string. More...
 

Query Subsystem Initialization and Shudown

void qof_query_init (void)
 Subsystem initialization and shutdown. More...
 
void qof_query_shutdown (void)
 

Low-Level API Functions

QofQueryParamListqof_query_build_param_list (char const *param,...)
 
QofQuery * qof_query_create (void)
 Create a new query. More...
 
QofQuery * qof_query_create_for (QofIdTypeConst obj_type)
 
void qof_query_destroy (QofQuery *q)
 Frees the resources associate with a Query object. More...
 
void qof_query_search_for (QofQuery *query, QofIdTypeConst obj_type)
 Set the object type to be searched for. More...
 
void qof_query_set_book (QofQuery *q, QofBook *book)
 Set the book to be searched. More...
 
void qof_query_add_term (QofQuery *query, QofQueryParamList *param_list, QofQueryPredData *pred_data, QofQueryOp op)
 This is the general function that adds a new Query Term to a query. More...
 
void qof_query_add_guid_match (QofQuery *q, QofQueryParamList *param_list, const GncGUID *guid, QofQueryOp op)
 DOCUMENT ME !!
 
void qof_query_add_guid_list_match (QofQuery *q, QofQueryParamList *param_list, GList *guid_list, QofGuidMatch options, QofQueryOp op)
 DOCUMENT ME !!
 
void qof_query_add_boolean_match (QofQuery *q, QofQueryParamList *param_list, gboolean value, QofQueryOp op)
 Handy-dandy convenience routines, avoids having to create a separate predicate for boolean matches. More...
 
GList * qof_query_run (QofQuery *query)
 Perform the query, return the results. More...
 
GList * qof_query_last_run (QofQuery *query)
 Return the results of the last query, without causing the query to be re-run. More...
 
GList * qof_query_run_subquery (QofQuery *subquery, const QofQuery *primary_query)
 Perform a subquery, return the results. More...
 
void qof_query_clear (QofQuery *query)
 Remove all query terms from query. More...
 
void qof_query_purge_terms (QofQuery *q, QofQueryParamList *param_list)
 Remove query terms of a particular type from q. More...
 
int qof_query_has_terms (QofQuery *q)
 Return boolean FALSE if there are no terms in the query Can be used as a predicate to see if the query has been initialized (return value > 0) or is "blank" (return value == 0).
 
int qof_query_num_terms (QofQuery *q)
 Return the number of terms in the canonical form of the query.
 
gboolean qof_query_has_term_type (QofQuery *q, QofQueryParamList *term_param)
 DOCUMENT ME !!
 
GSList * qof_query_get_term_type (QofQuery *q, QofQueryParamList *term_param)
 
QofQuery * qof_query_copy (QofQuery *q)
 Make a copy of the indicated query.
 
QofQuery * qof_query_invert (QofQuery *q)
 Make a copy of the indicated query, inverting the sense of the search. More...
 
QofQuery * qof_query_merge (QofQuery *q1, QofQuery *q2, QofQueryOp op)
 Combine two queries together using the Boolean set (logical) operator 'op'. More...
 
void qof_query_merge_in_place (QofQuery *q1, QofQuery *q2, QofQueryOp op)
 Like qof_query_merge, but this will merge a copy of q2 into q1. More...
 
void qof_query_set_sort_order (QofQuery *q, QofQueryParamList *primary_sort_params, QofQueryParamList *secondary_sort_params, QofQueryParamList *tertiary_sort_params)
 When a query is run, the results are sorted before being returned. More...
 
void qof_query_set_sort_options (QofQuery *q, gint prim_op, gint sec_op, gint tert_op)
 
void qof_query_set_sort_increasing (QofQuery *q, gboolean prim_inc, gboolean sec_inc, gboolean tert_inc)
 When a query is run, the results are sorted before being returned. More...
 
void qof_query_set_max_results (QofQuery *q, int n)
 Set the maximum number of results that should be returned. More...
 
gboolean qof_query_equal (const QofQuery *q1, const QofQuery *q2)
 Compare two queries for equality. More...
 
void qof_query_print (QofQuery *query)
 Log the Query. More...
 
QofIdType qof_query_get_search_for (const QofQuery *q)
 Return the type of data we're querying for.
 
GList * qof_query_get_books (QofQuery *q)
 Return the list of books we're using.
 

Core Data Type Predicates

QofQueryPredData * qof_query_string_predicate (QofQueryCompare how, const gchar *str, QofStringMatch options, gboolean is_regex)
 
QofQueryPredData * qof_query_date_predicate (QofQueryCompare how, QofDateMatch options, time64 date)
 
QofQueryPredData * qof_query_numeric_predicate (QofQueryCompare how, QofNumericMatch options, gnc_numeric value)
 
QofQueryPredData * qof_query_guid_predicate (QofGuidMatch options, GList *guids)
 
QofQueryPredData * qof_query_int32_predicate (QofQueryCompare how, gint32 val)
 
QofQueryPredData * qof_query_int64_predicate (QofQueryCompare how, gint64 val)
 
QofQueryPredData * qof_query_double_predicate (QofQueryCompare how, double val)
 
QofQueryPredData * qof_query_boolean_predicate (QofQueryCompare how, gboolean val)
 
QofQueryPredData * qof_query_char_predicate (QofCharMatch options, const gchar *chars)
 
QofQueryPredData * qof_query_collect_predicate (QofGuidMatch options, QofCollection *coll)
 
QofQueryPredData * qof_query_choice_predicate (QofGuidMatch options, GList *guids)
 
QofQueryPredData * qof_query_core_predicate_copy (const QofQueryPredData *pdata)
 Copy a predicate. More...
 
void qof_query_core_predicate_free (QofQueryPredData *pdata)
 Destroy a predicate. More...
 
gboolean qof_query_date_predicate_get_date (const QofQueryPredData *pd, time64 *date)
 Retrieve a predicate. More...
 
char * qof_query_core_to_string (QofType, gpointer object, QofParam *getter)
 Return a printable string for a core data object. More...
 
int qof_string_number_compare_func (gpointer a, gpointer b, gint options, QofParam *this_param)
 Compare two parameter(strings) as if they are numbers! the two objects, a and b, are the objects being compared this_param is the QofParam for this parameter in the objects.
 

Detailed Description

BASIC QUERY API: With this API you can create arbitrary logical queries to find sets of arbitrary object.

To make simple queries (1 term, such as a search for a parameter with one value), create the appropriate QueryTerm structure and stick it in a Query object using xaccInitQuery. The QueryTerm should be malloc'd but the Query object will handle freeing it. To make compound queries, make multiple simple queries and combine them using qof_query_merge() and the logical operations of your choice.

SQL QUERY API: As an alternative to building queries one predicate at a time, you can use the SQL query interface. This interface will accept a string containing an SQL query, parse it, convert it into the core representation, and execute it.

STRUCTURE OF A QUERY: A Query is a logical function of any number of QueryTerms. A QueryTerm consists of a C function pointer (the Predicate) and a PredicateData structure containing data passed to the predicate function. The PredicateData structure is a constant associated with the Term and is identical for every object that is tested.

The terms of the Query may represent any logical function and are stored in canonical form, i.e. the function is expressed as a logical sum of logical products. So if you have QueryTerms a, b, c, d, e and you have the logical function a(b+c) + !(c(d+e)), it gets stored as ab + ac + !c + !c!e +!d!c + !d!e. This may not be optimal for evaluation of some functions but it's easy to store, easy to manipulate, and it doesn't require a complete algebra system to deal with.

The representation is of a GList of GLists of QueryTerms. The "backbone" GList q->terms represents the OR-chain, and every item on the backbone is a GList of QueryTerms representing an AND-chain corresponding to a single product-term in the canonical representation. QueryTerms are duplicated when necessary to fill out the canonical form, and the same predicate may be evaluated multiple times per split for complex queries. This is a place where we could probably optimize.

Enumeration Type Documentation

◆ QofCharMatch

A CHAR type is for a RECNCell, Comparisons for QOF_TYPE_CHAR 'ANY' will match any character in the string.

Match 'ANY' is a convenience/performance-enhanced predicate for the compound statement (value==char1) || (value==char2) || etc. Match 'NONE' is equivalent to (value != char1) && (value != char2) && etc.

Definition at line 132 of file qofquerycore.h.

133 {
134  QOF_CHAR_MATCH_ANY = 1,
135  QOF_CHAR_MATCH_NONE
136 } QofCharMatch;
QofCharMatch
A CHAR type is for a RECNCell, Comparisons for QOF_TYPE_CHAR 'ANY' will match any character in the st...
Definition: qofquerycore.h:132

◆ QofDateMatch

Comparisons for QOF_TYPE_DATE The QOF_DATE_MATCH_DAY comparison rounds the two time values to mid-day and then compares these rounded values.

The QOF_DATE_MATCH_NORMAL comparison matches the time values, down to the second.

Definition at line 83 of file qofquerycore.h.

84 {
85  QOF_DATE_MATCH_NORMAL = 1,
86  QOF_DATE_MATCH_DAY
87 } QofDateMatch;
QofDateMatch
Comparisons for QOF_TYPE_DATE The QOF_DATE_MATCH_DAY comparison rounds the two time values to mid-day...
Definition: qofquerycore.h:83

◆ QofGuidMatch

Enumerator
QOF_GUID_MATCH_ANY 

These expect a single object and expect the QofAccessFunc returns GncGUID*.

QOF_GUID_MATCH_ALL 

These expect a GList* of objects and calls the QofAccessFunc routine on each item in the list to obtain a GncGUID* for each object.

QOF_GUID_MATCH_LIST_ANY 

These expect a single object and expect the QofAccessFunc function to return a GList* of GncGUID* (the list is the property of the caller)

Definition at line 109 of file qofquerycore.h.

110 {
113  QOF_GUID_MATCH_ANY = 1,
114  QOF_GUID_MATCH_NONE,
115  QOF_GUID_MATCH_NULL,
122 } QofGuidMatch;
These expect a single object and expect the QofAccessFunc returns GncGUID*.
Definition: qofquerycore.h:113
QofGuidMatch
Definition: qofquerycore.h:109
These expect a single object and expect the QofAccessFunc function to return a GList* of GncGUID* (th...
Definition: qofquerycore.h:121
These expect a GList* of objects and calls the QofAccessFunc routine on each item in the list to obta...
Definition: qofquerycore.h:118

◆ QofNumericMatch

Comparisons for QOF_TYPE_NUMERIC, QOF_TYPE_DEBCRED.

XXX Should be deprecated, or at least wrapped up as a convenience function, this is based on the old bill gribble code, which assumed the amount was always positive, and then specified a funds-flow direction (credit, debit, or either).

The point being that 'match credit' is equivalent to the compound predicate (amount >= 0) && (amount 'op' value) while the 'match debit' predicate is equivalent to (amount <= 0) && (abs(amount) 'op' value)

Definition at line 101 of file qofquerycore.h.

102 {
103  QOF_NUMERIC_MATCH_DEBIT = 1,
104  QOF_NUMERIC_MATCH_CREDIT,
105  QOF_NUMERIC_MATCH_ANY
QofNumericMatch
Comparisons for QOF_TYPE_NUMERIC, QOF_TYPE_DEBCRED.
Definition: qofquerycore.h:101

◆ QofQueryCompare

Standard Query comparators, for how to compare objects in a predicate.

Note that not all core types implement all comparators

Definition at line 54 of file qofquerycore.h.

55 {
56  QOF_COMPARE_LT = 1,
57  QOF_COMPARE_LTE,
58  QOF_COMPARE_EQUAL,
59  QOF_COMPARE_GT,
60  QOF_COMPARE_GTE,
61  QOF_COMPARE_NEQ,
62  QOF_COMPARE_CONTAINS,
63  QOF_COMPARE_NCONTAINS
QofQueryCompare
Standard Query comparators, for how to compare objects in a predicate.
Definition: qofquerycore.h:54

◆ QofStringMatch

List of known core query data-types...

Each core query type defines it's set of optional "comparator qualifiers".

Definition at line 70 of file qofquerycore.h.

71 {
72  QOF_STRING_MATCH_NORMAL = 1,
73  QOF_STRING_MATCH_CASEINSENSITIVE
QofStringMatch
List of known core query data-types...
Definition: qofquerycore.h:70

Function Documentation

◆ qof_query_add_boolean_match()

void qof_query_add_boolean_match ( QofQuery *  q,
QofQueryParamList param_list,
gboolean  value,
QofQueryOp  op 
)

Handy-dandy convenience routines, avoids having to create a separate predicate for boolean matches.

We might want to create handy-dandy sugar routines for the other predicate types as well.

Definition at line 1329 of file qofquery.cpp.

1331 {
1332  QofQueryPredData *pdata;
1333  if (!q || !param_list) return;
1334 
1335  pdata = qof_query_boolean_predicate (QOF_COMPARE_EQUAL, value);
1336  qof_query_add_term (q, param_list, pdata, op);
1337 }
void qof_query_add_term(QofQuery *q, QofQueryParamList *param_list, QofQueryPredData *pred_data, QofQueryOp op)
This is the general function that adds a new Query Term to a query.
Definition: qofquery.cpp:665

◆ qof_query_add_term()

void qof_query_add_term ( QofQuery *  query,
QofQueryParamList param_list,
QofQueryPredData *  pred_data,
QofQueryOp  op 
)

This is the general function that adds a new Query Term to a query.

It will find the 'obj_type' object of the search item and compare the 'param_list' parameter to the predicate data via the comparator.

The param_list is a recursive list of parameters. For example, you can say 'split->memo' by creating a list of one element, "SPLIT_MEMO". You can say 'split->account->name' by creating a list of two elements, "SPLIT_ACCOUNT" and "ACCOUNT_NAME". The list becomes the property of the Query.

For example:

acct_name_pred_data = make_string_pred_data(QOF_STRING_MATCH_CASEINSENSITIVE, account_name); param_list = make_list (SPLIT_ACCOUNT, ACCOUNT_NAME, NULL); qof_query_add_term (query, param_list, QOF_COMPARE_EQUAL, acct_name_pred_data, QOF_QUERY_AND);

Please note that QofQuery does not, at this time, support joins. That is, one cannot specify a predicate that is a parameter list. Put another way, one cannot search for objects where obja->thingy == objb->stuff

Definition at line 665 of file qofquery.cpp.

667 {
668  QofQueryTerm *qt;
669  QofQuery *qr, *qs;
670 
671  if (!q || !param_list || !pred_data) return;
672 
673  qt = g_new0 (QofQueryTerm, 1);
674  qt->param_list = param_list;
675  qt->pdata = pred_data;
676  qs = qof_query_create ();
677  query_init (qs, qt);
678 
679  if (qof_query_has_terms (q))
680  qr = qof_query_merge (q, qs, op);
681  else
682  qr = qof_query_merge (q, qs, QOF_QUERY_OR);
683 
684  swap_terms (q, qr);
685  qof_query_destroy (qs);
686  qof_query_destroy (qr);
687 }
void qof_query_destroy(QofQuery *q)
Frees the resources associate with a Query object.
Definition: qofquery.cpp:992
QofQuery * qof_query_merge(QofQuery *q1, QofQuery *q2, QofQueryOp op)
Combine two queries together using the Boolean set (logical) operator &#39;op&#39;.
Definition: qofquery.cpp:1112
int qof_query_has_terms(QofQuery *q)
Return boolean FALSE if there are no terms in the query Can be used as a predicate to see if the quer...
Definition: qofquery.cpp:931
QofQuery * qof_query_create(void)
Create a new query.
Definition: qofquery.cpp:901

◆ qof_query_clear()

void qof_query_clear ( QofQuery *  query)

Remove all query terms from query.

query matches nothing after qof_query_clear().

Definition at line 888 of file qofquery.cpp.

889 {
890  QofQuery *q2 = qof_query_create ();
891  swap_terms (query, q2);
892  qof_query_destroy (q2);
893 
894  g_list_free (query->books);
895  query->books = NULL;
896  g_list_free (query->results);
897  query->results = NULL;
898  query->changed = 1;
899 }
void qof_query_destroy(QofQuery *q)
Frees the resources associate with a Query object.
Definition: qofquery.cpp:992
QofQuery * qof_query_create(void)
Create a new query.
Definition: qofquery.cpp:901

◆ qof_query_core_predicate_copy()

QofQueryPredData* qof_query_core_predicate_copy ( const QofQueryPredData *  pdata)

Copy a predicate.

Definition at line 1775 of file qofquerycore.cpp.

1776 {
1777  QueryPredicateCopyFunc copy;
1778 
1779  g_return_val_if_fail (pdata, NULL);
1780  g_return_val_if_fail (pdata->type_name, NULL);
1781 
1782  copy = qof_query_copy_predicate (pdata->type_name);
1783  return (copy (pdata));
1784 }

◆ qof_query_core_predicate_free()

void qof_query_core_predicate_free ( QofQueryPredData *  pdata)

Destroy a predicate.

Definition at line 1763 of file qofquerycore.cpp.

1764 {
1765  QueryPredDataFree free_fcn;
1766 
1767  g_return_if_fail (pdata);
1768  g_return_if_fail (pdata->type_name);
1769 
1770  free_fcn = qof_query_predicate_free (pdata->type_name);
1771  free_fcn (pdata);
1772 }

◆ qof_query_core_to_string()

char* qof_query_core_to_string ( QofType  ,
gpointer  object,
QofParam *  getter 
)

Return a printable string for a core data object.

Caller needs to g_free() the returned string.

Definition at line 1787 of file qofquerycore.cpp.

1789 {
1790  QueryToString toString;
1791 
1792  g_return_val_if_fail (type, NULL);
1793  g_return_val_if_fail (object, NULL);
1794  g_return_val_if_fail (getter, NULL);
1795 
1796  toString = reinterpret_cast<QueryToString>(g_hash_table_lookup (toStringTable, type));
1797  g_return_val_if_fail (toString, NULL);
1798 
1799  return toString (object, getter);
1800 }

◆ qof_query_create()

QofQuery* qof_query_create ( void  )

Create a new query.

Before running the query, a 'search-for' type must be set otherwise nothing will be returned. The results of the query is a list of the indicated search-for type.

Allocates and initializes a Query structure which must be freed by the user with qof_query_destroy(). A newly-allocated QofQuery object matches nothing (qof_query_run() will return NULL).

Definition at line 901 of file qofquery.cpp.

902 {
903  QofQuery *qp = g_new0 (QofQuery, 1);
904  qp->be_compiled = g_hash_table_new (g_direct_hash, g_direct_equal);
905  query_init (qp, NULL);
906  return qp;
907 }

◆ qof_query_date_predicate_get_date()

gboolean qof_query_date_predicate_get_date ( const QofQueryPredData *  pd,
time64 date 
)

Retrieve a predicate.

Definition at line 437 of file qofquerycore.cpp.

438 {
439  const query_date_t pdata = (const query_date_t)pd;
440 
441  if (pdata->pd.type_name != query_date_type)
442  return FALSE;
443  *date = pdata->date;
444  return TRUE;
445 }

◆ qof_query_destroy()

void qof_query_destroy ( QofQuery *  q)

Frees the resources associate with a Query object.

Definition at line 992 of file qofquery.cpp.

993 {
994  if (!q) return;
995  free_members (q);
996  query_clear_compiles (q);
997  g_hash_table_destroy (q->be_compiled);
998  g_free (q);
999 }

◆ qof_query_equal()

gboolean qof_query_equal ( const QofQuery *  q1,
const QofQuery *  q2 
)

Compare two queries for equality.

Query terms are compared each to each. This is a simplistic implementation – logical equivalences between different and/or trees are ignored.

Definition at line 1454 of file qofquery.cpp.

1455 {
1456  GList *or1, *or2;
1457 
1458  if (q1 == q2) return TRUE;
1459  if (!q1 || !q2) return FALSE;
1460 
1461  if (g_list_length (q1->terms) != g_list_length (q2->terms)) return FALSE;
1462  if (q1->max_results != q2->max_results) return FALSE;
1463 
1464  for (or1 = q1->terms, or2 = q2->terms; or1;
1465  or1 = or1->next, or2 = or2->next)
1466  {
1467  GList *and1, *and2;
1468 
1469  and1 = static_cast<GList*>(or1->data);
1470  and2 = static_cast<GList*>(or2->data);
1471 
1472  if (g_list_length (and1) != g_list_length (and2)) return FALSE;
1473 
1474  for ( ; and1; and1 = and1->next, and2 = and2->next)
1475  if (!qof_query_term_equal (static_cast<QofQueryTerm*>(and1->data),
1476  static_cast<QofQueryTerm*>(and2->data)))
1477  return FALSE;
1478  }
1479 
1480  if (!qof_query_sort_equal (&(q1->primary_sort), &(q2->primary_sort)))
1481  return FALSE;
1482  if (!qof_query_sort_equal (&(q1->secondary_sort), &(q2->secondary_sort)))
1483  return FALSE;
1484  if (!qof_query_sort_equal (&(q1->tertiary_sort), &(q2->tertiary_sort)))
1485  return FALSE;
1486 
1487  return TRUE;
1488 }

◆ qof_query_init()

void qof_query_init ( void  )

Subsystem initialization and shutdown.

Call init() once to initialize the query subsystem; call shutdown() to free up any resources associated with the query subsystem. Typically called during application startup, shutdown.

Definition at line 1342 of file qofquery.cpp.

1343 {
1344  ENTER (" ");
1345  qof_query_core_init ();
1346  qof_class_init ();
1347  LEAVE ("Completed initialization of QofQuery");
1348 }
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:268
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:278

◆ qof_query_invert()

QofQuery* qof_query_invert ( QofQuery *  q)

Make a copy of the indicated query, inverting the sense of the search.

In other words, if the original query search for all objects with a certain condition, the inverted query will search for all object with NOT that condition. The union of the results returned by the original and inverted queries equals the set of all searched objects. These to sets are disjoint (share no members in common).

This will return a newly allocated QofQuery object, or NULL on error. Free it with qof_query_destroy() when no longer needed.

Definition at line 1033 of file qofquery.cpp.

1034 {
1035  QofQuery * retval;
1036  QofQuery * right, * left, * iright, * ileft;
1037  QofQueryTerm * qt;
1038  GList * aterms;
1039  GList * cur;
1040  GList * new_oterm;
1041  int num_or_terms;
1042 
1043  if (!q)
1044  return NULL;
1045 
1046  num_or_terms = g_list_length(q->terms);
1047 
1048  switch (num_or_terms)
1049  {
1050  case 0:
1051  retval = qof_query_create();
1052  retval->max_results = q->max_results;
1053  break;
1054 
1055  /* This is the DeMorgan expansion for a single AND expression. */
1056  /* !(abc) = !a + !b + !c */
1057  case 1:
1058  retval = qof_query_create();
1059  retval->max_results = q->max_results;
1060  retval->books = g_list_copy (q->books);
1061  retval->search_for = q->search_for;
1062  retval->changed = 1;
1063 
1064  aterms = static_cast<GList*>(g_list_nth_data(q->terms, 0));
1065  new_oterm = NULL;
1066  for (cur = aterms; cur; cur = cur->next)
1067  {
1068  qt = copy_query_term(static_cast<QofQueryTerm*>(cur->data));
1069  qt->invert = !(qt->invert);
1070  new_oterm = g_list_append(NULL, qt);
1071  retval->terms = g_list_prepend(retval->terms, new_oterm);
1072  }
1073  retval->terms = g_list_reverse(retval->terms);
1074  break;
1075 
1076  /* If there are multiple OR-terms, we just recurse by
1077  * breaking it down to !(a + b + c) =
1078  * !a * !(b + c) = !a * !b * !c. */
1079  default:
1080  right = qof_query_create();
1081  right->terms = copy_or_terms(g_list_nth(q->terms, 1));
1082 
1083  left = qof_query_create();
1084  left->terms = g_list_append(NULL,
1085  copy_and_terms(static_cast<GList*>(g_list_nth_data(q->terms, 0))));
1086 
1087  iright = qof_query_invert(right);
1088  ileft = qof_query_invert(left);
1089 
1090  retval = qof_query_merge(iright, ileft, QOF_QUERY_AND);
1091  retval->books = g_list_copy (q->books);
1092  retval->max_results = q->max_results;
1093  retval->search_for = q->search_for;
1094  retval->changed = 1;
1095 
1096  qof_query_destroy(iright);
1097  qof_query_destroy(ileft);
1098  qof_query_destroy(right);
1099  qof_query_destroy(left);
1100  break;
1101  }
1102 
1103  return retval;
1104 }
void qof_query_destroy(QofQuery *q)
Frees the resources associate with a Query object.
Definition: qofquery.cpp:992
QofQuery * qof_query_merge(QofQuery *q1, QofQuery *q2, QofQueryOp op)
Combine two queries together using the Boolean set (logical) operator &#39;op&#39;.
Definition: qofquery.cpp:1112
QofQuery * qof_query_invert(QofQuery *q)
Make a copy of the indicated query, inverting the sense of the search.
Definition: qofquery.cpp:1033
QofQuery * qof_query_create(void)
Create a new query.
Definition: qofquery.cpp:901

◆ qof_query_last_run()

GList* qof_query_last_run ( QofQuery *  query)

Return the results of the last query, without causing the query to be re-run.

Do NOT free the resulting list. This list is managed internally by QofQuery.

Definition at line 880 of file qofquery.cpp.

881 {
882  if (!query)
883  return NULL;
884 
885  return query->results;
886 }

◆ qof_query_merge()

QofQuery* qof_query_merge ( QofQuery *  q1,
QofQuery *  q2,
QofQueryOp  op 
)

Combine two queries together using the Boolean set (logical) operator 'op'.

For example, if the operator 'op' is set to QUERY_AND, then the set of results returned by the query will will be the Boolean set intersection of the results returned by q1 and q2. Similarly, QUERY_OR maps to set union, etc.

Both queries must have compatible search-types. If both queries are set, they must search for the same object type. If only one is set, the resulting query will search for the set type. If neither query has the search-type set, the result will be unset as well.

This will return a newly allocated QofQuery object, or NULL on error. Free it with qof_query_destroy() when no longer needed. Note that if either input query is NULL then the returned query is NOT newly allocated – it will return the non-NULL query. You only need to call this function when both q1 and q2 are non-NULL.

Definition at line 1112 of file qofquery.cpp.

1113 {
1114 
1115  QofQuery * retval = NULL;
1116  QofQuery * i1, * i2;
1117  QofQuery * t1, * t2;
1118  GList * i, * j;
1119  QofIdType search_for;
1120 
1121  if (!q1) return q2;
1122  if (!q2) return q1;
1123 
1124  if (q1->search_for && q2->search_for)
1125  g_return_val_if_fail (g_strcmp0 (q1->search_for, q2->search_for) == 0,
1126  NULL);
1127 
1128  search_for = (q1->search_for ? q1->search_for : q2->search_for);
1129 
1130  /* Avoid merge surprises if op==QOF_QUERY_AND but q1 is empty.
1131  * The goal of this tweak is to allow the user to start with
1132  * an empty q1 and then append to it recursively
1133  * (and q1 (and q2 (and q3 (and q4 ....))))
1134  * without bombing out because the append started with an
1135  * empty list.
1136  * We do essentially the same check in qof_query_add_term()
1137  * so that the first term added to an empty query doesn't screw up.
1138  */
1139  if ((QOF_QUERY_AND == op) &&
1140  ( (0 == qof_query_has_terms (q1)) || (0 == qof_query_has_terms (q2)) ))
1141  {
1142  op = QOF_QUERY_OR;
1143  }
1144 
1145  switch (op)
1146  {
1147  case QOF_QUERY_OR:
1148  retval = qof_query_create();
1149  retval->terms =
1150  g_list_concat(copy_or_terms(q1->terms), copy_or_terms(q2->terms));
1151  retval->books = merge_books (q1->books, q2->books);
1152  retval->max_results = q1->max_results;
1153  retval->changed = 1;
1154  break;
1155 
1156  case QOF_QUERY_AND:
1157  retval = qof_query_create();
1158  retval->books = merge_books (q1->books, q2->books);
1159  retval->max_results = q1->max_results;
1160  retval->changed = 1;
1161 
1162  /* g_list_append() can take forever, so let's build the list in
1163  * reverse and then reverse it at the end, to deal better with
1164  * "large" queries.
1165  */
1166  for (i = q1->terms; i; i = i->next)
1167  {
1168  for (j = q2->terms; j; j = j->next)
1169  {
1170  retval->terms =
1171  g_list_prepend(retval->terms,
1172  g_list_concat
1173  (copy_and_terms(static_cast<GList*>(i->data)),
1174  copy_and_terms(static_cast<GList*>(j->data))));
1175  }
1176  }
1177  retval->terms = g_list_reverse(retval->terms);
1178  break;
1179 
1180  case QOF_QUERY_NAND:
1181  /* !(a*b) = (!a + !b) */
1182  i1 = qof_query_invert(q1);
1183  i2 = qof_query_invert(q2);
1184  retval = qof_query_merge(i1, i2, QOF_QUERY_OR);
1185  qof_query_destroy(i1);
1186  qof_query_destroy(i2);
1187  break;
1188 
1189  case QOF_QUERY_NOR:
1190  /* !(a+b) = (!a*!b) */
1191  i1 = qof_query_invert(q1);
1192  i2 = qof_query_invert(q2);
1193  retval = qof_query_merge(i1, i2, QOF_QUERY_AND);
1194  qof_query_destroy(i1);
1195  qof_query_destroy(i2);
1196  break;
1197 
1198  case QOF_QUERY_XOR:
1199  /* a xor b = (a * !b) + (!a * b) */
1200  i1 = qof_query_invert(q1);
1201  i2 = qof_query_invert(q2);
1202  t1 = qof_query_merge(q1, i2, QOF_QUERY_AND);
1203  t2 = qof_query_merge(i1, q2, QOF_QUERY_AND);
1204  retval = qof_query_merge(t1, t2, QOF_QUERY_OR);
1205 
1206  qof_query_destroy(i1);
1207  qof_query_destroy(i2);
1208  qof_query_destroy(t1);
1209  qof_query_destroy(t2);
1210  break;
1211  }
1212 
1213  retval->search_for = search_for;
1214  return retval;
1215 }
const gchar * QofIdType
QofIdType declaration.
Definition: qofid.h:85
void qof_query_destroy(QofQuery *q)
Frees the resources associate with a Query object.
Definition: qofquery.cpp:992
QofQuery * qof_query_merge(QofQuery *q1, QofQuery *q2, QofQueryOp op)
Combine two queries together using the Boolean set (logical) operator &#39;op&#39;.
Definition: qofquery.cpp:1112
QofQuery * qof_query_invert(QofQuery *q)
Make a copy of the indicated query, inverting the sense of the search.
Definition: qofquery.cpp:1033
int qof_query_has_terms(QofQuery *q)
Return boolean FALSE if there are no terms in the query Can be used as a predicate to see if the quer...
Definition: qofquery.cpp:931
QofQuery * qof_query_create(void)
Create a new query.
Definition: qofquery.cpp:901

◆ qof_query_merge_in_place()

void qof_query_merge_in_place ( QofQuery *  q1,
QofQuery *  q2,
QofQueryOp  op 
)

Like qof_query_merge, but this will merge a copy of q2 into q1.

q2 remains unchanged.

Definition at line 1218 of file qofquery.cpp.

1219 {
1220  QofQuery *tmp_q;
1221 
1222  if (!q1 || !q2)
1223  return;
1224 
1225  tmp_q = qof_query_merge (q1, q2, op);
1226  swap_terms (q1, tmp_q);
1227  qof_query_destroy (tmp_q);
1228 }
void qof_query_destroy(QofQuery *q)
Frees the resources associate with a Query object.
Definition: qofquery.cpp:992
QofQuery * qof_query_merge(QofQuery *q1, QofQuery *q2, QofQueryOp op)
Combine two queries together using the Boolean set (logical) operator &#39;op&#39;.
Definition: qofquery.cpp:1112

◆ qof_query_print()

void qof_query_print ( QofQuery *  query)

Log the Query.

Deprecated:
Do not call directly, use the standard log module code: ::qof_log_set_level(QOF_MOD_QUERY, QOF_LOG_DEBUG); or ::qof_log_set_default(QOF_LOG_DEBUG);
Deprecated:
access via qof_log instead.

The query will be logged automatically if qof_log_set_default or qof_log_set_level(QOF_MOD_QUERY, ...) are set to QOF_LOG_DEBUG or higher.

This function cycles through a QofQuery object, and prints out the values of the various members of the query

Definition at line 1520 of file qofquery.cpp.

1521 {
1522  GList *output;
1523  GString *str;
1524  QofQuerySort *s[3];
1525  gint maxResults = 0, numSorts = 3;
1526 
1527  ENTER (" ");
1528 
1529  if (!query)
1530  {
1531  LEAVE("query is (null)");
1532  return;
1533  }
1534 
1535  output = NULL;
1536  str = NULL;
1537  maxResults = qof_query_get_max_results (query);
1538 
1539  output = qof_query_printSearchFor (query, output);
1540  output = qof_query_printTerms (query, output);
1541 
1542  qof_query_get_sorts (query, &s[0], &s[1], &s[2]);
1543 
1544  if (s[0])
1545  {
1546  output = qof_query_printSorts (s, numSorts, output);
1547  }
1548 
1549  str = g_string_new (" ");
1550  g_string_printf (str, "Maximum number of results: %d", maxResults);
1551  output = g_list_append (output, str);
1552 
1553  qof_query_printOutput (output);
1554  LEAVE (" ");
1555 }
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:268
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:278

◆ qof_query_purge_terms()

void qof_query_purge_terms ( QofQuery *  q,
QofQueryParamList param_list 
)

Remove query terms of a particular type from q.

The "type" of a term is determined by the type of data that gets passed to the predicate function. XXX ??? Huh? remove anything of that predicate type, or just the particular predicate ?

Definition at line 689 of file qofquery.cpp.

690 {
691  QofQueryTerm *qt;
692  GList *_or_, *_and_;
693 
694  if (!q || !param_list) return;
695 
696  for (_or_ = q->terms; _or_; _or_ = _or_->next)
697  {
698  for (_and_ = static_cast<GList*>(_or_->data); _and_;
699  _and_ = static_cast<GList*>(_and_->next))
700  {
701  qt = static_cast<QofQueryTerm*>(_and_->data);
702  if (!param_list_cmp (qt->param_list, param_list))
703  {
704  if (g_list_length (static_cast<GList*>(_or_->data)) == 1)
705  {
706  q->terms = g_list_remove_link (static_cast<GList*>(q->terms), _or_);
707  g_list_free_1 (_or_);
708  _or_ = q->terms;
709  break;
710  }
711  else
712  {
713  _or_->data = g_list_remove_link (static_cast<GList*>(_or_->data), _and_);
714  g_list_free_1 (_and_);
715  _and_ = static_cast<GList*>(_or_->data);
716  if (!_and_) break;
717  }
718  q->changed = 1;
719  free_query_term (qt);
720  }
721  }
722  if (!_or_) break;
723  }
724 }

◆ qof_query_run()

GList* qof_query_run ( QofQuery *  query)

Perform the query, return the results.

The returned list is a list of the 'search-for' type that was previously set with the qof_query_search_for() or the qof_query_create_for() routines. The returned list will have been sorted using the indicated sort order, and trimmed to the max_results length.

Do NOT free the resulting list. This list is managed internally by QofQuery.

Definition at line 848 of file qofquery.cpp.

849 {
850  /* Just a wrapper */
851  return qof_query_run_internal(q, qof_query_run_cb, NULL);
852 }

◆ qof_query_run_subquery()

GList* qof_query_run_subquery ( QofQuery *  subquery,
const QofQuery *  primary_query 
)

Perform a subquery, return the results.

Instead of running over a book, the subquery runs over the results of the primary query.

Do NOT free the resulting list. This list is managed internally by QofQuery.

Definition at line 863 of file qofquery.cpp.

864 {
865  if (!subq) return NULL;
866  if (!primaryq) return NULL;
867 
868  /* Make sure we're searching for the same thing */
869  g_return_val_if_fail (subq->search_for, NULL);
870  g_return_val_if_fail (primaryq->search_for, NULL);
871  g_return_val_if_fail(!g_strcmp0(subq->search_for, primaryq->search_for),
872  NULL);
873 
874  /* Perform the subquery */
875  return qof_query_run_internal(subq, qof_query_run_subq_cb,
876  (gpointer)primaryq);
877 }

◆ qof_query_search_for()

void qof_query_search_for ( QofQuery *  query,
QofIdTypeConst  obj_type 
)

Set the object type to be searched for.

The results of performing the query will be a list of this obj_type.

Definition at line 909 of file qofquery.cpp.

910 {
911  if (!q || !obj_type)
912  return;
913 
914  if (g_strcmp0 (q->search_for, obj_type))
915  {
916  q->search_for = (QofIdType) obj_type;
917  q->changed = 1;
918  }
919 }
const gchar * QofIdType
QofIdType declaration.
Definition: qofid.h:85

◆ qof_query_set_book()

void qof_query_set_book ( QofQuery *  q,
QofBook *  book 
)

Set the book to be searched.

Books contain/identify collections of objects; the search will be performed over those books specified with this function. If no books are set, no results will be returned (since there is nothing to search over).

You can search multiple books. To specify multiple books, call this function multiple times with different arguments. XXX needed qof_query_clear_books() to reset the list ...

Definition at line 1308 of file qofquery.cpp.

1309 {
1310  QofQueryParamList *slist = NULL;
1311  if (!q || !book) return;
1312 
1313  /* Make sure this book is only in the list once */
1314  if (g_list_index (q->books, book) == -1)
1315  q->books = g_list_prepend (q->books, book);
1316 
1317  slist = g_slist_prepend (slist, static_cast<void*>(const_cast<char*>(QOF_PARAM_GUID)));
1318  slist = g_slist_prepend (slist, static_cast<void*>(const_cast<char*>(QOF_PARAM_BOOK)));
1319  qof_query_add_guid_match (q, slist,
1320  qof_instance_get_guid(book), QOF_QUERY_AND);
1321 }
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance.
#define QOF_PARAM_BOOK
"Known" Object Parameters – all objects must support these
Definition: qofquery.h:109
GSList QofQueryParamList
A list of parameters (QofIdType) used to describe a parameter to use in a predicate or when sorting...
Definition: qofquerycore.h:151
void qof_query_add_guid_match(QofQuery *q, QofQueryParamList *param_list, const GncGUID *guid, QofQueryOp op)
DOCUMENT ME !!
Definition: qofquery.cpp:1292

◆ qof_query_set_max_results()

void qof_query_set_max_results ( QofQuery *  q,
int  n 
)

Set the maximum number of results that should be returned.

If 'max-results' is set to -1, then all of the results are returned. If there are more results than 'max-results', then the result list is trimmed. Note that there is an important interplay between 'max-results' and the sort order: only the last bit of results are returned. For example, if the sort order is set to be increasing date order, then only the objects with the most recent dates will be returned.

Definition at line 1271 of file qofquery.cpp.

1272 {
1273  if (!q) return;
1274  q->max_results = n;
1275 }

◆ qof_query_set_sort_increasing()

void qof_query_set_sort_increasing ( QofQuery *  q,
gboolean  prim_inc,
gboolean  sec_inc,
gboolean  tert_inc 
)

When a query is run, the results are sorted before being returned.

This routine can be used to control the direction of the ordering. A value of TRUE indicates the sort will be in increasing order, a value of FALSE will order results in decreasing order.

Note that if there are more results than the 'max-results' value, then only the last max-results will be returned. For example, if the sort is set to be increasing date order, then only the objects with the most recent dates will be returned.

Definition at line 1262 of file qofquery.cpp.

1264 {
1265  if (!q) return;
1266  q->primary_sort.increasing = prim_inc;
1267  q->secondary_sort.increasing = sec_inc;
1268  q->tertiary_sort.increasing = tert_inc;
1269 }

◆ qof_query_set_sort_order()

void qof_query_set_sort_order ( QofQuery *  q,
QofQueryParamList primary_sort_params,
QofQueryParamList secondary_sort_params,
QofQueryParamList tertiary_sort_params 
)

When a query is run, the results are sorted before being returned.

This routine can be used to set the parameters on which the sort will be performed. Two objects in the result list will be compared using the 'primary_sort_params', and sorted based on that order. If the comparison shows that they are equal, then the 'secondary_sort_params' will be used. If still equal, then the tertiary parameters will be compared. Any or all of these parameter lists may be NULL. Any of these parameter lists may be set to QUERY_DEFAULT_SORT.

Note that if there are more results than the 'max-results' value, then only the last max-results will be returned. For example, if the sort is set to be increasing date order, then only the objects with the most recent dates will be returned.

The input lists become the property of QofQuery and are managed by it. They will be freed when the query is destroyed (or when new lists are set).

Definition at line 1231 of file qofquery.cpp.

1233 {
1234  if (!q) return;
1235  if (q->primary_sort.param_list)
1236  g_slist_free (q->primary_sort.param_list);
1237  q->primary_sort.param_list = params1;
1238  q->primary_sort.options = 0;
1239 
1240  if (q->secondary_sort.param_list)
1241  g_slist_free (q->secondary_sort.param_list);
1242  q->secondary_sort.param_list = params2;
1243  q->secondary_sort.options = 0;
1244 
1245  if (q->tertiary_sort.param_list)
1246  g_slist_free (q->tertiary_sort.param_list);
1247  q->tertiary_sort.param_list = params3;
1248  q->tertiary_sort.options = 0;
1249 
1250  q->changed = 1;
1251 }