// Copyright (C) 2004-2006 Autodesk, Inc. // // This library is free software; you can redistribute it and/or // modify it under the terms of version 2.1 of the GNU Lesser // General Public License as published by the Free Software Foundation. // // 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 using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.IO; using OSGeo.FDO.Schema; using OSGeo.FDO.Connections; using OSGeo.FDO.Commands.Schema; using OSGeo.FDO.Commands; using OSGeo.FDO; using unit_test.Framework; namespace unit_test.ProviderTests { class SchemaTests : BaseTestWithConnection { const string LOCATION = @"..\..\..\..\..\TestData\Testing"; const string LOCATION2 = @"..\..\..\..\..\TestData\t\x5348\x524dsting\"; public SchemaTests(ShpTestProvider connectProvider) : base(connectProvider) { } private void show_schema(FeatureSchemaCollection schemas) { for (int i = 0; i < schemas.Count; i++) { FeatureSchema schema = schemas[i]; Console.WriteLine("Schema: " + schema.Name); if ((schema.Description != null) && (schema.Description != "")) Console.WriteLine(" Description: " + schema.Description); ClassCollection classes = schema.Classes; for (int j = 0; j < classes.Count; j++) { ClassDefinition cls = classes[j]; // Output basic class info: if (cls.ClassType == ClassType.ClassType_FeatureClass) { string name = cls.Name; Console.WriteLine(" Feature Class: " + name); } //Console.WriteLine (" Feature Class: " + cls.Name); else Console.WriteLine(" Class: " + cls.Name); if ((cls.Description != null) && (cls.Description != "")) Console.WriteLine(" Description: " + cls.Description); ClassCapabilities classCapabilities = cls.Capabilities; Console.WriteLine(" Class Capabilities:"); if (classCapabilities == null) Console.WriteLine(" (Not available)."); else { Console.WriteLine(" Supports locking: " + (classCapabilities.SupportsLocking ? "yes" : "no")); Console.WriteLine(" Supports long transactions: " + (classCapabilities.SupportsLongTransactions ? "yes" : "no")); } // Output identity properties: DataPropertyDefinitionCollection identity = cls.IdentityProperties; for (int k = 0; k < identity.Count; k++) { DataPropertyDefinition definition = identity[k]; Console.WriteLine(" Id: " + definition.Name); if ((definition.Description != null) && (definition.Description != "")) Console.WriteLine(" Description: " + definition.Description); //Console.WriteLine (" Type: " + ShpTests.%ls Length: %d Precision: %d " + // ShpTests::GetDataTypeString (definition.DataType), // definition.Length, // definition.GetPrecision (), // definition.Getnullable () ? "nullable" : "Notnul"); } // Output regular properties: PropertyDefinitionCollection properties = cls.Properties; for (int k = 0; k < properties.Count; k++) { PropertyDefinition definition = properties[k]; if (definition.PropertyType == PropertyType.PropertyType_DataProperty) { DataPropertyDefinition data_definition = (DataPropertyDefinition)definition; if (!identity.Contains(data_definition)) { Console.WriteLine(" Property: " + definition.Name); if ((data_definition.Description != null) && (data_definition.Description != "")) Console.WriteLine(" Description: " + data_definition.Description); //Console.WriteLine (" Type: %ls Length: %d Precision: %d " + // ShpTests::GetDataTypeString (data_definition.DataType), // data_definition.Length, // data_definition.GetPrecision (), // data_definition.Getnullable () ? "nullable" : "Notnul"); } } else if (definition.PropertyType == PropertyType.PropertyType_ObjectProperty) { Console.WriteLine(" Object Property: " + definition.Name); if ((definition.Description != null) && (definition.Description != "")) Console.WriteLine(" Description: " + definition.Description); } else if (definition.PropertyType == PropertyType.PropertyType_GeometricProperty) { GeometricPropertyDefinition geometry_definition = (GeometricPropertyDefinition)definition; Console.WriteLine(" Geometric Property: " + geometry_definition.Name); if ((geometry_definition.Description != null) && (geometry_definition.Description != "")) Console.WriteLine(" Description: " + geometry_definition.Description); int types = geometry_definition.GeometryTypes; if (0 != (types & 0x01)) Console.WriteLine(" GeometricType_Point types allowed"); if (0 != (types & 0x02)) Console.WriteLine(" GeometricType_Curve types allowed"); if (0 != (types & 0x04)) Console.WriteLine(" GeometricType_Surface types allowed"); if (0 != (types & 0x08)) Console.WriteLine(" GeometricType_Solid types allowed"); } } // Output schema attribute dictionary: SchemaAttributeDictionary dictionary = cls.Attributes; int count = dictionary.AttributeNames.Length; string[] names = dictionary.AttributeNames; if ((0 != count) && (null != names)) { Console.WriteLine(" MetaData:"); string name; for (int t = 0; t < count; t++) { if (0 != t) Console.Write(","); name = names[t]; string value = dictionary.GetAttributeValue(name); Console.WriteLine(name + " = " + value); } Console.WriteLine(); } } } } //**********************Runtime error, debug later********************* // /// Test basic describe operation. / // public void Test_describe () // { // try // { // IConnection connection = base.ConnectionNew; // connection.ConnectionString = @"DefaultFileLocation=..\..\TestData\Ontario2"; // connection.Open(); // IDescribeSchema describe = (IDescribeSchema)connection.CreateCommand(CommandType.CommandType_DescribeSchema); // FeatureSchemaCollection schemas = describe.Execute (); //#if DEBUG // show_schema (schemas); //#endif // connection.Close(); // FeatureSchema oldSchema = schemas[0]; // ClassCollection oldClasses = oldSchema.Classes; // ClassDefinition oldClass = oldClasses[0]; // IConnection connection1 = base.ConnectionNew; // connection1.ConnectionString = @"DefaultFileLocation=..\..\TestData\Ontario2"; // connection1.Open(); // string NEW_SCHEMA_NAME = "NewSchema"; // string NEW_CLASS_NAME = oldClass.Name; // FeatureSchema schema = new FeatureSchema(NEW_SCHEMA_NAME, ""); // ClassCollection classes = schema.Classes; // DataPropertyDefinition id = new DataPropertyDefinition("Id", "integer"); // id.DataType = DataType.DataType_Int32; // DataPropertyDefinition street = new DataPropertyDefinition ("Street", "text"); // street.DataType = DataType.DataType_String; // street.Length = 64; // DataPropertyDefinition area = new DataPropertyDefinition("Area", "double"); // area.DataType = DataType.DataType_Decimal; // area.Precision =20; // area.Scale = 8; // DataPropertyDefinition vacant = new DataPropertyDefinition("Vacant", "boolean"); // vacant.DataType = DataType.DataType_Boolean; // DataPropertyDefinition birthday = new DataPropertyDefinition("Birthday", "date"); // birthday.DataType = DataType.DataType_DateTime; // // build a location geometry property // GeometricPropertyDefinition location = new GeometricPropertyDefinition ("Geometry", "geometry"); // location.GeometryTypes = 0x01; // location.HasElevation = true; // location.HasMeasure = true; // //// assemble the feature class // FeatureClass feature = new FeatureClass (NEW_CLASS_NAME, "test class created with apply schema"); // PropertyDefinitionCollection properties = feature.Properties; // properties.Add (id); // properties.Add (street); // properties.Add (area); // properties.Add (vacant); // properties.Add (birthday); // properties.Add (location); // feature.GeometryProperty = location; // DataPropertyDefinitionCollection identities = feature.IdentityProperties; // identities.Add (id); // // submit the new schema // classes.Add (feature); // IApplySchema apply = (IApplySchema)connection1.CreateCommand(CommandType.CommandType_ApplySchema); // apply.FeatureSchema = schema; // apply.Execute(); // connection1.Close(); // } // catch (OSGeo.Common.Exception ex) // { // Debug.Fail(ex.Message); // } // catch (System.Exception ex) // { // Debug.Fail(ex.Message); // } // } //**********************Runtime error, debug later********************* ///// Test describe operation with nonexistant schema. / //public void Test_describe_bogus() //{ // try // { // IDescribeSchema describe = (IDescribeSchema)base.ConnectionInitialized.CreateCommand(CommandType.CommandType_DescribeSchema); // // ensure asking for a nonexistant schema yields the proper exception // try // { // describe.SchemaName = "Bogus"; // FeatureSchemaCollection schemas = describe.Execute(); // Debug.Fail("no exception asking for a nonexistant schema"); // } // catch (OSGeo.Common.Exception e) // { // // check for expected message // Debug.Assert(e.Message.IndexOf("Schema 'Bogus' not found. ") != -1, "wrong exception"); // } // } // catch (OSGeo.Common.Exception ex) // { // Debug.Fail(ex.Message); // } // catch (System.Exception ex) // { // Debug.Fail(ex.Message); // } //} /// Test basic apply operation. / public void Tests_apply () { try { string NEW_SCHEMA_NAME = "NewSchema"; string NEW_CLASS_NAME = "Test"; // Clean up leftovers from previous tests: ShpTests.CleanUpClass(base.ConnectionInitialized, null, NEW_CLASS_NAME); IApplySchema apply = (IApplySchema)base.ConnectionInitialized.CreateCommand (CommandType.CommandType_ApplySchema); FeatureSchema schema = new FeatureSchema (NEW_SCHEMA_NAME, ""); ClassCollection classes = schema.Classes; DataPropertyDefinition id = new DataPropertyDefinition("Id", "integer"); id.DataType = DataType.DataType_Int32; DataPropertyDefinition street = new DataPropertyDefinition("Street", "text"); street.DataType = DataType.DataType_String; street.Length = 64; DataPropertyDefinition area = new DataPropertyDefinition("Area", "double"); area.DataType = DataType.DataType_Decimal; area.Precision = 20; area.Scale = 8; DataPropertyDefinition vacant = new DataPropertyDefinition("Vacant", "boolean"); vacant.DataType = DataType.DataType_Boolean; DataPropertyDefinition birthday = new DataPropertyDefinition("Birthday", "date"); birthday.DataType = DataType.DataType_DateTime; // build a location geometry property GeometricPropertyDefinition location = new GeometricPropertyDefinition ("Geometry", "geometry"); location.GeometryTypes = 0x01; location.HasElevation = true; location.HasMeasure = true; //// assemble the feature class FeatureClass feature = new FeatureClass (NEW_CLASS_NAME, "test class created with apply schema"); PropertyDefinitionCollection properties = feature.Properties; properties.Add (id); properties.Add (street); properties.Add (area); properties.Add (vacant); properties.Add (birthday); properties.Add (location); feature.GeometryProperty = location; DataPropertyDefinitionCollection identities = feature.IdentityProperties; identities.Add (id); // submit the new schema classes.Add (feature); apply.FeatureSchema = schema; apply.Execute (); // check that the new schema shows up in the list IDescribeSchema describe = (IDescribeSchema)base.ConnectionInitialized.CreateCommand (CommandType.CommandType_DescribeSchema); FeatureSchemaCollection schemas = describe.Execute (); IDisposableCollection collection = schemas.FindClass (NEW_CLASS_NAME); Debug.Assert (collection.Count == 1, "no class found"); FeatureClass cls = (FeatureClass )collection[0]; Debug.Assert (NEW_CLASS_NAME == cls.Name, "wrong name"); Debug.Assert (cls.Description == "test class created with apply schema", "wrong description"); // check it's contents properties = cls.Properties; DataPropertyDefinition featid = (DataPropertyDefinition)properties["Id"]; Debug.Assert (featid.DataType == DataType.DataType_Int32, "id wrong type"); street = (DataPropertyDefinition)properties["Street"]; Debug.Assert (street.DataType == DataType.DataType_String, "street wrong type" ); Debug.Assert (street.Length == 64, "street wrong size" ); area = (DataPropertyDefinition)properties["Area"]; Debug.Assert (area.DataType == DataType.DataType_Decimal, "area wrong type"); vacant = (DataPropertyDefinition)properties["Vacant"]; Debug.Assert (vacant.DataType == DataType.DataType_Boolean, "vacant wrong type" ); birthday = (DataPropertyDefinition)properties["Birthday"]; Debug.Assert (birthday.DataType == DataType.DataType_DateTime, "birthday wrong type"); location = (GeometricPropertyDefinition)properties["Geometry"]; Debug.Assert (location.GeometryTypes== 0x01, "wrong geometry types"); Debug.Assert (location.HasElevation, "wrong elevation"); Debug.Assert (location.HasMeasure, "wrong measure"); // OK, now delete the class schema = schemas[NEW_SCHEMA_NAME]; classes = schema.Classes; ClassDefinition definition = classes[NEW_CLASS_NAME]; definition.Delete (); apply.FeatureSchema = schema; apply.Execute (); } catch (OSGeo.Common.Exception ex) { Debug.Fail(ex.Message); } catch (System.Exception ex) { Debug.Fail(ex.Message); } } /// Test nameless schema apply operation. / public void Test_apply_nameless () { try { string NEW_SCHEMA_NAME = ""; string NEW_CLASS_NAME = "Test"; // Clean up leftovers from previous tests: ShpTests.CleanUpClass(base.ConnectionInitialized, null, NEW_CLASS_NAME); IApplySchema apply = (IApplySchema)base.ConnectionInitialized.CreateCommand (CommandType.CommandType_ApplySchema); FeatureSchema schema = new FeatureSchema (NEW_SCHEMA_NAME, ""); ClassCollection classes = schema.Classes; DataPropertyDefinition id = new DataPropertyDefinition("Id", "integer"); id.DataType = DataType.DataType_Int32; DataPropertyDefinition street = new DataPropertyDefinition("Street", "text"); street.DataType = DataType.DataType_String; street.Length = 64; // build a location geometry property GeometricPropertyDefinition location = new GeometricPropertyDefinition ("Geometry", "geometry"); location.GeometryTypes = 0x01; location.HasElevation = true; location.HasMeasure = true; //// assemble the feature class FeatureClass feature = new FeatureClass (NEW_CLASS_NAME, "test class created with apply schema"); PropertyDefinitionCollection properties = feature.Properties; properties.Add (id); properties.Add (street); properties.Add (location); feature.GeometryProperty = location; DataPropertyDefinitionCollection identities = feature.IdentityProperties; identities.Add (id); bool applied = false; try { // submit the new schema classes.Add (feature); apply.FeatureSchema = schema; apply.Execute (); applied = true; } catch (OSGeo.Common.Exception ge) { // check for expected message Debug.Assert (ge.Message.IndexOf("No schema specified for the apply schema command.") != -1, "wrong exception"); } // check that the new schema doesn't show up in the list IDescribeSchema describe = (IDescribeSchema)base.ConnectionInitialized.CreateCommand (CommandType.CommandType_DescribeSchema); FeatureSchemaCollection schemas = describe.Execute (); IDisposableCollection collection = schemas.FindClass (NEW_CLASS_NAME); int count = collection.Count; if (0 != count) { // delete the class schema = schemas[NEW_SCHEMA_NAME]; classes = schema.Classes; ClassDefinition definition = classes[NEW_CLASS_NAME]; definition.Delete(); apply.FeatureSchema = schema; apply.Execute(); } Debug.Assert (!applied, "nameless schema applied"); Debug.Assert (0 == count, "class found from nameless schema apply"); } catch (OSGeo.Common.Exception ex) { Debug.Fail(ex.Message); } catch (System.Exception ex) { Debug.Fail(ex.Message); } } /// Test nameless class creation. / public void Test_create_nameless () { try { string NEW_SCHEMA_NAME = "NewSchema"; string NEW_CLASS_NAME = ""; // Clean up leftovers from previous tests: ShpTests.CleanUpClass(base.ConnectionInitialized, null, NEW_CLASS_NAME); IApplySchema apply = (IApplySchema)base.ConnectionInitialized.CreateCommand (CommandType.CommandType_ApplySchema); FeatureSchema schema = new FeatureSchema (NEW_SCHEMA_NAME, ""); ClassCollection classes = schema.Classes; DataPropertyDefinition id = new DataPropertyDefinition("Id", "integer"); id.DataType = DataType.DataType_Int32; DataPropertyDefinition street = new DataPropertyDefinition("Street", "text"); street.DataType = DataType.DataType_String; street.Length = 64; // build a location geometry property GeometricPropertyDefinition location = new GeometricPropertyDefinition ("Geometry", "geometry"); location.GeometryTypes = 0x01; location.HasElevation = true; location.HasMeasure = true; //// assemble the feature class FeatureClass feature = new FeatureClass (NEW_CLASS_NAME, "test class created with apply schema"); PropertyDefinitionCollection properties = feature.Properties; properties.Add (id); properties.Add (street); properties.Add (location); feature.GeometryProperty = location; DataPropertyDefinitionCollection identities = feature.IdentityProperties; identities.Add (id); bool applied = false; try { // submit the new schema classes.Add (feature); apply.FeatureSchema = schema; apply.Execute (); applied = true; } catch (OSGeo.Common.Exception ge) { // check for expected message Debug.Assert (ge.Message.IndexOf("The class name '' is invalid.") != -1, "wrong exception"); } // check that the new class doesn't show up in the schema IDescribeSchema describe = (IDescribeSchema)base.ConnectionInitialized.CreateCommand (CommandType.CommandType_DescribeSchema); FeatureSchemaCollection schemas = describe.Execute (); IDisposableCollection collection = schemas.FindClass (NEW_CLASS_NAME); int count = collection.Count; if (0 != count) { // delete the class schema = schemas[NEW_SCHEMA_NAME]; classes = schema.Classes; ClassDefinition definition = classes[NEW_CLASS_NAME]; definition.Delete (); apply.FeatureSchema = schema; apply.Execute (); } Debug.Assert (!applied, "nameless class created"); Debug.Assert (0 == count, "class found from nameless schema apply"); } catch (OSGeo.Common.Exception ex) { Debug.Fail(ex.Message); } catch (System.Exception ex) { Debug.Fail(ex.Message); } } //// Executes a describe schema mapping (with default values, no config file) command. public void Test_schema_mapping_defaults_test() { try { IConnection mConnection = base.ConnectionInitialized; mConnection.Close (); mConnection.ConnectionString = @"DefaultFileLocation=..\..\..\..\..\TestData\Testing"; Debug.Assert (mConnection.Open() == ConnectionState.ConnectionState_Open, "connection state not open"); IDescribeSchemaMapping describeSchemaMappingCmd = (IDescribeSchemaMapping)mConnection.CreateCommand(CommandType.CommandType_DescribeSchemaMapping); describeSchemaMappingCmd.IncludeDefaults = true; PhysicalSchemaMappingCollection mappings = describeSchemaMappingCmd.Execute(); IDescribeSchema describeSchemaCmd = (IDescribeSchema)mConnection.CreateCommand(CommandType.CommandType_DescribeSchema); FeatureSchemaCollection logicalSchemas = describeSchemaCmd.Execute(); // test the schema mappings: //***************cann't implement*************************** //_TestSchemaMappings(mappings, logicalSchemas); } catch (OSGeo.Common.Exception ex) { Debug.Fail(ex.Message); } catch (System.Exception ex) { Debug.Fail(ex.Message); } } //// Executes a describe schema mapping (without default values, no config file) command. public void Test_schema_mapping_no_defaults_test() { try { IConnection mConnection = base.ConnectionInitialized; IDescribeSchemaMapping describeSchemaMappingCmd = (IDescribeSchemaMapping)mConnection.CreateCommand(CommandType.CommandType_DescribeSchemaMapping); describeSchemaMappingCmd.IncludeDefaults = false; PhysicalSchemaMappingCollection mappings = describeSchemaMappingCmd.Execute(); Debug.Assert(mappings.Count==0, "default mappings should be empty"); // test the schema mappings: //***************cann't implement*************************** //_TestSchemaMappings(mappings, null); } catch (OSGeo.Common.Exception ex) { Debug.Fail(ex.Message); } catch (System.Exception ex) { Debug.Fail(ex.Message); } } // Helper method; iterates the given schema mappings, comparing the mappings to // the logical schema (if one is given). //private void _TestSchemaMappings(PhysicalSchemaMappingCollection mappings, FeatureSchemaCollection logicalSchemas) //{ // if (mappings == null) // Debug.Fail("FAILED - DescribeSchemaMapping returned null collection"); // int numMappings = mappings.Count; // if (logicalSchemas != null) // { // // Match logical count to mapping count // Debug.Assert(numMappings==logicalSchemas.Count, "Number of schema mappings != number of logical schemas"); // } // for (int i=0; i