static int get_num_xactions_before_date(QofBook *book, time64 close_date) { QofQuery *q; GSList *param; QofQueryPredData *pred; GList *res, *n; int cnt = 0; q = qof_query_create_for(GNC_ID_TRANS); qof_query_set_max_results(q, -1); qof_query_set_book (q, book); /* Look for transactions earlier than the closing date */ param = g_slist_prepend (NULL, TRANS_DATE_POSTED); pred = qof_query_date_predicate (QOF_COMPARE_LTE, QOF_DATE_MATCH_NORMAL, close_date); qof_query_add_term (q, param, pred, QOF_QUERY_FIRST_TERM); /* Run the query, find how many transactions there are */ res = qof_query_run (q); cnt = 0; for (n = res; n; n = n->next) cnt ++; qof_query_destroy (q); return cnt; }
static void gnc_ledger_display_make_query (GNCLedgerDisplay *ld, gint limit, SplitRegisterType type) { Account *leader; GList *accounts; if (!ld) return; switch (ld->ld_type) { case LD_SINGLE: case LD_SUBACCOUNT: break; case LD_GL: return; default: PERR ("unknown ledger type: %d", ld->ld_type); return; } qof_query_destroy (ld->query); ld->query = qof_query_create_for(GNC_ID_SPLIT); /* This is a bit of a hack. The number of splits should be * configurable, or maybe we should go back a time range instead * of picking a number, or maybe we should be able to exclude * based on reconciled status. Anyway, this works for now. */ if ((limit != 0) && (type != SEARCH_LEDGER)) qof_query_set_max_results (ld->query, limit); qof_query_set_book (ld->query, gnc_get_current_book()); leader = gnc_ledger_display_leader (ld); if (ld->ld_type == LD_SUBACCOUNT) accounts = gnc_account_get_descendants (leader); else accounts = NULL; accounts = g_list_prepend (accounts, leader); xaccQueryAddAccountMatch (ld->query, accounts, QOF_GUID_MATCH_ANY, QOF_QUERY_AND); g_list_free (accounts); }
/** Creates a new query that searches for an GncEntry item with * description string equal to the given "desc" argument. The query * will find the single GncEntry with the latest (=newest) * DATE_ENTERED. */ static QofQuery *new_query_for_entry_desc(GncEntryLedger *reg, const char* desc, gboolean use_invoice) { QofQuery *query = NULL; QofQueryPredData *predData = NULL; GSList *param_list = NULL; GSList *primary_sort_params = NULL; const char* should_be_null = (use_invoice ? ENTRY_BILL : ENTRY_INVOICE); g_assert(reg); g_assert(desc); /* The query itself and its book */ query = qof_query_create_for (GNC_ID_ENTRY); qof_query_set_book (query, reg->book); /* Predicate data: We want to compare one string, namely the given * argument */ predData = qof_query_string_predicate (QOF_COMPARE_EQUAL, desc, QOF_STRING_MATCH_CASEINSENSITIVE, FALSE); /* Search Parameter: We want to query on the ENTRY_DESC column */ param_list = qof_query_build_param_list (ENTRY_DESC, NULL); /* Register this in the query */ qof_query_add_term (query, param_list, predData, QOF_QUERY_FIRST_TERM); /* For invoice entries, Entry->Bill must be NULL, and vice versa */ qof_query_add_guid_match (query, qof_query_build_param_list (should_be_null, QOF_PARAM_GUID, NULL), NULL, QOF_QUERY_AND); /* Set the sort order: By DATE_ENTERED, increasing, and returning * only one single resulting item. */ primary_sort_params = qof_query_build_param_list(ENTRY_DATE_ENTERED, NULL); qof_query_set_sort_order (query, primary_sort_params, NULL, NULL); qof_query_set_sort_increasing (query, TRUE, TRUE, TRUE); qof_query_set_max_results(query, 1); return query; }
/******************************************************************* * get_earliest_in_book * * Find the earliest date occuring in the book. Do this by making * a query and sorting by date. Since the truncated sort returns * only the *last* search results, sort in decreasing order. *******************************************************************/ static time64 get_earliest_in_book (QofBook *book) { QofQuery *q; GSList *p1, *p2; GList *res; time64 earliest; q = qof_query_create_for (GNC_ID_SPLIT); qof_query_set_max_results (q, 1); qof_query_set_book (q, book); /* Sort by transaction date */ p1 = g_slist_prepend (NULL, TRANS_DATE_POSTED); p1 = g_slist_prepend (p1, SPLIT_TRANS); p2 = g_slist_prepend (NULL, QUERY_DEFAULT_SORT); qof_query_set_sort_order (q, p1, p2, NULL); /* Reverse the sort order */ qof_query_set_sort_increasing (q, FALSE, FALSE, FALSE); /* Run the query, find the earliest transaction date */ res = qof_query_run (q); if (res) { earliest = xaccQueryGetEarliestDateFound (q); } else { /* If no results, we don't want to bomb totally */ earliest = gnc_time (0); } qof_query_destroy (q); return earliest; }
int main (int argc, char *argv[]) { int err, fake_argc = 1; char * fake_argv[] = {"hello", 0}; QofBook *book; Account *root; char *bufp; int rc, sz; /* intitialize the engine */ gnc_engine_init (fake_argc, fake_argv); /* contact the database, which is a flat file for this demo */ book = qof_book_new (); rc = gnc_book_begin (book, "file:/tmp/demo.gnucash", FALSE); if (!rc) goto bookerrexit; rc = gnc_book_load (book); if (!rc) goto bookerrexit; /* the root pointer points to our local cache of the data */ root = gnc_book_get_root_account (book); /* --------------------------------------------------- */ /* done with initialization, go into event loop */ while (FCGI_Accept() >= 0) { GList *split_list; Query *q = NULL; char *request_method; int read_len = 0; /* get the request method */ request_method = getenv ("REQUEST_METHOD"); /* Lets pretend that method=get means user has logged * in. Send the user the accounts and currencies, * but not the transactions/splits. */ if (!strcmp ("GET", request_method)) { gncxml_write_account_tree_to_buf(root, &bufp, &sz); /* print the HTTP header */ printf("Content-type: text/gnc-xml\r\n" "Content-Length: %d\r\n" "\r\n", sz); /* send the xml to the client */ printf ("%s", bufp); free (bufp); /* wait for the next request */ continue; } if (!strcmp ("POST", request_method)) { char * content_length = getenv("CONTENT_LENGTH"); read_len = atoi (content_length); /* read 'read_len' bytes from stdin ... */ bufp = (char *) malloc (read_len); fread (bufp, read_len, 1, stdin); /* conver the xml input into a gnucash query structure... */ q = gncxml_read_query (bufp, read_len); xaccQuerySetGroup (q, root); /* hack -- limit to 30 splits ... */ qof_query_set_max_results (q, 30); split_list = qof_query_run (q); qof_query_destroy (q); /* wait for the next request */ continue; } /* if we got to here, an error -- unknown method */ printf("Content-type: text/plain\r\n" "\r\n" "unknown request type \n"); } bookerrexit: err = gnc_book_get_error (book); /* 500 Server Error */ FCGI_SetExitStatus (500); printf("Content-type: text/plain\r\n\r\n" "error was %s\n", strerror (err)); FCGI_Finish(); /* close the book */ qof_book_destroy (book); /* shut down the engine */ gnc_engine_shutdown (); sleep (1); return 0; }
int main (int argc, char *argv[]) { int err, fake_argc = 1; char * fake_argv[] = {"hello", 0}; QofBook *book; Account *root; char *request_bufp, *reply_bufp; int rc, sz; /* intitialize the engine */ gnc_engine_init (fake_argc, fake_argv); /* contact the database, which is a flat file for this demo */ /* this should really be an SQL server */ book = qof_book_new (); rc = gnc_book_begin (book, "file:/tmp/demo.gnucash", FALSE); if (!rc) goto bookerrexit; rc = gnc_book_load (book); if (!rc) goto bookerrexit; /* the root pointer points to our local cache of the data */ root = gnc_book_get_root_account (book); /* --------------------------------------------------- */ /* done with initialization, go into event loop */ while (FCGI_Accept() >= 0) { GList *split_list; Query *q = NULL; const char *request_method; const char *user_agent; const char *auth_string; const char *content_length; gchar guidstr[GUID_ENCODING_LENGTH+1]; int read_len = 0; int send_accts = 0; /* get the user agent; reject if wrong agent */ user_agent = getenv ("HTTP_USER_AGENT"); if (strncmp ("gnucash", user_agent, 7)) { reject_user_agent (user_agent); continue; } /* get the request method */ request_method = getenv ("REQUEST_METHOD"); if (strcmp ("POST", request_method)) { /* method=post is the only spported method*/ reject_method(request_method); continue; } /* ----------------------------------------------- */ /* look for an authentication cookie */ auth_string = find_cookie ("gnc-server"); /* found the cookie, lets make sure that it is valid */ if (auth_string) { gboolean valid_session; valid_session = have_session (auth_string); if (!valid_session) { /* XXX invalid sessions are a sign of hacking; * this event should be noted in a security log * and the server admin contacted. */ reject_session (auth_string); continue; } } /* go ahead and read the message body. * we'll need this soon enough */ content_length = getenv("CONTENT_LENGTH"); read_len = atoi (content_length); /* read 'read_len' bytes from stdin ... */ request_bufp = (char *) g_malloc (read_len); fread (request_bufp, read_len, 1, stdin); /* if no previously authenticated session, * authenticate now */ if (!auth_string) { char *name = NULL, *passwd = NULL; parse_for_login (request_bufp, &name, &passwd); auth_string = auth_user (name, passwd, guidstr); if (!auth_string) { reject_auth(); g_free (request_bufp); continue; } send_accts = 1; } /* ----------------------------------------------- */ /* send only the accounts to the user */ if (send_accts) { /* print the HTTP header */ printf("Content-type: text/gnc-xml\r\n" "Set-Cookie: %s\r\n" "Content-Length: %d\r\n" "\r\n", auth_string, sz); /* since this is the first time the user is logging * in, send them the full set of accounts. * (Do not send them any transactions yet). */ gncxml_write_account_tree_to_buf(root, &reply_bufp, &sz); /* send the xml to the client */ printf ("%s", reply_bufp); g_free (request_bufp); /* wait for the next request */ continue; } /* ----------------------------------------------- */ /* If we got to here, then the ser should be sending * us a query xml. * we should somehow error check that what we got * is really a valid query */ /* conver the xml input into a gnucash query structure... */ q = gncxml_read_query (request_bufp, read_len); xaccQuerySetGroup (q, root); /* hack -- limit to 30 splits ... */ qof_query_set_max_results (q, 30); split_list = qof_query_run (q); /* poke those splits into an ccount group structure */ /* XXX not implemented */ /* send the account group structure back to the user */ /* XXX not implemented */ qof_query_destroy (q); g_free (request_bufp); } bookerrexit: err = gnc_book_get_error (book); /* 500 Server Error */ FCGI_SetExitStatus (500); printf("Content-type: text/plain\r\n\r\n" "error was %s\n", strerror (err)); FCGI_Finish(); /* close the book */ qof_book_destroy (book); /* shut down the engine */ gnc_engine_shutdown (); sleep (1); /* must return a non-zero error code, otherwise fastcgi * attempts to respawn this daemon. */ return 500; }