Copyright (C) 2003 Linas Vepstas <linas@linas.org>
Definition in file qofquery.h.
#include "guid.h"
#include "qofbook.h"
#include "qofquerycore.h"
#include "qofchoice.h"
Go to the source code of this file.
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 (char 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) |
int | qof_query_has_terms (QofQuery *q) |
int | 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, int n) |
gboolean | qof_query_equal (QofQuery *q1, QofQuery *q2) |
void | qof_query_print (QofQuery *query) |
QofIdType | qof_query_get_search_for (QofQuery *q) |
GList * | qof_query_get_books (QofQuery *q) |
Defines | |
#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 _QofQuery | QofQuery |
Enumerations | |
enum | QofQueryOp { QOF_QUERY_AND = 1, QOF_QUERY_OR, QOF_QUERY_NAND, QOF_QUERY_NOR, QOF_QUERY_XOR } |
|
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 1243 of file qofquery.c. 01245 { 01246 QofQueryPredData *pdata; 01247 if (!q || !param_list) return; 01248 01249 pdata = qof_query_boolean_predicate (QOF_COMPARE_EQUAL, value); 01250 qof_query_add_term (q, param_list, pdata, op); 01251 }
|
|
DOCUMENT ME !! Definition at line 1191 of file qofquery.c. 01194 { 01195 QofQueryPredData *pdata; 01196 01197 if (!q || !param_list) return; 01198 01199 if (!guid_list) 01200 g_return_if_fail (options == QOF_GUID_MATCH_NULL); 01201 01202 pdata = qof_query_guid_predicate (options, guid_list); 01203 qof_query_add_term (q, param_list, pdata, op); 01204 }
|
|
DOCUMENT ME !! Definition at line 1206 of file qofquery.c. 01208 { 01209 GList *g = NULL; 01210 01211 if (!q || !param_list) return; 01212 01213 if (guid) 01214 g = g_list_prepend (g, (gpointer)guid); 01215 01216 qof_query_add_guid_list_match (q, param_list, g, 01217 g ? QOF_GUID_MATCH_ANY : QOF_GUID_MATCH_NULL, op); 01218 01219 g_list_free (g); 01220 }
|
|
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 comparitor. 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 631 of file qofquery.c. 00633 { 00634 QofQueryTerm *qt; 00635 QofQuery *qr, *qs; 00636 00637 if (!q || !param_list || !pred_data) return; 00638 00639 qt = g_new0 (QofQueryTerm, 1); 00640 qt->param_list = param_list; 00641 qt->pdata = pred_data; 00642 qs = qof_query_create (); 00643 query_init (qs, qt); 00644 00645 if (qof_query_has_terms (q)) 00646 qr = qof_query_merge (q, qs, op); 00647 else 00648 qr = qof_query_merge (q, qs, QOF_QUERY_OR); 00649 00650 swap_terms (q, qr); 00651 qof_query_destroy (qs); 00652 qof_query_destroy (qr); 00653 }
|
|
Remove all query terms from query. query matches nothing after qof_query_clear(). Definition at line 806 of file qofquery.c. 00807 { 00808 QofQuery *q2 = qof_query_create (); 00809 swap_terms (query, q2); 00810 qof_query_destroy (q2); 00811 00812 g_list_free (query->books); 00813 query->books = NULL; 00814 g_list_free (query->results); 00815 query->results = NULL; 00816 query->changed = 1; 00817 }
|
|
Make a copy of the indicated query Definition at line 912 of file qofquery.c. 00913 { 00914 QofQuery *copy; 00915 GHashTable *ht; 00916 00917 if (!q) return NULL; 00918 copy = qof_query_create (); 00919 ht = copy->be_compiled; 00920 free_members (copy); 00921 00922 memcpy (copy, q, sizeof (QofQuery)); 00923 00924 copy->be_compiled = ht; 00925 copy->terms = copy_or_terms (q->terms); 00926 copy->books = g_list_copy (q->books); 00927 copy->results = g_list_copy (q->results); 00928 00929 copy_sort (&(copy->primary_sort), &(q->primary_sort)); 00930 copy_sort (&(copy->secondary_sort), &(q->secondary_sort)); 00931 copy_sort (&(copy->tertiary_sort), &(q->tertiary_sort)); 00932 00933 copy->changed = 1; 00934 00935 return copy; 00936 }
|
|
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 819 of file qofquery.c. 00820 { 00821 QofQuery *qp = g_new0 (QofQuery, 1); 00822 qp->be_compiled = g_hash_table_new (g_direct_hash, g_direct_equal); 00823 query_init (qp, NULL); 00824 return qp; 00825 }
|
|
Frees the resources associate with a Query object. Definition at line 903 of file qofquery.c. 00904 { 00905 if (!q) return; 00906 free_members (q); 00907 query_clear_compiles (q); 00908 g_hash_table_destroy (q->be_compiled); 00909 g_free (q); 00910 }
|
|
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 1368 of file qofquery.c. 01369 { 01370 GList *or1, *or2; 01371 01372 if (q1 == q2) return TRUE; 01373 if (!q1 || !q2) return FALSE; 01374 01375 if (g_list_length (q1->terms) != g_list_length (q2->terms)) return FALSE; 01376 if (q1->max_results != q2->max_results) return FALSE; 01377 01378 for (or1 = q1->terms, or2 = q2->terms; or1; 01379 or1 = or1->next, or2 = or2->next) 01380 { 01381 GList *and1, *and2; 01382 01383 and1 = or1->data; 01384 and2 = or2->data; 01385 01386 if (g_list_length (and1) != g_list_length (and2)) return FALSE; 01387 01388 for ( ; and1; and1 = and1->next, and2 = and2->next) 01389 if (!qof_query_term_equal (and1->data, and2->data)) 01390 return FALSE; 01391 } 01392 01393 if (!qof_query_sort_equal (&(q1->primary_sort), &(q2->primary_sort))) 01394 return FALSE; 01395 if (!qof_query_sort_equal (&(q1->secondary_sort), &(q2->secondary_sort))) 01396 return FALSE; 01397 if (!qof_query_sort_equal (&(q1->tertiary_sort), &(q2->tertiary_sort))) 01398 return FALSE; 01399 01400 return TRUE; 01401 }
|
|
Return the list of books we're using Definition at line 1237 of file qofquery.c. 01238 { 01239 if (!q) return NULL; 01240 return q->books; 01241 }
|
|
Return the type of data we're querying for Definition at line 1276 of file qofquery.c. 01277 { 01278 if (!q) return NULL; 01279 return q->search_for; 01280 }
|
|
DOCUMENT ME !! Definition at line 864 of file qofquery.c. 00865 { 00866 GList *or; 00867 GList *and; 00868 00869 if (!q || !term_param) 00870 return FALSE; 00871 00872 for(or = q->terms; or; or = or->next) { 00873 for(and = or->data; and; and = and->next) { 00874 QofQueryTerm *qt = and->data; 00875 if (!param_list_cmp (term_param, qt->param_list)) 00876 return TRUE; 00877 } 00878 } 00879 00880 return FALSE; 00881 }
|
|
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 848 of file qofquery.c. 00849 { 00850 if (!q) return 0; 00851 return g_list_length (q->terms); 00852 }
|
|
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 1256 of file qofquery.c. 01257 { 01258 ENTER (" "); 01259 qof_query_core_init (); 01260 qof_class_init (); 01261 LEAVE ("Completed initialization of QofQuery"); 01262 }
|
|
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 944 of file qofquery.c. 00945 { 00946 QofQuery * retval; 00947 QofQuery * right, * left, * iright, * ileft; 00948 QofQueryTerm * qt; 00949 GList * aterms; 00950 GList * cur; 00951 GList * new_oterm; 00952 int num_or_terms; 00953 00954 if (!q) 00955 return NULL; 00956 00957 num_or_terms = g_list_length(q->terms); 00958 00959 switch(num_or_terms) 00960 { 00961 case 0: 00962 retval = qof_query_create(); 00963 retval->max_results = q->max_results; 00964 break; 00965 00966 /* This is the DeMorgan expansion for a single AND expression. */ 00967 /* !(abc) = !a + !b + !c */ 00968 case 1: 00969 retval = qof_query_create(); 00970 retval->max_results = q->max_results; 00971 retval->books = g_list_copy (q->books); 00972 retval->search_for = q->search_for; 00973 retval->changed = 1; 00974 00975 aterms = g_list_nth_data(q->terms, 0); 00976 new_oterm = NULL; 00977 for(cur=aterms; cur; cur=cur->next) { 00978 qt = copy_query_term(cur->data); 00979 qt->invert = !(qt->invert); 00980 new_oterm = g_list_append(NULL, qt); 00981 00982 /* g_list_append() can take forever, so let's do this for speed 00983 * in "large" queries. 00984 */ 00985 retval->terms = g_list_reverse(retval->terms); 00986 retval->terms = g_list_prepend(retval->terms, new_oterm); 00987 retval->terms = g_list_reverse(retval->terms); 00988 } 00989 break; 00990 00991 /* If there are multiple OR-terms, we just recurse by 00992 * breaking it down to !(a + b + c) = 00993 * !a * !(b + c) = !a * !b * !c. */ 00994 default: 00995 right = qof_query_create(); 00996 right->terms = copy_or_terms(g_list_nth(q->terms, 1)); 00997 00998 left = qof_query_create(); 00999 left->terms = g_list_append(NULL, 01000 copy_and_terms(g_list_nth_data(q->terms, 0))); 01001 01002 iright = qof_query_invert(right); 01003 ileft = qof_query_invert(left); 01004 01005 retval = qof_query_merge(iright, ileft, QOF_QUERY_AND); 01006 retval->books = g_list_copy (q->books); 01007 retval->max_results = q->max_results; 01008 retval->search_for = q->search_for; 01009 retval->changed = 1; 01010 01011 qof_query_destroy(iright); 01012 qof_query_destroy(ileft); 01013 qof_query_destroy(right); 01014 qof_query_destroy(left); 01015 break; 01016 } 01017 01018 return retval; 01019 }
|
|
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 798 of file qofquery.c. 00799 { 00800 if (!query) 00801 return NULL; 00802 00803 return query->results; 00804 }
|
|
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 1027 of file qofquery.c. 01028 { 01029 01030 QofQuery * retval = NULL; 01031 QofQuery * i1, * i2; 01032 QofQuery * t1, * t2; 01033 GList * i, * j; 01034 QofIdType search_for; 01035 01036 if(!q1) return q2; 01037 if(!q2) return q1; 01038 01039 if (q1->search_for && q2->search_for) 01040 g_return_val_if_fail (safe_strcmp (q1->search_for, q2->search_for) == 0, 01041 NULL); 01042 01043 search_for = (q1->search_for ? q1->search_for : q2->search_for); 01044 01045 /* Avoid merge surprises if op==QOF_QUERY_AND but q1 is empty. 01046 * The goal of this tweak is to all the user to start with 01047 * an empty q1 and then append to it recursively 01048 * (and q1 (and q2 (and q3 (and q4 ....)))) 01049 * without bombing out because the append started with an 01050 * empty list. 01051 * We do essentially the same check in qof_query_add_term() 01052 * so that the first term added to an empty query doesn't screw up. 01053 */ 01054 if ((QOF_QUERY_AND == op) && (0 == qof_query_has_terms (q1))) 01055 { 01056 op = QOF_QUERY_OR; 01057 } 01058 01059 switch(op) 01060 { 01061 case QOF_QUERY_OR: 01062 retval = qof_query_create(); 01063 retval->terms = 01064 g_list_concat(copy_or_terms(q1->terms), copy_or_terms(q2->terms)); 01065 retval->books = merge_books (q1->books, q2->books); 01066 retval->max_results = q1->max_results; 01067 retval->changed = 1; 01068 break; 01069 01070 case QOF_QUERY_AND: 01071 retval = qof_query_create(); 01072 retval->books = merge_books (q1->books, q2->books); 01073 retval->max_results = q1->max_results; 01074 retval->changed = 1; 01075 01076 /* g_list_append() can take forever, so let's build the list in 01077 * reverse and then reverse it at the end, to deal better with 01078 * "large" queries. 01079 */ 01080 for(i=q1->terms; i; i=i->next) 01081 { 01082 for(j=q2->terms; j; j=j->next) 01083 { 01084 retval->terms = 01085 g_list_prepend(retval->terms, 01086 g_list_concat 01087 (copy_and_terms(i->data), 01088 copy_and_terms(j->data))); 01089 } 01090 } 01091 retval->terms = g_list_reverse(retval->terms); 01092 break; 01093 01094 case QOF_QUERY_NAND: 01095 /* !(a*b) = (!a + !b) */ 01096 i1 = qof_query_invert(q1); 01097 i2 = qof_query_invert(q2); 01098 retval = qof_query_merge(i1, i2, QOF_QUERY_OR); 01099 qof_query_destroy(i1); 01100 qof_query_destroy(i2); 01101 break; 01102 01103 case QOF_QUERY_NOR: 01104 /* !(a+b) = (!a*!b) */ 01105 i1 = qof_query_invert(q1); 01106 i2 = qof_query_invert(q2); 01107 retval = qof_query_merge(i1, i2, QOF_QUERY_AND); 01108 qof_query_destroy(i1); 01109 qof_query_destroy(i2); 01110 break; 01111 01112 case QOF_QUERY_XOR: 01113 /* a xor b = (a * !b) + (!a * b) */ 01114 i1 = qof_query_invert(q1); 01115 i2 = qof_query_invert(q2); 01116 t1 = qof_query_merge(q1, i2, QOF_QUERY_AND); 01117 t2 = qof_query_merge(i1, q2, QOF_QUERY_AND); 01118 retval = qof_query_merge(t1, t2, QOF_QUERY_OR); 01119 01120 qof_query_destroy(i1); 01121 qof_query_destroy(i2); 01122 qof_query_destroy(t1); 01123 qof_query_destroy(t2); 01124 break; 01125 } 01126 01127 retval->search_for = search_for; 01128 return retval; 01129 }
|
|
Like qof_query_merge, but this will merge a copy of q2 into q1. q2 remains unchanged. Definition at line 1132 of file qofquery.c. 01133 { 01134 QofQuery *tmp_q; 01135 01136 if (!q1 || !q2) 01137 return; 01138 01139 tmp_q = qof_query_merge (q1, q2, op); 01140 swap_terms (q1, tmp_q); 01141 qof_query_destroy (tmp_q); 01142 }
|
|
Return the number of terms in the canonical form of the query. Definition at line 854 of file qofquery.c. 00855 { 00856 GList *o; 00857 int n = 0; 00858 if (!q) return 0; 00859 for (o = q->terms; o; o=o->next) 00860 n += g_list_length(o->data); 00861 return n; 00862 }
|
|
Definition at line 1433 of file qofquery.c. 01434 { 01435 GList *output; 01436 GString *str; 01437 QofQuerySort *s[3]; 01438 gint maxResults = 0, numSorts = 3; 01439 01440 ENTER (" "); 01441 01442 if (!query) { 01443 LEAVE("query is (null)"); 01444 return; 01445 } 01446 01447 output = NULL; 01448 str = NULL; 01449 maxResults = qof_query_get_max_results (query); 01450 01451 output = qof_query_printSearchFor (query, output); 01452 output = qof_query_printTerms (query, output); 01453 01454 qof_query_get_sorts (query, &s[0], &s[1], &s[2]); 01455 01456 if (s[0]) 01457 { 01458 output = qof_query_printSorts (s, numSorts, output); 01459 } 01460 01461 str = g_string_new (" "); 01462 g_string_printf (str, "Maximum number of results: %d", maxResults); 01463 output = g_list_append (output, str); 01464 01465 qof_query_printOutput (output); 01466 LEAVE (" "); 01467 }
|
|
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 655 of file qofquery.c. 00656 { 00657 QofQueryTerm *qt; 00658 GList *or, *and; 00659 00660 if (!q || !param_list) return; 00661 00662 for (or = q->terms; or; or = or->next) { 00663 for (and = or->data; and; and = and->next) { 00664 qt = and->data; 00665 if (!param_list_cmp (qt->param_list, param_list)) { 00666 if (g_list_length (or->data) == 1) { 00667 q->terms = g_list_remove_link (q->terms, or); 00668 g_list_free_1 (or); 00669 or = q->terms; 00670 break; 00671 } else { 00672 or->data = g_list_remove_link (or->data, and); 00673 g_list_free_1 (and); 00674 and = or->data; 00675 if (!and) break; 00676 } 00677 q->changed = 1; 00678 free_query_term (qt); 00679 } 00680 } 00681 if (!or) break; 00682 } 00683 }
|
|
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 685 of file qofquery.c. 00686 { 00687 GList *matching_objects = NULL; 00688 GList *node; 00689 int object_count = 0; 00690 00691 if (!q) return NULL; 00692 g_return_val_if_fail (q->search_for, NULL); 00693 g_return_val_if_fail (q->books, NULL); 00694 ENTER (" q=%p", q); 00695 00696 /* XXX: Prioritize the query terms? */ 00697 00698 /* prepare the Query for processing */ 00699 if (q->changed) 00700 { 00701 query_clear_compiles (q); 00702 compile_terms (q); 00703 } 00704 00705 /* Maybe log this sucker */ 00706 if (qof_log_check (log_module, QOF_LOG_DETAIL)) qof_query_print (q); 00707 00708 /* Now run the query over all the objects and save the results */ 00709 { 00710 QofQueryCB qcb; 00711 00712 memset (&qcb, 0, sizeof (qcb)); 00713 qcb.query = q; 00714 00715 /* For each book */ 00716 for (node=q->books; node; node=node->next) 00717 { 00718 QofBook *book = node->data; 00719 QofBackend *be = book->backend; 00720 00721 /* run the query in the backend */ 00722 if (be) 00723 { 00724 gpointer compiled_query = g_hash_table_lookup (q->be_compiled, book); 00725 00726 if (compiled_query && be->run_query) 00727 { 00728 (be->run_query) (be, compiled_query); 00729 } 00730 } 00731 00732 /* And then iterate over all the objects */ 00733 qof_object_foreach (q->search_for, book, (QofEntityForeachCB) check_item_cb, &qcb); 00734 } 00735 00736 matching_objects = qcb.list; 00737 object_count = qcb.count; 00738 } 00739 PINFO ("matching objects=%p count=%d", matching_objects, object_count); 00740 00741 /* There is no absolute need to reverse this list, since it's being 00742 * sorted below. However, in the common case, we will be searching 00743 * in a confined location where the objects are already in order, 00744 * thus reversing will put us in the correct order we want and make 00745 * the sorting go much faster. 00746 */ 00747 matching_objects = g_list_reverse(matching_objects); 00748 00749 /* Now sort the matching objects based on the search criteria 00750 * sortQuery is an unforgivable use of static global data... 00751 * I just can't figure out how else to do this sanely. 00752 */ 00753 if (q->primary_sort.comp_fcn || q->primary_sort.obj_cmp || 00754 (q->primary_sort.use_default && q->defaultSort)) 00755 { 00756 sortQuery = q; 00757 matching_objects = g_list_sort(matching_objects, sort_func); 00758 sortQuery = NULL; 00759 } 00760 00761 /* Crop the list to limit the number of splits. */ 00762 if((object_count > q->max_results) && (q->max_results > -1)) 00763 { 00764 if(q->max_results > 0) 00765 { 00766 GList *mptr; 00767 00768 /* mptr is set to the first node of what will be the new list */ 00769 mptr = g_list_nth(matching_objects, object_count - q->max_results); 00770 /* mptr should not be NULL, but let's be safe */ 00771 if (mptr != NULL) 00772 { 00773 if (mptr->prev != NULL) mptr->prev->next = NULL; 00774 mptr->prev = NULL; 00775 } 00776 g_list_free(matching_objects); 00777 matching_objects = mptr; 00778 } 00779 else 00780 { 00781 /* q->max_results == 0 */ 00782 g_list_free(matching_objects); 00783 matching_objects = NULL; 00784 } 00785 object_count = q->max_results; 00786 } 00787 00788 q->changed = 0; 00789 00790 g_list_free(q->results); 00791 q->results = matching_objects; 00792 00793 LEAVE (" q=%p", q); 00794 return matching_objects; 00795 }
|
|
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 827 of file qofquery.c. 00828 { 00829 if (!q || !obj_type) 00830 return; 00831 00832 if (safe_strcmp (q->search_for, obj_type)) { 00833 q->search_for = (QofIdType) obj_type; 00834 q->changed = 1; 00835 } 00836 }
|
|
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 1222 of file qofquery.c. 01223 { 01224 GSList *slist = NULL; 01225 if (!q || !book) return; 01226 01227 /* Make sure this book is only in the list once */ 01228 if (g_list_index (q->books, book) == -1) 01229 q->books = g_list_prepend (q->books, book); 01230 01231 slist = g_slist_prepend (slist, QOF_PARAM_GUID); 01232 slist = g_slist_prepend (slist, QOF_PARAM_BOOK); 01233 qof_query_add_guid_match (q, slist, 01234 qof_book_get_guid(book), QOF_QUERY_AND); 01235 }
|
|
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 1185 of file qofquery.c. 01186 { 01187 if (!q) return; 01188 q->max_results = n; 01189 }
|
|
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 1176 of file qofquery.c. 01178 { 01179 if (!q) return; 01180 q->primary_sort.increasing = prim_inc; 01181 q->secondary_sort.increasing = sec_inc; 01182 q->tertiary_sort.increasing = tert_inc; 01183 }
|
|
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 1145 of file qofquery.c. 01147 { 01148 if (!q) return; 01149 if (q->primary_sort.param_list) 01150 g_slist_free (q->primary_sort.param_list); 01151 q->primary_sort.param_list = params1; 01152 q->primary_sort.options = 0; 01153 01154 if (q->secondary_sort.param_list) 01155 g_slist_free (q->secondary_sort.param_list); 01156 q->secondary_sort.param_list = params2; 01157 q->secondary_sort.options = 0; 01158 01159 if (q->tertiary_sort.param_list) 01160 g_slist_free (q->tertiary_sort.param_list); 01161 q->tertiary_sort.param_list = params3; 01162 q->tertiary_sort.options = 0; 01163 01164 q->changed = 1; 01165 }
|