Fix query<->scm for new kvp queries.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@5772 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Dave Peticolas 2001-11-06 00:49:46 +00:00
parent d2c12c2e9c
commit 86c55a3e22
11 changed files with 539 additions and 36 deletions

View File

@ -495,12 +495,12 @@ guile_main (int argc, char **argv)
/* g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING); */
glist_exclude_type (KVP_TYPE_BINARY);
glist_exclude_type (KVP_TYPE_GLIST);
kvp_exclude_type (KVP_TYPE_BINARY);
kvp_exclude_type (KVP_TYPE_GLIST);
/* The random double generator is making values
* that postgres doesn't like. */
glist_exclude_type (KVP_TYPE_DOUBLE);
kvp_exclude_type (KVP_TYPE_DOUBLE);
set_max_kvp_depth (3);
set_max_kvp_frame_elements (3);

View File

@ -86,23 +86,32 @@ libgncmod_engine_la_LIBADD = ${GNUCASH_ENGINE_BASE_LIBS}
libgw_glib_la_SOURCES = gw-glib.c glib-helpers.c
libgw_glib_la_LDFLAGS = -module ${G_WRAP_LINK_ARGS}
libgw_engine_la_SOURCES=gw-engine.c engine-helpers.c
libgw_engine_la_LDFLAGS=-module ${G_WRAP_LINK_ARGS}
libgw_kvp_la_SOURCES = gw-kvp.c kvp-scm.c
libgw_kvp_la_LDFLAGS = -module ${G_WRAP_LINK_ARGS}
libgw_engine_la_SOURCES = gw-engine.c engine-helpers.c
libgw_engine_la_LDFLAGS = -module ${G_WRAP_LINK_ARGS}
gncmoddir = ${GNC_SHAREDIR}/guile-modules/gnucash
gncmod_DATA = engine.scm
gncscmdir = ${GNC_SHAREDIR}/scm
gncscm_DATA=commodity-table.scm engine-init.scm engine-interface.scm \
engine-utilities.scm gnc-numeric.scm iso-4217-currencies.scm
gncscm_DATA = \
commodity-table.scm \
engine-init.scm \
engine-interface.scm \
engine-utilities.scm \
gnc-numeric.scm \
iso-4217-currencies.scm
gwmoddir = ${GNC_GWRAP_LIBDIR}
gwmod_DATA = \
gw-engine.scm gw-glib.scm gw-kvp.scm \
gw-engine-spec.scm gw-glib-spec.scm gw-kvp-spec.scm
gw-engine.scm \
gw-glib.scm \
gw-kvp.scm \
gw-engine-spec.scm \
gw-glib-spec.scm \
gw-kvp-spec.scm
EXTRA_DIST = \
.cvsignore \

View File

@ -1434,7 +1434,7 @@ xaccQueryTermEqual (QueryTerm *qt1, QueryTerm *qt2)
n2 = qt2->data.kvp.path;
for ( ; n1 && n2; n1 = n1->next, n2 = n2->next)
if (!safe_strcmp (n1->data, n2->data))
if (safe_strcmp (n1->data, n2->data) != 0)
return FALSE;
if (n1 || n2)

View File

