之前困惑于GtkClist中数据类型与MySQL数据类型之间转换的问题,在gtk-app-dvel-list邮件列表上发了一个主题提问:
Arthur1989 says:
Hello, I used clist to display data iI fetch from mysql server,but when writing data back into the table of database, I got this question: the data type of clist is always gchar *, while there are quite a lot of other data types in mysql. What can I do to get this question solved? Any tips will be appreciated.
今天发现居然有人把实现的源码都贴到邮件里了..转到博客记下.
Shawn Bakhtlar(***@hotmail.com)replys:
//Ran into the same problem. //I use a structure like _IsiField { int type, int pos, int .... } //Then create my own list with _IsiList { GList Fields; GList rows; } //Every time retrieve a set of values, I have a routing which sets type to a G_TYPE, which corresponds to the MYSQL_TYPE //Here is what I do: GList * isi_database_fetch_fields(IsiDatabase *self) { MYSQL_FIELD *field; IsiFields *l; GList *gl = NULL; guint column = 0; /* Sanity Check */ g_return_val_if_fail(self != NULL, NULL); g_return_val_if_fail(self->priv != NULL, NULL); g_return_val_if_fail(self->priv->dispose_has_run != TRUE, NULL); g_return_val_if_fail(self->priv->res != NULL, NULL); /* Rewind the feild set */ mysql_field_seek(self->priv->res,0L); while((field = mysql_fetch_field(self->priv->res))) { /* Initialize a new IsiFields structure */ //l = (IsiFields*) g_new0(IsiFields, 1); l = g_new0(IsiFields, 1); /* Set the values */ l->alias = g_strdup(field->name); l->name = g_strdup(field->org_name); l->length = field->length; /* always make fields visable */ l->hidden = FALSE; l->sortable = FALSE; l->pos = column++; switch (field->type){ /* Integer types */ case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_INT24: /* Check for signage */ if (field->flags &amp; UNSIGNED_FLAG) l->type = G_TYPE_UINT; else l->type = G_TYPE_INT; break; /* Long types */ case MYSQL_TYPE_LONG: case MYSQL_TYPE_LONGLONG: /* Check for signage */ if (field->flags &amp; UNSIGNED_FLAG) l->type = G_TYPE_ULONG; else l->type = G_TYPE_LONG; break; /* Decimal types */ case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_DOUBLE: l->type = G_TYPE_DOUBLE; break; /* Bit types */ case MYSQL_TYPE_BIT: l->type = G_TYPE_BOOLEAN; break; /* ENUM types */ case MYSQL_TYPE_ENUM: l->type = G_TYPE_ENUM; break; /* All other types */ default: case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_SET: case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_DATE: case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_YEAR: case MYSQL_TYPE_GEOMETRY: case MYSQL_TYPE_NULL: if(l->length <= 1){ l->type = G_TYPE_CHAR; }else{ l->type = G_TYPE_STRING; } break; } /*DEBUG*/ //g_print("%s %d %d \n", l->alias,l->type,l->length); /* Save pointer to list */ gl = g_list_append(gl,(gpointer)l); } return gl; } //now convert the row data to a GList and you have two GLists in your one lists, one with the field header info, the other with the data. //and create the liststore like this: GtkTreeModel * isi_display_liststore_create(IsiDisplay *self, GList *fields) { guint num_fields, i; IsiFields *l; GtkTreeModel *model; GType *types; guint search_col_adj = 0; /* Sanity Check */ g_return_val_if_fail(self != NULL, NULL); g_return_val_if_fail(self->priv != NULL, NULL); g_return_val_if_fail(self->priv->dispose_has_run != TRUE, NULL); /* Get the number of fields */ if(fields != NULL){ num_fields = g_list_length(fields); /* Initialize values based on number of columns */ types = (GType*) g_new0( GType, num_fields); for(i=0;i<num_fields;i++){ l = (IsiFields*)g_list_nth_data(fields,i); types[i] = l->type; } /* create the model store for data input */ model = (GtkTreeModel*) gtk_list_store_newv(num_fields,types); g_free(types); for(i=0;i<num_fields;i++){ l = (IsiFields*)g_list_nth_data(fields,i); /* Setup sorting functions for the modle */ switch(l->type){ case G_TYPE_INT: l->sortable=TRUE; gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model), l->pos, sort_by_int,(gpointer) l->pos, NULL); break; case G_TYPE_UINT: l->sortable=TRUE; gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model), l->pos, sort_by_uint,(gpointer) l->pos, NULL); break; case G_TYPE_LONG: l->sortable=TRUE; gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model), l->pos, sort_by_long,(gpointer) l->pos, NULL); break; case G_TYPE_ULONG: l->sortable=TRUE; gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model), l->pos, sort_by_ulong,(gpointer) l->pos, NULL); break; case G_TYPE_DOUBLE: l->sortable=TRUE; gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model), l->pos, sort_by_double,(gpointer) l->pos, NULL); break; case G_TYPE_STRING: l->sortable=TRUE; gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model), l->pos, sort_by_string,(gpointer) l->pos, NULL); break; } } return model; } //Hope this helps, //Shawn
认真的看了一下,发现原来和自己想的差不多,都是事先记录好MySQL数据表中每列的数据类型,往回写时做个判断进行转换..只不过我是想用类似于map
PS: 本文在vim下通过vimpress插件编辑发布,不知道浏览器看起来怎样,呵呵..
据说Ubuntu新版本出内存泄漏问题了..你博客旁边那个日期会不会延期呢
汗.希望ubuntu不要跟fedora一样就好了,不跳水才是不正常的.