static void compute_columns (GdaDataAccessWrapper *model) { if (model->priv->rows_mapping) { /* use model->priv->rows_mapping to create columns, and correct it if * needed to remove out of range columns */ gint *nmapping; gint i, j, nb_cols; g_assert (!model->priv->columns); nmapping = g_new (gint, model->priv->nb_cols); nb_cols = gda_data_model_get_n_columns (model->priv->model); for (i = 0, j = 0; i < model->priv->nb_cols; i++) { gint nb = model->priv->rows_mapping [i]; if (nb >= nb_cols) continue; GdaColumn *column; column = gda_data_model_describe_column (model->priv->model, nb); if (!column) continue; model->priv->columns = g_slist_append (model->priv->columns, gda_column_copy (column)); nmapping [j] = nb; j++; } model->priv->nb_cols = j; g_free (model->priv->rows_mapping); model->priv->rows_mapping = nmapping; } else model->priv->nb_cols = gda_data_model_get_n_columns (model->priv->model); }
static GdaColumn * gda_data_model_array_describe_column (GdaDataModel *model, gint col) { GdaColumn *column; if (col >= gda_data_model_get_n_columns (model)) { g_warning ("Column %d out of range (0-%d)", col, gda_data_model_get_n_columns (model) - 1); return NULL; } gint tmp; tmp = col; column = g_hash_table_lookup (((GdaDataModelArray*) model)->priv->column_spec, &tmp); if (!column) { column = gda_column_new (); g_signal_connect (G_OBJECT (column), "g-type-changed", G_CALLBACK (column_g_type_changed_cb), model); gda_column_set_position (column, col); gint *ptr; ptr = g_new (gint, 1); *ptr = col; g_hash_table_insert (((GdaDataModelArray*) model)->priv->column_spec, ptr, column); } return column; }
/* * executed in the sub thread (the one which can manipulate @sub_model) */ GdaDataModel * _gda_thread_recordset_new (GdaConnection *cnc, GdaThreadWrapper *wrapper, GdaDataModel *sub_model) { GdaThreadRecordset *model; gint ncols, i, nblobs; gint *blobs_conv = NULL; model = GDA_THREAD_RECORDSET (g_object_new (GDA_TYPE_THREAD_RECORDSET, "connection", cnc, NULL)); _gda_data_select_share_private_data (GDA_DATA_SELECT (sub_model), GDA_DATA_SELECT (model)); model->priv->wrapper = g_object_ref (wrapper); model->priv->sub_model = g_object_ref (sub_model); ncols = gda_data_model_get_n_columns (sub_model); nblobs = 0; for (i = 0; i < ncols; i++) { GdaColumn *col; col = gda_data_model_describe_column (sub_model, i); if (gda_column_get_g_type (col) == GDA_TYPE_BLOB) { if (!blobs_conv) blobs_conv = g_new0 (gint, ncols); blobs_conv [nblobs] = i; nblobs++; } } model->priv->blobs_conv = blobs_conv; model->priv->nblobs = nblobs; COPY_PUBLIC_DATA (sub_model, model); return GDA_DATA_MODEL (model); }
static void gda_data_meta_wrapper_set_property (GObject *object, guint param_id, const GValue *value, GParamSpec *pspec) { GdaDataMetaWrapper *model; model = GDA_DATA_META_WRAPPER (object); if (model->priv) { switch (param_id) { case PROP_MODEL: { GdaDataModel *mod = g_value_get_object(value); if (mod) { g_return_if_fail (GDA_IS_DATA_MODEL (mod)); if (! (gda_data_model_get_access_flags (mod) & GDA_DATA_MODEL_ACCESS_RANDOM)) { g_warning ("Internal implementation error: data model does not support random access"); return; } if (model->priv->model) g_object_unref (model->priv->model); model->priv->model = mod; g_object_ref (mod); model->priv->nb_cols = gda_data_model_get_n_columns (mod); } break; } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; } } }
/** * gda_data_model_array_copy_model: * @src: a #GdaDataModel to copy data from * @error: a place to store errors, or %NULL * * Makes a copy of @src into a new #GdaDataModelArray object * * Returns: (transfer full) (allow-none): a new data model, or %NULL if an error occurred */ GdaDataModelArray * gda_data_model_array_copy_model (GdaDataModel *src, GError **error) { GdaDataModel *model; gint nbfields, i; g_return_val_if_fail (GDA_IS_DATA_MODEL (src), NULL); nbfields = gda_data_model_get_n_columns (src); model = gda_data_model_array_new (nbfields); if (g_object_get_data (G_OBJECT (src), "name")) g_object_set_data_full (G_OBJECT (model), "name", g_strdup (g_object_get_data (G_OBJECT (src), "name")), g_free); if (g_object_get_data (G_OBJECT (src), "descr")) g_object_set_data_full (G_OBJECT (model), "descr", g_strdup (g_object_get_data (G_OBJECT (src), "descr")), g_free); for (i = 0; i < nbfields; i++) { GdaColumn *copycol, *srccol; gchar *colid; srccol = gda_data_model_describe_column (src, i); copycol = gda_data_model_describe_column (model, i); g_object_get (G_OBJECT (srccol), "id", &colid, NULL); g_object_set (G_OBJECT (copycol), "id", colid, NULL); g_free (colid); gda_column_set_description (copycol, gda_column_get_description (srccol)); gda_column_set_name (copycol, gda_column_get_name (srccol)); gda_column_set_dbms_type (copycol, gda_column_get_dbms_type (srccol)); gda_column_set_g_type (copycol, gda_column_get_g_type (srccol)); gda_column_set_position (copycol, gda_column_get_position (srccol)); gda_column_set_allow_null (copycol, gda_column_get_allow_null (srccol)); } if (! gda_data_model_import_from_model (model, src, FALSE, NULL, error)) { g_object_unref (model); model = NULL; } /*else gda_data_model_dump (model, stdout);*/ return (GdaDataModelArray*) model; }
/** * oseaserver_command_get_dataset: * @datamodel: A GdaDataModel to extract data from. * * Convenienve function to translate a given @datamodel into a * CoyoteDataSet structure. * * Return value: A translated CoyoteDataSet or NULL if fails. **/ CoyoteDataSet * oseaserver_command_get_dataset (GdaDataModel * datamodel) { gint rows, columns, i, j; CoyoteDataSet * result; GdaValue * value = NULL; gchar * str_value = NULL; g_return_val_if_fail (datamodel, NULL); rows = gda_data_model_get_n_rows (datamodel); columns = gda_data_model_get_n_columns (datamodel); result = coyote_dataset_new (); for (i = 0; i < rows; i++) { for (j = 0; j < columns; j ++) { value = gda_value_copy ( gda_data_model_get_value_at (datamodel, j, i) ); str_value = gda_value_stringify (value); coyote_dataset_add (result, str_value); g_free (str_value); if (value->type != GDA_VALUE_TYPE_NUMERIC) gda_value_free (value); else { #warning We must remove this if when gda fix its gda_value_copy bug } } if (i == (rows - 1)) break; coyote_dataset_new_row (result); } return result; }
static void _midgard_sql_query_result_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { MidgardSqlQueryResult *self = MIDGARD_SQL_QUERY_RESULT (object); switch (property_id) { case PROPERTY_MODEL: self->model = g_value_dup_object (value); self->n_columns = gda_data_model_get_n_columns (GDA_DATA_MODEL (self->model)); self->n_rows = gda_data_model_get_n_rows (GDA_DATA_MODEL (self->model)); break; case PROPERTY_SELECTOR: self->selector = g_value_dup_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, property_id, pspec); break; } }
void _propagate_columns (MidgardSqlQueryResult *self, guint *n_objects, GError **error) { /* No model, no columns. Return NULL and set error */ if (self->model == NULL || self->n_columns == 0) { g_set_error (error, MIDGARD_VALIDATION_ERROR, MIDGARD_VALIDATION_ERROR_INTERNAL, "QueryResult holds empty data model"); return; } guint i = 0; if (self->columns != NULL) { *n_objects = self->n_columns; return; } g_set_error (error, MIDGARD_VALIDATION_ERROR, MIDGARD_VALIDATION_ERROR_INTERNAL, "Columns should be propagated with temporary midgard_sql_query_result_set_columns()"); return; GdaDataModel *model = GDA_DATA_MODEL (self->model); self->n_columns = gda_data_model_get_n_columns (model); *n_objects = self->n_columns; if (self->n_columns == 0) return; self->columns = g_new (MidgardSqlQueryColumn*, self->n_columns); for (i = 0; i < self->n_columns; i++) { MidgardQueryProperty *query_property = midgard_query_property_new (gda_data_model_get_column_title (model, i), NULL); self->columns[i] = midgard_sql_query_column_new (query_property, "FIXME", gda_data_model_get_column_name (model, i)); } return; }
GtkWidget * do_form_model_change (GtkWidget *do_widget) { if (!window) { GdaStatement *stmt; GtkWidget *vbox; GtkWidget *label; GdaDataModel *models [3]; window = gtk_dialog_new_with_buttons ("Changing data in a GdauiForm", GTK_WINDOW (do_widget), 0, "Close", GTK_RESPONSE_NONE, NULL); g_signal_connect (window, "response", G_CALLBACK (gtk_widget_destroy), NULL); g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5); gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (window))), vbox, TRUE, TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (vbox), 5); label = gtk_label_new ("The data in the same GdauiForm widget can be change don the fly."); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); /* creating data models */ stmt = gda_sql_parser_parse_string (demo_parser, "SELECT * FROM products ORDER BY ref, category LIMIT 15", NULL, NULL); models[0] = gda_connection_statement_execute_select (demo_cnc, stmt, NULL, NULL); gda_data_select_compute_modification_statements (GDA_DATA_SELECT (models[0]), NULL); g_object_unref (stmt); stmt = gda_sql_parser_parse_string (demo_parser, "SELECT * FROM products WHERE price > 20.2 ORDER BY ref, category LIMIT 10", NULL, NULL); models[1] = gda_connection_statement_execute_select (demo_cnc, stmt, NULL, NULL); gda_data_select_compute_modification_statements (GDA_DATA_SELECT (models[1]), NULL); g_object_unref (stmt); stmt = gda_sql_parser_parse_string (demo_parser, "SELECT name, price, ref, category FROM products WHERE price > 20.2 ORDER BY name LIMIT 30", NULL, NULL); models[2] = gda_connection_statement_execute_select (demo_cnc, stmt, NULL, NULL); gda_data_select_compute_modification_statements (GDA_DATA_SELECT (models[2]), NULL); g_object_unref (stmt); /* allow choosing which data model to display */ label = gtk_label_new (""); gtk_widget_set_halign (label, GTK_ALIGN_START); gtk_label_set_markup (GTK_LABEL (label), "<b>Choose which data model to display:</b>"); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); GtkWidget *layout, *rb; GSList *group = NULL; gint i; layout = gtk_grid_new (); gtk_box_pack_start (GTK_BOX (vbox), layout, FALSE, FALSE, 0); for (i = 0; i < 3; i++) { gchar *str; str = g_strdup_printf ("%d columns x %d rows", gda_data_model_get_n_columns (models[i]), gda_data_model_get_n_rows (models[i])); rb = gtk_radio_button_new_with_label (group, str); g_free (str); gtk_grid_attach (GTK_GRID (layout), rb, i, 0, 1, 1); g_signal_connect (rb, "toggled", G_CALLBACK (model_toggled_cb), models[i]); g_object_set_data_full (G_OBJECT (rb), "model", models[i], g_object_unref); group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb)); } /* Create the form widget */ label = gtk_label_new (""); gtk_widget_set_halign (label, GTK_ALIGN_START); gtk_label_set_markup (GTK_LABEL (label), "<b>GdauiForm:</b>"); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); form = gdaui_form_new (models[0]); g_object_set (G_OBJECT (form), "info-flags", GDAUI_DATA_PROXY_INFO_CURRENT_ROW | GDAUI_DATA_PROXY_INFO_ROW_MOVE_BUTTONS | GDAUI_DATA_PROXY_INFO_ROW_MODIFY_BUTTONS, NULL); gtk_box_pack_start (GTK_BOX (vbox), form, TRUE, TRUE, 0); GdaDataProxy *proxy; proxy = gdaui_data_proxy_get_proxy (GDAUI_DATA_PROXY (form)); g_object_set (proxy, "cache-changes", TRUE, NULL); } gboolean visible; g_object_get (G_OBJECT (window), "visible", &visible, NULL); if (!visible) gtk_widget_show_all (window); else { gtk_widget_destroy (window); window = NULL; } return window; }
GList * midgard_core_qb_set_object_from_query (MidgardQueryBuilder *builder, guint select_type, MidgardObject **nobject) { g_assert(builder != NULL); guint ret_rows, ret_fields; MidgardConnection *mgd = builder->priv->mgd; gchar *sql = midgard_core_qb_get_sql( builder, select_type, midgard_query_builder_get_object_select(builder, select_type)); GSList *olist = NULL; MidgardDBObjectClass *dbklass = MIDGARD_DBOBJECT_CLASS(g_type_class_peek(builder->priv->type)); if (!dbklass) { MIDGARD_ERRNO_SET_STRING (mgd, MGD_ERR_INTERNAL, "Failed to peek MidgardDBObjectClass pointer"); return NULL; } if (dbklass->dbpriv->set_from_sql) { if (select_type != MQB_SELECT_GUID) { olist = dbklass->dbpriv->set_from_sql(mgd, builder->priv->type, ((const gchar *)sql)); g_free(sql); return (GList *)olist; } } GdaDataModel *model = midgard_core_query_get_model(builder->priv->mgd, sql); g_free(sql); if(!model) return NULL; MidgardObject *object = NULL; gint rows, columns; const GValue *gvalue = NULL; ret_rows = gda_data_model_get_n_rows(model); ret_fields = gda_data_model_get_n_columns(model); /* records found , allocate as many objects as many returned rows */ GList *list = NULL; if(ret_rows == 0) { g_object_unref(model); return list; } /* We count rows only */ if(select_type == MQB_SELECT_GUID) { gvalue = midgard_data_model_get_value_at(model, 0, 0); if (!gvalue || !G_IS_VALUE (gvalue)) { g_object_unref (model); return 0; } MidgardTypeHolder *holder = g_new(MidgardTypeHolder, 1); GValue val = {0, }; g_value_init (&val, G_TYPE_INT64); g_value_transform (gvalue, &val); holder->elements = (guint)g_value_get_int64((GValue*)&val); list = g_list_append(list, holder); g_object_unref(model); g_value_unset (&val); return list; } /* Get every row */ for (rows = 0; rows < ret_rows; rows++) { if(!nobject) object = g_object_new (builder->priv->type, "connection", mgd, NULL); else object = *nobject; MGD_OBJECT_IN_STORAGE (object) = TRUE; if(dbklass->dbpriv->__set_from_sql != NULL) { dbklass->dbpriv->__set_from_sql(MIDGARD_DBOBJECT(object), model, rows); } else { /* Compute number of metadata properties */ guint n_md_props = 0; MidgardMetadata *mklass = (MidgardMetadata *)MGD_DBCLASS_METADATA_CLASS (dbklass); if (mklass) n_md_props = g_hash_table_size (MGD_DBCLASS_STORAGE_DATA (mklass)->prophash); guint __cols = n_md_props + 1; /* Add one for guid */ /* we have guid and metadata columns first */ for (columns = __cols; columns < ret_fields; columns++) { gvalue = midgard_data_model_get_value_at(model, columns, rows); const gchar *coltitle = gda_data_model_get_column_title(model, columns); GParamSpec *pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(object), coltitle); if(G_IS_VALUE(gvalue)) { if (!pspec) { g_warning("Failed to found (unregistered) %s property (%s class)", coltitle, G_OBJECT_TYPE_NAME(object)); continue; } if (G_VALUE_TYPE (gvalue) == GDA_TYPE_BINARY && G_TYPE_FUNDAMENTAL (pspec->value_type) == G_TYPE_STRING) { gchar *stringified = midgard_core_query_binary_stringify ((GValue *)gvalue); g_object_set (G_OBJECT (object), coltitle, stringified, NULL); g_free (stringified); } else if (pspec->value_type != G_VALUE_TYPE (gvalue)) { GValue _convert = {0, }; g_value_init (&_convert, pspec->value_type); if (g_value_transform (gvalue, &_convert)) { /* FIXME, remove workaround once it's fixed in GDA */ /* https://bugzilla.gnome.org/show_bug.cgi?id=617550 */ guint dbtype = mgd->priv->config->priv->dbtype; if (dbtype == MIDGARD_DB_TYPE_MYSQL && G_VALUE_TYPE (gvalue) == GDA_TYPE_BLOB) { gchar *tmp_str = __default_unescape_string (g_value_get_string (&_convert)); if (tmp_str) g_value_take_string (&_convert, tmp_str); } g_object_set_property (G_OBJECT (object), coltitle, &_convert); } else { g_warning ("Failed to convert %s to %s for %s property", G_VALUE_TYPE_NAME (gvalue), G_VALUE_TYPE_NAME (&_convert), coltitle); } g_value_unset (&_convert); } else { g_object_set_property(G_OBJECT(object), coltitle, gvalue); } } else if (gda_value_is_null(gvalue)) { switch (pspec->value_type) { case G_TYPE_INT: case G_TYPE_UINT: g_object_set(G_OBJECT(object), coltitle, 0, NULL); break; case G_TYPE_STRING: g_object_set(G_OBJECT(object), coltitle, "", NULL); break; default: g_warning("Found (%s) not a value at %d.%d (%s)", g_type_name(pspec->value_type), columns, rows, gda_data_model_get_column_title(model, columns)); break; } } } } /* Set guid */ const gchar *guid; gvalue = midgard_data_model_get_value_at(model, 0, rows); if(G_IS_VALUE(gvalue) && G_VALUE_HOLDS_STRING(gvalue)){ guid = g_value_get_string(gvalue); g_free((gchar *)MIDGARD_DBOBJECT(object)->dbpriv->guid); MIDGARD_DBOBJECT(object)->dbpriv->guid = g_strdup(guid); } /* Set metadata */ MidgardMetadata *metadata = MGD_DBOBJECT_METADATA (object); if (metadata) { GParamSpec *pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(object), "metadata"); if (pspec) __mqb_set_metadata(metadata, model, rows); } list = g_list_append(list, G_OBJECT(object)); } g_object_unref(model); return list; }
/** * base_tool_output_data_model_to_string: */ gchar * base_tool_output_data_model_to_string (GdaDataModel *model, ToolOutputFormat format, FILE *stream, GdaSet *options) { if (!GDA_IS_DATA_MODEL (model)) return NULL; if (format & BASE_TOOL_OUTPUT_FORMAT_DEFAULT) { gchar *tmp; GdaSet *local_options; gint width; base_tool_input_get_size (&width, NULL); local_options = gda_set_new_inline (6, "NAME", G_TYPE_BOOLEAN, TRUE, "NULL_AS_EMPTY", G_TYPE_BOOLEAN, TRUE, "MAX_WIDTH", G_TYPE_INT, width, "COLUMN_SEPARATORS", G_TYPE_BOOLEAN, TRUE, "SEPARATOR_LINE", G_TYPE_BOOLEAN, TRUE, "NAMES_ON_FIRST_LINE", G_TYPE_BOOLEAN, TRUE); if (options) gda_set_merge_with_set (local_options, options); tmp = gda_data_model_export_to_string (model, GDA_DATA_MODEL_IO_TEXT_TABLE, NULL, 0, NULL, 0, local_options); g_object_unref (local_options); if (GDA_IS_DATA_SELECT (model)) { gchar *tmp2, *tmp3; gdouble etime; g_object_get ((GObject*) model, "execution-delay", &etime, NULL); tmp2 = g_strdup_printf ("%s: %.03f s", _("Execution delay"), etime); tmp3 = g_strdup_printf ("%s\n%s", tmp, tmp2); g_free (tmp); g_free (tmp2); return tmp3; } else return tmp; } else if (format & BASE_TOOL_OUTPUT_FORMAT_XML) return gda_data_model_export_to_string (model, GDA_DATA_MODEL_IO_DATA_ARRAY_XML, NULL, 0, NULL, 0, NULL); else if (format & BASE_TOOL_OUTPUT_FORMAT_CSV) { gchar *retval; GdaSet *optexp; optexp = make_options_set_from_string ("csv", options); retval = gda_data_model_export_to_string (model, GDA_DATA_MODEL_IO_TEXT_SEPARATED, NULL, 0, NULL, 0, optexp); if (optexp) g_object_unref (optexp); return retval; } else if (format & BASE_TOOL_OUTPUT_FORMAT_HTML) { xmlBufferPtr buffer; xmlNodePtr top, div, table, node, row_node, col_node, header, meta; gint ncols, nrows, i, j; gchar *str; top = xmlNewNode (NULL, BAD_CAST "html"); header = xmlNewChild (top, NULL, BAD_CAST "head", NULL); meta = xmlNewChild (header, NULL, BAD_CAST "meta", NULL); xmlSetProp (meta, BAD_CAST "http-equiv", BAD_CAST "content-type"); xmlSetProp (meta, BAD_CAST "content", BAD_CAST "text/html; charset=UTF-8"); div = xmlNewChild (top, NULL, BAD_CAST "body", NULL); table = xmlNewChild (div, NULL, BAD_CAST "table", NULL); xmlSetProp (table, BAD_CAST "border", BAD_CAST "1"); if (g_object_get_data (G_OBJECT (model), "name")) xmlNewTextChild (table, NULL, BAD_CAST "caption", g_object_get_data (G_OBJECT (model), "name")); ncols = gda_data_model_get_n_columns (model); nrows = gda_data_model_get_n_rows (model); row_node = xmlNewChild (table, NULL, BAD_CAST "tr", NULL); for (j = 0; j < ncols; j++) { const gchar *cstr; cstr = gda_data_model_get_column_title (model, j); col_node = xmlNewTextChild (row_node, NULL, BAD_CAST "th", BAD_CAST cstr); xmlSetProp (col_node, BAD_CAST "align", BAD_CAST "center"); } for (i = 0; i < nrows; i++) { row_node = xmlNewChild (table, NULL, BAD_CAST "tr", NULL); xmlSetProp (row_node, BAD_CAST "valign", BAD_CAST "top"); for (j = 0; j < ncols; j++) { const GValue *value; value = gda_data_model_get_value_at (model, j, i, NULL); if (!value) { col_node = xmlNewChild (row_node, NULL, BAD_CAST "td", BAD_CAST "ERROR"); xmlSetProp (col_node, BAD_CAST "align", BAD_CAST "left"); } else { str = gda_value_stringify (value); col_node = xmlNewTextChild (row_node, NULL, BAD_CAST "td", BAD_CAST str); xmlSetProp (col_node, BAD_CAST "align", BAD_CAST "left"); g_free (str); } } } node = xmlNewChild (div, NULL, BAD_CAST "p", NULL); str = g_strdup_printf (ngettext ("(%d row)", "(%d rows)", nrows), nrows); xmlNodeSetContent (node, BAD_CAST str); g_free (str); buffer = xmlBufferCreate (); xmlNodeDump (buffer, NULL, top, 0, 1); str = g_strdup ((gchar *) xmlBufferContent (buffer)); xmlBufferFree (buffer); xmlFreeNode (top); return str; } else TO_IMPLEMENT; return NULL; }
void _gda_postgres_compute_types (GdaConnection *cnc, GdaPostgresReuseable *rdata) { if (rdata->types_oid_hash) return; rdata->types_oid_hash = g_hash_table_new_full (g_int_hash, g_int_equal, NULL, (GDestroyNotify) gda_postgres_type_oid_free); rdata->types_dbtype_hash = g_hash_table_new (g_str_hash, g_str_equal); GdaDataModel *model, *model_avoid, *model_anyoid = NULL; gint ncols, nrows, i; gchar *avoid_types = NULL; GString *string; if (rdata->version_float == 0) _gda_postgres_compute_version (cnc, rdata, NULL); if (rdata->version_float < 7.3) { gchar *query; avoid_types = "'SET', 'cid', 'oid', 'int2vector', 'oidvector', 'regproc', 'smgr', 'tid', 'unknown', 'xid'"; /* main query to fetch infos about the data types */ query = g_strdup_printf ("SELECT pg_type.oid, typname, usename, obj_description(pg_type.oid) " "FROM pg_type, pg_user " "WHERE typowner=usesysid AND typrelid = 0 AND typname !~ '^_' " "AND typname not in (%s) " "ORDER BY typname", avoid_types); model = execute_select (cnc, rdata, query); g_free (query); /* query to fetch non returned data types */ query = g_strdup_printf ("SELECT pg_type.oid FROM pg_type WHERE typname in (%s)", avoid_types); model_avoid = execute_select (cnc, rdata, query); g_free (query); } else { gchar *query; avoid_types = "'any', 'anyarray', 'anyelement', 'cid', 'cstring', 'int2vector', 'internal', 'language_handler', 'oidvector', 'opaque', 'record', 'refcursor', 'regclass', 'regoper', 'regoperator', 'regproc', 'regprocedure', 'regtype', 'SET', 'smgr', 'tid', 'trigger', 'unknown', 'void', 'xid'"; /* main query to fetch infos about the data types */ query = g_strdup_printf ( "SELECT t.oid, t.typname, u.usename, pg_catalog.obj_description(t.oid), t.typinput " "FROM pg_catalog.pg_type t LEFT JOIN pg_catalog.pg_user u ON (t.typowner=u.usesysid), pg_catalog.pg_namespace n " "WHERE n.oid = t.typnamespace " "AND pg_catalog.pg_type_is_visible(t.oid) " /*--AND (n.nspname = 'public' OR n.nspname = 'pg_catalog')*/ "AND typname !~ '^_' " "AND (t.typrelid = 0 OR " "(SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) " "AND t.typname not in (%s) " "ORDER BY typname", avoid_types); model = execute_select (cnc, rdata, query); g_free (query); /* query to fetch non returned data types */ query = g_strdup_printf ("SELECT t.oid FROM pg_catalog.pg_type t WHERE t.typname in (%s)", avoid_types); model_avoid = execute_select (cnc, rdata, query); g_free (query); /* query to fetch the oid of the 'any' data type */ model_anyoid = execute_select (cnc, rdata, "SELECT t.oid FROM pg_catalog.pg_type t WHERE t.typname = 'any'"); } if (rdata->version_float == 0) _gda_postgres_compute_version (cnc, rdata, NULL); if (!model || !model_avoid || ((rdata->version_float >= 7.3) && !model_anyoid)) { if (model) g_object_unref (model); if (model_avoid) g_object_unref (model_avoid); if (model_anyoid) g_object_unref (model_anyoid); return; } /* Data types returned to the Gda client */ nrows = gda_data_model_get_n_rows (model); ncols = gda_data_model_get_n_columns (model); if (nrows == 0) g_warning ("PostgreSQL provider did not find any data type (expect some mis-behaviours) please report the error to bugzilla.gnome.org"); for (i = 0; i < nrows; i++) { const GValue *conv_func_name = NULL; const GValue *values[4]; gint j; gboolean allread = TRUE; if (ncols >= 5) conv_func_name = gda_data_model_get_value_at (model, 4, i, NULL); for (j = 0; j < 4; j++) { values[j] = gda_data_model_get_value_at (model, j, i, NULL); if (!values [j]) { allread = FALSE; break; } } if (allread && (G_VALUE_TYPE (values[1]) == G_TYPE_STRING)) { GdaPostgresTypeOid *td; td = g_new0 (GdaPostgresTypeOid, 1); td->name = g_value_dup_string (values [1]); td->oid = (guint) g_ascii_strtoull (g_value_get_string (values[0]), NULL, 10); td->type = postgres_name_to_g_type (td->name, conv_func_name ? g_value_get_string (conv_func_name) : NULL); if (G_VALUE_TYPE (values[3]) == G_TYPE_STRING) td->comments = g_value_dup_string (values [3]); if (G_VALUE_TYPE (values[2]) == G_TYPE_STRING) td->owner = g_value_dup_string (values [2]); g_hash_table_insert (rdata->types_oid_hash, &(td->oid), td); g_hash_table_insert (rdata->types_dbtype_hash, &(td->name), td); } } /* Make a string of data types internal to postgres and not returned, for future queries */ string = NULL; nrows = gda_data_model_get_n_rows (model_avoid); for (i = 0; i < nrows; i++) { const GValue *cvalue; cvalue = gda_data_model_get_value_at (model_avoid, 0, i, NULL); if (cvalue && (G_VALUE_TYPE (cvalue) == G_TYPE_STRING)) { if (!string) string = g_string_new (g_value_get_string (cvalue)); else { g_string_append (string, ", "); g_string_append (string, g_value_get_string (cvalue)); } } } rdata->avoid_types = avoid_types; if (string) rdata->avoid_types_oids = g_string_free (string, FALSE); g_object_unref (model); g_object_unref (model_avoid); /* make a string of the oid of type 'any' */ rdata->any_type_oid = NULL; if (model_anyoid) { if (gda_data_model_get_n_rows (model_anyoid) == 1) { const GValue *cvalue; cvalue = gda_data_model_get_value_at (model_anyoid, 0, 0, NULL); if (cvalue && (G_VALUE_TYPE (cvalue) == G_TYPE_STRING)) rdata->any_type_oid = g_value_dup_string (cvalue); } g_object_unref (model_anyoid); } }
/** * Display a list with projects and let the user select one. Returns the project * id of the selected one. */ static gint sql_plugin_retrieve_project_id (PlannerPlugin *plugin, gchar *server, gchar *port, gchar *database, gchar *login, gchar *password) { GdaConnection *conn; GdaDataModel *model; gboolean success; GdaClient *client; GladeXML *gui; GtkWidget *dialog; GtkWidget *treeview; GtkWidget *ok_button; GtkListStore *liststore; GtkCellRenderer *cell; GtkTreeViewColumn *col; gint i; gint response; gint project_id; GtkTreeSelection *selection; GtkTreeIter iter; gchar *db_txt; const gchar *dsn_name = "planner-auto"; const gchar *provider = "PostgreSQL"; gchar *filename; db_txt = g_strdup_printf (CONNECTION_FORMAT_STRING,server,database); gda_config_save_data_source (dsn_name, provider, db_txt, "planner project", login, password, FALSE); g_free (db_txt); client = gda_client_new (); conn = sql_get_tested_connection (dsn_name, server, database, client, plugin); if (conn == NULL) { return -1; } success = sql_execute_command (conn, "BEGIN"); if (!success) { g_warning ("BEGIN command failed."); return -1; } success = sql_execute_command (conn, "DECLARE mycursor CURSOR FOR SELECT proj_id, name," "phase, revision FROM project ORDER by proj_id ASC"); if (!success) { g_warning ("DECLARE CURSOR command failed (project)."); return -1; } model = sql_execute_query (conn, "FETCH ALL in mycursor"); if (model == NULL) { g_warning ("FETCH ALL failed."); return -1; } filename = mrp_paths_get_glade_dir ("sql.glade"); gui = glade_xml_new (filename, "select_dialog", NULL); g_free (filename); dialog = glade_xml_get_widget (gui, "select_dialog"); treeview = glade_xml_get_widget (gui, "project_treeview"); ok_button = glade_xml_get_widget (gui, "ok_button"); g_object_unref (gui); liststore = gtk_list_store_new (4, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT); gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (liststore)); cell = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new_with_attributes (_("ID"), cell, "text", COL_ID, NULL); gtk_tree_view_column_set_resizable (col, TRUE); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), col); cell = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new_with_attributes (_("Project"), cell, "text", COL_NAME, NULL); gtk_tree_view_column_set_resizable (col, TRUE); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), col); cell = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new_with_attributes (_("Phase"), cell, "text", COL_PHASE, NULL); gtk_tree_view_column_set_resizable (col, TRUE); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), col); cell = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new_with_attributes (_("Revision"), cell, "text", COL_REVISION, NULL); gtk_tree_view_column_set_resizable (col, TRUE); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), col); gtk_tree_view_columns_autosize (GTK_TREE_VIEW (treeview)); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); g_signal_connect (selection, "changed", G_CALLBACK (selection_changed_cb), ok_button); g_signal_connect (treeview, "row_activated", G_CALLBACK (row_activated_cb), ok_button); for (i = 0; i < gda_data_model_get_n_rows (model); i++) { gint id; gchar *name; gchar *phase; gint revision; id = get_int (model, i, 0); name = get_string (model, i, 1); phase = get_string (model, i, 2); revision = get_int (model, i, 3); /* FIXME: needs fixing in the database backend. */ if (strcmp (phase, "NULL") == 0) { g_free (phase); phase = g_strdup (""); } gtk_list_store_append (GTK_LIST_STORE (liststore), &iter); gtk_list_store_set (GTK_LIST_STORE (liststore), &iter, COL_ID, id, COL_NAME, name, COL_PHASE, phase, COL_REVISION, revision, -1); g_free (name); g_free (phase); } if (gda_data_model_get_n_columns (model) == 0) { gtk_widget_set_sensitive (ok_button, FALSE); } g_object_unref (model); sql_execute_command (conn,"CLOSE mycursor"); gtk_widget_show_all (dialog); response = gtk_dialog_run (GTK_DIALOG (dialog)); project_id = -1; switch (response) { case GTK_RESPONSE_CANCEL: case GTK_RESPONSE_DELETE_EVENT: break; case GTK_RESPONSE_OK: if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) { break; } gtk_tree_model_get (GTK_TREE_MODEL (liststore), &iter, COL_ID, &project_id, -1); break; }; gtk_widget_destroy (dialog); return project_id; }
/** * gda_data_model_array_copy_model_ext: * @src: a #GdaDataModel to copy data from * @ncols: size of @cols * @cols: (array length=ncols): array of @src's columns to copy into the new array, not %NULL * @error: a place to store errors, or %NULL * * Like gda_data_model_array_copy_model(), makes a copy of @src, but copies only some * columns. * * Returns: (transfer full) (allow-none): a new data model, or %NULL if an error occurred * * Since: 5.2.0 */ GdaDataModelArray * gda_data_model_array_copy_model_ext (GdaDataModel *src, gint ncols, gint *cols, GError **error) { GdaDataModel *model; gint nbfields, i; g_return_val_if_fail (GDA_IS_DATA_MODEL (src), NULL); g_return_val_if_fail (cols, NULL); g_return_val_if_fail (ncols > 0, NULL); /* check columns' validity */ nbfields = gda_data_model_get_n_columns (src); for (i = 0; i < ncols; i++) { if ((cols[i] < 0) || (cols[i] >= nbfields)) { g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_COLUMN_OUT_OF_RANGE_ERROR, _("Column %d out of range (0-%d)"), cols[i], nbfields - 1); return NULL; } } /* initialize new model */ model = gda_data_model_array_new (ncols); if (g_object_get_data (G_OBJECT (src), "name")) g_object_set_data_full (G_OBJECT (model), "name", g_strdup (g_object_get_data (G_OBJECT (src), "name")), g_free); if (g_object_get_data (G_OBJECT (src), "descr")) g_object_set_data_full (G_OBJECT (model), "descr", g_strdup (g_object_get_data (G_OBJECT (src), "descr")), g_free); /* map new columns */ GHashTable *hash; hash = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, NULL); for (i = 0; i < ncols; i++) { gint *ptr; ptr = g_new (gint, 1); *ptr = i; g_hash_table_insert (hash, ptr, GINT_TO_POINTER (cols[i])); GdaColumn *copycol, *srccol; gchar *colid; srccol = gda_data_model_describe_column (src, cols[i]); copycol = gda_data_model_describe_column (model, i); g_object_get (G_OBJECT (srccol), "id", &colid, NULL); g_object_set (G_OBJECT (copycol), "id", colid, NULL); g_free (colid); gda_column_set_description (copycol, gda_column_get_description (srccol)); gda_column_set_name (copycol, gda_column_get_name (srccol)); gda_column_set_dbms_type (copycol, gda_column_get_dbms_type (srccol)); gda_column_set_g_type (copycol, gda_column_get_g_type (srccol)); gda_column_set_position (copycol, gda_column_get_position (srccol)); gda_column_set_allow_null (copycol, gda_column_get_allow_null (srccol)); } if (! gda_data_model_import_from_model (model, src, FALSE, hash, error)) { g_hash_table_destroy (hash); g_object_unref (model); model = NULL; } /*else gda_data_model_dump (model, stdout);*/ g_hash_table_destroy (hash); return (GdaDataModelArray*) model; }
static void extract_named_parameters (GdaServerOperation *op, const gchar *root_path, GtkTextBuffer *tbuffer) { GdaServerOperationNode *node; GtkTextIter iter; gchar *str; node = gda_server_operation_get_node_info (op, root_path); g_return_if_fail (node); gtk_text_buffer_get_end_iter (tbuffer, &iter); gtk_text_buffer_insert (tbuffer, &iter, " * ", -1); if (node->status == GDA_SERVER_OPERATION_STATUS_REQUIRED) gtk_text_buffer_insert_with_tags_by_name (tbuffer, &iter, root_path, -1, "req_pathname", NULL); else gtk_text_buffer_insert_with_tags_by_name (tbuffer, &iter, root_path, -1, "opt_pathname", NULL); gtk_text_buffer_insert (tbuffer, &iter, " (", -1); switch (node->type) { case GDA_SERVER_OPERATION_NODE_PARAMLIST: { GSList *params; str = g_strdup_printf ("GdaSet @%p)\n", node->plist); gtk_text_buffer_insert (tbuffer, &iter, str, -1); g_free (str); for (params = node->plist->holders; params; params = params->next) { gchar *npath; npath = g_strdup_printf ("%s/%s", root_path, gda_holder_get_id (GDA_HOLDER (params->data))); extract_named_parameters (op, npath, tbuffer); g_free (npath); } break; } case GDA_SERVER_OPERATION_NODE_DATA_MODEL: { gint i, ncols; str = g_strdup_printf ("GdaDataModel @%p)\n", node->model); gtk_text_buffer_insert (tbuffer, &iter, str, -1); g_free (str); ncols = gda_data_model_get_n_columns (node->model); for (i = 0; i < ncols; i++) { GdaColumn *col = gda_data_model_describe_column (node->model, i); gchar *npath, *str; g_object_get (G_OBJECT (col), "id", &str, NULL); npath = g_strdup_printf ("%s/@%s", root_path, str); g_free (str); extract_named_parameters (op, npath, tbuffer); g_free (npath); } break; } case GDA_SERVER_OPERATION_NODE_PARAM: { gchar *str; const GValue *value; gtk_text_buffer_insert (tbuffer, &iter, "GdaHolder) = ", -1); value = gda_holder_get_value (node->param); str = gda_value_stringify (value); gtk_text_buffer_insert (tbuffer, &iter, str, -1); gtk_text_buffer_insert (tbuffer, &iter, "\n", -1); g_free (str); break; } case GDA_SERVER_OPERATION_NODE_SEQUENCE: { gtk_text_buffer_insert (tbuffer, &iter, "Sequence)\n", -1); guint i, size = gda_server_operation_get_sequence_size (op, root_path); for (i = 0; i < size; i++) { gchar **names; names = gda_server_operation_get_sequence_item_names (op, root_path); guint n; for (n = 0; names [n]; n++) { gchar *npath; npath = g_strdup_printf ("%s/%u%s", root_path, i, names [n]); extract_named_parameters (op, npath, tbuffer); g_free (npath); } g_strfreev (names); } break; } case GDA_SERVER_OPERATION_NODE_SEQUENCE_ITEM: gtk_text_buffer_insert (tbuffer, &iter, "Sequence item)\n", -1); break; case GDA_SERVER_OPERATION_NODE_DATA_MODEL_COLUMN: { gint j, nrows; gtk_text_buffer_insert (tbuffer, &iter, "Model column)\n", -1); nrows = gda_data_model_get_n_rows (node->model); for (j = 0; j < nrows; j++) { gchar *npath, *str; const GValue *value; npath = g_strdup_printf ("%s/%d", root_path, j); value = gda_data_model_get_value_at (node->model, gda_column_get_position (node->column), j, NULL); if (value) str = gda_value_stringify (value); else str = g_strdup ("Error: could not read data model's value"); gtk_text_buffer_insert (tbuffer, &iter, " * ", -1); gtk_text_buffer_insert_with_tags_by_name (tbuffer, &iter, npath, -1, "opt_pathname", NULL); g_free (npath); gtk_text_buffer_insert (tbuffer, &iter, " (GValue) = ", -1); gtk_text_buffer_insert (tbuffer, &iter, str, -1); gtk_text_buffer_insert (tbuffer, &iter, "\n", -1); g_free (str); } break; } default: gtk_text_buffer_insert (tbuffer, &iter, "???", -1); break; } }
/* * Load data from file @file into table @table */ gboolean test_cnc_load_data_from_file (GdaConnection *cnc, const gchar *table, const gchar *full_file, GError **error) { GdaStatement *stmt = NULL; GdaSet *params = NULL; GdaDataModel *import; gint nrows, ncols, i; GdaMetaStruct *mstruct = NULL; GSList *list; gboolean retval = TRUE; /* loading XML file */ import = gda_data_model_import_new_file (full_file, TRUE, NULL); if (gda_data_model_import_get_errors (GDA_DATA_MODEL_IMPORT (import))) { g_set_error (error, TEST_ERROR, TEST_ERROR_GENERIC, "Error loading '%s' file", full_file); return FALSE; } /* retrieving meta data info */ GdaMetaDbObject *table_dbo; GValue *name_value; g_value_set_string ((name_value = gda_value_new (G_TYPE_STRING)), table); mstruct = gda_meta_struct_new (gda_connection_get_meta_store (cnc), GDA_META_STRUCT_FEATURE_NONE); table_dbo = gda_meta_struct_complement (mstruct, GDA_META_DB_TABLE, NULL, NULL, name_value, error); gda_value_free (name_value); if (! table_dbo) { retval = FALSE; goto out; } /* creating INSERT statement */ GdaSqlStatement *st; GdaSqlStatementInsert *ist; GSList *insert_values_list = NULL; ist = g_new0 (GdaSqlStatementInsert, 1); GDA_SQL_ANY_PART (ist)->type = GDA_SQL_ANY_STMT_INSERT; ist->table = gda_sql_table_new (GDA_SQL_ANY_PART (ist)); ist->table->table_name = g_strdup (table); GdaMetaTable *mtable = GDA_META_TABLE (table_dbo); for (list = mtable->columns; list; list = list->next) { GdaMetaTableColumn *tcol = GDA_META_TABLE_COLUMN (list->data); GdaSqlField *field; /* field */ field = gda_sql_field_new (GDA_SQL_ANY_PART (ist)); field->field_name = g_strdup (tcol->column_name); ist->fields_list = g_slist_append (ist->fields_list, field); /* value */ GdaSqlParamSpec *pspec = g_new0 (GdaSqlParamSpec, 1); GdaSqlExpr *expr; pspec->name = g_strdup (tcol->column_name); pspec->g_type = tcol->gtype; pspec->nullok = tcol->nullok; expr = gda_sql_expr_new (GDA_SQL_ANY_PART (ist)); expr->param_spec = pspec; insert_values_list = g_slist_append (insert_values_list, expr); } ist->values_list = g_slist_append (NULL, insert_values_list); st = gda_sql_statement_new (GDA_SQL_STATEMENT_INSERT); st->contents = ist; stmt = g_object_new (GDA_TYPE_STATEMENT, "structure", st, NULL); gda_sql_statement_free (st); g_object_unref (mstruct); if (! gda_statement_get_parameters (stmt, ¶ms, error)) { retval = FALSE; goto out; } /* executing inserts */ nrows = gda_data_model_get_n_rows (import); ncols = gda_data_model_get_n_columns (import); if (!gda_connection_begin_transaction (cnc, NULL, GDA_TRANSACTION_ISOLATION_UNKNOWN, error)) { retval = FALSE; goto out; } for (i = 0; i < nrows; i++) { gint j; GSList *list; for (list = params->holders, j = 0; list && (j < ncols); list = list->next, j++) { const GValue *cvalue = gda_data_model_get_value_at (import, j, i, error); if (!cvalue) { gda_connection_rollback_transaction (cnc, NULL, NULL); retval = FALSE; goto out; } if (! gda_holder_set_value (GDA_HOLDER (list->data), cvalue, error)) { gda_connection_rollback_transaction (cnc, NULL, NULL); retval = FALSE; goto out; } } if (list || (j < ncols)) { g_set_error (error, TEST_ERROR, TEST_ERROR_GENERIC, "%s", "Incoherent number of columns in table and imported data"); gda_connection_rollback_transaction (cnc, NULL, NULL); retval = FALSE; goto out; } if (gda_connection_statement_execute_non_select (cnc, stmt, params, NULL, error) == -1) { gda_connection_rollback_transaction (cnc, NULL, NULL); retval = FALSE; goto out; } } if (! gda_connection_commit_transaction (cnc, NULL, error)) retval = FALSE; out: if (import) g_object_unref (import); if (stmt) g_object_unref (stmt); if (params) g_object_unref (params); return retval; }