@ -164,7 +164,7 @@ gnc_guid_p(SCM guid_scm) {
GUID guid;
if (!gh_string_p(guid_scm))
return (0 == 1);
return FALSE;
gh_get_substr(guid_scm, string, 0, GUID_ENCODING_LENGTH);
string[GUID_ENCODING_LENGTH] = '\0';
@ -303,6 +303,18 @@ gnc_scm2amt_match_sign (SCM how_scm)
return gnc_gw_enum_scm2val ("<gnc:amt-match-sign>", how_scm);
}
static SCM
gnc_kvp_match_how2scm (kvp_match_t how)
{
return gnc_gw_enum_val2scm ("<gnc:kvp-match-how>", how);
}
static kvp_match_t
gnc_scm2kvp_match_how (SCM how_scm)
{
return gnc_gw_enum_scm2val ("<gnc:kvp-match-how>", how_scm);
}
static SCM
gnc_sort_type2scm (sort_type_t sort_type)
{
@ -386,6 +398,18 @@ gnc_scm2balance_match_how (SCM how_scm)
return gnc_scm2bitfield ("<gnc:balance-match-how>", how_scm);
}
static SCM
gnc_kvp_match_where2scm (kvp_match_where_t where)
{
return gnc_bitfield2scm ("<gnc:kvp-match-where>", where);
}
static kvp_match_where_t
gnc_scm2kvp_match_where (SCM where_scm)
{
return gnc_scm2bitfield ("<gnc:kvp-match-where>", where_scm);
}
static SCM
gnc_acct_guid_glist2scm (GList *account_guids)
{
@ -438,6 +462,328 @@ acct_guid_glist_free (GList *guids)
g_list_free (guids);
}
static SCM
gnc_kvp_path2scm (GSList *path)
{
SCM path_scm = SCM_EOL;
GSList *node;
for (node = path; node; node = node->next)
{
const char *key = node->data;
if (key)
path_scm = gh_cons (gh_str02scm (key), path_scm);
}
return gh_reverse (path_scm);
}
static GSList *
gnc_scm2kvp_path (SCM path_scm)
{
GSList *path = NULL;
if (!gh_list_p (path_scm))
return NULL;
while (!gh_null_p (path_scm))
{
SCM key_scm = gh_car (path_scm);
char *key, *tmp;
if (!gh_string_p (key_scm))
break;
tmp = gh_scm2newstr (key_scm, NULL);
key = g_strdup (tmp);
if (tmp) free (tmp);
path = g_slist_prepend (path, key);
path_scm = gh_cdr (path_scm);
}
return g_slist_reverse (path);
}
static void
gnc_kvp_path_free (GSList *path)
{
GSList *node;
for (node = path; node; node = node->next)
g_free (node->data);
g_slist_free (path);
}
static SCM
gnc_kvp_value_type2scm (kvp_value_t how)
{
return gnc_gw_enum_val2scm ("<gnc:kvp-value-t>", how);
}
static kvp_value_t
gnc_scm2kvp_value_type (SCM value_type_scm)
{
return gnc_gw_enum_scm2val ("<gnc:kvp-value-t>", value_type_scm);
}
static SCM gnc_kvp_frame2scm (kvp_frame *frame);
static SCM
gnc_kvp_value2scm (kvp_value *value)
{
SCM value_scm = SCM_EOL;
kvp_value_t value_t;
SCM scm;
if (!value) return SCM_BOOL_F;
value_t = kvp_value_get_type (value);
value_scm = gh_cons (gnc_kvp_value_type2scm (value_t), value_scm);
switch (value_t)
{
case KVP_TYPE_GINT64:
scm = gnc_gint64_to_scm (kvp_value_get_gint64 (value));
break;
case KVP_TYPE_DOUBLE:
scm = gh_double2scm (kvp_value_get_double (value));
break;
case KVP_TYPE_STRING:
scm = gh_str02scm (kvp_value_get_string (value));
break;
case KVP_TYPE_GUID:
scm = gnc_guid2scm (*kvp_value_get_guid (value));
break;
case KVP_TYPE_BINARY:
scm = SCM_BOOL_F;
break;
case KVP_TYPE_NUMERIC: {
gnc_numeric n = kvp_value_get_numeric (value);
scm = gh_cons (gnc_gint64_to_scm (n.num),
gnc_gint64_to_scm (n.denom));
break;
}
case KVP_TYPE_GLIST: {
GList *node;
scm = SCM_EOL;
for (node = kvp_value_get_glist (value); node; node = node->next)
scm = gh_cons (gnc_kvp_value2scm (node->data), scm);
scm = gh_reverse (scm);
break;
}
case KVP_TYPE_FRAME:
scm = gnc_kvp_frame2scm (kvp_value_get_frame (value));
break;
default:
scm = SCM_BOOL_F;
break;
}
value_scm = gh_cons (scm, value_scm);
return gh_reverse (value_scm);
}
typedef struct
{
SCM scm;
} KVPSCMData;
static void
kvp_frame_slot2scm (const char *key, kvp_value *value, gpointer data)
{
KVPSCMData *ksd = data;
SCM value_scm;
SCM key_scm;
SCM pair;
key_scm = gh_str02scm (key);
value_scm = gnc_kvp_value2scm (value);
pair = gh_cons (key_scm, value_scm);
ksd->scm = gh_cons (pair, ksd->scm);
}
static SCM
gnc_kvp_frame2scm (kvp_frame *frame)
{
KVPSCMData ksd;
if (!frame) return SCM_BOOL_F;
ksd.scm = SCM_EOL;
kvp_frame_for_each_slot (frame, kvp_frame_slot2scm, &ksd);
return ksd.scm;
}
static kvp_frame * gnc_scm2kvp_frame (SCM frame_scm);
static kvp_value *
gnc_scm2kvp_value (SCM value_scm)
{
kvp_value_t value_t;
kvp_value *value;
SCM type_scm;
SCM val_scm;
if (!gh_list_p (value_scm) || gh_null_p (value_scm))
return NULL;
type_scm = gh_car (value_scm);
value_t = gnc_scm2kvp_value_type (type_scm);
value_scm = gh_cdr (value_scm);
if (!gh_list_p (value_scm) || gh_null_p (value_scm))
return NULL;
val_scm = gh_car (value_scm);
switch (value_t)
{
case KVP_TYPE_GINT64:
value = kvp_value_new_gint64 (gnc_scm_to_gint64 (val_scm));
break;
case KVP_TYPE_DOUBLE:
value = kvp_value_new_double (gh_scm2double (val_scm));
break;
case KVP_TYPE_STRING: {
char *str = gh_scm2newstr (val_scm, NULL);
value = kvp_value_new_string (str);
if (str) free (str);
break;
}
case KVP_TYPE_GUID: {
GUID guid = gnc_scm2guid (val_scm);
value = kvp_value_new_guid (&guid);
break;
}
case KVP_TYPE_BINARY:
return NULL;
break;
case KVP_TYPE_NUMERIC: {
gnc_numeric n;
SCM denom;
SCM num;
if (!gh_pair_p (val_scm))
return NULL;
num = gh_car (val_scm);
denom = gh_cdr (val_scm);
n = gnc_numeric_create (gnc_scm_to_gint64 (num),
gnc_scm_to_gint64 (denom));
value = kvp_value_new_gnc_numeric (n);
break;
}
case KVP_TYPE_GLIST: {
GList *list = NULL;
GList *node;
for (; gh_list_p (val_scm) && !gh_null_p (val_scm);
val_scm = gh_cdr (val_scm))
{
SCM scm = gh_car (val_scm);
list = g_list_prepend (list, gnc_scm2kvp_value (scm));
}
list = g_list_reverse (list);
value = kvp_value_new_glist (list);
for (node = list; node; node = node->next)
kvp_value_delete (node->data);
g_list_free (list);
break;
}
case KVP_TYPE_FRAME: {
kvp_frame *frame;
frame = gnc_scm2kvp_frame (val_scm);
value = kvp_value_new_frame (frame);
kvp_frame_delete (frame);
break;
}
default:
g_warning ("unexpected type: %d", value_t);
return NULL;
}
return value;
}
static kvp_frame *
gnc_scm2kvp_frame (SCM frame_scm)
{
kvp_frame * frame;
if (!gh_list_p (frame_scm)) return NULL;
frame = kvp_frame_new ();
for (; gh_list_p (frame_scm) && !gh_null_p (frame_scm);
frame_scm = gh_cdr (frame_scm))
{
SCM pair = gh_car (frame_scm);
kvp_value *value;
SCM key_scm;
SCM val_scm;
char *key;
if (!gh_pair_p (pair))
continue;
key_scm = gh_car (pair);
val_scm = gh_cdr (pair);
if (!gh_string_p (key_scm))
continue;
key = gh_scm2newstr (key_scm, NULL);
if (!key)
continue;
value = gnc_scm2kvp_value (val_scm);
if (!value)
{
free (key);
continue;
}
kvp_frame_set_slot_nc (frame, key, value);
free (key);
}
return frame;
}
static SCM
gnc_queryterm2scm (QueryTerm *qt)
{
@ -489,6 +835,13 @@ gnc_queryterm2scm (QueryTerm *qt)
qt_scm = gh_cons (gnc_guid2scm (qt->data.guid.guid), qt_scm);
break;
case PD_KVP:
qt_scm = gh_cons (gnc_kvp_match_how2scm (qt->data.kvp.how), qt_scm);
qt_scm = gh_cons (gnc_kvp_match_where2scm (qt->data.kvp.where), qt_scm);
qt_scm = gh_cons (gnc_kvp_path2scm (qt->data.kvp.path), qt_scm);
qt_scm = gh_cons (gnc_kvp_value2scm (qt->data.kvp.value), qt_scm);
break;
default:
g_warning ("query type %d not supported", qt->data.type);
return SCM_BOOL_F;
@ -801,6 +1154,57 @@ gnc_scm2query_term_query (SCM query_term_scm)
ok = TRUE;
break;
case PD_KVP: {
GSList *path;
kvp_value *value;
kvp_match_t how;
kvp_match_where_t where;
/* how */
if (gh_null_p (query_term_scm))
break;
scm = gh_car (query_term_scm);
query_term_scm = gh_cdr (query_term_scm);
how = gnc_scm2kvp_match_how (scm);
/* where */
if (gh_null_p (query_term_scm))
break;
scm = gh_car (query_term_scm);
query_term_scm = gh_cdr (query_term_scm);
where = gnc_scm2kvp_match_where (scm);
/* path */
if (gh_null_p (query_term_scm))
break;
scm = gh_car (query_term_scm);
query_term_scm = gh_cdr (query_term_scm);
path = gnc_scm2kvp_path (scm);
/* value */
if (gh_null_p (query_term_scm))
break;
scm = gh_car (query_term_scm);
query_term_scm = gh_cdr (query_term_scm);
value = gnc_scm2kvp_value (scm);
xaccQueryAddKVPMatch (q, path, value, how, where, QUERY_OR);
gnc_kvp_path_free (path);
kvp_value_delete (value);
}
ok = TRUE;
break;
default:
break;
}

