QOF: Query: Querying for Objects

QOF 0.7.5

Modules | Files | Data Structures | Macros | Typedefs | Enumerations
Query: Querying for Objects
Query Object Framework

## Modules
| SQL Interface to Query

## Files
file | qofquery.h
| find objects that match a certain expression.
file | qofquerycore.h
| API for providing core Query data types.
file | qofsql.h
| QOF client-side SQL parser, interfacing with libgda.

## Data Structures
struct | _QofQueryPredData

## Macros
#define | QOF_MOD_QUERY "qof-query"
#define | QOF_QUERY_FIRST_TERM QOF_QUERY_AND
#define | QUERY_DEFAULT_SORT "QofQueryDefaultSort"
#define | QOF_PARAM_BOOK "book"
#define | QOF_PARAM_GUID "guid"
#define | QOF_PARAM_KVP "kvp"
#define | QOF_PARAM_ACTIVE "active"
#define | QOF_PARAM_VERSION "version"

## Typedefs
typedef struct _QofQuery | QofQuery
typedef struct _QofQueryPredData | QofQueryPredData

## Enumerations
enum | QofQueryOp { QOF_QUERY_AND = 1, QOF_QUERY_OR, QOF_QUERY_NAND, QOF_QUERY_NOR, QOF_QUERY_XOR }
enum | QofQueryCompare { QOF_COMPARE_LT = 1, QOF_COMPARE_LTE, QOF_COMPARE_EQUAL, QOF_COMPARE_GT, QOF_COMPARE_GTE, QOF_COMPARE_NEQ }
enum | QofStringMatch { QOF_STRING_MATCH_NORMAL = 1, QOF_STRING_MATCH_CASEINSENSITIVE }
enum | QofDateMatch { QOF_DATE_MATCH_NORMAL = 1, QOF_DATE_MATCH_DAY }
enum | QofNumericMatch { QOF_NUMERIC_MATCH_DEBIT = 1, QOF_NUMERIC_MATCH_CREDIT, QOF_NUMERIC_MATCH_ANY }
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 }

## Query Subsystem Initialization and Shudown
void | qof_query_init (void)
void | qof_query_shutdown (void)

## Low-Level API Functions
GSList * | qof_query_build_param_list (gchar const *param,...)
QofQuery * | qof_query_create (void)
QofQuery * | qof_query_create_for (QofIdTypeConst obj_type)
void | qof_query_destroy (QofQuery *q)
void | qof_query_search_for (QofQuery *query, QofIdTypeConst obj_type)
void | qof_query_set_book (QofQuery *q, QofBook *book)
void | qof_query_add_term (QofQuery *query, GSList *param_list, QofQueryPredData *pred_data, QofQueryOp op)
void | qof_query_add_guid_match (QofQuery *q, GSList *param_list, const GUID *guid, QofQueryOp op)
void | qof_query_add_guid_list_match (QofQuery *q, GSList *param_list, GList *guid_list, QofGuidMatch options, QofQueryOp op)
void | qof_query_add_boolean_match (QofQuery *q, GSList *param_list, gboolean value, QofQueryOp op)
GList * | qof_query_run (QofQuery *query)
GList * | qof_query_last_run (QofQuery *query)
void | qof_query_clear (QofQuery *query)
void | qof_query_purge_terms (QofQuery *q, GSList *param_list)
gint | qof_query_has_terms (QofQuery *q)
gint | qof_query_num_terms (QofQuery *q)
gboolean | qof_query_has_term_type (QofQuery *q, GSList *term_param)
GSList * | qof_query_get_term_type (QofQuery *q, GSList *term_param)
QofQuery * | qof_query_copy (QofQuery *q)
QofQuery * | qof_query_invert (QofQuery *q)
QofQuery * | qof_query_merge (QofQuery *q1, QofQuery *q2, QofQueryOp op)
void | qof_query_merge_in_place (QofQuery *q1, QofQuery *q2, QofQueryOp op)
void | qof_query_set_sort_order (QofQuery *q, GSList *primary_sort_params, GSList *secondary_sort_params, GSList *tertiary_sort_params)
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)
void | qof_query_set_max_results (QofQuery *q, gint n)
gboolean | qof_query_equal (QofQuery *q1, QofQuery *q2)
QofIdType | qof_query_get_search_for (QofQuery *q)
GList * | qof_query_get_books (QofQuery *q)

