using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using OSGeo.FDO; using OSGeo.FDO.Schema; using OSGeo.FDO.Expression; using OSGeo.FDO.Commands; using OSGeo.FDO.Commands.Feature; using OSGeo.FDO.Commands.DataStore; using OSGeo.FDO.Connections; using OSGeo.FDO.Xml; using OSGeo.FDO.Commands.Schema; using OSGeo.FDO.Commands.SpatialContext; using unit_test.Framework; namespace unit_test.ProviderTests { class SchemaTests : BaseTestWithConnection { public SchemaTests(TestProvider connectProvider) : base(connectProvider) { Console.WriteLine("start SchemaTests"); } public override void SetUp() { base.SetUp(); } public override void TearDown() { base.TearDown(); } public void Test_Constraints() { IConnection mConnection = base.ConnectionInitialized; string fullpath = @"..\..\..\..\TestData\PARCEL_NEW.SDF"; File.Delete(fullpath); ICreateDataStore CreateCmd = (ICreateDataStore)mConnection.CreateCommand(CommandType.CommandType_CreateDataStore); IDataStorePropertyDictionary dictionary = CreateCmd.DataStoreProperties; string[] names = dictionary.PropertyNames; dictionary.SetProperty(names[0], fullpath); CreateCmd.Execute(); mConnection.ConnectionString = @"File=..\..\..\..\TestData\PARCEL_NEW.SDF"; Debug.Assert(mConnection.ConnectionState == ConnectionState.ConnectionState_Closed, "connection state not closed"); ConnectionState state = mConnection.Open(); Debug.Assert(state == ConnectionState.ConnectionState_Open, "connection state not open"); Debug.Assert(mConnection.ConnectionState == ConnectionState.ConnectionState_Open, "connection state not open"); ICreateSpatialContext CreateCreateSpatialContext = (ICreateSpatialContext)mConnection.CreateCommand(CommandType.CommandType_CreateSpatialContext); CreateCreateSpatialContext.CoordinateSystemWkt = "[LL84]"; CreateCreateSpatialContext.Description = "World Coordinate System, Degrees"; CreateCreateSpatialContext.Name = "World Geodetic Coordinate System, 1984"; CreateCreateSpatialContext.XYTolerance = 17.0; CreateCreateSpatialContext.ZTolerance = 3.14159; CreateCreateSpatialContext.Execute(); IApplySchema applyschema = (IApplySchema)mConnection.CreateCommand(CommandType.CommandType_ApplySchema); FeatureSchema schema = new FeatureSchema("MySchema", ""); FeatureClass clas = new FeatureClass("MyClass", ""); ClassCollection classes = schema.Classes; classes.Add(clas); PropertyDefinitionCollection properties = clas.Properties; GeometricPropertyDefinition geometry = new GeometricPropertyDefinition("Geom", ""); geometry.GeometryTypes = 7; // Point, Line, Polygon properties.Add(geometry); clas.GeometryProperty = geometry; DataPropertyDefinition id = new DataPropertyDefinition("FeatId", ""); id.DataType = DataType.DataType_Int32; id.Nullable = false; id.ReadOnly = true; id.IsAutoGenerated = true; properties.Add(id); DataPropertyDefinitionCollection idProps = clas.IdentityProperties; idProps.Add(id); DataPropertyDefinition dpd = new DataPropertyDefinition("NotNullString", ""); dpd.Nullable = false; dpd.DataType = DataType.DataType_String; properties.Add(dpd); dpd = new DataPropertyDefinition("StringRange", ""); PropertyValueConstraintRange rangeConstraint = new PropertyValueConstraintRange(); rangeConstraint.MaxInclusive = false; rangeConstraint.MaxValue = new StringValue("Rich"); rangeConstraint.MinInclusive = true; rangeConstraint.MinValue = new StringValue("Poor"); dpd.ValueConstraint = rangeConstraint; dpd.Nullable = true; dpd.DataType = DataType.DataType_String; properties.Add(dpd); dpd = new DataPropertyDefinition("Int32Range", "The key of the object"); dpd.DataType = DataType.DataType_Int32; rangeConstraint = new PropertyValueConstraintRange(); rangeConstraint.MaxInclusive = true; rangeConstraint.MaxValue = new Int32Value(Int32.MaxValue); rangeConstraint.MinInclusive = true; rangeConstraint.MinValue = new Int32Value(0); dpd.Nullable = true; dpd.ValueConstraint = rangeConstraint; properties.Add(dpd); dpd = new DataPropertyDefinition("StringEnum", ""); PropertyValueConstraintList listConstraint = new PropertyValueConstraintList(); DataValueCollection listValues = listConstraint.ConstraintList; listValues.Add(new StringValue("Up")); listValues.Add(new StringValue("Down")); listValues.Add(new StringValue("Left")); listValues.Add(new StringValue("Right")); dpd.Nullable = true; dpd.ValueConstraint = listConstraint; dpd.DataType = DataType.DataType_String; properties.Add(dpd); dpd = new DataPropertyDefinition("Int32Enum", ""); listConstraint = new PropertyValueConstraintList(); listValues = listConstraint.ConstraintList; listValues.Add(new Int32Value(1)); listValues.Add(new Int32Value(2)); listValues.Add(new Int32Value(3)); listValues.Add(new Int32Value(5)); listValues.Add(new Int32Value(7)); listValues.Add(new Int32Value(9)); dpd.Nullable = true; dpd.ValueConstraint = listConstraint; dpd.DataType = DataType.DataType_Int32; properties.Add(dpd); applyschema.FeatureSchema = schema; applyschema.Execute(); IDescribeSchema descSchema = (IDescribeSchema)mConnection.CreateCommand(CommandType.CommandType_DescribeSchema); FeatureSchemaCollection schemas = descSchema.Execute(); Debug.Assert(schemas.Count == 1, "Expecting 1 schema"); schema = schemas[0]; Debug.Assert(schema.Name == "MySchema", "Expecting 'MySchema' schema"); classes = schema.Classes; Debug.Assert(classes.Count == 1, "Expecting 1 class"); ClassDefinition classDef = classes[0]; Debug.Assert(classDef.Name == "MyClass", "Expecting 'MyClass' class"); dpd = (DataPropertyDefinition)classDef.Properties["Int32Range"]; rangeConstraint = (PropertyValueConstraintRange)dpd.ValueConstraint; Int32Value minVal = (Int32Value)rangeConstraint.MinValue; Int32Value maxVal = (Int32Value)rangeConstraint.MaxValue; Debug.Assert(minVal.Int32 == 0); Debug.Assert(maxVal.Int32 == Int32.MaxValue); mConnection.Close(); Debug.Assert(mConnection.ConnectionState == ConnectionState.ConnectionState_Closed, "connection state not closed"); Console.WriteLine("Test_Constraints runs successfully !"); } public void Test_LargeDataVolumeInsert() { IConnection mConnection = base.ConnectionInitialized; mConnection.ConnectionString = @"File=..\..\..\..\TestData\PARCEL_NEW.SDF"; Debug.Assert(mConnection.ConnectionState == ConnectionState.ConnectionState_Closed, "connection state not closed"); ConnectionState state = mConnection.Open(); Debug.Assert(state == ConnectionState.ConnectionState_Open, "connection state not open"); Debug.Assert(mConnection.ConnectionState == ConnectionState.ConnectionState_Open, "connection state not open"); IInsert insertCmd = (IInsert)mConnection.CreateCommand(CommandType.CommandType_Insert); insertCmd.SetFeatureClassName("MyClass"); PropertyValueCollection propVals = insertCmd.PropertyValues; PropertyValue propVal1 = new PropertyValue(); propVal1.Name = new Identifier("NotNullString"); PropertyValue propVal2 = new PropertyValue(); propVal2.Name = new Identifier("StringRange"); PropertyValue propVal3 = new PropertyValue(); propVal3.Name = new Identifier("Int32Range"); PropertyValue propVal4 = new PropertyValue(); propVal4.Name = new Identifier("StringEnum"); PropertyValue propVal5 = new PropertyValue(); propVal5.Name = new Identifier("Geom"); Expression expr1 = Expression.Parse("'AB'"); Expression expr2 = Expression.Parse("'Poor'"); Expression expr4 = Expression.Parse("'Down'"); Expression expr5 = Expression.Parse("GEOMFROMTEXT('LINESTRING XY (100000.0 100000.0, 200000.0 200000.0, 100000.0 300000.0)')"); Int32Value intVal = new Int32Value(0); propVals.Clear(); propVals.Add(propVal1); propVals.Add(propVal2); propVals.Add(propVal3); propVals.Add(propVal4); propVals.Add(propVal5); propVal1.Value = (ValueExpression)expr1; propVal2.Value = (ValueExpression)expr2; propVal3.Value = (ValueExpression)intVal; propVal4.Value = (ValueExpression)expr4; propVal5.Value = (ValueExpression)expr5; IFeatureReader reader; for (Int32 counter = 0; counter < 200000; counter++) { intVal.Int32 = counter; reader = insertCmd.Execute(); reader.Close(); reader.Dispose(); } Console.WriteLine("Test_LargeDataVolumeInsert runs successfully !"); } private static Expression ParseByDataType(string data, DataType dataType) { Expression expr = null; bool bIsNull = false; // NOTE: blob parsing doesn't work yet (ever?) in FDO: if (dataType != DataType.DataType_BLOB) { expr = Expression.Parse(data); if (expr is BooleanValue) { bIsNull = true; } else { bIsNull = false; } } switch (dataType) { case DataType.DataType_Boolean: { if (bIsNull) { BooleanValue val = new BooleanValue(); val.SetNull(); expr = val; } else { BooleanValue value = (BooleanValue)(expr); if (value == null) { Debug.Fail("Wrong data type!"); } } } break; case DataType.DataType_Byte: { if (bIsNull) { ByteValue val = new ByteValue(); val.SetNull(); expr = val; } else { Int32Value value = (Int32Value)(expr); if (value == null) { Debug.Fail("Wrong data type!"); } expr = new ByteValue((byte)value.Int32); } } break; case DataType.DataType_Int16: { if (bIsNull) { Int16Value val = new Int16Value(); val.SetNull(); expr = val; } else { Int32Value value = (Int32Value)(expr); if (value == null) { Debug.Fail("Wrong data type!"); } expr = new Int16Value((Int16)value.Int32); } } break; case DataType.DataType_Int32: { if (bIsNull) { Int32Value val = new Int32Value(); val.SetNull(); expr = val; } else { Int32Value value = (Int32Value)(expr); if (value == null) { Debug.Fail("Wrong data type!"); } } } break; case DataType.DataType_Int64: { if (bIsNull) { Int64Value val = new Int64Value(); val.SetNull(); expr = val; } else { Int64Value value = (Int64Value)(expr); if (value == null) { Debug.Fail("Wrong data type!"); } expr = new Int64Value((Int64)value.Int64); } } break; case DataType.DataType_Single: { if (bIsNull) { SingleValue val = new SingleValue(); val.SetNull(); expr = val; } else { DoubleValue value = (DoubleValue)(expr); if (value == null) { Debug.Fail("Wrong data type!"); } expr = new SingleValue((float)value.Double); } } break; case DataType.DataType_Double: { if (bIsNull) { DoubleValue val = new DoubleValue(); val.SetNull(); expr = val; } else { DoubleValue value = (DoubleValue)(expr); if (value == null) { Debug.Fail("Wrong data type!"); } } } break; case DataType.DataType_DateTime: { if (bIsNull) { DateTimeValue val = new DateTimeValue(); val.SetNull(); expr = val; } else { DateTimeValue value = (DateTimeValue)expr; if (value == null) { Debug.Fail("Wrong data type!"); } } } break; case DataType.DataType_Decimal: { if (bIsNull) { DecimalValue val = new DecimalValue(); val.SetNull(); expr = val; } else { DoubleValue valueDouble = (DoubleValue)expr; if (valueDouble != null) expr = new DecimalValue((double)valueDouble.Double); else { Int32Value valueInt32 = (Int32Value)expr; if (valueInt32 != null) expr = new DecimalValue((double)valueInt32.Int32); else Debug.Fail("Wrong data type!"); } } } break; case DataType.DataType_String: { if (bIsNull) { StringValue val = new StringValue(); val.SetNull(); expr = val; } else { StringValue value = (StringValue)expr; if (value == null) { Debug.Fail("Wrong data type!"); } } } break; default: Debug.Fail("Unhandled data type!"); break; } return expr; } } }