[libgda] Meta Data information schema updated to version 4 * Added 'schema_default' column to '_schemata' tab



commit dacaa9e33b62c5ba2118e2b248a5ab4c56bf49a6
Author: Daniel Espinosa <despinosa src gnome org>
Date:   Fri Feb 17 14:41:28 2012 -0600

    Meta Data information schema updated to version 4
    * Added 'schema_default' column to '_schemata' table. Allows to
    find default schema used to add new tables to
    * GdaData Unit Test and Fixes for GdaData.DbTable/Table
    * GdaData fixes warnings for unhandled errors

 libgda/data/DbFieldInfo.vala                     |   36 ++++---
 libgda/data/DbTable.vala                         |    2 +-
 libgda/data/FieldInfo.vala                       |    2 +-
 libgda/data/GdaData-5.0.gir                      |   51 ++++-----
 libgda/data/Record.vala                          |   13 ++-
 libgda/data/RecordCollection.vala                |  102 +++++++++++-------
 libgda/data/SelectQuery.vala                     |  100 +++++++++---------
 libgda/data/Table.vala                           |  124 ++++++++++++++--------
 libgda/gda-meta-store.c                          |    3 +-
 libgda/information_schema.xml                    |    1 +
 libgda/providers-support/gda-meta-column-types.h |   21 +---
 providers/reuseable/postgres/gda-postgres-meta.c |    4 +-
 samples/Gir/meta_store.py                        |   10 ++
 tests/vala/CheckTable.vala                       |   72 +++++++++----
 tests/vala/Makefile.am                           |   22 ++--
 15 files changed, 334 insertions(+), 229 deletions(-)
---
diff --git a/libgda/data/DbFieldInfo.vala b/libgda/data/DbFieldInfo.vala
index 14883ef..7287b47 100644
--- a/libgda/data/DbFieldInfo.vala
+++ b/libgda/data/DbFieldInfo.vala
@@ -40,16 +40,22 @@ namespace GdaData {
 				return Attribute.NONE;
 			if (str == "PRIMARY_KEY")
 				return Attribute.PRIMARY_KEY;
+			if (str == "PRIMARY KEY")
+				return Attribute.PRIMARY_KEY;
 			if (str == "UNIQUE")
 				return Attribute.UNIQUE;
 			if (str == "FOREIGN_KEY")
 				return Attribute.FOREIGN_KEY;
+			if (str == "FOREIGN KEY")
+				return Attribute.FOREIGN_KEY;
 			if (str == "CHECK")
 				return Attribute.CHECK;
 			if (str == "HAVE_DEFAULT")
 				return Attribute.HAVE_DEFAULT;
-			if (str == "IS_AUTO_INCREMENT")
-				return Attribute.IS_AUTO_INCREMENT;
+			if (str == "CAN_BE_NULL")
+				return Attribute.CAN_BE_NULL;
+			if (str == "AUTO_INCREMENT")
+				return Attribute.AUTO_INCREMENT;
 			
 			return Attribute.NONE;
 		}
@@ -61,22 +67,20 @@ namespace GdaData {
 			FOREIGN_KEY,
 			CHECK,
 			HAVE_DEFAULT,
-			IS_AUTO_INCREMENT
+			CAN_BE_NULL,
+			AUTO_INCREMENT
 		}
 		
 		// Constrains
 		public abstract ForeignKey  fkey   { get; set; }
 		