## Core Data Type Predicates
QofQueryPredData * | qof_query_string_predicate (QofQueryCompare how, const gchar *str, QofStringMatch options, gboolean is_regex)
QofQueryPredData * | qof_query_time_predicate (QofQueryCompare how, QofDateMatch options, QofTime *qt)
QofQueryPredData * | qof_query_numeric_predicate (QofQueryCompare how, QofNumericMatch options, QofNumeric 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_kvp_predicate (QofQueryCompare how, GSList *path, const KvpValue *value)
QofQueryPredData * | qof_query_kvp_predicate_path (QofQueryCompare how, const gchar *path, const KvpValue *value)
QofQueryPredData * | qof_query_core_predicate_copy (QofQueryPredData *pdata)
void | qof_query_core_predicate_free (QofQueryPredData *pdata)
gboolean | qof_query_time_predicate_get_time (QofQueryPredData *pd, QofTime *qt)
gchar * | qof_query_core_to_string (QofType, gpointer object, QofParam *getter)

## 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 malloced 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.

## Macro Definition Documentation

## ◆ QOF_PARAM_BOOK

#define QOF_PARAM_BOOK "book"

"Known" Object Parameters – all objects must support these

Definition at line 104 of file qofquery.h.

## ◆ QOF_PARAM_KVP

#define QOF_PARAM_KVP "kvp"

"Known" Object Parameters – some objects might support these

Definition at line 108 of file qofquery.h.

## ◆ QOF_QUERY_FIRST_TERM

#define QOF_QUERY_FIRST_TERM QOF_QUERY_AND

First/only term is same as 'and'

Definition at line 98 of file qofquery.h.

## ◆ QUERY_DEFAULT_SORT

#define QUERY_DEFAULT_SORT "QofQueryDefaultSort"

Default sort object type

Definition at line 101 of file qofquery.h.

## Typedef Documentation

## ◆ QofQuery

typedef struct _QofQuery QofQuery

A Query

Definition at line 85 of file qofquery.h.

## ◆ QofQueryPredData

typedef struct _QofQueryPredData QofQueryPredData

PREDICATE DATA TYPES: All the predicate data types are rolled up into the union type PredicateData. The "type" field specifies which type the union is.

Definition at line 46 of file qofquerycore.h.

## Enumeration Type Documentation

## ◆ QofCharMatch

enum QofCharMatch

A CHAR type is for a RECNCell, Comparisons for QOF_TYPE_CHAR 'ANY' will match any charagter 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 127 of file qofquerycore.h.

128 {
129 QOF_CHAR_MATCH_ANY = 1,
130 QOF_CHAR_MATCH_NONE
131 } QofCharMatch;
QofCharMatch
QofCharMatch
Definition: qofquerycore.h:127

## ◆ QofDateMatch

enum 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 78 of file qofquerycore.h.

79 {
80 QOF_DATE_MATCH_NORMAL = 1,
81 QOF_DATE_MATCH_DAY
82 } QofDateMatch;
QofDateMatch
QofDateMatch
Definition: qofquerycore.h:78

## ◆ QofGuidMatch

enum QofGuidMatch

Enumerator
QOF_GUID_MATCH_ANY | These expect a single object and expect the QofAccessFunc returns GUID*
QOF_GUID_MATCH_ALL | These expect a GList* of objects and calls the QofAccessFunc routine on each item in the list to obtain a GUID* for each object
QOF_GUID_MATCH_LIST_ANY | These expect a single object and expect the QofAccessFunc function to return a GList* of GUID* (the list is the property of the caller)

Definition at line 104 of file qofquerycore.h.

105 {
108 QOF_GUID_MATCH_ANY = 1,
109 QOF_GUID_MATCH_NONE,
110 QOF_GUID_MATCH_NULL,
113 QOF_GUID_MATCH_ALL,
116 QOF_GUID_MATCH_LIST_ANY,
117 } QofGuidMatch;
QOF_GUID_MATCH_ANY
Definition: qofquerycore.h:108
QofGuidMatch
QofGuidMatch
Definition: qofquerycore.h:104
QOF_GUID_MATCH_LIST_ANY
Definition: qofquerycore.h:116
QOF_GUID_MATCH_ALL
Definition: qofquerycore.h:113

## ◆ QofNumericMatch

enum 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 96 of file qofquerycore.h.

97 {
98 QOF_NUMERIC_MATCH_DEBIT = 1,
99 QOF_NUMERIC_MATCH_CREDIT,
100 QOF_NUMERIC_MATCH_ANY
101 } QofNumericMatch;
QofNumericMatch
QofNumericMatch
Definition: qofquerycore.h:96

## ◆ QofQueryCompare

enum QofQueryCompare

Standard Query comparitors, for how to compare objects in a predicate. Note that not all core types implement all comparitors

Definition at line 51 of file qofquerycore.h.

52 {
53 QOF_COMPARE_LT = 1,
54 QOF_COMPARE_LTE,
55 QOF_COMPARE_EQUAL,
56 QOF_COMPARE_GT,
57 QOF_COMPARE_GTE,
58 QOF_COMPARE_NEQ
59 } QofQueryCompare;
QofQueryCompare
QofQueryCompare
Definition: qofquerycore.h:51

## ◆ QofQueryOp

enum QofQueryOp

Query Term Operators, for combining Query Terms

Definition at line 88 of file qofquery.h.

89 {
90 QOF_QUERY_AND = 1,
91 QOF_QUERY_OR,
92 QOF_QUERY_NAND,
93 QOF_QUERY_NOR,
94 QOF_QUERY_XOR
95 } QofQueryOp;
QofQueryOp
QofQueryOp
Definition: qofquery.h:88

## ◆ QofStringMatch

enum QofStringMatch

List of known core query data-types... Each core query type defines it's set of optional "comparitor qualifiers".

Definition at line 65 of file qofquerycore.h.

66 {
67 QOF_STRING_MATCH_NORMAL = 1,
68 QOF_STRING_MATCH_CASEINSENSITIVE
69 } QofStringMatch;
QofStringMatch
QofStringMatch
Definition: qofquerycore.h:65

## Function Documentation

## ◆ qof_query_add_boolean_match()

void qof_query_add_boolean_match | ( | QofQuery * | q,
|  | GSList * | 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 1360 of file qofquery.c.

1362 {
1363 QofQueryPredData *pdata;
1364 if (!q || !param_list)
1365 return;
1366
1367 pdata = qof_query_boolean_predicate (QOF_COMPARE_EQUAL, value);
1368 qof_query_add_term (q, param_list, pdata, op);
1369 }
qof_query_add_term
void qof_query_add_term(QofQuery *q, GSList *param_list, QofQueryPredData *pred_data, QofQueryOp op)
Definition: qofquery.c:691
_QofQueryPredData
Definition: qofquerycore.h:138

## ◆ qof_query_add_guid_list_match()

void qof_query_add_guid_list_match | ( | QofQuery * | q,
|  | GSList * | param_list,
|  | GList * | guid_list,
|  | QofGuidMatch | options,
|  | QofQueryOp | op
| ) |  |

DOCUMENT ME !!

Definition at line 1301 of file qofquery.c.

1303 {
1304 QofQueryPredData *pdata;
1305
1306 if (!q || !param_list)
1307 return;
1308
1309 if (!guid_list)
1310 g_return_if_fail (options == QOF_GUID_MATCH_NULL);
1311
1312 pdata = qof_query_guid_predicate (options, guid_list);
1313 qof_query_add_term (q, param_list, pdata, op);
1314 }
qof_query_add_term
void qof_query_add_term(QofQuery *q, GSList *param_list, QofQueryPredData *pred_data, QofQueryOp op)
Definition: qofquery.c:691
_QofQueryPredData
Definition: qofquerycore.h:138

## ◆ qof_query_add_guid_match()

void qof_query_add_guid_match | ( | QofQuery * | q,
|  | GSList * | param_list,
|  | const GUID * | guid,
|  | QofQueryOp | op
| ) |  |

DOCUMENT ME !!

Definition at line 1317 of file qofquery.c.

1319 {
1320 GList *g = NULL;
1321
1322 if (!q || !param_list)
1323 return;
1324
1325 if (guid)
1326 g = g_list_prepend (g, (gpointer) guid);
1327
1328 qof_query_add_guid_list_match (q, param_list, g,
1329 g ? QOF_GUID_MATCH_ANY : QOF_GUID_MATCH_NULL, op);
1330
1331 g_list_free (g);
1332 }
QOF_GUID_MATCH_ANY
Definition: qofquerycore.h:108
qof_query_add_guid_list_match
void qof_query_add_guid_list_match(QofQuery *q, GSList *param_list, GList *guid_list, QofGuidMatch options, QofQueryOp op)
Definition: qofquery.c:1301

## ◆ qof_query_add_term()

void qof_query_add_term | ( | QofQuery * | query,
|  | GSList * | 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. The list becomes the property of the Query.

    QofQueryPredData *time_pred_data;
    QofQuery *query;
    QofParam *param;
    QofTime *qoftime;

    time_pred_data = qof_query_time_predicate (QOF_COMPARE_GTE,
        QOF_DATE_MATCH_DAY, qoftime);
    qof_query_add_term (query,
        qof_query_build_param_list ((gchar*)param->param_name,
        NULL), time_pred_data, QOF_QUERY_AND);

Note
  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 You can simulate a join by using recursive or sequential queries.

Definition at line 691 of file qofquery.c.

693 {
694 QofQueryTerm *qt;
695 QofQuery *qr, *qs;
696
697 if (!q || !param_list || !pred_data)
698 return;
699
700 qt = g_new0 (QofQueryTerm, 1);
701 qt->param_list = param_list;
702 qt->pdata = pred_data;
703 qs = qof_query_create ();
704 query_init (qs, qt);
705
706 if (qof_query_has_terms (q))
707 qr = qof_query_merge (q, qs, op);
708 else
709 qr = qof_query_merge (q, qs, QOF_QUERY_OR);
710
711 swap_terms (q, qr);
712 qof_query_destroy (qs);
713 qof_query_destroy (qr);
714 }
QofQuery
struct _QofQuery QofQuery
Definition: qofquery.h:85
qof_query_destroy
void qof_query_destroy(QofQuery *q)
Definition: qofquery.c:998
qof_query_has_terms
gint qof_query_has_terms(QofQuery *q)
Definition: qofquery.c:933
qof_query_merge
QofQuery * qof_query_merge(QofQuery *q1, QofQuery *q2, QofQueryOp op)
Definition: qofquery.c:1127
qof_query_create
QofQuery * qof_query_create(void)
Definition: qofquery.c:900

## ◆ 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 886 of file qofquery.c.

887 {
888 QofQuery *q2 = qof_query_create ();
889 swap_terms (query, q2);
890 qof_query_destroy (q2);
891
892 g_list_free (query->books);
893 query->books = NULL;
894 g_list_free (query->results);
895 query->results = NULL;
896 query->changed = 1;
897 }
QofQuery
struct _QofQuery QofQuery
Definition: qofquery.h:85
qof_query_destroy
void qof_query_destroy(QofQuery *q)
Definition: qofquery.c:998
qof_query_create
QofQuery * qof_query_create(void)
Definition: qofquery.c:900

## ◆ qof_query_copy()

QofQuery* qof_query_copy | ( | QofQuery * | q | ) |

Make a copy of the indicated query

Definition at line 1009 of file qofquery.c.

1010 {
1011 QofQuery *copy;
1012 GHashTable *ht;
1013
1014 if (!q)
1015 return NULL;
1016 copy = qof_query_create ();
1017 ht = copy->be_compiled;
1018 free_members (copy);
1019
1020 memcpy (copy, q, sizeof (QofQuery));
1021
1022 copy->be_compiled = ht;
1023 copy->terms = copy_or_terms (q->terms);
1024 copy->books = g_list_copy (q->books);
1025 copy->results = g_list_copy (q->results);
1026
1027 copy_sort (&(copy->primary_sort), &(q->primary_sort));
1028 copy_sort (&(copy->secondary_sort), &(q->secondary_sort));
1029 copy_sort (&(copy->tertiary_sort), &(q->tertiary_sort));
1030
1031 copy->changed = 1;
1032
1033 return copy;
1034 }
QofQuery
struct _QofQuery QofQuery
Definition: qofquery.h:85
qof_query_create
QofQuery * qof_query_create(void)
Definition: qofquery.c:900

## ◆ qof_query_core_predicate_copy()

QofQueryPredData* qof_query_core_predicate_copy | ( | QofQueryPredData * | pdata | ) |

Copy a predicate.

Definition at line 2054 of file qofquerycore.c.

2055 {
2056 QueryPredicateCopyFunc copy;
2057
2058 g_return_val_if_fail (pdata, NULL);
2059 g_return_val_if_fail (pdata->type_name, NULL);
2060
2061 copy = qof_query_copy_predicate (pdata->type_name);
2062 return (copy (pdata));
2063 }

## ◆ qof_query_core_predicate_free()

void qof_query_core_predicate_free | ( | QofQueryPredData * | pdata | ) |

Destroy a predicate.

Definition at line 2042 of file qofquerycore.c.

2043 {
2044 QueryPredDataFree free_fcn;
2045
2046 g_return_if_fail (pdata);
2047 g_return_if_fail (pdata->type_name);
2048
2049 free_fcn = qof_query_predicate_free (pdata->type_name);
2050 free_fcn (pdata);
2051 }

## ◆ qof_query_core_to_string()

gchar* 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 2066 of file qofquerycore.c.

2068 {
2069 QueryToString toString;
2070
2071 g_return_val_if_fail (type, NULL);
2072 g_return_val_if_fail (object, NULL);
2073 g_return_val_if_fail (getter, NULL);
2074
2075 toString = g_hash_table_lookup (toStringTable, type);
2076 g_return_val_if_fail (toString, NULL);
2077
2078 return toString (object, getter);
2079 }

## ◆ 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 900 of file qofquery.c.

901 {
902 QofQuery *qp = g_new0 (QofQuery, 1);
903 qp->be_compiled = g_hash_table_new (g_direct_hash, g_direct_equal);
904 query_init (qp, NULL);
905 return qp;
906 }
QofQuery
struct _QofQuery QofQuery
Definition: qofquery.h:85

## ◆ qof_query_create_for()

QofQuery* qof_query_create_for | ( | QofIdTypeConst | obj_type | ) |

create a query with a search type preset.

Definition at line 922 of file qofquery.c.

923 {
924 QofQuery *q;
925 if (!obj_type)
926 return NULL;
927 q = qof_query_create ();
928 qof_query_search_for (q, obj_type);
929 return q;
930 }
QofQuery
struct _QofQuery QofQuery
Definition: qofquery.h:85
qof_query_create
QofQuery * qof_query_create(void)
Definition: qofquery.c:900
qof_query_search_for
void qof_query_search_for(QofQuery *q, QofIdTypeConst obj_type)
Definition: qofquery.c:909

## ◆ qof_query_destroy()

void qof_query_destroy | ( | QofQuery * | q | ) |

Frees the resources associated with a Query object.

Definition at line 998 of file qofquery.c.

999 {
1000 if (!q)
1001 return;
1002 free_members (q);
1003 query_clear_compiles (q);
1004 g_hash_table_destroy (q->be_compiled);
1005 g_free (q);
1006 }

## ◆ qof_query_equal()

gboolean qof_query_equal | ( | QofQuery * | q1,
|  | 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 1512 of file qofquery.c.

1513 {
1514 GList *or1, *or2;
1515
1516 if (q1 == q2)
1517 return TRUE;
1518 if (!q1 || !q2)
1519 return FALSE;
1520
1521 if (g_list_length (q1->terms) != g_list_length (q2->terms))
1522 return FALSE;
1523 if (q1->max_results != q2->max_results)
1524 return FALSE;
1525
1526 for (or1 = q1->terms, or2 = q2->terms; or1;
1527 or1 = or1->next, or2 = or2->next)
1528 {
1529 GList *and1, *and2;
1530
1531 and1 = or1->data;
1532 and2 = or2->data;
1533
1534 if (g_list_length (and1) != g_list_length (and2))
1535 return FALSE;
1536
1537 for (; and1; and1 = and1->next, and2 = and2->next)
1538 if (!qof_query_term_equal (and1->data, and2->data))
1539 return FALSE;
1540 }
1541
1542 if (!qof_query_sort_equal (&(q1->primary_sort), &(q2->primary_sort)))
1543 return FALSE;
1544 if (!qof_query_sort_equal (&(q1->secondary_sort),
1545 &(q2->secondary_sort)))
1546 return FALSE;
1547 if (!qof_query_sort_equal (&(q1->tertiary_sort), &(q2->tertiary_sort)))
1548 return FALSE;
1549
1550 return TRUE;
1551 }

## ◆ qof_query_get_books()

GList* qof_query_get_books | ( | QofQuery * | q | ) |

Return the list of books we're using

Definition at line 1352 of file qofquery.c.

1353 {
1354 if (!q)
1355 return NULL;
1356 return q->books;
1357 }

## ◆ qof_query_get_search_for()

QofIdType qof_query_get_search_for | ( | QofQuery * | q | ) |

Return the type of data we're querying for

Definition at line 1400 of file qofquery.c.

1401 {
1402 if (!q)
1403 return NULL;
1404 return q->search_for;
1405 }

## ◆ qof_query_has_term_type()

gboolean qof_query_has_term_type | ( | QofQuery * | q,
|  | GSList * | term_param
| ) |  |

DOCUMENT ME !!

Definition at line 953 of file qofquery.c.

954 {
955 GList *or;
956 GList *and;
957
958 if (!q || !term_param)
959 return FALSE;
960
961 for (or = q->terms; or; or = or->next)
962 {
963 for (and = or->data; and; and = and->next)
964 {
965 QofQueryTerm *qt = and->data;
966 if (!param_list_cmp (term_param, qt->param_list))
967 return TRUE;
968 }
969 }
970
971 return FALSE;
972 }

## ◆ qof_query_has_terms()

gint 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).

Definition at line 933 of file qofquery.c.

934 {
935 if (!q)
936 return 0;
937 return g_list_length (q->terms);
938 }

## ◆ qof_query_init()

void qof_query_init | ( | void |  | ) |

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

Definition at line 1375 of file qofquery.c.

1376 {
1377 ENTER (" ");
1378 qof_query_core_init ();
1379 qof_class_init ();
1380 qof_date_init ();
1381 LEAVE ("Completed initialization of QofQuery");
1382 }
LEAVE
#define LEAVE(format, args...)
Definition: qoflog.h:227
qof_date_init
void qof_date_init(void)
initialise the QofDate tables
Definition: qofdate.c:67
ENTER
#define ENTER(format, args...)
Definition: qoflog.h:217

## ◆ 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 1043 of file qofquery.c.

1044 {
1045 QofQuery *retval;
1046 QofQuery *right, *left, *iright, *ileft;
1047 QofQueryTerm *qt;
1048 GList *aterms;
1049 GList *cur;
1050 GList *new_oterm;
1051 gint num_or_terms;
1052
1053 if (!q)
1054 return NULL;
1055
1056 num_or_terms = g_list_length (q->terms);
1057
1058 switch (num_or_terms)
1059 {
1060 case 0:
1061 retval = qof_query_create ();
1062 retval->max_results = q->max_results;
1063 break;
1064
1065 /* This is the DeMorgan expansion for a single AND expression. */
1066 /* !(abc) = !a + !b + !c */
1067 case 1:
1068 retval = qof_query_create ();
1069 retval->max_results = q->max_results;
1070 retval->books = g_list_copy (q->books);
1071 retval->search_for = q->search_for;
1072 retval->changed = 1;
1073
1074 aterms = g_list_nth_data (q->terms, 0);
1075 new_oterm = NULL;
1076 for (cur = aterms; cur; cur = cur->next)
1077 {
1078 qt = copy_query_term (cur->data);
1079 qt->invert = !(qt->invert);
1080 new_oterm = g_list_append (NULL, qt);
1081
1082 /* g_list_append() can take forever, so let's do this for speed
1083 * in "large" queries.
1084 */
1085 retval->terms = g_list_reverse (retval->terms);
1086 retval->terms = g_list_prepend (retval->terms, new_oterm);
1087 retval->terms = g_list_reverse (retval->terms);
1088 }
1089 break;
1090
1091 /* If there are multiple OR-terms, we just recurse by
1092 * breaking it down to !(a + b + c) =
1093 * !a * !(b + c) = !a * !b * !c. */
1094 default:
1095 right = qof_query_create ();
1096 right->terms = copy_or_terms (g_list_nth (q->terms, 1));
1097
1098 left = qof_query_create ();
1099 left->terms = g_list_append (NULL,
1100 copy_and_terms (g_list_nth_data (q->terms, 0)));
1101
1102 iright = qof_query_invert (right);
1103 ileft = qof_query_invert (left);
1104
1105 retval = qof_query_merge (iright, ileft, QOF_QUERY_AND);
1106 retval->books = g_list_copy (q->books);
1107 retval->max_results = q->max_results;
1108 retval->search_for = q->search_for;
1109 retval->changed = 1;
1110
1111 qof_query_destroy (iright);
1112 qof_query_destroy (ileft);
1113 qof_query_destroy (right);
1114 qof_query_destroy (left);
1115 break;
1116 }
1117
1118 return retval;
1119 }
QofQuery
struct _QofQuery QofQuery
Definition: qofquery.h:85
qof_query_destroy
void qof_query_destroy(QofQuery *q)
Definition: qofquery.c:998
qof_query_merge
QofQuery * qof_query_merge(QofQuery *q1, QofQuery *q2, QofQueryOp op)
Definition: qofquery.c:1127
qof_query_invert
QofQuery * qof_query_invert(QofQuery *q)
Definition: qofquery.c:1043
qof_query_create
QofQuery * qof_query_create(void)
Definition: qofquery.c:900

## ◆ qof_query_kvp_predicate()

QofQueryPredData* qof_query_kvp_predicate | ( | QofQueryCompare | how,
|  | GSList * | path,
|  | const KvpValue * | value
| ) |  |

The qof_query_kvp_predicate() matches the object that has the value 'value' located at the path 'path'. In a certain sense, the 'path' is handled as if it were a paramter.

Definition at line 1285 of file qofquerycore.c.

1287 {
1288 query_kvp_t pdata;
1289 GSList *node;
1290
1291 g_return_val_if_fail (path && value, NULL);
1292
1293 pdata = g_new0 (query_kvp_def, 1);
1294 pdata->pd.type_name = query_kvp_type;
1295 pdata->pd.how = how;
1296 pdata->value = kvp_value_copy (value);
1297 pdata->path = g_slist_copy (path);
1298 for (node = pdata->path; node; node = node->next)
1299 node->data = g_strdup (node->data);
1300
1301 return ((QofQueryPredData *) pdata);
1302 }
kvp_value_copy
KvpValue * kvp_value_copy(const KvpValue *value)
Definition: kvpframe.c:1601
query_kvp_def
Definition: qofquerycore-p.h:135
_QofQueryPredData
Definition: qofquerycore.h:138

## ◆ qof_query_kvp_predicate_path()

QofQueryPredData* qof_query_kvp_predicate_path | ( | QofQueryCompare | how,
|  | const gchar * | path,
|  | const KvpValue * | value
| ) |  |

Same predicate as above, except that 'path' is assumed to be a string containing slash-separated pathname.

## ◆ 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 877 of file qofquery.c.

878 {
879 if (!query)
880 return NULL;
881
882 return query->results;
883 }

## ◆ 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.

Definition at line 1127 of file qofquery.c.

1128 {
1129
1130 QofQuery *retval = NULL;
1131 QofQuery *i1, *i2;
1132 QofQuery *t1, *t2;
1133 GList *i, *j;
1134 QofIdType search_for;
1135
1136 if (!q1)
1137 return q2;
1138 if (!q2)
1139 return q1;
1140
1141 if (q1->search_for && q2->search_for)
1142 g_return_val_if_fail (safe_strcmp (q1->search_for,
1143 q2->search_for) == 0, NULL);
1144
1145 search_for = (q1->search_for ? q1->search_for : q2->search_for);
1146
1147 /* Avoid merge surprises if op==QOF_QUERY_AND but q1 is empty.
1148 * The goal of this tweak is to all the user to start with
1149 * an empty q1 and then append to it recursively
1150 * (and q1 (and q2 (and q3 (and q4 ....))))
1151 * without bombing out because the append started with an
1152 * empty list.
1153 * We do essentially the same check in qof_query_add_term()
1154 * so that the first term added to an empty query doesn't screw up.
1155 */
1156 if ((QOF_QUERY_AND == op) && (0 == qof_query_has_terms (q1)))
1157 {
1158 op = QOF_QUERY_OR;
1159 }
1160
1161 switch (op)
1162 {
1163 case QOF_QUERY_OR:
1164 retval = qof_query_create ();
1165 retval->terms =
1166 g_list_concat (copy_or_terms (q1->terms),
1167 copy_or_terms (q2->terms));
1168 retval->books = merge_books (q1->books, q2->books);
1169 retval->max_results = q1->max_results;
1170 retval->changed = 1;
1171 break;
1172
1173 case QOF_QUERY_AND:
1174 retval = qof_query_create ();
1175 retval->books = merge_books (q1->books, q2->books);
1176 retval->max_results = q1->max_results;
1177 retval->changed = 1;
1178
1179 /* g_list_append() can take forever, so let's build the list in
1180 * reverse and then reverse it at the end, to deal better with
1181 * "large" queries.
1182 */
1183 for (i = q1->terms; i; i = i->next)
1184 {
1185 for (j = q2->terms; j; j = j->next)
1186 {
1187 retval->terms =
1188 g_list_prepend (retval->terms,
1189 g_list_concat
1190 (copy_and_terms (i->data), copy_and_terms (j->data)));
1191 }
1192 }
1193 retval->terms = g_list_reverse (retval->terms);
1194 break;
1195
1196 case QOF_QUERY_NAND:
1197 /* !(a*b) = (!a + !b) */
1198 i1 = qof_query_invert (q1);
1199 i2 = qof_query_invert (q2);
1200 retval = qof_query_merge (i1, i2, QOF_QUERY_OR);
1201 qof_query_destroy (i1);
1202 qof_query_destroy (i2);
1203 break;
1204
1205 case QOF_QUERY_NOR:
1206 /* !(a+b) = (!a*!b) */
1207 i1 = qof_query_invert (q1);
1208 i2 = qof_query_invert (q2);
1209 retval = qof_query_merge (i1, i2, QOF_QUERY_AND);
1210 qof_query_destroy (i1);
1211 qof_query_destroy (i2);
1212 break;
1213
1214 case QOF_QUERY_XOR:
1215 /* a xor b = (a * !b) + (!a * b) */
1216 i1 = qof_query_invert (q1);
1217 i2 = qof_query_invert (q2);
1218 t1 = qof_query_merge (q1, i2, QOF_QUERY_AND);
1219 t2 = qof_query_merge (i1, q2, QOF_QUERY_AND);
1220 retval = qof_query_merge (t1, t2, QOF_QUERY_OR);
1221
1222 qof_query_destroy (i1);
1223 qof_query_destroy (i2);
1224 qof_query_destroy (t1);
1225 qof_query_destroy (t2);
1226 break;
1227 }
1228
1229 retval->search_for = search_for;
1230 return retval;
1231 }
QofIdType
const gchar * QofIdType
Definition: qofid.h:81
QofQuery
struct _QofQuery QofQuery
Definition: qofquery.h:85
qof_query_destroy
void qof_query_destroy(QofQuery *q)
Definition: qofquery.c:998
qof_query_has_terms
gint qof_query_has_terms(QofQuery *q)
Definition: qofquery.c:933
qof_query_merge
QofQuery * qof_query_merge(QofQuery *q1, QofQuery *q2, QofQueryOp op)
Definition: qofquery.c:1127
qof_query_invert
QofQuery * qof_query_invert(QofQuery *q)
Definition: qofquery.c:1043
safe_strcmp
gint safe_strcmp(const gchar *da, const gchar *db)
Definition: qofutil.c:72
qof_query_create
QofQuery * qof_query_create(void)
Definition: qofquery.c:900

## ◆ 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 1234 of file qofquery.c.

1235 {
1236 QofQuery *tmp_q;
1237
1238 if (!q1 || !q2)
1239 return;
1240
1241 tmp_q = qof_query_merge (q1, q2, op);
1242 swap_terms (q1, tmp_q);
1243 qof_query_destroy (tmp_q);
1244 }
QofQuery
struct _QofQuery QofQuery
Definition: qofquery.h:85
qof_query_destroy
void qof_query_destroy(QofQuery *q)
Definition: qofquery.c:998
qof_query_merge
QofQuery * qof_query_merge(QofQuery *q1, QofQuery *q2, QofQueryOp op)
Definition: qofquery.c:1127

## ◆ qof_query_num_terms()

gint qof_query_num_terms | ( | QofQuery * | q | ) |

Return the number of terms in the canonical form of the query.

Definition at line 941 of file qofquery.c.

942 {
943 GList *o;
944 gint n = 0;
945 if (!q)
946 return 0;
947 for (o = q->terms; o; o = o->next)
948 n += g_list_length (o->data);
949 return n;
950 }

## ◆ qof_query_purge_terms()

void qof_query_purge_terms | ( | QofQuery * | q,
|  | GSList * | param_list
| ) |  |

Remove query terms of a particular QofType from the query. The "type" of a term is determined by the QofType that gets passed to the predicate function. All query terms of this type are removed.

Definition at line 717 of file qofquery.c.

718 {
719 QofQueryTerm *qt;
720 GList *or, *and;
721
722 if (!q || !param_list)
723 return;
724
725 for (or = q->terms; or; or = or->next)
726 {
727 for (and = or->data; and; and = and->next)
728 {
729 qt = and->data;
730 if (!param_list_cmp (qt->param_list, param_list))
731 {
732 if (g_list_length (or->data) == 1)
733 {
734 q->terms = g_list_remove_link (q->terms, or);
735 g_list_free_1 (or);
736 or = q->terms;
737 break;
738 }
739 else
740 {
741 or->data = g_list_remove_link (or->data, and);
742 g_list_free_1 (and);
743 and = or->data;
744 if (!and)
745 break;
746 }
747 q->changed = 1;
748 free_query_term (qt);
749 }
750 }
751 if (!or)
752 break;
753 }
754 }

## ◆ 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 trimed to the max_results length.

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

Definition at line 757 of file qofquery.c.

758 {
759 GList *matching_objects = NULL;
760 GList *node;
761 gint object_count = 0;
762
763 if (!q)
764 return NULL;
765 g_return_val_if_fail (q->search_for, NULL);
766 g_return_val_if_fail (q->books, NULL);
767 ENTER (" q=%p", q);
768
769 /* XXX: Prioritize the query terms? */
770
771 /* prepare the Query for processing */
772 if (q->changed)
773 {
774 query_clear_compiles (q);
775 compile_terms (q);
776 }
777
778 /* Maybe log this sucker */
779 if (qof_log_check (log_module, QOF_LOG_DETAIL))
780 qof_query_print (q);
781
782 /* Now run the query over all the objects and save the results */
783 {
784 QofQueryCB qcb;
785
786 memset (&qcb, 0, sizeof (qcb));
787 qcb.query = q;
788
789 /* For each book */
790 for (node = q->books; node; node = node->next)
791 {
792 QofBook *book = node->data;
793 QofBackend *be = book->backend;
794
795 /* run the query in the backend */
796 if (be)
797 {
798 gpointer compiled_query =
799 g_hash_table_lookup (q->be_compiled, book);
800
801 if (compiled_query && be->run_query)
802 {
803 (be->run_query) (be, compiled_query);
804 }
805 }
806
807 /* And then iterate over all the objects */
808 qof_object_foreach (q->search_for, book,
809 (QofEntityForeachCB) check_item_cb, &qcb);
810 }
811
812 matching_objects = qcb.list;
813 object_count = qcb.count;
814 }
815 PINFO ("matching objects=%p count=%d", matching_objects, object_count);
816
817 /* There is no absolute need to reverse this list, since it's being
818 * sorted below. However, in the common case, we will be searching
819 * in a confined location where the objects are already in order,
820 * thus reversing will put us in the correct order we want and make
821 * the sorting go much faster.
822 */
823 matching_objects = g_list_reverse (matching_objects);
824
825 /* Now sort the matching objects based on the search criteria
826 * sortQuery is an unforgivable use of static global data...
827 * I just can't figure out how else to do this sanely.
828 */
829 if (q->primary_sort.comp_fcn || q->primary_sort.obj_cmp ||
830 (q->primary_sort.use_default && q->defaultSort))
831 {
832 sortQuery = q;
833 matching_objects = g_list_sort (matching_objects, sort_func);
834 sortQuery = NULL;
835 }
836
837 /* Crop the list to limit the number of splits. */
838 if ((object_count > q->max_results) && (q->max_results > -1))
839 {
840 if (q->max_results > 0)
841 {
842 GList *mptr;
843
844 /* mptr is set to the first node of what will be the new list */
845 mptr =
846 g_list_nth (matching_objects,
847 object_count - q->max_results);
848 /* mptr should not be NULL, but let's be safe */
849 if (mptr != NULL)
850 {
851 if (mptr->prev != NULL)
852 mptr->prev->next = NULL;
853 mptr->prev = NULL;
854 }
855 g_list_free (matching_objects);
856 matching_objects = mptr;
857 }
858 else
859 {
860 /* q->max_results == 0 */
861 g_list_free (matching_objects);
862 matching_objects = NULL;
863 }
864 object_count = q->max_results;
865 }
866
867 q->changed = 0;
868
869 g_list_free (q->results);
870 q->results = matching_objects;
871
872 LEAVE (" q=%p", q);
873 return matching_objects;
874 }
PINFO
#define PINFO(format, args...)
Definition: qoflog.h:199
qof_object_foreach
void qof_object_foreach(QofIdTypeConst type_name, QofBook *book, QofEntityForeachCB cb, gpointer user_data)
Definition: qofobject.c:174
qof_query_print
void qof_query_print(QofQuery *query)
Definition: qofquery.c:1577
QofEntityForeachCB
void(* QofEntityForeachCB)(QofEntity *, gpointer user_data)
Definition: qofid.h:187
qof_log_check
gboolean qof_log_check(QofLogModule log_module, QofLogLevel log_level)
Definition: qoflog.c:204
LEAVE
#define LEAVE(format, args...)
Definition: qoflog.h:227
_QofBook::backend
QofBackend * backend
Definition: qofbook-p.h:87
_QofBook
Definition: qofbook-p.h:48
ENTER
#define ENTER(format, args...)
Definition: qoflog.h:217
QofBackend_s
Definition: qofbackend-p.h:283

## ◆ 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.c.

910 {
911 if (!q || !obj_type)
912 return;
913
914 if (safe_strcmp (q->search_for, obj_type))
915 {
916 q->search_for = (QofIdType) obj_type;
917 q->changed = 1;
918 }
919 }
QofIdType
const gchar * QofIdType
Definition: qofid.h:81
safe_strcmp
gint safe_strcmp(const gchar *da, const gchar *db)
Definition: qofutil.c:72

## ◆ 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 1335 of file qofquery.c.

1336 {
1337 GSList *slist = NULL;
1338 if (!q || !book)
1339 return;
1340
1341 /* Make sure this book is only in the list once */
1342 if (g_list_index (q->books, book) == -1)
1343 q->books = g_list_prepend (q->books, book);
1344
1345 slist = g_slist_prepend (slist, QOF_PARAM_GUID);
1346 slist = g_slist_prepend (slist, QOF_PARAM_BOOK);
1347 qof_query_add_guid_match (q, slist,
1348 qof_entity_get_guid ((QofEntity*)book), QOF_QUERY_AND);
1349 }
QofEntity_s
Definition: qofid.h:147
QOF_PARAM_BOOK
#define QOF_PARAM_BOOK
Definition: qofquery.h:104
qof_query_add_guid_match
void qof_query_add_guid_match(QofQuery *q, GSList *param_list, const GUID *guid, QofQueryOp op)
Definition: qofquery.c:1317
qof_entity_get_guid
const GUID * qof_entity_get_guid(QofEntity *ent)
Definition: qofid.c:105

## ◆ qof_query_set_max_results()

void qof_query_set_max_results | ( | QofQuery * | q,
|  | gint | 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 1293 of file qofquery.c.

1294 {
1295 if (!q)
1296 return;
1297 q->max_results = n;
1298 }

## ◆ 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 1282 of file qofquery.c.

1284 {
1285 if (!q)
1286 return;
1287 q->primary_sort.increasing = prim_inc;
1288 q->secondary_sort.increasing = sec_inc;
1289 q->tertiary_sort.increasing = tert_inc;
1290 }

## ◆ qof_query_set_sort_order()

void qof_query_set_sort_order | ( | QofQuery * | q,
|  | GSList * | primary_sort_params,
|  | GSList * | secondary_sort_params,
|  | GSList * | tertiary_sort_params
| ) |  |

When a query is run, the results are sorted before being returned. This routine can be used to set the paramters 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 params 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 1247 of file qofquery.c.

1249 {
1250 if (!q)
1251 return;
1252 if (q->primary_sort.param_list)
1253 g_slist_free (q->primary_sort.param_list);
1254 q->primary_sort.param_list = params1;
1255 q->primary_sort.options = 0;
1256
1257 if (q->secondary_sort.param_list)
1258 g_slist_free (q->secondary_sort.param_list);
1259 q->secondary_sort.param_list = params2;
1260 q->secondary_sort.options = 0;
1261
1262 if (q->tertiary_sort.param_list)
1263 g_slist_free (q->tertiary_sort.param_list);
1264 q->tertiary_sort.param_list = params3;
1265 q->tertiary_sort.options = 0;
1266
1267 q->changed = 1;
1268 }

## ◆ qof_query_time_predicate_get_time()

gboolean qof_query_time_predicate_get_time | ( | QofQueryPredData * | pd,
|  | QofTime * | qt
| ) |  |

Retrieve a predicate.

Definition at line 381 of file qofquerycore.c.

383 {
384 query_time_t pdata = (query_time_t) pd;
385
386 if (pdata->pd.type_name != query_time_type)
387 return FALSE;
388 qt = pdata->qt;
389 return TRUE;
390 }
query_time_def
Definition: qofquerycore-p.h:83