View File

@ -470,13 +470,11 @@ decode_md5_string(const char *string, unsigned char *data)
return TRUE;
badstring:
PERR ("bad string, stopped at %d\n", count);
for (count = 0; count < 16; count++)
{
data[count] = 0;
}
return FALSE;
}
char *

View File

@ -384,14 +384,15 @@
(let ((wt (gw:wrap-enumeration mod '<gnc:query-term-type>
"pd_type_t" "const pd_type_t")))
(gw:enum-add-value! wt "PD_DATE" 'pd-date)
(gw:enum-add-value! wt "PD_AMOUNT" 'pd-amount)
(gw:enum-add-value! wt "PD_ACCOUNT" 'pd-account)
(gw:enum-add-value! wt "PD_STRING" 'pd-string)
(gw:enum-add-value! wt "PD_CLEARED" 'pd-cleared)
(gw:enum-add-value! wt "PD_AMOUNT" 'pd-amount)
(gw:enum-add-value! wt "PD_BALANCE" 'pd-balance)
(gw:enum-add-value! wt "PD_CLEARED" 'pd-cleared)
(gw:enum-add-value! wt "PD_DATE" 'pd-date)
(gw:enum-add-value! wt "PD_GUID" 'pd-guid)
(gw:enum-add-value! wt "PD_KVP" 'pd-kvp)
(gw:enum-add-value! wt "PD_MISC" 'pd-misc)
(gw:enum-add-value! wt "PD_STRING" 'pd-string)
#t)
(let ((wt (gw:wrap-enumeration mod '<gnc:query-pred-type>
@ -404,6 +405,7 @@
(gw:enum-add-value! wt "PR_DATE" 'pr-date)
(gw:enum-add-value! wt "PR_DESC" 'pr-desc)
(gw:enum-add-value! wt "PR_GUID" 'pr-guid)
(gw:enum-add-value! wt "PR_KVP" 'pr-kvp)
(gw:enum-add-value! wt "PR_MEMO" 'pr-memo)
(gw:enum-add-value! wt "PR_NUM" 'pr-num)
(gw:enum-add-value! wt "PR_PRICE" 'pr-price)
@ -451,6 +453,35 @@
(gw:enum-add-value! wt "QUERY_MATCH_ANY" 'query-match-any)
#t)
(let ((wt (gw:wrap-enumeration mod '<gnc:kvp-match-how>
"kvp_match_t" "const kvp_match_t")))
(gw:enum-add-value! wt "KVP_MATCH_LT" 'kvp-match-lt)
(gw:enum-add-value! wt "KVP_MATCH_LTE" 'kvp-match-lte)
(gw:enum-add-value! wt "KVP_MATCH_EQ" 'kvp-match-eq)
(gw:enum-add-value! wt "KVP_MATCH_GTE" 'kvp-match-gte)
(gw:enum-add-value! wt "KVP_MATCH_GT" 'kvp-match-gt)
#t)
(let ((wt (gw:wrap-enumeration mod '<gnc:kvp-match-where>
"kvp_match_where_t"
"const kvp_match_where_t")))
(gw:enum-add-value! wt "KVP_MATCH_SPLIT" 'kvp-match-split)
(gw:enum-add-value! wt "KVP_MATCH_TRANS" 'kvp-match-trans)
(gw:enum-add-value! wt "KVP_MATCH_ACCOUNT" 'kvp-match-account)
#t)
(let ((wt (gw:wrap-enumeration mod '<gnc:kvp-value-t>
"kvp_value_t" "const kvp_value_t")))
(gw:enum-add-value! wt "KVP_TYPE_GINT64" 'kvp-type-gint64)
(gw:enum-add-value! wt "KVP_TYPE_DOUBLE" 'kvp-type-double)
(gw:enum-add-value! wt "KVP_TYPE_NUMERIC" 'kvp-type-numeric)
(gw:enum-add-value! wt "KVP_TYPE_STRING" 'kvp-type-string)
(gw:enum-add-value! wt "KVP_TYPE_GUID" 'kvp-type-guid)
(gw:enum-add-value! wt "KVP_TYPE_BINARY" 'kvp-type-binary)
(gw:enum-add-value! wt "KVP_TYPE_GLIST" 'kvp-type-glist)
(gw:enum-add-value! wt "KVP_TYPE_FRAME" 'kvp-type-frame)
#t)
(let ((we
(gw:wrap-enumeration mod '<gnc:AccountType>
"GNCAccountType" "const GNCAccountType")))

View File

@ -13,10 +13,15 @@ gnc_kvp_value_ptr_p(SCM arg)
return TRUE;
}
/* NOTE: There are some problems with this approach. Currently,
* guids are stored simply as strings in scheme, so some
* strings could be mistaken for guids, although that is
* unlikely. The general problem is distinguishing kvp
* types based only on the scheme type. */
kvp_value*
gnc_scm_to_kvp_value_ptr(SCM val)
{
if(gnc_gh_gint64_p(val))
if(gh_exact_p (val) && gnc_gh_gint64_p(val))
{
return kvp_value_new_gint64(gnc_scm_to_gint64(val));
}
@ -43,9 +48,7 @@ gnc_scm_to_kvp_value_ptr(SCM val)
return ret;
}
/* FIXME: add binary handler here when it's figured out */
else if(gh_list_p(val))
{
}
/* FIXME: add list handler here */
/* FIXME: add frame handler here when it's figured out */
return NULL;
}
@ -73,6 +76,8 @@ gnc_kvp_value_ptr_to_scm(kvp_value* val)
return gnc_guid2scm(*tempguid);
}
break;
/* FIXME: handle types below */
case KVP_TYPE_BINARY:
break;
case KVP_TYPE_GLIST:

View File

@ -57,7 +57,7 @@ set_max_kvp_frame_elements (gint max_kvp_frame_elements)
}
void
glist_exclude_type (kvp_value_t kvp_type)
kvp_exclude_type (kvp_value_t kvp_type)
{
gint *key;
@ -71,7 +71,7 @@ glist_exclude_type (kvp_value_t kvp_type)
}
static gboolean
glist_type_excluded (kvp_value_t kvp_type)
kvp_type_excluded (kvp_value_t kvp_type)
{
gint key = kvp_type;
@ -403,7 +403,7 @@ get_random_kvp_value_depth (int type, gint depth)
if (datype == KVP_TYPE_GLIST && depth >= kvp_max_depth)
return NULL;
if (glist_type_excluded (datype))
if (kvp_type_excluded (datype))
return NULL;
switch(datype)
@ -1170,6 +1170,32 @@ get_random_queryop(void)
return get_random_int_in_range (1, QUERY_XOR);
}
static GSList *
get_random_kvp_path (void)
{
GSList *path;
gint len;
path = NULL;
len = get_random_int_in_range (1, kvp_max_depth);
while (len--)
path = g_slist_prepend (path, get_random_string ());
return g_slist_reverse (path);
}
static void
free_random_kvp_path (GSList *path)
{
GSList *node;
for (node = path; node; node = node->next)
g_free (node->data);
g_slist_free (path);
}
Query *
get_random_query(void)
{
@ -1184,9 +1210,11 @@ get_random_query(void)
while (num_terms-- > 0)
{
pr_type_t pr_type;
kvp_value *value;
Timespec *start;
Timespec *end;
GList *guids;
GSList *path;
char *string;
GUID *guid;
@ -1226,14 +1254,19 @@ get_random_query(void)
case PR_BALANCE:
xaccQueryAddBalanceMatch
(q,
get_random_int_in_range (1, BALANCE_UNBALANCED),
get_random_int_in_range (1, BALANCE_BALANCED | BALANCE_UNBALANCED),
get_random_queryop ());
break;
case PR_CLEARED:
xaccQueryAddClearedMatch
(q,
get_random_int_in_range (1, CLEARED_VOIDED),
get_random_int_in_range (1,
CLEARED_NO |
CLEARED_CLEARED |
CLEARED_RECONCILED |
CLEARED_FROZEN |
CLEARED_VOIDED),
get_random_queryop ());
break;
@ -1266,6 +1299,25 @@ get_random_query(void)
g_free (guid);
break;
case PR_KVP:
path = get_random_kvp_path ();
do
{
value = get_random_kvp_value_depth (-2, kvp_max_depth);
} while (!value);
xaccQueryAddKVPMatch (q,
path,
value,
get_random_int_in_range (1, KVP_MATCH_GT),
get_random_int_in_range (1,
KVP_MATCH_SPLIT |
KVP_MATCH_TRANS |
KVP_MATCH_ACCOUNT),
get_random_queryop ());
kvp_value_delete (value);
free_random_kvp_path (path);
break;
case PR_MEMO:
string = get_random_string ();
xaccQueryAddMemoMatch (q,

View File

@ -33,7 +33,7 @@ GUID* get_random_guid(void);
GList* get_random_glist(void);
void random_glist_strings_only (gboolean strings_only);
void glist_exclude_type (kvp_value_t kvp_type);
void kvp_exclude_type (kvp_value_t kvp_type);
void set_max_kvp_depth (gint max_kvp_depth);
void set_max_kvp_frame_elements (gint max_kvp_frame_elements);
void set_max_group_depth (gint max_group_depth);

View File

@ -13,6 +13,7 @@ LDADD = \
../libgncmod-engine.la \
../libgw-engine.la \
../libgw-glib.la \
../libgw-kvp.la \
../test-core/libgncmod-test-engine.la \
${GLIB_LIBS} \
-lltdl

View File

@ -63,6 +63,9 @@ main_helper (int argc, char **argv)
xaccLogDisable ();
/* scm conversion doesn't handle binary atm */
kvp_exclude_type (KVP_TYPE_BINARY);
run_tests ();
print_test_results ();