int main (int argc, char *argv []) { GdaDataModel *model; gint i, nrows; GError *error = NULL; gda_init (); model = g_object_new (TYPE_CUSTOM_DATA_MODEL, "filename", DATABASE, NULL); gda_data_model_dump (model, stdout); nrows = gda_data_model_get_n_rows (model); i = gda_data_model_append_row (model, &error); if (i < 0) { g_print ("Could not append row: %s\n", error && error->message ? error->message : "no detail"); exit (1); } else { GValue *value; GdaBinary bin; Key m_key; Value m_value; strncpy (m_key.color, "black", COLORSIZE); m_key.type = 100; bin.data = (gpointer) &m_key; bin.binary_length = sizeof (Key); value = gda_value_new (GDA_TYPE_BINARY); gda_value_set_binary (value, &bin); if (!gda_data_model_set_value_at (model, 0, i, value, &error)) { g_print ("Could not set key: %s\n", error && error->message ? error->message : "no detail"); exit (1); } gda_value_free (value); m_value.size = 100.1; strncpy (m_value.name, "blackhole", NAMESIZE); bin.data = (gpointer) &m_value; bin.binary_length = sizeof (Value); value = gda_value_new (GDA_TYPE_BINARY); gda_value_set_binary (value, &bin); if (!gda_data_model_set_value_at (model, 1, i, value, &error)) { g_print ("Could not set key: %s\n", error && error->message ? error->message : "no detail"); exit (1); } gda_value_free (value); } g_object_unref (model); return 0; }
static GdaRow * new_row_from_mysql_stmt (GdaMysqlRecordset *imodel, G_GNUC_UNUSED gint rownum, GError **error) { //g_print ("%s(): NCOLS=%d ROWNUM=%d\n", __func__, ((GdaDataSelect *) imodel)->prep_stmt->ncols, rownum); int res; MYSQL_BIND *mysql_bind_result; g_return_val_if_fail (imodel->priv->mysql_stmt != NULL, NULL); mysql_bind_result = ((GdaMysqlPStmt *) ((GdaDataSelect *) imodel)->prep_stmt)->mysql_bind_result; g_assert (mysql_bind_result); res = mysql_stmt_fetch (imodel->priv->mysql_stmt); if (res == MYSQL_NO_DATA) { /* should not happen */ g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR, "%s", "No more data, please report this bug to " "http://bugzilla.gnome.org/ for the \"libgda\" product and the MySQL provider."); } else if (res == MYSQL_DATA_TRUNCATED) { GString *string; string = g_string_new ("Truncated data, please report this bug to " "http://bugzilla.gnome.org/ for the \"libgda\" product and the MySQL provider."); gint col; for (col = 0; col < ((GdaDataSelect *) imodel)->prep_stmt->ncols; ++col) { my_bool truncated; mysql_bind_result[col].error = &truncated; mysql_stmt_fetch_column (imodel->priv->mysql_stmt, &(mysql_bind_result[col]), (unsigned int)col, 0); if (truncated) g_string_append_printf (string, "\n column %d is truncated\n", col); mysql_bind_result[col].error = NULL; } g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR, "%s", string->str); g_string_free (string, TRUE); return NULL; } else if (res) { _gda_mysql_make_error (imodel->priv->cnc, NULL, imodel->priv->mysql_stmt, error); return NULL; } /* g_print ("%s: SQL=%s\n", __func__, ((GdaDataSelect *) imodel)->prep_stmt->sql); */ GdaRow *row = gda_row_new (((GdaDataSelect *) imodel)->prep_stmt->ncols); gint col; for (col = 0; col < ((GdaDataSelect *) imodel)->prep_stmt->ncols; ++col) { gint i = col; GValue *value = gda_row_get_value (row, i); GType type = ((GdaDataSelect *) imodel)->prep_stmt->types[i]; /*g_print ("%s: #%d : TYPE=%d, GTYPE=%s\n", __func__, i, mysql_bind_result[i].buffer_type, g_type_name (type));*/ my_bool is_null = FALSE; unsigned long length; g_memmove (&is_null, mysql_bind_result[i].is_null, sizeof (my_bool)); if (is_null) { gda_value_set_null (value); continue; } else gda_value_reset_with_type (value, type); switch (mysql_bind_result[i].buffer_type) { case MYSQL_TYPE_SHORT: { short int bvalue = 0; g_memmove (&bvalue, mysql_bind_result[i].buffer, sizeof (bvalue)); g_value_set_int (value, bvalue); break; } case MYSQL_TYPE_TINY: { signed char bvalue = 0; g_memmove (&bvalue, mysql_bind_result[i].buffer, sizeof (bvalue)); g_value_set_int (value, bvalue); break; } case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: case MYSQL_TYPE_YEAR: { int bvalue = 0; g_memmove (&bvalue, mysql_bind_result[i].buffer, sizeof (bvalue)); if (type == G_TYPE_INT) g_value_set_int (value, bvalue); else if (type == G_TYPE_LONG) g_value_set_long (value, (long) bvalue); else if (type == G_TYPE_BOOLEAN) g_value_set_boolean (value, bvalue ? TRUE : FALSE); else { gda_row_invalidate_value (row, value); g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, _("Type %s not mapped for value %d"), g_type_name (type), bvalue); } break; } case MYSQL_TYPE_LONGLONG: { long long bvalue = 0; g_memmove (&bvalue, mysql_bind_result[i].buffer, sizeof (bvalue)); if (type == G_TYPE_BOOLEAN) g_value_set_boolean (value, bvalue ? TRUE : FALSE); else if (type == G_TYPE_INT) g_value_set_int (value, bvalue); else if (type == G_TYPE_LONG) g_value_set_long (value, bvalue); else { gda_row_invalidate_value (row, value); g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, _("Type %s not mapped for value %lld"), g_type_name (type), bvalue); } break; } case MYSQL_TYPE_NULL: gda_value_set_null (value); break; case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: { MYSQL_TIME bvalue = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; g_memmove (&bvalue, mysql_bind_result[i].buffer, sizeof (bvalue)); if (type == GDA_TYPE_TIME) { GdaTime time = { .hour = bvalue.hour, .minute = bvalue.minute, .second = bvalue.second, .fraction = bvalue.second_part, .timezone = 0 /* GMT */ }; gda_value_set_time (value, &time); } else if (type == G_TYPE_DATE) { GDate *date = g_date_new_dmy ((bvalue.day != 0) ? bvalue.day : 1, (bvalue.month != 0) ? bvalue.month : 1, (bvalue.year != 0) ? bvalue.year : 1970); g_value_take_boxed (value, date); } else if (type == GDA_TYPE_TIMESTAMP) { GdaTimestamp timestamp = { .year = bvalue.year, .month = bvalue.month, .day = bvalue.day, .hour = bvalue.hour, .minute = bvalue.minute, .second = bvalue.second, .fraction = bvalue.second_part, .timezone = 0 /* GMT */ }; gda_value_set_timestamp (value, ×tamp); } else { gda_row_invalidate_value (row, value); g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, _("Type %s not mapped for value %d/%d/%d %d:%d:%d.%lu"), g_type_name (type), bvalue.year, bvalue.month, bvalue.day, bvalue.hour, bvalue.minute, bvalue.second, bvalue.second_part); } break; } case MYSQL_TYPE_FLOAT: { float bvalue = 0.; g_memmove (&bvalue, mysql_bind_result[i].buffer, sizeof (bvalue)); if (type == G_TYPE_FLOAT) g_value_set_float (value, (float) bvalue); else { gda_row_invalidate_value (row, value); g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, _("Type %s not mapped for value %f"), g_type_name (type), bvalue); } break; } case MYSQL_TYPE_DOUBLE: { double bvalue = 0.0; g_memmove (&bvalue, mysql_bind_result[i].buffer, sizeof (bvalue)); if (type == G_TYPE_DOUBLE) g_value_set_double (value, bvalue); else { gda_row_invalidate_value (row, value); g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, _("Type %s not mapped for value %f"), g_type_name (type), bvalue); } break; } case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_BIT: { char *bvalue = NULL; g_memmove (&length, mysql_bind_result[i].length, sizeof (unsigned long)); if (length > 0) { bvalue = g_malloc (length + 1); memcpy (bvalue, mysql_bind_result[i].buffer, length); bvalue [length] = 0; } if (type == G_TYPE_STRING) g_value_set_string (value, bvalue); else if (type == GDA_TYPE_BINARY) { GdaBinary binary = { .data = (guchar*) bvalue, .binary_length = length }; gda_value_set_binary (value, &binary); } else if (type == GDA_TYPE_BLOB) { /* we don't use GdaMysqlBlobOp because it looks like the MySQL * API does not support BLOBs accessed in a random way, * so we return the whole BLOB at once */ GdaBlob blob = { {(guchar*) bvalue, length}, NULL }; gda_value_set_blob (value, &blob); } else if (type == GDA_TYPE_NUMERIC) { if (length > 0) { GdaNumeric *numeric; numeric = gda_numeric_new (); gda_numeric_set_from_string (numeric, bvalue); gda_numeric_set_precision (numeric, 6); gda_numeric_set_width (numeric, length); gda_value_set_numeric (value, numeric); gda_numeric_free (numeric); } } else if (type == G_TYPE_DOUBLE) { if (length > 0) g_value_set_double (value, g_ascii_strtod (bvalue, NULL)); else { /* error: wrong column type */ gda_row_invalidate_value (row, value); g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, _("Invalid column bind data type. %d\n"), mysql_bind_result[i].buffer_type); break; } } else if (type == G_TYPE_INT) { if (length > 0) g_value_set_int (value, atoi (bvalue)); else { /* error: wrong column type */ gda_row_invalidate_value (row, value); g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, _("Invalid column bind data type. %d\n"), mysql_bind_result[i].buffer_type); break; } } else if (type == G_TYPE_BOOLEAN) { if (length > 0) g_value_set_boolean (value, atoi (bvalue)); else { /* error: wrong column type */ gda_row_invalidate_value (row, value); g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, _("Invalid column bind data type. %d\n"), mysql_bind_result[i].buffer_type); break; } } else { gda_row_invalidate_value (row, value); g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, _("Type %s not mapped for value %s"), g_type_name (type), bvalue); } g_free (bvalue); break; }
int main (int argc, char *argv []) { GdaDataModel *model; gint i, nrows; GError *error = NULL; gda_init (); if (! g_file_test (DATABASE, G_FILE_TEST_EXISTS)) { g_print ("File '%s' does not exist\n", DATABASE); exit (1); } model = gda_data_model_bdb_new (DATABASE, NULL); gda_data_model_dump (model, stdout); nrows = gda_data_model_get_n_rows (model); for (i = 0; i < nrows; i++) { Key *key; Value *value; const GValue *c_value; const GdaBinary *bin; g_print ("=============== ROW %d\n", i); c_value= gda_data_model_get_value_at (model, 0, i, &error); if (!c_value) { g_print ("Could not get value from data model: %s\n", error && error->message ? error->message : "No detail"); exit (1); } bin = gda_value_get_binary (c_value); key = (Key *)bin->data; g_print ("color/type = %s/%d\n", key->color, key->type); c_value= gda_data_model_get_value_at (model, 1, i, &error); if (!c_value) { g_print ("Could not get value from data model: %s\n", error && error->message ? error->message : "No detail"); exit (1); } bin = gda_value_get_binary (c_value); value = (Value *)bin->data; g_print ("size/name = %f/%s\n", value->size, value->name); } i = gda_data_model_append_row (model, &error); if (i < 0) { g_print ("Could not append row: %s\n", error && error->message ? error->message : "no detail"); exit (1); } else { { /* EXTRA tests */ gda_data_model_dump (model, stdout); if (!gda_data_model_remove_row (model, i, &error)) { g_print ("Could not remove row: %s\n", error && error->message ? error->message : "no detail"); exit (1); } gda_data_model_dump (model, stdout); gchar *str = "AAA"; GValue *value = gda_value_new_binary ((guchar*) str, 4); if (!gda_data_model_set_value_at (model, 1, 2, value, &error)) { g_print ("Could not set value: %s\n", error && error->message ? error->message : "no detail"); exit (1); } gda_data_model_dump (model, stdout); exit (0); } GValue *value; GdaBinary bin; Key m_key; Value m_value; strncpy (m_key.color, "black", COLORSIZE); m_key.type = 100; bin.data = (gpointer) &m_key; bin.binary_length = sizeof (Key); value = gda_value_new (GDA_TYPE_BINARY); gda_value_set_binary (value, &bin); if (!gda_data_model_set_value_at (model, 0, i, value, &error)) { g_print ("Could not set key: %s\n", error && error->message ? error->message : "no detail"); exit (1); } gda_value_free (value); m_value.size = 100.1; strncpy (m_value.name, "blackhole", NAMESIZE); bin.data = (gpointer) &m_value; bin.binary_length = sizeof (Value); value = gda_value_new (GDA_TYPE_BINARY); gda_value_set_binary (value, &bin); if (!gda_data_model_set_value_at (model, 1, i, value, &error)) { g_print ("Could not set key: %s\n", error && error->message ? error->message : "no detail"); exit (1); } gda_value_free (value); } g_object_unref (model); return 0; }