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;
}
}
}