[libgda] SQlite: handle meta data of views using non native SQLite functions
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] SQlite: handle meta data of views using non native SQLite functions
- Date: Sat, 3 Sep 2011 20:21:42 +0000 (UTC)
commit b360b08cb4319e4a78a91a2feadcbc88f06a1ca9
Author: Vivien Malerba <malerba gnome-db org>
Date: Sat Sep 3 22:06:04 2011 +0200
SQlite: handle meta data of views using non native SQLite functions
libgda/gda-meta-struct.c | 10 +++++++-
libgda/gda-meta-struct.h | 4 +++
libgda/sqlite/gda-sqlite-meta.c | 47 +++++++++++++++++++++++++++++----------
3 files changed, 48 insertions(+), 13 deletions(-)
---
diff --git a/libgda/gda-meta-struct.c b/libgda/gda-meta-struct.c
index 22d85ef..d22fda0 100644
--- a/libgda/gda-meta-struct.c
+++ b/libgda/gda-meta-struct.c
@@ -933,7 +933,7 @@ _meta_struct_complement (GdaMetaStruct *mstruct, GdaMetaDbObjectType type,
}
case GDA_META_DB_TABLE: {
/* columns */
- gchar *sql = "SELECT c.column_name, c.data_type, c.gtype, c.is_nullable, t.table_short_name, t.table_full_name, c.column_default, t.table_owner, c.array_spec, c.extra, c.column_comments FROM _columns as c NATURAL JOIN _tables as t WHERE table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string ORDER BY ordinal_position";
+ gchar *sql = "SELECT c.column_name, c.data_type, c.gtype, c.is_nullable, t.table_short_name, t.table_full_name, c.column_default, t.table_owner, c.array_spec, c.extra, c.column_comments FROM _tables as t LEFT NATURAL JOIN _columns as c WHERE table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string ORDER BY ordinal_position";
GdaMetaTable *mt;
GdaDataModel *model;
gint i, nrows;
@@ -969,6 +969,14 @@ _meta_struct_complement (GdaMetaStruct *mstruct, GdaMetaDbObjectType type,
dbo->obj_owner = g_value_dup_string (cvalue);
}
+ cvalue = gda_data_model_get_value_at (model, 0, 0, error);
+ if (cvalue && (G_VALUE_TYPE (cvalue) == GDA_TYPE_NULL)) {
+ if (type == GDA_META_DB_VIEW) {
+ /* we don't have the list of columns for the view.
+ * This can sometimes happen in SQLite */
+ nrows = 0;
+ }
+ }
mt = GDA_META_TABLE (dbo);
for (i = 0; i < nrows; i++) {
GdaMetaTableColumn *tcol;
diff --git a/libgda/gda-meta-struct.h b/libgda/gda-meta-struct.h
index e449136..66feed5 100644
--- a/libgda/gda-meta-struct.h
+++ b/libgda/gda-meta-struct.h
@@ -122,6 +122,10 @@ typedef enum {
*
* This structure specifies a #GdaMetaDbObject to represent a table's specific attributes,
* its contents must not be modified.
+ *
+ * Note that in some cases, the columns cannot be determined for views, and in this case the
+ * @columns will be %NULL (this can be the case for example with SQLite where a view
+ * uses a function which is not natively provided by SQLite.
*/
typedef struct {
/*< public >*/
diff --git a/libgda/sqlite/gda-sqlite-meta.c b/libgda/sqlite/gda-sqlite-meta.c
index e2d2058..a888de9 100644
--- a/libgda/sqlite/gda-sqlite-meta.c
+++ b/libgda/sqlite/gda-sqlite-meta.c
@@ -55,6 +55,8 @@ static gchar *internal_sql[] = {
"PRAGMA database_list",
/* I_PRAGMA_TABLE_INFO */
+ /* warning: this can return an error as "no such function XXX" if a view has been
+ * defined using a function not native of SQLite (and thus not available in Libgda) */
"PRAGMA table_info (##tblname::string)",
/* I_PRAGMA_INDEX_LIST */
@@ -959,15 +961,22 @@ fill_columns_model (GdaConnection *cnc, SqliteConnectionData *cdata,
GType col_types[] = {G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT,
G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_NONE};
GdaStatement *stmt;
+ GError *lerror = NULL;
schema_name = g_value_get_string (p_table_schema);
- stmt = get_statement (I_PRAGMA_TABLE_INFO, schema_name, g_value_get_string (p_table_name), error);
+ stmt = get_statement (I_PRAGMA_TABLE_INFO, schema_name, g_value_get_string (p_table_name), NULL);
tmpmodel = gda_connection_statement_execute_select_full (cnc, stmt, pragma_set,
GDA_STATEMENT_MODEL_RANDOM_ACCESS,
- col_types, error);
+ col_types, &lerror);
g_object_unref (stmt);
- if (!tmpmodel)
- return FALSE;
+ if (!tmpmodel) {
+ if (lerror && lerror->message && !strstr (lerror->message, "no such function")) {
+ g_propagate_error (error, lerror);
+ return FALSE;
+ }
+ else
+ return TRUE;
+ }
nrows = gda_data_model_get_n_rows (tmpmodel);
for (i = 0; i < nrows; i++) {
@@ -1237,6 +1246,7 @@ fill_constraints_tab_model (GdaConnection *cnc, SqliteConnectionData *cdata, Gda
const gchar *schema_name;
gint i;
GdaStatement *stmt;
+ GError *lerror = NULL;
schema_name = g_value_get_string (p_table_schema);
@@ -1249,13 +1259,19 @@ fill_constraints_tab_model (GdaConnection *cnc, SqliteConnectionData *cdata, Gda
G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_NONE};
gboolean has_pk = FALSE;
- stmt = get_statement (I_PRAGMA_TABLE_INFO, schema_name, g_value_get_string (p_table_name), error);
+ stmt = get_statement (I_PRAGMA_TABLE_INFO, schema_name, g_value_get_string (p_table_name), NULL);
tmpmodel = gda_connection_statement_execute_select_full (cnc, stmt, pragma_set,
GDA_STATEMENT_MODEL_RANDOM_ACCESS,
- pk_col_types, error);
+ pk_col_types, &lerror);
g_object_unref (stmt);
- if (!tmpmodel)
- return FALSE;
+ if (!tmpmodel) {
+ if (lerror && lerror->message && !strstr (lerror->message, "no such function")) {
+ g_propagate_error (error, lerror);
+ return FALSE;
+ }
+ else
+ return TRUE;
+ }
nrows = gda_data_model_get_n_rows (tmpmodel);
for (i = 0; i < nrows; i++) {
@@ -1799,13 +1815,20 @@ fill_key_columns_model (GdaConnection *cnc, SqliteConnectionData *cdata, GdaData
GType pk_col_types[] = {G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT,
G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_NONE};
gint ord_pos = 1;
- stmt = get_statement (I_PRAGMA_TABLE_INFO, schema_name, g_value_get_string (p_table_name), error);
+ GError *lerror = NULL;
+ stmt = get_statement (I_PRAGMA_TABLE_INFO, schema_name, g_value_get_string (p_table_name), NULL);
tmpmodel = gda_connection_statement_execute_select_full (cnc, stmt, pragma_set,
GDA_STATEMENT_MODEL_RANDOM_ACCESS,
- pk_col_types, error);
+ pk_col_types, &lerror);
g_object_unref (stmt);
- if (!tmpmodel)
- return FALSE;
+ if (!tmpmodel) {
+ if (lerror && lerror->message && !strstr (lerror->message, "no such function")) {
+ g_propagate_error (error, lerror);
+ return FALSE;
+ }
+ else
+ return TRUE;
+ }
nrows = gda_data_model_get_n_rows (tmpmodel);
for (i = 0; i < nrows; i++) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]