3 using System.Collections.Generic;
5 using System.Data.Common;
6 using System.Data.Metadata.Edm;
12 internal class NpgsqlProviderManifest : DbXmlEnabledProviderManifest
14 public NpgsqlProviderManifest(string serverVersion)
15 : base(CreateXmlReaderForResource("Npgsql.NpgsqlProviderManifest.Manifest.xml"))
19 protected override XmlReader GetDbInformation(string informationType)
21 XmlReader xmlReader = null;
23 if (informationType == StoreSchemaDefinition)
25 xmlReader = CreateXmlReaderForResource("Npgsql.NpgsqlSchema.ssdl");
27 else if (informationType == StoreSchemaMapping)
29 xmlReader = CreateXmlReaderForResource("Npgsql.NpgsqlSchema.msl");
32 if (xmlReader == null)
33 throw new ArgumentOutOfRangeException("informationType");
38 private const string MaxLengthFacet = "MaxLength";
39 private const string ScaleFacet = "Scale";
40 private const string PrecisionFacet = "Precision";
41 private const string FixedLengthFacet = "FixedLength";
43 public override TypeUsage GetEdmType(TypeUsage storeType)
45 if (storeType == null)
46 throw new ArgumentNullException("storeType");
48 string storeTypeName = storeType.EdmType.Name;
49 PrimitiveType primitiveType = StoreTypeNameToEdmPrimitiveType[storeTypeName];
50 // TODO: come up with way to determin if unicode is used
51 bool isUnicode = true;
54 switch (storeTypeName)
63 return TypeUsage.CreateDefaultTypeUsage(primitiveType);
68 if (storeType.Facets.TryGetValue(ScaleFacet, false, out facet) &&
69 !facet.IsUnbounded && facet.Value != null)
71 scale = (byte)facet.Value;
72 if (storeType.Facets.TryGetValue(PrecisionFacet, false, out facet) &&
73 !facet.IsUnbounded && facet.Value != null)
75 precision = (byte)facet.Value;
76 return TypeUsage.CreateDecimalTypeUsage(primitiveType, precision, scale);
79 return TypeUsage.CreateDecimalTypeUsage(primitiveType);
82 if (storeType.Facets.TryGetValue(MaxLengthFacet, false, out facet) &&
83 !facet.IsUnbounded && facet.Value != null)
84 return TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, true, (int)facet.Value);
86 return TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, true);
88 if (storeType.Facets.TryGetValue(MaxLengthFacet, false, out facet) &&
89 !facet.IsUnbounded && facet.Value != null)
90 return TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, false, (int)facet.Value);
92 return TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, false);
95 return TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, false);
97 // TODO: make sure the arguments are correct here
98 if (storeType.Facets.TryGetValue(PrecisionFacet, false, out facet) &&
99 !facet.IsUnbounded && facet.Value != null)
101 return TypeUsage.CreateDateTimeTypeUsage(primitiveType, (byte)facet.Value);
105 return TypeUsage.CreateDateTimeTypeUsage(primitiveType, null);
108 return TypeUsage.CreateDateTimeTypeUsage(primitiveType, 0);
111 if (storeType.Facets.TryGetValue(MaxLengthFacet, false, out facet) &&
112 !facet.IsUnbounded && facet.Value != null)
114 return TypeUsage.CreateBinaryTypeUsage(primitiveType, false, (int)facet.Value);
116 return TypeUsage.CreateBinaryTypeUsage(primitiveType, false);
118 //TypeUsage.CreateBinaryTypeUsage
119 //TypeUsage.CreateDateTimeTypeUsage
120 //TypeUsage.CreateDecimalTypeUsage
121 //TypeUsage.CreateStringTypeUsage
123 throw new NotSupportedException();
126 public override TypeUsage GetStoreType(TypeUsage edmType)
129 throw new ArgumentNullException("edmType");
131 PrimitiveType primitiveType = edmType.EdmType as PrimitiveType;
132 if (primitiveType == null)
133 throw new ArgumentException("Store does not support specified edm type");
135 // TODO: come up with way to determin if unicode is used
136 bool isUnicode = true;
139 switch (primitiveType.PrimitiveTypeKind)
141 case PrimitiveTypeKind.Boolean:
142 return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["bool"]);
143 case PrimitiveTypeKind.Int16:
144 return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int2"]);
145 case PrimitiveTypeKind.Int32:
146 return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int4"]);
147 case PrimitiveTypeKind.Int64:
148 return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int8"]);
149 case PrimitiveTypeKind.Single:
150 return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["float4"]);
151 case PrimitiveTypeKind.Double:
152 return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["float8"]);
153 case PrimitiveTypeKind.Decimal:
157 if (edmType.Facets.TryGetValue(ScaleFacet, false, out facet) &&
158 !facet.IsUnbounded && facet.Value != null)
160 scale = (byte)facet.Value;
161 if (edmType.Facets.TryGetValue(PrecisionFacet, false, out facet) &&
162 !facet.IsUnbounded && facet.Value != null)
164 precision = (byte)facet.Value;
165 return TypeUsage.CreateDecimalTypeUsage(StoreTypeNameToStorePrimitiveType["numeric"], precision, scale);
168 return TypeUsage.CreateDecimalTypeUsage(StoreTypeNameToStorePrimitiveType["numeric"]);
170 case PrimitiveTypeKind.String:
172 // TODO: could get character, character varying, text
173 if (edmType.Facets.TryGetValue(FixedLengthFacet, false, out facet) &&
174 !facet.IsUnbounded && facet.Value != null)
176 PrimitiveType characterPrimitive = StoreTypeNameToStorePrimitiveType["bpchar"];
177 if (edmType.Facets.TryGetValue(MaxLengthFacet, false, out facet) &&
178 !facet.IsUnbounded && facet.Value != null)
180 return TypeUsage.CreateStringTypeUsage(characterPrimitive, isUnicode, true, (int)facet.Value);
182 // this may not work well
183 return TypeUsage.CreateStringTypeUsage(characterPrimitive, isUnicode, true);
185 if (edmType.Facets.TryGetValue(MaxLengthFacet, false, out facet) &&
186 !facet.IsUnbounded && facet.Value != null)
188 return TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["varchar"], isUnicode, false, (int)facet.Value);
190 // assume text since it is not fixed length and has no max length
191 return TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["text"], isUnicode, false);
193 case PrimitiveTypeKind.DateTime:
194 if (edmType.Facets.TryGetValue(PrecisionFacet, false, out facet) &&
195 !facet.IsUnbounded && facet.Value != null)
197 return TypeUsage.CreateDateTimeTypeUsage(StoreTypeNameToStorePrimitiveType["timestamp"], (byte)facet.Value);
201 return TypeUsage.CreateDateTimeTypeUsage(StoreTypeNameToStorePrimitiveType["timestamp"], null);
203 case PrimitiveTypeKind.Binary:
205 if (edmType.Facets.TryGetValue(MaxLengthFacet, false, out facet) &&
206 !facet.IsUnbounded && facet.Value != null)
208 return TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["bytea"], false, (int)facet.Value);
210 return TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["bytea"], false);
212 case PrimitiveTypeKind.Guid:
213 return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["uuid"]);
215 // PrimitiveTypeKind.Byte:
216 // PrimitiveTypeKind.SByte:
217 // PrimitiveTypeKind.DateTimeOffset:
218 // PrimitiveTypeKind.Time:
221 throw new NotSupportedException();
224 private static XmlReader CreateXmlReaderForResource(string resourceName)
226 return XmlReader.Create(System.Reflection.Assembly.GetAssembly(typeof(NpgsqlProviderManifest)).GetManifestResourceStream(resourceName));