-		[Compact]
 		public class ForeignKey {
-			public string    name;
-			public string    refname;
-			public DbTable   reftable;
-			public Match     match;
-			public Rule      update_rule;
-			public Rule      delete_rule;
-			
-			public ForeignKey copy () { return new ForeignKey (); }
+			public string    name          { get; set; }
+			public string    refname       { get; set; }
+			public DbTable   reftable      { get; set; }
+			public Match     match         { get; set; }
+			public Rule      update_rule   { get; set; }
+			public Rule      delete_rule   { get; set; }
 			
 			public static Match match_from_string (string str)
 			{
@@ -88,16 +92,22 @@ namespace GdaData {
 				return Match.NONE;
 			}
 			
-			public static Rule rule_from_string (string str)
+			public static Rule rule_from_string (string? str)
 			{
 				if (str == "CASCADE")
 					return Rule.CASCADE;
+				if (str == "SET_NULL")
+					return Rule.SET_NULL;
 				if (str == "SET NULL")
 					return Rule.SET_NULL;
+				if (str == "SET_DEFAULT")
+					return Rule.SET_DEFAULT;
 				if (str == "SET DEFAULT")
 					return Rule.SET_DEFAULT;
 				if (str == "RESTRICT")
 					return Rule.RESTRICT;
+				if (str == "NO_ACTION")
+					return Rule.NO_ACTION;
 				if (str == "NO ACTION")
 					return Rule.NO_ACTION;
 	
diff --git a/libgda/data/DbTable.vala b/libgda/data/DbTable.vala
index 5e2175f..689f895 100644
--- a/libgda/data/DbTable.vala
+++ b/libgda/data/DbTable.vala
@@ -29,7 +29,7 @@ namespace GdaData
 		public abstract TableType                        table_type    { get; set; }
 		public abstract Collection<DbRecord>             records       { owned get; }
 		public abstract Collection<DbTable>              depends       { owned get; }
-		public abstract Collection<DbTable>              references    { owned get; }
+		public abstract Collection<DbTable>              referenced    { owned get; }
 		public abstract Collection<DbFieldInfo>          fields        { owned get; }
 		public abstract Collection<DbFieldInfo>          primary_keys  { owned get; }
 		
diff --git a/libgda/data/FieldInfo.vala b/libgda/data/FieldInfo.vala
index f0cab47..3306fe4 100644
--- a/libgda/data/FieldInfo.vala
+++ b/libgda/data/FieldInfo.vala
@@ -49,6 +49,6 @@ namespace GdaData {
 		public int precision   { get { return _precision; } set { _precision = value; } }
 		public int scale       { get { return _scale; } set { _scale = value; } }
 		
-		public DbFieldInfo.ForeignKey  fkey   { get  { return _fk; } set { _fk = value.copy (); } }
+		public DbFieldInfo.ForeignKey  fkey   { get  { return _fk; } set { _fk = value; } }
 	}
 }
diff --git a/libgda/data/GdaData-5.0.gir b/libgda/data/GdaData-5.0.gir
index ab1331f..e07221e 100644
--- a/libgda/data/GdaData-5.0.gir
+++ b/libgda/data/GdaData-5.0.gir
@@ -122,7 +122,7 @@
 				<type name="GdaData.DbTable" c:type="GdaDataDbTable*"/>
 			</type>
 		</field>
-		<field name="_references">
+		<field name="_referenced">
 			<type name="Gee.HashMap" c:type="GeeHashMap*">
 				<type name="utf8" c:type="gchar*"/>
 				<type name="GdaData.DbTable" c:type="GdaDataDbTable*"/>
@@ -417,6 +417,7 @@
 		</field>
 	</record>
 	<interface name="DbTable" c:type="GdaDataDbTable" glib:type-name="GdaDataDbTable" glib:get-type="gda_data_db_table_get_type" glib:type-struct="DbTableIface">
+		<prerequisite name="GObject.Object"/>
 		<prerequisite name="GdaData.DbObject"/>
 		<prerequisite name="GdaData.DbNamedObject"/>
 		<function name="type_from_string" c:identifier="gda_data_db_table_type_from_string">
@@ -448,7 +449,7 @@
 				<type name="GdaData.DbTable" c:type="GdaDataDbTable*"/>
 			</type>
 		</property>
-		<property name="references">
+		<property name="referenced">
 			<type name="Gee.Collection" c:type="GeeCollection*">
 				<type name="GdaData.DbTable" c:type="GdaDataDbTable*"/>
 			</type>
@@ -900,32 +901,10 @@
 		<member name="foreign_key" c:identifier="GDA_DATA_DB_FIELD_INFO_ATTRIBUTE_FOREIGN_KEY" value="8"/>
 		<member name="check" c:identifier="GDA_DATA_DB_FIELD_INFO_ATTRIBUTE_CHECK" value="16"/>
 		<member name="have_default" c:identifier="GDA_DATA_DB_FIELD_INFO_ATTRIBUTE_HAVE_DEFAULT" value="32"/>
-		<member name="is_auto_increment" c:identifier="GDA_DATA_DB_FIELD_INFO_ATTRIBUTE_IS_AUTO_INCREMENT" value="64"/>
+		<member name="can_be_null" c:identifier="GDA_DATA_DB_FIELD_INFO_ATTRIBUTE_CAN_BE_NULL" value="64"/>
+		<member name="auto_increment" c:identifier="GDA_DATA_DB_FIELD_INFO_ATTRIBUTE_AUTO_INCREMENT" value="128"/>
 	</bitfield>
 	<record name="DbFieldInfoForeignKey">
-		<field name="name">
-			<type name="utf8" c:type="gchar*"/>
-		</field>
-		<field name="refname">
-			<type name="utf8" c:type="gchar*"/>
-		</field>
-		<field name="reftable">
-			<type name="GdaData.DbTable" c:type="GdaDataDbTable*"/>
-		</field>
-		<field name="match">
-			<type name="GdaData.DbFieldInfoForeignKeyMatch" c:type="GdaDataDbFieldInfoForeignKeyMatch"/>
-		</field>
-		<field name="update_rule">
-			<type name="GdaData.DbFieldInfoForeignKeyRule" c:type="GdaDataDbFieldInfoForeignKeyRule"/>
-		</field>
-		<field name="delete_rule">
-			<type name="GdaData.DbFieldInfoForeignKeyRule" c:type="GdaDataDbFieldInfoForeignKeyRule"/>
-		</field>
-		<method name="copy" c:identifier="gda_data_db_field_info_foreign_key_copy">
-			<return-value transfer-ownership="full">
-				<type name="GdaData.DbFieldInfoForeignKey" c:type="GdaDataDbFieldInfoForeignKey*"/>
-			</return-value>
-		</method>
 		<function name="match_from_string" c:identifier="gda_data_db_field_info_foreign_key_match_from_string">
 			<parameters>
 				<parameter name="str" transfer-ownership="none">
@@ -938,7 +917,7 @@
 		</function>
 		<function name="rule_from_string" c:identifier="gda_data_db_field_info_foreign_key_rule_from_string">
 			<parameters>
-				<parameter name="str" transfer-ownership="none">
+				<parameter name="str" transfer-ownership="none" allow-none="1">
 					<type name="utf8" c:type="const gchar*"/>
 				</parameter>
 			</parameters>
@@ -951,6 +930,24 @@
 				<type name="GdaData.DbFieldInfoForeignKey" c:type="GdaDataDbFieldInfoForeignKey*"/>
 			</return-value>
 		</constructor>
+		<property name="name" writable="1">
+			<type name="utf8" c:type="gchar*"/>
+		</property>
+		<property name="refname" writable="1">
+			<type name="utf8" c:type="gchar*"/>
+		</property>
+		<property name="reftable" writable="1">
+			<type name="GdaData.DbTable" c:type="GdaDataDbTable*"/>
+		</property>
+		<property name="match" writable="1">
+			<type name="GdaData.DbFieldInfoForeignKeyMatch" c:type="GdaDataDbFieldInfoForeignKeyMatch"/>
+		</property>
+		<property name="update-rule" writable="1">
+			<type name="GdaData.DbFieldInfoForeignKeyRule" c:type="GdaDataDbFieldInfoForeignKeyRule"/>
+		</property>
+		<property name="delete-rule" writable="1">
+			<type name="GdaData.DbFieldInfoForeignKeyRule" c:type="GdaDataDbFieldInfoForeignKeyRule"/>
+		</property>
 	</record>
 	<enumeration name="DbFieldInfoForeignKeyMatch" c:type="GdaDataDbFieldInfoForeignKeyMatch" glib:type-name="GdaDataDbFieldInfoForeignKeyMatch" glib:get-type="gda_data_db_field_info_foreign_key_match_get_type">
 		<member name="full" c:identifier="GDA_DATA_DB_FIELD_INFO_FOREIGN_KEY_MATCH_FULL" value="0"/>
diff --git a/libgda/data/Record.vala b/libgda/data/Record.vala
index 281e1b9..aa201ea 100644
--- a/libgda/data/Record.vala
+++ b/libgda/data/Record.vala
@@ -219,11 +219,14 @@ namespace GdaData {
         public int compare_to (DbRecord object)
         {
         	int r = 0;
-        	foreach (DbField f in fields) {
-        		var fl = object.get_field (f.name);
-        		if (Gda.value_compare (f.value, fl.value) != 0)
-        			return -1;
-        	}
+        	try {
+		    	foreach (DbField f in fields) {
+		    		var fl = object.get_field (f.name);
+		    		if (Gda.value_compare (f.value, fl.value) != 0)
+		    			return -1;
+		    	}
+		    }
+		    catch (Error e) { GLib.warning (e.message); }
         	return r;
         }
     }
diff --git a/libgda/data/RecordCollection.vala b/libgda/data/RecordCollection.vala
index 749bd98..01a3c42 100644
--- a/libgda/data/RecordCollection.vala
+++ b/libgda/data/RecordCollection.vala
@@ -46,56 +46,70 @@ namespace GdaData {
 					_model.set_value_at (_model.get_column_index (f.name), r, f.value);
 				}
 				return true;
-			} catch {}
+			} 
+			catch (Error e) { GLib.warning (e.message); }
 			return false; 
 		}
 		public override void clear ()
 		{ 
-			var iter = _model.create_iter ();
-			while (iter.move_next ()) {
-				_model.remove_row (iter.get_row ());
+			try {
+				var iter = _model.create_iter ();
+				while (iter.move_next ()) {
+					_model.remove_row (iter.get_row ());
+				}
+				((DataProxy) _model).apply_all_changes ();
 			}
-			((DataProxy) _model).apply_all_changes ();
+			catch (Error e) { GLib.warning (e.message); }
 		}
 		public override bool contains (DbRecord item)
 		{
-			var iter = _model.create_iter ();
-			while (iter.move_next ()) {
-				bool found = true;
-				foreach (DbField k in item.keys) {
-					Value id = iter.get_value_at (iter.data_model.get_column_index (k.name));
-					Value v = k.value;
-					if (Gda.value_compare (id,v) != 0)
-						found = false;
+			try {
+				var iter = _model.create_iter ();
+				while (iter.move_next ()) {
+					bool found = true;
+					foreach (DbField k in item.keys) {
+						Value id = iter.get_value_at (iter.data_model.get_column_index (k.name));
+						Value v = k.value;
+						if (Gda.value_compare (id,v) != 0)
+							found = false;
+					}
+					if (found) return true;
 				}
-				if (found) return true;
 			}
+			catch (Error e) { GLib.warning (e.message); }
 			return false;
 		}
 		public override Gee.Iterator<DbRecord> iterator () 
 		{ 
-			var iter = _model.create_iter ();
+			Gda.DataModelIter iter;
+			try {
+				iter = _model.create_iter ();
+			}
+			catch (Error e) { GLib.warning (e.message); }
 			return new RecordCollectionIterator (iter, _table); 
 		}
 		public override bool remove (DbRecord item)
 		{
-			var iter = _model.create_iter ();
-			while (iter.move_next ()) {
-				bool found = true;
-				foreach (DbField k in item.keys) {
-					Value id = iter.get_value_at (iter.data_model.get_column_index (k.name));
-					Value v = k.value;
-					if (Gda.value_compare (id,v) != 0)
-						found = false;
-				}
-				if (found) {
-					try {
-						_model.remove_row (iter.get_row ());
-						((DataProxy)_model).apply_all_changes ();
-						return true;
-					} catch {}
+			try {
+				var iter = _model.create_iter ();
+				while (iter.move_next ()) {
+					bool found = true;
+					foreach (DbField k in item.keys) {
+						Value id = iter.get_value_at (iter.data_model.get_column_index (k.name));
+						Value v = k.value;
+						if (Gda.value_compare (id,v) != 0)
+							found = false;
+					}
+					if (found) {
+						try {
+							_model.remove_row (iter.get_row ());
+							((DataProxy)_model).apply_all_changes ();
+							return true;
+						} catch {}
+					}
 				}
 			}
+			catch (Error e) { GLib.warning (e.message); }
 			return false;
 		}
 		public override bool read_only { 
@@ -214,9 +228,12 @@ namespace GdaData {
 			var r = new Record ();
 			r.connection = _table.connection;
 			r.table = _table;
-			for (int c = 0; c < _iter.data_model.get_n_columns (); c++) {
-				r.set_field_value (_iter.data_model.get_column_name (c), _iter.get_value_at (c));
+			try {
+				for (int c = 0; c < _iter.data_model.get_n_columns (); c++) {
+					r.set_field_value (_iter.data_model.get_column_name (c), _iter.get_value_at (c));
+				}
 			}
+			catch (Error e) { GLib.message (e.message); }
 			return r;
 		}
 		public bool has_next () 
@@ -231,17 +248,24 @@ namespace GdaData {
 		}
 		public bool next () 
 		{ 
-			if (this.has_next ()) {
-				if (_elements.size > 0) {
-					_iter.move_to_row (_elements.get (++filter_pos));
-					return true;
+			try {
+				if (this.has_next ()) {
+					if (_elements.size > 0) {
+						_iter.move_to_row (_elements.get (++filter_pos));
+						return true;
+					}
+					else
+						return _iter.move_next ();
 				}
-				else
-					return _iter.move_next ();
 			}
+			catch (Error e) { GLib.message (e.message); }
 			return false;
 		}
-		public void remove () { _iter.data_model.remove_row (_iter.current_row); }
+		public void remove () 
+		{ 
+			try { _iter.data_model.remove_row (_iter.current_row); }
+			catch (Error e) { GLib.message (e.message); }
+		}
 		public bool read_only 
 		{ 
 			get { 
diff --git a/libgda/data/SelectQuery.vala b/libgda/data/SelectQuery.vala
index 8f79fc0..11001be 100644
--- a/libgda/data/SelectQuery.vala
+++ b/libgda/data/SelectQuery.vala
@@ -39,55 +39,55 @@ namespace GdaData {
         
         public Connection connection { set; get; }
         
-        public SelectQuery()
-        {
-        	this._fields.add ("*");
-        	this.table = "";
-        }
-        
-        public void add_field (string field)
-        {
-        	if (this._fields.get (0) == "*")
-        	{
-        		this._fields.clear ();
-        	}
-	        
-	        this._fields.add (field);
-        }
-        
-        public SqlBuilder build ()
-        	requires (this.table != "")
-        {
-        	this._sql = new SqlBuilder (Gda.SqlStatementType.SELECT);
-        	
-        	foreach (string f in this._fields) {
-	        	this._sql.select_add_field (f, null, null);
-	        }            
-			return this._sql;
-        }
-        
-        public void set_fields_to_all () 
-        {
-        	this._fields.clear ();
-        	this._fields.add ("*");
-        }
-        
-        public void set_condition (string field, Value v, SqlOperatorType op) 
-        {
-        	var f_id = this._sql.add_id (field);
-			var e_id = this._sql.add_expr_value (null, v);
-			var c_id = this._sql.add_cond (op, f_id, e_id, 0);
-			this._sql.set_where (c_id);
-        }
-        
-        public DataModel execute () 
-            throws Error 
-            requires (this.connection.is_opened ())
-        {
-            /* Build Select Query */
-            var b = this.build ();
-		    var s = b.get_statement ();
-		    return this.connection.statement_execute_select (s, null);
-        }
+//        public SelectQuery()
+//        {
+//        	this._fields.add ("*");
+//        	this.table = "";
+//        }
+//        
+//        public void add_field (string field)
+//        {
+//        	if (this._fields.get (0) == "*")
+//        	{
+//        		this._fields.clear ();
+//        	}
+//	        
+//	        this._fields.add (field);
+//        }
+//        
+//        public SqlBuilder build ()
+//        	requires (this.table != "")
+//        {
+//        	this._sql = new SqlBuilder (Gda.SqlStatementType.SELECT);
+//        	
+//        	foreach (string f in this._fields) {
+//	        	this._sql.select_add_field (f, null, null);
+//	        }            
+//			return this._sql;
+//        }
+//        
+//        public void set_fields_to_all () 
+//        {
+//        	this._fields.clear ();
+//        	this._fields.add ("*");
+//        }
+//        
+//        public void set_condition (string field, Value v, SqlOperatorType op) 
+//        {
+//        	var f_id = this._sql.add_id (field);
+//			var e_id = this._sql.add_expr_value (null, v);
+//			var c_id = this._sql.add_cond (op, f_id, e_id, 0);
+//			this._sql.set_where (c_id);
+//        }
+//        
+//        public DataModel execute () 
+//            throws Error 
+//            requires (this.connection.is_opened ())
+//        {
+//            /* Build Select Query */
+//            var b = this.build ();
+//		    var s = b.get_statement ();
+//		    return this.connection.statement_execute_select (s, null);
+//        }
     }
 }
diff --git a/libgda/data/Table.vala b/libgda/data/Table.vala
index 5d27edb..48df8b5 100644
--- a/libgda/data/Table.vala
+++ b/libgda/data/Table.vala
@@ -28,7 +28,7 @@ namespace GdaData
 		protected DbRecordCollection          _records;
 		protected HashMap<string,DbFieldInfo> _fields = new HashMap<string,DbFieldInfo> ();
 		protected HashMap<string,DbTable>     _depends = new HashMap<string,DbTable> ();
-		protected HashMap<string,DbTable>     _references = new HashMap<string,DbTable> ();
+		protected HashMap<string,DbTable>     _referenced = new HashMap<string,DbTable> ();
 		
 		public Table.with_fields_info (HashMap<string,DbFieldInfo> fields)
 		{
@@ -42,6 +42,7 @@ namespace GdaData
 		{
 			var store = connection.get_meta_store ();
 			_fields.clear ();
+			string cond = "";
 			
 			var ctx = new Gda.MetaContext ();
 			ctx.set_table ("_columns");
@@ -51,28 +52,55 @@ namespace GdaData
 			
 			var vals = new HashTable<string,Value?> (str_hash,str_equal);
 			vals.set ("name", name);
-			vals.set ("schema", schema.name);
-			vals.set ("catalog", schema.catalog.name);
-			var mt = store.extract ("SELECT * FROM _columns WHERE table_schema = ##schema::string AND table_catalog = ##catalog::string AND table_name  = ##name::string", vals);
-			for (int r = 0; r < mt.get_n_columns (); r++) 
+			if (schema == null)
+			{
+				var cxc = new Gda.MetaContext ();
+				cxc.set_table ("_information_schema_catalog_name");
+				connection.update_meta_store (cxc);
+				var catm = store.extract ("SELECT * FROM _information_schema_catalog_name", null);
+				catalog = new Catalog ();
+				catalog.connection = connection;
+				catalog.name = (string) catm.get_value_at (catm.get_column_index ("catalog_name"), 0);
+				var cxs = new Gda.MetaContext ();
+				cxs.set_table ("_schemata");
+				connection.update_meta_store (cxs);
+				var schm = store.extract ("SELECT * FROM _schemata WHERE schema_default = TRUE", null);
+				schema = new Schema ();
+				schema.connection = connection;
+				schema.name = (string) schm.get_value_at (schm.get_column_index ("schema_name"), 0);
+			}
+			else
+			{
+				vals.set ("schema", schema.name);
+				cond += " AND table_schema = ##schema::string";
+			}
+			if (catalog != null)
+			{
+				// Not using default catalog
+				vals.set ("catalog", schema.catalog.name);
+				cond += " AND table_catalog = ##catalog::string";
+			}
+			
+			var mt = store.extract ("SELECT * FROM _columns WHERE table_name  = ##name::string" + cond, vals);
+			for (int r = 0; r < mt.get_n_rows (); r++) 
 			{
 				var fi = new FieldInfo ();
 				fi.name = (string) mt.get_value_at (mt.get_column_index ("column_name"), r);
-				
+				fi.desc = (string) mt.get_value_at (mt.get_column_index ("column_comments"), r);
 				// Set attributes
 				fi.attributes = DbFieldInfo.Attribute.NONE;
 				bool fcbn = (bool) mt.get_value_at (mt.get_column_index ("is_nullable"), r);
 				if (fcbn)
-					fi.attributes = fi.attributes & DbField.Attribute.CAN_BE_NULL;
-				string fai = (string) mt.get_value_at (mt.get_column_index ("extras"), r);
+					fi.attributes = fi.attributes | DbFieldInfo.Attribute.CAN_BE_NULL;
+				string fai = (string) mt.get_value_at (mt.get_column_index ("extra"), r);
 				if (fai == "AUTO_INCREMENT")
-					fi.attributes = fi.attributes & DbFieldInfo.Attribute.IS_AUTO_INCREMENT;
+					fi.attributes = fi.attributes | DbFieldInfo.Attribute.AUTO_INCREMENT;
 				
 				// Default Value
 				string fdv = (string) mt.get_value_at (mt.get_column_index ("column_default"), r);
-				Type ft = (Type) mt.get_value_at (mt.get_column_index ("gtype"), r);
+				Type ft = Gda.g_type_from_string ((string) mt.get_value_at (mt.get_column_index ("gtype"), r));
 				if (fdv != null) {
-					fi.attributes = fi.attributes & DbField.Attribute.CAN_BE_DEFAULT;
+					fi.attributes = fi.attributes | DbFieldInfo.Attribute.HAVE_DEFAULT;
 					fi.default_value = DbField.value_from_string (fdv, ft);
 				}
 				
@@ -89,32 +117,31 @@ namespace GdaData
 				_fields.set (fi.name, fi);
 			}
 			// Constraints
+			stdout.printf ("Cheking FiledInfo Constraints ...\n");
 			ctx.set_table ("_table_constraints");
 			connection.update_meta_store (ctx);
 			ctx.set_table ("_key_column_usage");
 			connection.update_meta_store (ctx);
-			ctx.set_table ("_referential_constraints");
-			connection.update_meta_store (ctx);
-			var mc = store.extract ("SELECT * FROM _table_constraints WHERE table_schema = ##schema::string AND table_catalog = ##catalog::string AND table_name  = ##name::string", vals);
-			for (int r = 0; r < mc.get_n_columns (); r++) 
+			var mc = store.extract ("SELECT * FROM _table_constraints WHERE table_name  = ##name::string" + cond,
+									vals);
+			stdout.printf ("table REF_CONST: \n"+mc.dump_as_string ());
+			for (int r = 0; r < mc.get_n_rows (); r++) 
 			{
 				string ct = (string) mc.get_value_at (mc.get_column_index ("constraint_type"), r);
 				string cn = (string) mc.get_value_at (mc.get_column_index ("constraint_name"), r);
-				var vals2 = new HashTable<string,Value?> (str_hash,str_equal);
-				vals2.set ("name", name);
-				vals2.set ("schema", schema);
-				vals2.set ("catalog", schema.catalog.name);
-				vals2.set ("constraint_name", cn);
-				var mpk = store.extract ("SELECT * FROM _key_column_usage WHERE table_schema = ##schema::string AND table_catalog = ##catalog::string AND table_name  = ##name::string AND constraint_name = ##constraint", vals2);
-				var colname = (string) mpk.get_value_at (mpk.get_column_index ("column_name"), r);
-				
+				vals.set ("constraint_name", cn);
+				var mpk = store.extract ("SELECT * FROM _key_column_usage WHERE table_name  = ##name::string AND constraint_name = ##constraint_name::string" + cond, vals);
+				var colname = (string) mpk.get_value_at (mpk.get_column_index ("column_name"), 0);
 				var f = _fields.get (colname);
-				f.attributes = f.attributes & DbFieldInfo.attribute_from_string (ct);
+				f.attributes = f.attributes | DbFieldInfo.attribute_from_string (ct);
+				stdout.printf("Conts type: " + ct + " : Getted Field: " + f.name + ": Attrib= " + ((int)f.attributes).to_string () + "\n");
 				
 				if (DbFieldInfo.Attribute.FOREIGN_KEY in f.attributes) 
 				{
-					f.attributes = f.attributes & DbFieldInfo.Attribute.FOREIGN_KEY;
-					var mfk = store.extract ("SELECT * FROM _referential_constraints WHERE table_schema = ##schema::string AND table_catalog = ##catalog::string AND table_name  = ##name::string AND constraint_name = ##constraint", vals2);
+					ctx.set_table ("_referential_constraints");
+					connection.update_meta_store (ctx);
+					var mfk = store.extract ("SELECT * FROM _referential_constraints WHERE table_name  = ##name::string AND constraint_name = ##constraint_name::string" + cond, vals);
+					stdout.printf ("REF_CONST: \n"+mfk.dump_as_string ());
 					f.fkey = new DbFieldInfo.ForeignKey ();
 					f.fkey.name = cn;
 					f.fkey.refname = (string) mfk.get_value_at (mfk.get_column_index ("ref_constraint_name"), 0);
@@ -144,8 +171,9 @@ namespace GdaData
 				}
 				if (DbFieldInfo.Attribute.CHECK in  f.attributes) 
 				{
-					// FIXME: Implement
+					// FIXME: Implement save CHECK expression 
 				}
+				_fields.set (f.name, f);
 			}
 		}
 		public void save () throws Error {}
@@ -176,29 +204,39 @@ namespace GdaData
 		public DbSchema  schema { get; set; }
 		public Collection<DbRecord> records { 
 			owned get  {
-				var q = new Gda.SqlBuilder (SqlStatementType.SELECT);
-				q.set_table (name);
-				q.select_add_field ("*", null, null);
-				var s = q.get_statement ();
-	    		var m = this.connection.statement_execute_select (s, null);
-				_records = new RecordCollection (m, this);
+				try {
+					var q = new Gda.SqlBuilder (SqlStatementType.SELECT);
+					q.set_table (name);
+					q.select_add_field ("*", null, null);
+					var s = q.get_statement ();
+					var m = this.connection.statement_execute_select (s, null);
+					_records = new RecordCollection (m, this);
+				}
+				catch (Error e) { GLib.warning (e.message); }
 				return _records;
 			}
 		}
 		public Collection<DbTable> depends    { owned get { return _depends.values; } }
-		public Collection<DbTable> references { 
+		public Collection<DbTable> referenced { 
 			owned get {
-				foreach (DbTable t in schema.tables) {
-					t.update ();
-					foreach (DbTable td in t.depends) {
-						if (name == td.name && schema.name == td.schema.name && catalog.name == td.catalog.name)
-						{
-							_references.set (t.name, t);
-							break;
+				try {
+					if (schema == null)
+						this.update ();
+					foreach (DbTable t in schema.tables) {
+						t.update ();
+						foreach (DbTable td in t.depends) {
+							if (name == td.name && 
+								schema.name == td.schema.name && 
+								catalog.name == td.catalog.name)
+							{
+								_referenced.set (t.name, t);
+								break;
+							}
 						}
 					}
-				}
-				return _references.values; 
+				} 
+				catch (Error e) { GLib.warning (e.message); }
+				return _referenced.values; 
 			} 
 		}
 	}
diff --git a/libgda/gda-meta-store.c b/libgda/gda-meta-store.c
index 70df537..6118890 100644
--- a/libgda/gda-meta-store.c
+++ b/libgda/gda-meta-store.c
@@ -33,8 +33,9 @@
  *      version 1 for libgda between 4.0.0 and 4.1.3
  *      version 2 for libgda >= 4.1.4: added the "_table_indexes" and "_index_column_usage" tables
  *      version 3 for libgda >= 4.2.4: added the "__declared_fk" table
+ *      version 4 for libgda >= 5.2.0: added "schema_default" to "_schemata" table
  */
-#define CURRENT_SCHEMA_VERSION "3"
+#define CURRENT_SCHEMA_VERSION "4"
 
 #include <string.h>
 #include <glib/gi18n-lib.h>
diff --git a/libgda/information_schema.xml b/libgda/information_schema.xml
index f794faa..cff4fda 100644
--- a/libgda/information_schema.xml
+++ b/libgda/information_schema.xml
@@ -48,6 +48,7 @@
     <column name="schema_name" pkey="TRUE" ident="TRUE"/>
     <column name="schema_owner" nullok="TRUE" descr="Name of the schema"/>
     <column name="schema_internal" type="boolean"  descr="Tells if the schema is specific to the database implementation (and usually can't be modified)"/>
+    <column name="schema_default" type="boolean"  descr="Tells if the schema is used by default when creating a new table without schema name"/>
     <fkey ref_table="_information_schema_catalog_name">
       <part column="catalog_name" ref_column="catalog_name"/>
     </fkey>
diff --git a/libgda/providers-support/gda-meta-column-types.h b/libgda/providers-support/gda-meta-column-types.h
index c055c78..764f287 100644
--- a/libgda/providers-support/gda-meta-column-types.h
+++ b/libgda/providers-support/gda-meta-column-types.h
@@ -1,20 +1,9 @@
 /*
- * Copyright (C) 2009 Vivien Malerba <malerba gnome-db org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA  02110-1301, USA.
+ * File generated by the tools/information-schema-types program from the
+ * libgda/information_schema.xml file,
+ * This file contains declaration of the expected data types when
+ * extracting meta data, it should be updated when the libgda/information_schema.xml file changes
+ * DO NOT MODIFY
  */
 
 
diff --git a/providers/reuseable/postgres/gda-postgres-meta.c b/providers/reuseable/postgres/gda-postgres-meta.c
index 9f25150..60d7e16 100644
--- a/providers/reuseable/postgres/gda-postgres-meta.c
+++ b/providers/reuseable/postgres/gda-postgres-meta.c
@@ -105,10 +105,10 @@ static gchar *internal_sql[] = {
 	"SELECT t.typname, 'pg_catalog.' || t.typname, 'gchararray', pg_catalog.obj_description(t.oid), NULL, CASE WHEN t.typname ~ '^_' THEN TRUE WHEN typtype = 'p' THEN TRUE WHEN t.typname in ('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', 'oid', 'aclitem') THEN TRUE ELSE FALSE END, CAST (t.oid AS varchar) FROM pg_catalog.pg_type t, pg_catalog.pg_user u, pg_catalog.pg_namespace n WHERE t.typowner=u.usesysid AND n.oid = t.typnamespace AND pg_catalog.pg_type_is_visible(t.oid) AND (typtype='b' OR typtype='p') AND typelem = 0",
 
 	/* I_STMT_SCHEMAS */
-	"SELECT current_database() AS catalog_name, n.nspname AS schema_name, u.rolname AS schema_owner, CASE WHEN n.nspname ~ '^pg_' THEN TRUE WHEN n.nspname = 'information_schema' THEN TRUE ELSE FALSE END FROM pg_namespace n, pg_roles u WHERE n.nspowner = u.oid AND current_database() = ##cat::string",
+	"SELECT current_database() AS catalog_name, n.nspname AS schema_name, u.rolname AS schema_owner, CASE WHEN n.nspname ~ '^pg_' THEN TRUE WHEN n.nspname = 'information_schema' THEN TRUE ELSE FALSE END, CASE WHEN n.nspname = 'public' THEN TRUE ELSE FALSE END AS schema_default FROM pg_namespace n, pg_roles u WHERE n.nspowner = u.oid AND current_database() = ##cat::string",
 
 	/* I_STMT_SCHEMAS_ALL */
-	"SELECT current_database() AS catalog_name, n.nspname AS schema_name, u.rolname AS schema_owner, CASE WHEN n.nspname ~ '^pg_' THEN TRUE WHEN n.nspname = 'information_schema' THEN TRUE ELSE FALSE END FROM pg_namespace n, pg_roles u WHERE n.nspowner = u.oid",
+	"SELECT current_database() AS catalog_name, n.nspname AS schema_name, u.rolname AS schema_owner, CASE WHEN n.nspname ~ '^pg_' THEN TRUE WHEN n.nspname = 'information_schema' THEN TRUE ELSE FALSE END, CASE WHEN n.nspname = 'public' THEN TRUE ELSE FALSE END AS schema_default FROM pg_namespace n, pg_roles u WHERE n.nspowner = u.oid",
 
 	/* I_STMT_SCHEMA_NAMED */
 	"SELECT current_database() AS catalog_name, n.nspname AS schema_name, u.rolname AS schema_owner, CASE WHEN n.nspname ~ '^pg_' THEN TRUE WHEN n.nspname = 'information_schema' THEN TRUE ELSE FALSE END FROM pg_namespace n, pg_roles u WHERE n.nspowner = u.oid AND current_database() = ##cat::string AND n.nspname = ##name::string",
diff --git a/samples/Gir/meta_store.py b/samples/Gir/meta_store.py
index 1dd0248..d66650e 100644
--- a/samples/Gir/meta_store.py
+++ b/samples/Gir/meta_store.py
@@ -21,11 +21,13 @@ print metatables.dump_as_string ()
 print "Adding a new table..."
 c.execute_non_select_command("CREATE TABLE customers (name string PRIMARY KEY, description string)")
 c.execute_non_select_command("INSERT INTO customers (name, description) VALUES ( \"IBMac\", \"International BMac\")")
+
 print "Updating Meta Store for table 'customers'..."
 cx.set_column ("table_name", "customers", c)
 c.update_meta_store (cx)
 metatables2 = ms.extract ("SELECT * FROM _tables", None)
 print metatables2.dump_as_string ()
+
 print "Dropping table 'customers' to re-create it with different columns..."
 print "Showing 'customers' columns"
 f = ms.extract ("SELECT * FROM _columns WHERE table_name = \"customers\"", None)
@@ -33,9 +35,17 @@ print f.dump_as_string ()
 c.execute_non_select_command("DROP TABLE customers")
 c.execute_non_select_command("CREATE TABLE customers (name string PRIMARY KEY, account integer, description string)")
 c.execute_non_select_command("INSERT INTO customers (name, account, description) VALUES ( \"IBMac\", 30395, \"International BMac\")")
+
 print "Updating Meta Store for table 'customers' columns..."
 cx.set_table ("_columns")
 c.update_meta_store (cx)
 f2 = ms.extract ("SELECT * FROM _columns WHERE table_name = \"customers\"", None)
 print f2.dump_as_string ()
 
+print "Updating Meta Store for catalog and schemas..."
+cx2 = Gda.MetaContext ()
+cx2.set_table ("_information_schema_catalog_name")
+c.update_meta_store (cx2)
+cm = ms.extract ("SELECT * FROM _information_schema_catalog_name", None)
+print "Catalog:\n" + cm.dump_as_string ()
+
diff --git a/tests/vala/CheckTable.vala b/tests/vala/CheckTable.vala
index 8709a0a..20b175a 100644
--- a/tests/vala/CheckTable.vala
+++ b/tests/vala/CheckTable.vala
@@ -1,7 +1,7 @@
 /* -*- Mode: Vala; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
  * libgdadata Unit Tests
- * Copyright (C) Daniel Espinosa Ortiz 2011 <esodan gmail com>
+ * Copyright (C) Daniel Espinosa Ortiz 2012 <esodan gmail com>
  * 
  * libgda is free software: you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published
@@ -31,36 +31,42 @@ namespace Check {
 			try {
 				GLib.FileUtils.unlink("table.db");
 				stdout.printf("Creating Database...\n");
-				this.connection = Connection.open_from_string("SQLite", "DB_DIR=.;DB_NAME=dataobject", null, Gda.ConnectionOptions.NONE);
+				this.connection = Connection.open_from_string("SQLite", "DB_DIR=.;DB_NAME=table", null, Gda.ConnectionOptions.NONE);
 				stdout.printf("Creating table 'user'...\n");
-				this.connection.execute_non_select_command("CREATE TABLE user (id integer PRIMARY KEY AUTOINCREMENT, name string UNIQUE, city string)");
-				this.connection.execute_non_select_command("INSERT INTO user (id, name, city) VALUES (1, \"Daniel\", \"Mexico\")");
-				this.connection.execute_non_select_command("INSERT INTO user (id, name, city) VALUES (2, \"Jhon\", \"USA\")");
+				this.connection.execute_non_select_command("CREATE TABLE user (id integer PRIMARY KEY AUTOINCREMENT, name string UNIQUE, city string, company integer REFERENCES company (id) ON DELETE SET NULL ON UPDATE CASCADE)");
+				this.connection.execute_non_select_command("INSERT INTO user (id, name, city, company) VALUES (1, \"Daniel\", \"Mexico\", 1)");
+				this.connection.execute_non_select_command("INSERT INTO user (id, name, city) VALUES (2, \"Jhon\", \"USA\", 2)");
 				
 				stdout.printf("Creating table 'company'...\n");
 				this.connection.execute_non_select_command("CREATE TABLE company (id int PRIMARY KEY, name string, responsability string)");
 				this.connection.execute_non_select_command("INSERT INTO company (id, name, responsability) VALUES (1, \"Telcsa\", \"Programing\")");
 				this.connection.execute_non_select_command("INSERT INTO company (id, name, responsability) VALUES (2, \"Viasa\", \"Accessories\")");
-				this.connection.update_meta_store(null);
+				this.connection.execute_non_select_command("CREATE TABLE salary (id integer PRIMARY KEY AUTOINCREMENT, user integer REFERENCES user (id) ON DELETE CASCADE ON UPDATE CASCADE, income float DEFAULT 10.0)");
+				this.connection.execute_non_select_command("INSERT INTO salary (id, user, income) VALUES (1,1,55.0)");
+				this.connection.execute_non_select_command("INSERT INTO salary (id, user, income) VALUES (2,2,65.0)");
 			}
 			catch (Error e) {
 				stdout.printf ("Couln't create temporary database...\nERROR: %s\n", e.message);
 			}
 		}
 		
-		public int update ()
+		public void init ()
 			throws Error
 		{
-			stdout.printf(">>> NEW TEST: GdaData.DbTable -- Update\n");
-			int fails = 0;
 			stdout.printf("Creating new table\n");
 			table = new Table ();
 			stdout.printf("Setting connection\n");
-			t.connection = this.connection;
+			table.connection = this.connection;
 			stdout.printf("Setting name\n");
-			t.name = "user";
+			table.name = "user";
+		}
+		public int update ()
+			throws Error
+		{
+			stdout.printf(">>> NEW TEST: GdaData.DbTable -- Update\n");
+			int fails = 0;
 			stdout.printf(">>> Updating meta information\n");
-			t.update ();
+			table.update ();
 			return fails;
 		}
 		
@@ -69,24 +75,47 @@ namespace Check {
 		{
 			stdout.printf(">>> NEW TEST: Gda.DbTable - Fields...\n");
 			int fails = 0;
-			var f = new Gee.HashSet<string> ();
-			f.add ("id");
-			f.add ("name");
-			f.add ("city");
+			var f = new Gee.HashMap<string,int> ();
+			f.set ("id", 0);
+			f.set ("name", 0);
+			f.set ("city", 0);
+			f.set ("company",0);
 			foreach (DbFieldInfo fi in table.fields)
 			{
-				if (! f.contains (fi.name))
+				if (! f.keys.contains (fi.name))
 				{
 					fails++;
 					break;
 				}
 			}
-			var f2 = new Gee.HashSet<string> ();
-			f2.add ("id");
-			f2.add ("name");
+			var f2 = new Gee.HashMap<string,int> ();
+			f2.set ("id",0);
+			f2.set ("name",0);
 			foreach (DbFieldInfo fi2 in table.primary_keys)
 			{
-				if (! f2.contains (fi2.name))
+				if (! f2.keys.contains (fi2.name))
+				{
+					fails++;
+					break;
+				}
+			}
+			
+			var f3 = new Gee.HashMap<string,int> ();
+			f3.set ("company",0);
+			foreach (DbTable t in table.depends)
+			{
+				if (! f3.keys.contains (t.name))
+				{
+					fails++;
+					break;
+				}
+			}
+			
+			var f4 = new Gee.HashMap<string,int> ();
+			f4.set ("salary",0);
+			foreach (DbTable t2 in table.referenced)
+			{
+				if (! f4.keys.contains (t2.name))
 				{
 					fails++;
 					break;
@@ -103,6 +132,7 @@ namespace Check {
 			int failures = 0;
 			var app = new Tests ();
 			try {
+				app.init ();
 				failures += app.update ();
 				failures += app.fields ();
 				//failures += app.records ();
diff --git a/tests/vala/Makefile.am b/tests/vala/Makefile.am
index 10df461..9f57fc7 100644
--- a/tests/vala/Makefile.am
+++ b/tests/vala/Makefile.am
@@ -13,7 +13,7 @@ AM_CPPFLAGS = \
 
 TESTS_ENVIRONMENT = 
 TESTS = check_dataobject check_datamodeliterator check_table
-check_PROGRAMS = check_dataobject check_datamodeliterator
+check_PROGRAMS = check_dataobject check_datamodeliterator check_table
 
 BUILT_SOURCES = \
     check_dataobject.vala.stamp \
@@ -58,8 +58,8 @@ check_datamodeliterator.vala.stamp: $(check_datamodeliterator_VALASOURCES)
 	$(VALA_COMPILER) $(VALAFLAGS) -C -H check_datamodeliterator.h $^
 	@touch $@
 
-check_table.vala.stamp: $(check_datamodeliterator_VALASOURCES)
-	$(VALA_COMPILER) $(VALAFLAGS) -C -H check_datamodeliterator.h $^
+check_table.vala.stamp: $(check_table_VALASOURCES)
+	$(VALA_COMPILER) $(VALAFLAGS) -C -H check_table.h $^
 	@touch $@
 
 check_dataobject_SOURCES = $(check_dataobject_VALASOURCES:.vala=.c) check_dataobject.h
@@ -68,30 +68,30 @@ check_dataobject_CFLAGS= \
     -I$(top_builddir)/libgda/data \
     $(NULL)
 check_dataobject_LDADD = \
-    $(top_builddir)/libgda/libgda-5.0.la \
+	$(top_builddir)/libgda/libgda-5.0.la \
 	$(top_builddir)/libgda/data/libgdadata-5.0.la \
 	$(COREDEPS_LIBS) \
 	$(GEE_LIBS)
 
 check_datamodeliterator_SOURCES = $(check_datamodeliterator_VALASOURCES:.vala=.c) check_datamodeliterator.h
 check_datamodeliterator_CFLAGS= \
-    -I$(top_builddir) \
-    -I$(top_builddir)/libgda/data \
-    $(NULL)
+	-I$(top_builddir) \
+	-I$(top_builddir)/libgda/data \
+	$(NULL)
 check_datamodeliterator_LDADD = \
-    $(top_builddir)/libgda/libgda-5.0.la \
+	$(top_builddir)/libgda/libgda-5.0.la \
 	$(top_builddir)/libgda/data/libgdadata-5.0.la \
 	$(COREDEPS_LIBS) \
 	$(GEE_LIBS)
 
 
-check_table_SOURCES = $(check_datamodeliterator_VALASOURCES:.vala=.c) check_datamodeliterator.h
+check_table_SOURCES = $(check_table_VALASOURCES:.vala=.c) check_table.h
 check_table_CFLAGS= \
     -I$(top_builddir) \
     -I$(top_builddir)/libgda/data \
     $(NULL)
 check_table_LDADD = \
-    $(top_builddir)/libgda/libgda-5.0.la \
+	$(top_builddir)/libgda/libgda-5.0.la \
 	$(top_builddir)/libgda/data/libgdadata-5.0.la \
 	$(COREDEPS_LIBS) \
 	$(GEE_LIBS)
@@ -101,6 +101,8 @@ CLEANFILES += \
     check_dataobject.h \
     $(check_datamodeliterator_VALASOURCES:.vala=.c) \
     check_datamodeliterator.h \
+    $(check_table_VALASOURCES:.vala=.c) \
+    check_table.h \
     dataobject.db \
     datamodeliterator.db \
     table.db \



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]