[libgda] GdaDataPivot improvements
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] GdaDataPivot improvements
- Date: Sun, 25 Sep 2011 20:20:45 +0000 (UTC)
commit ef21ade50a64ebc201293c9bcbc97f09bc37144f
Author: Vivien Malerba <malerba gnome-db org>
Date: Sun Sep 25 22:19:53 2011 +0200
GdaDataPivot improvements
libgda/gda-data-pivot.c | 105 +++++++++++++++++++++++++++++------------------
tools/gda-sql.1.in | 11 ++++-
tools/gda-sql.c | 37 +++++++++++-----
3 files changed, 99 insertions(+), 54 deletions(-)
---
diff --git a/libgda/gda-data-pivot.c b/libgda/gda-data-pivot.c
index 1cd91f8..8c87c93 100644
--- a/libgda/gda-data-pivot.c
+++ b/libgda/gda-data-pivot.c
@@ -1005,12 +1005,6 @@ gda_data_pivot_populate (GdaDataPivot *pivot, GError **error)
gboolean retval = FALSE;
g_return_val_if_fail (GDA_IS_DATA_PIVOT (pivot), FALSE);
- if (!pivot->priv->column_fields || (pivot->priv->column_fields->len == 0)) {
- g_set_error (error, GDA_DATA_PIVOT_ERROR, GDA_DATA_PIVOT_USAGE_ERROR,
- "%s", _("No column field defined"));
- return FALSE;
- }
-
if (!pivot->priv->row_fields || (pivot->priv->row_fields->len == 0)) {
g_set_error (error, GDA_DATA_PIVOT_ERROR, GDA_DATA_PIVOT_USAGE_ERROR,
"%s", _("No row field defined"));
@@ -1037,11 +1031,13 @@ gda_data_pivot_populate (GdaDataPivot *pivot, GError **error)
g_string_append (string, ", ");
g_string_append (string, part);
}
- for (i = 0; i < pivot->priv->column_fields->len; i++) {
- gchar *part;
- part = g_array_index (pivot->priv->column_fields, gchar *, i);
- g_string_append (string, ", ");
- g_string_append (string, part);
+ if (pivot->priv->column_fields) {
+ for (i = 0; i < pivot->priv->column_fields->len; i++) {
+ gchar *part;
+ part = g_array_index (pivot->priv->column_fields, gchar *, i);
+ g_string_append (string, ", ");
+ g_string_append (string, part);
+ }
}
if (pivot->priv->data_fields) {
for (i = 0; i < pivot->priv->data_fields->len; i++) {
@@ -1175,17 +1171,23 @@ gda_data_pivot_populate (GdaDataPivot *pivot, GError **error)
/*
* Column handling
*/
- for (col = 0; col < (gint) pivot->priv->column_fields->len;
- col++) {
- const GValue *ivalue;
+ gint colsmax;
+ if (pivot->priv->column_fields)
+ colsmax = (gint) pivot->priv->column_fields->len;
+ else
+ colsmax = 1;
+ for (col = 0; col < colsmax; col++) {
+ const GValue *ivalue = NULL;
GError *lerror = NULL;
- ivalue = gda_data_model_iter_get_value_at_e (iter,
- col + pivot->priv->row_fields->len,
- &lerror);
- if (!ivalue || lerror) {
- clean_previous_population (pivot);
- g_propagate_error (error, lerror);
- goto out;
+ if (pivot->priv->column_fields) {
+ ivalue = gda_data_model_iter_get_value_at_e (iter,
+ col + pivot->priv->row_fields->len,
+ &lerror);
+ if (!ivalue || lerror) {
+ clean_previous_population (pivot);
+ g_propagate_error (error, lerror);
+ goto out;
+ }
}
gint di, dimax;
@@ -1215,25 +1217,35 @@ gda_data_pivot_populate (GdaDataPivot *pivot, GError **error)
/* create new column */
GdaColumn *column;
GString *name;
- gchar *tmp;
name = g_string_new ("");
- if (pivot->priv->column_fields->len > 1) {
+ if (pivot->priv->column_fields &&
+ pivot->priv->column_fields->len > 1) {
GdaColumn *column;
column = gda_data_model_describe_column (model,
pivot->priv->row_fields->len + col);
g_string_append_printf (name, "[%s]",
gda_column_get_name (column));
}
- tmp = gda_value_stringify (ivalue);
- g_string_append (name, tmp);
- g_free (tmp);
+ if (ivalue) {
+ gchar *tmp;
+ tmp = gda_value_stringify (ivalue);
+ g_string_append (name, tmp);
+ g_free (tmp);
+ }
if ((di >= 0) && (dimax > 0)) {
GdaColumn *column;
- column = gda_data_model_describe_column (model,
- pivot->priv->row_fields->len + pivot->priv->column_fields->len + di);
- g_string_append_printf (name, "[%s]",
- gda_column_get_name (column));
+ gint vcol;
+ vcol = pivot->priv->row_fields->len + di;
+ if (pivot->priv->column_fields)
+ vcol += pivot->priv->column_fields->len;
+ column = gda_data_model_describe_column (model, vcol);
+ if (pivot->priv->column_fields)
+ g_string_append_printf (name, "[%s]",
+ gda_column_get_name (column));
+ else
+ g_string_append (name,
+ gda_column_get_name (column));
}
column = gda_column_new ();
@@ -1249,7 +1261,7 @@ gda_data_pivot_populate (GdaDataPivot *pivot, GError **error)
ColumnData *ncoldata;
ncoldata = g_new (ColumnData, 1);
- ncoldata->value = gda_value_copy ((GValue*) ivalue);
+ ncoldata->value = ivalue ? gda_value_copy ((GValue*) ivalue) : NULL;
ncoldata->column_fields_index = col;
ncoldata->data_pos = di;
colindex = g_new (gint, 1);
@@ -1263,9 +1275,11 @@ gda_data_pivot_populate (GdaDataPivot *pivot, GError **error)
if (di >= 0) {
const GValue *cvalue;
GError *lerror = NULL;
- cvalue = gda_data_model_iter_get_value_at_e (iter,
- pivot->priv->row_fields->len + pivot->priv->column_fields->len + di,
- &lerror);
+ gint vcol;
+ vcol = pivot->priv->row_fields->len + di;
+ if (pivot->priv->column_fields)
+ vcol += pivot->priv->column_fields->len;
+ cvalue = gda_data_model_iter_get_value_at_e (iter, vcol, &lerror);
if (!cvalue || lerror) {
g_object_unref (nrow);
g_propagate_error (error, lerror);
@@ -1307,7 +1321,6 @@ gda_data_pivot_populate (GdaDataPivot *pivot, GError **error)
}
if (gda_data_model_iter_get_row (iter) != -1) {
/* an error occurred! */
- g_print ("////////\n");
goto out;
}
@@ -1355,6 +1368,7 @@ gda_data_pivot_populate (GdaDataPivot *pivot, GError **error)
av = gda_row_get_value (arow, i);
CellData ccdata, *pcdata;
+ GType coltype = GDA_TYPE_NULL;
ccdata.row = j;
ccdata.col = i;
ccdata.values = NULL;
@@ -1363,8 +1377,8 @@ gda_data_pivot_populate (GdaDataPivot *pivot, GError **error)
if (pcdata) {
cell_data_compute_aggregate (pcdata);
if (pcdata->computed_value) {
- gda_value_reset_with_type (av,
- G_VALUE_TYPE (pcdata->computed_value));
+ coltype = G_VALUE_TYPE (pcdata->computed_value);
+ gda_value_reset_with_type (av, coltype);
g_value_copy (pcdata->computed_value, av);
}
else
@@ -1375,9 +1389,12 @@ gda_data_pivot_populate (GdaDataPivot *pivot, GError **error)
GdaDataPivotAggregate agg;
agg = GPOINTER_TO_INT (g_object_get_data ((GObject*) ecolumn, "agg"));
empty = aggregate_get_empty_value (agg);
- gda_value_reset_with_type (av, G_VALUE_TYPE (empty));
+ coltype = G_VALUE_TYPE (empty);
+ gda_value_reset_with_type (av, coltype);
g_value_copy (empty, av);
}
+ if (coltype != GDA_TYPE_NULL)
+ gda_column_set_g_type (ecolumn, coltype);
}
}
pivot->priv->results = results;
@@ -1570,7 +1587,10 @@ guint column_data_hash (gconstpointer key)
{
ColumnData *cd;
cd = (ColumnData*) key;
- return _gda_value_hash (cd->value) + cd->column_fields_index + cd->data_pos;
+ if (cd->value)
+ return _gda_value_hash (cd->value) + cd->column_fields_index + cd->data_pos;
+ else
+ return cd->column_fields_index + cd->data_pos;
}
static gboolean
@@ -1582,7 +1602,12 @@ column_data_equal (gconstpointer a, gconstpointer b)
if ((cda->column_fields_index != cdb->column_fields_index) ||
(cda->data_pos != cdb->data_pos))
return FALSE;
- return gda_value_differ (cda->value, cdb->value) ? FALSE : TRUE;
+ if (cda->value && cdb->value)
+ return gda_value_differ (cda->value, cdb->value) ? FALSE : TRUE;
+ else if (cda->value || cdb->value)
+ return FALSE;
+ else
+ return TRUE;
}
static void
diff --git a/tools/gda-sql.1.in b/tools/gda-sql.1.in
index 2a6c2e3..36c5554 100644
--- a/tools/gda-sql.1.in
+++ b/tools/gda-sql.1.in
@@ -271,16 +271,21 @@ database's schema).
.IP \fB.o\fP
Sends output to a file or |pipe. Full syntax is: \fB.o <FILE_NAME>\fP or \fB.o |<COMMAND>\fP.
.IP \fB.pivot\fP
-Performs data summarization on a data set. Full syntax is: \fB.pivot <SELECT> <ROW_FIELDS> <COLUMN_FIELDS> [<DATA_FIELDS> [...]]\fP.
+Performs data summarization on a data set. Full syntax is: \fB.pivot <SELECT> <ROW_FIELDS> [<COLUMN_FIELDS> [<DATA_FIELDS> [...]]]\fP.
The \fI<SELECT>\fP defines the data set to perform summarization on.
The \fI<ROW_FIELDS>\fP defines the fields from the data set from which each individual value will
yield to a row in the analysis (it can be any valid selectable SQL expression on the data set's
fields); multiple expressions can be provided, separated by commas (forming a valid SQL expression).
+In this case a row will be created for each combination of values of each of the expression.
The \fI<COLUMN_FIELDS>\fP defines the fields from the data set from which each individual value will
-yield to a column in the analysis. Its syntax is similar to the \fI<ROW_FIELDS>\fP one.
+yield to a column in the analysis. Its syntax is similar to the \fI<ROW_FIELDS>\fP one. If not
+specified (or if specified as a single dash ("-") caracter), then only one column will be created.
+Note that, if the \fI<DATA_FIELDS>\fP argument is
+specified each column created from the \fI<COLUMN_FIELDS>\fP will in fact lead to the creation
+of as many \fI<DATA_FIELDS>\fP arguments provided.
The \fI<DATA_FIELDS>\fP arguments are entirely optional and indicates the way data summarization
is done for each pair of (row,column) values (the default is to count occurrences). The syntax
@@ -294,6 +299,8 @@ Examples:
\fB.pivot "SELECT * FROM products" category "CASE WHEN price < 15 THEN 'low' ELSE 'high' END" [AVG]price \fP
+\fB.pivot "SELECT * FROM sales" category,product - [AVG]quantity\fP
+
.IP \fB.q\fP
Quits the application.
diff --git a/tools/gda-sql.c b/tools/gda-sql.c
index 82337ee..d0e590b 100644
--- a/tools/gda-sql.c
+++ b/tools/gda-sql.c
@@ -4671,11 +4671,8 @@ extra_command_pivot (SqlConsole *console, GdaConnection *cnc, const gchar **args
_("Missing row fields specifications"));
return NULL;
}
- if (!column_fields) {
- g_set_error (error, 0, 0, "%s",
- _("Missing column fields specifications"));
- return NULL;
- }
+ if (column_fields && !strcmp (column_fields, "-"))
+ column_fields = NULL;
/* execute SELECT */
gboolean was_in_trans;
@@ -4705,7 +4702,8 @@ extra_command_pivot (SqlConsole *console, GdaConnection *cnc, const gchar **args
return NULL;
}
- if (! gda_data_pivot_add_field (pivot, GDA_DATA_PIVOT_FIELD_COLUMN,
+ if (column_fields &&
+ ! gda_data_pivot_add_field (pivot, GDA_DATA_PIVOT_FIELD_COLUMN,
column_fields, NULL, error)) {
g_object_unref (pivot);
return NULL;
@@ -4717,6 +4715,7 @@ extra_command_pivot (SqlConsole *console, GdaConnection *cnc, const gchar **args
gint i;
for (i = 3; args[i] && *args[i]; i++) {
const gchar *df = args[i];
+ const gchar *alias = "count";
GdaDataPivotAggregate agg = GDA_DATA_PIVOT_COUNT;
if (*df == '[') {
const gchar *tmp;
@@ -4729,16 +4728,26 @@ extra_command_pivot (SqlConsole *console, GdaConnection *cnc, const gchar **args
return NULL;
}
df++;
- if (! g_ascii_strncasecmp (df, "sum", 3) && (df[3] == ']'))
+ if (! g_ascii_strncasecmp (df, "sum", 3) && (df[3] == ']')) {
agg = GDA_DATA_PIVOT_SUM;
- else if (! g_ascii_strncasecmp (df, "avg", 3) && (df[3] == ']'))
+ alias = "sum";
+ }
+ else if (! g_ascii_strncasecmp (df, "avg", 3) && (df[3] == ']')) {
agg = GDA_DATA_PIVOT_AVG;
- else if (! g_ascii_strncasecmp (df, "max", 3) && (df[3] == ']'))
+ alias = "avg";
+ }
+ else if (! g_ascii_strncasecmp (df, "max", 3) && (df[3] == ']')) {
agg = GDA_DATA_PIVOT_MAX;
- else if (! g_ascii_strncasecmp (df, "min", 3) && (df[3] == ']'))
+ alias = "max";
+ }
+ else if (! g_ascii_strncasecmp (df, "min", 3) && (df[3] == ']')) {
agg = GDA_DATA_PIVOT_MIN;
- else if (! g_ascii_strncasecmp (df, "count", 5) && (df[5] == ']'))
+ alias = "min";
+ }
+ else if (! g_ascii_strncasecmp (df, "count", 5) && (df[5] == ']')) {
agg = GDA_DATA_PIVOT_COUNT;
+ alias = "count";
+ }
else {
g_timer_destroy (timer);
g_object_unref (pivot);
@@ -4748,11 +4757,15 @@ extra_command_pivot (SqlConsole *console, GdaConnection *cnc, const gchar **args
}
df = tmp+1;
}
- if (! gda_data_pivot_add_data (pivot, agg, df, NULL, error)) {
+ gchar *tmp;
+ tmp = g_strdup_printf ("%s_%s", alias, df);
+ if (! gda_data_pivot_add_data (pivot, agg, df, tmp, error)) {
+ g_free (tmp);
g_timer_destroy (timer);
g_object_unref (pivot);
return NULL;
}
+ g_free (tmp);
}
if (! gda_data_pivot_populate (pivot, error)) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]