using System; using System.Collections.Generic; using System.Data; using Migrator.Framework; namespace Migrator.Providers { /// /// This class maps a DbType to names. /// /// /// Associations may be marked with a capacity. Calling the Get() /// method with a type and actual size n will return the associated /// name with smallest capacity >= n, if available and an unmarked /// default type otherwise. /// Eg, setting /// /// Names.Put(DbType, "TEXT" ); /// Names.Put(DbType, 255, "VARCHAR($l)" ); /// Names.Put(DbType, 65534, "LONGVARCHAR($l)" ); /// /// will give you back the following: /// /// Names.Get(DbType) // --> "TEXT" (default) /// Names.Get(DbType,100) // --> "VARCHAR(100)" (100 is in [0:255]) /// Names.Get(DbType,1000) // --> "LONGVARCHAR(1000)" (100 is in [256:65534]) /// Names.Get(DbType,100000) // --> "TEXT" (default) /// /// On the other hand, simply putting /// /// Names.Put(DbType, "VARCHAR($l)" ); /// /// would result in /// /// Names.Get(DbType) // --> "VARCHAR($l)" (will cause trouble) /// Names.Get(DbType,100) // --> "VARCHAR(100)" /// Names.Get(DbType,1000) // --> "VARCHAR(1000)" /// Names.Get(DbType,10000) // --> "VARCHAR(10000)" /// /// public class TypeNames { public const string LengthPlaceHolder = "$l"; public const string PrecisionPlaceHolder = "$p"; public const string ScalePlaceHolder = "$s"; private readonly Dictionary> weighted = new Dictionary>(); private readonly Dictionary defaults = new Dictionary(); /// /// Get default type name for specified type /// /// the type key /// the default type name associated with the specified key public string Get(DbType typecode) { string result; if (!defaults.TryGetValue(typecode, out result)) { throw new ArgumentException("Dialect does not support DbType." + typecode, "typecode"); } return result; } /// /// Get the type name specified type and size /// /// the type key /// the SQL length /// the SQL scale /// the SQL precision /// /// The associated name with smallest capacity >= size if available and the /// default type name otherwise /// public string Get(DbType typecode, int size, int precision, int scale) { SortedList map; weighted.TryGetValue(typecode, out map); if (map != null && map.Count > 0) { foreach (KeyValuePair entry in map) { if (size <= entry.Key) { return Replace(entry.Value, size, precision, scale); } } } //Could not find a specific type for the size, using the default return Replace(Get(typecode), size, precision, scale); } private static string Replace(string type, int size, int precision, int scale) { type = StringUtils.ReplaceOnce(type, LengthPlaceHolder, size.ToString()); type = StringUtils.ReplaceOnce(type, ScalePlaceHolder, scale.ToString()); return StringUtils.ReplaceOnce(type, PrecisionPlaceHolder, precision.ToString()); } /// /// Set a type name for specified type key and capacity /// /// the type key /// the (maximum) type size/length /// The associated name public void Put(DbType typecode, int capacity, string value) { SortedList map; if (!weighted.TryGetValue(typecode, out map)) { // add new ordered map weighted[typecode] = map = new SortedList(); } map[capacity] = value; } /// /// /// /// /// public void Put(DbType typecode, string value) { defaults[typecode] = value; } } }