00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00030 #include "config.h"
00031
00032 #include <glib.h>
00033 #include <string.h>
00034
00035 #include "perr.h"
00036
00037 #include "duifield.h"
00038 #include "duifield-sql.h"
00039 #include "duifieldmap.h"
00040 #include "duifilter.h"
00041 #include "duiresolver.h"
00042 #include "duitxnreport.h"
00043
00044 struct DuiTxnReport_s
00045 {
00046 gchar * row_name;
00048 GList *columns;
00050 gint nest_level;
00057 DuiFieldMap *match;
00058
00060 DuiResolver * resolver;
00061 };
00062
00063
00064
00065 DuiTxnReport *
00066 dui_txnreport_new (const gchar * name, gint nest)
00067 {
00068 DuiTxnReport *row;
00069
00070 row = g_new (DuiTxnReport, 1);
00071 row->row_name = NULL;
00072 if (name) row->row_name = g_strdup (name);
00073
00074 row->columns = NULL;
00075 row->nest_level = nest;
00076 row->match = NULL;
00077
00078 return row;
00079 }
00080
00081
00082
00083 void
00084 dui_txnreport_destroy (DuiTxnReport *row)
00085 {
00086 GList *cnode;
00087
00088 g_free (row->row_name);
00089 dui_field_map_destroy (row->match);
00090
00091 for (cnode=row->columns; cnode; cnode=cnode->next)
00092 {
00093 DuiFieldMap *fm = cnode->data;
00094 dui_field_map_destroy (fm);
00095 }
00096 g_list_free (row->columns);
00097
00098 g_free (row);
00099 }
00100
00101
00102
00103 const gchar *
00104 dui_txnreport_get_name (DuiTxnReport *row)
00105 {
00106 if (!row) return NULL;
00107 return row->row_name;
00108 }
00109
00110 gint
00111 dui_txnreport_get_nest (DuiTxnReport *row)
00112 {
00113 if (!row) return 0;
00114 return row->nest_level;
00115 }
00116
00117
00118
00119 void
00120 dui_txnreport_add_term (DuiTxnReport *row, DuiFieldMap *fm)
00121 {
00122 if (!row || !fm) return;
00123 dui_resolver_add_field (row->resolver, &fm->source);
00124 dui_resolver_add_field (row->resolver, &fm->target);
00125 dui_field_map_resolve (fm);
00126
00127 row->columns = g_list_append (row->columns, fm);
00128 }
00129
00130 void
00131 dui_txnreport_add_match_term (DuiTxnReport *row, DuiFieldMap *fm)
00132 {
00133 if (!row || !fm) return;
00134
00135 if (row->match)
00136 {
00137 PERR ("Target Row Matcher already specified!\n");
00138 }
00139 dui_resolver_add_field (row->resolver, &fm->source);
00140 dui_resolver_add_field (row->resolver, &fm->target);
00141 dui_field_map_resolve (fm);
00142
00143 row->match = fm;
00144 }
00145
00146 void
00147 dui_txnreport_set_resolver (DuiTxnReport * row, DuiResolver *res)
00148 {
00149 GList *cnode;
00150 DuiFieldMap *fm;
00151 if (!row) return;
00152 row->resolver = res;
00153
00154
00155 fm = row->match;
00156 if (fm)
00157 {
00158 dui_resolver_add_field (res, &fm->source);
00159 dui_resolver_add_field (res, &fm->target);
00160 dui_field_map_resolve (fm);
00161 }
00162
00163 for (cnode=row->columns; cnode; cnode=cnode->next)
00164 {
00165 fm = cnode->data;
00166 dui_resolver_add_field (res, &fm->source);
00167 dui_resolver_add_field (res, &fm->target);
00168 dui_field_map_resolve (fm);
00169 }
00170 }
00171
00172
00173
00174
00175
00176
00177 gboolean
00178 dui_txnreport_is_empty (DuiTxnReport * row, DuiDBRecordSet *recs)
00179 {
00180 gint more_rows = 1;
00181
00182 if (!row) return TRUE;
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 dui_recordset_rewind (recs);
00195 while (more_rows)
00196 {
00197 GList *cnode;
00198 for (cnode=row->columns; cnode; cnode=cnode->next)
00199 {
00200 DuiFieldMap *col = cnode->data;
00201 const gchar * val;
00202
00203 dui_field_resolve_recordset (&col->source, recs);
00204 val = dui_field_map_get_value (col);
00205 if (val)
00206 {
00207 PINFO ("have data rows for row=%p %s", row, row->row_name);
00208 return FALSE;
00209 }
00210 }
00211
00212 more_rows = dui_recordset_fetch_row (recs);
00213 }
00214 PINFO ("empty row=%p %s", row, row->row_name);
00215 return TRUE;
00216 }
00217
00218
00219
00220
00221 void
00222 dui_txnreport_run (DuiTxnReport * row, DuiDBRecordSet *recs)
00223 {
00224 gint more_rows = 1;
00225 DuiField *iterator = NULL;
00226
00227 if (!row) return;
00228 ENTER ("(rowname=%s, recs=%p)", row->row_name, recs);
00229
00230
00231 if (row->match)
00232 {
00233 iterator = &row->match->target;
00234 }
00235
00236 dui_field_iter_pre (iterator, (0 == row->nest_level));
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 dui_recordset_rewind (recs);
00247 more_rows = 1;
00248 while (more_rows)
00249 {
00250 gboolean do_transfer;
00251
00252 if (row->match)
00253 {
00254 dui_field_resolve_recordset (&row->match->source, recs);
00255 dui_field_map_transfer_data (row->match);
00256 }
00257
00258 do_transfer = dui_field_iter_next (iterator);
00259
00260 if (do_transfer)
00261 {
00262 GList *cnode;
00263 for (cnode=row->columns; cnode; cnode=cnode->next)
00264 {
00265 DuiFieldMap *col = cnode->data;
00266
00267 dui_field_resolve_recordset (&col->source, recs);
00268 dui_field_iter_column (&col->target, iterator);
00269
00270
00271 dui_field_map_transfer_data (col);
00272 }
00273 }
00274
00275 more_rows = 0;
00276 if (recs) more_rows = dui_recordset_fetch_row (recs);
00277 PINFO ("recs=%p more_rows=%d", recs, more_rows);
00278 }
00279
00280 dui_field_iter_post (iterator);
00281 LEAVE ("(rowname=%s) iterator=%p", row->row_name, iterator);
00282 }
00283
00286