using System.Text;
namespace Mono.Data.Tds {
+ public delegate object FrameworkValueGetter (object rawValue, ref bool updated);
+
public class TdsMetaParameter
{
+ #region Static
+ public const int maxVarCharCharacters = 2147483647; // According to MS, max size is 2GB, 1 Byte Characters
+ public const int maxNVarCharCharacters = 1073741823; // According to MS, max size is 2GB, 2 Byte Characters
+ #endregion
+
#region Fields
TdsParameterDirection direction = TdsParameterDirection.Input;
bool isNullable;
object value;
bool isVariableSizeType;
+ FrameworkValueGetter frameworkValueGetter;
+ object rawValue;
+ bool isUpdated;
#endregion // Fields
{
}
+ public TdsMetaParameter (string name, FrameworkValueGetter valueGetter)
+ : this (name, String.Empty, null)
+ {
+ frameworkValueGetter = valueGetter;
+ }
+
public TdsMetaParameter (string name, string typeName, object value)
{
ParameterName = name;
Value = value;
}
+ public TdsMetaParameter (string name, int size, bool isNullable, byte precision, byte scale, FrameworkValueGetter valueGetter)
+ {
+ ParameterName = name;
+ Size = size;
+ IsNullable = isNullable;
+ Precision = precision;
+ Scale = scale;
+ frameworkValueGetter = valueGetter;
+ }
+
#region Properties
public TdsParameterDirection Direction {
}
public object Value {
- get { return value; }
- set { this.value = value; }
+ get {
+ if (frameworkValueGetter != null) {
+ object newValue = frameworkValueGetter (rawValue, ref isUpdated);
+ if (isUpdated)
+ value = newValue;
+ }
+
+ if (isUpdated) {
+ value = ResizeValue (value);
+ isUpdated = false;
+ }
+ return value;
+ }
+ set {
+ rawValue = this.value = value;
+ isUpdated = true;
+ }
+ }
+
+ public object RawValue {
+ get { return rawValue; }
+ set { Value = value; }
}
public byte Precision {
public int Size {
get { return GetSize (); }
set {
- size = value;
+ size = value;
+ isUpdated = true;
isSizeSet = true;
}
}
set { isVariableSizeType = value; }
}
+ public bool IsVarNVarCharMax
+ {
+ get { return (TypeName == "ntext" && size >= maxNVarCharCharacters); }
+ }
+
+ public bool IsVarCharMax
+ {
+ get { return (TypeName == "text" && size >= maxVarCharCharacters); }
+ }
+
+ public bool IsAnyVarCharMax
+ {
+ get { return IsVarNVarCharMax || IsVarCharMax; }
+ }
+
+ public bool IsNonUnicodeText
+ {
+ get {
+ TdsColumnType colType = GetMetaType();
+ return (colType == TdsColumnType.VarChar ||
+ colType == TdsColumnType.BigVarChar ||
+ colType == TdsColumnType.Text ||
+ colType == TdsColumnType.Char ||
+ colType == TdsColumnType.BigChar);
+ }
+ }
+
+ public bool IsMoneyType
+ {
+ get {
+ TdsColumnType colType = GetMetaType();
+ return (colType == TdsColumnType.Money ||
+ colType == TdsColumnType.MoneyN ||
+ colType == TdsColumnType.Money4 ||
+ colType == TdsColumnType.SmallMoney);
+ }
+ }
+
+ public bool IsDateTimeType
+ {
+ get {
+ TdsColumnType colType = GetMetaType();
+ return (colType == TdsColumnType.DateTime ||
+ colType == TdsColumnType.DateTime4 ||
+ colType == TdsColumnType.DateTimeN);
+ }
+ }
+
+ public bool IsTextType
+ {
+ get {
+ TdsColumnType colType = GetMetaType();
+ return (colType == TdsColumnType.VarChar ||
+ colType == TdsColumnType.BigVarChar ||
+ colType == TdsColumnType.BigChar ||
+ colType == TdsColumnType.Char ||
+ colType == TdsColumnType.BigNVarChar ||
+ colType == TdsColumnType.NChar ||
+ colType == TdsColumnType.Text ||
+ colType == TdsColumnType.NText);
+ }
+ }
+
+ public bool IsDecimalType
+ {
+ get {
+ TdsColumnType colType = GetMetaType();
+ return (colType == TdsColumnType.Decimal ||
+ colType == TdsColumnType.Numeric);
+ }
+ }
+
#endregion // Properties
#region Methods
+ object ResizeValue (object newValue)
+ {
+ if (newValue == DBNull.Value || newValue == null)
+ return newValue;
+
+ if (!isSizeSet || size <= 0)
+ return newValue;
+
+ // if size is set, truncate the value to specified size
+ string text = newValue as string;
+ if (text != null) {
+ if (TypeName == "nvarchar" ||
+ TypeName == "nchar" ||
+ TypeName == "xml") {
+ if (text.Length > size)
+ return text.Substring (0, size);
+ }
+ } else if (newValue.GetType () == typeof (byte [])) {
+ byte [] buffer = (byte []) newValue;
+ if (buffer.Length > size) {
+ byte [] tmpVal = new byte [size];
+ Array.Copy (buffer, tmpVal, size);
+ return tmpVal;
+ }
+ }
+ return newValue;
+ }
+
internal string Prepare ()
{
string typeName = TypeName;
}
if (size > 8000) {
- typeName = "image";
+ typeName = "varbinary(max)";
}
}
switch (typeName) {
case "decimal":
case "numeric":
- // msdotnet sends a default precision of 28
+ // msdotnet sends a default precision of 29
result.Append (String.Format ("({0},{1})",
- (Precision == (byte)0 ? (byte)28 : Precision), Scale));
+ (Precision == (byte)0 ? (byte)38 : Precision), Scale));
break;
case "varchar":
case "varbinary":
if (size <= 0)
size = 1;
}
- result.Append (String.Format ("({0})", size));
+ result.Append (size > 8000 ? "(max)" : String.Format ("({0})", size));
break;
case "nvarchar":
- result.Append (String.Format ("({0})", Size > 0 ? Size : 4000));
+ case "xml":
+ int paramSize = Size < 0 ? GetActualSize () / 2 : Size;
+ result.Append (paramSize > 0 ? (paramSize > 4000 ? "(max)" : String.Format ("({0})", paramSize)) : "(4000)");
break;
case "char":
case "nchar":
switch (Value.GetType ().ToString ()) {
case "System.String":
- return ((string) value).Length;
+ int len = ((string)value).Length;
+ if (TypeName == "nvarchar" || TypeName == "nchar"
+ || TypeName == "ntext"
+ || TypeName == "xml")
+ len *= 2;
+ return len ;
case "System.Byte[]":
return ((byte[]) value).Length;
}
private int GetSize ()
{
- if (IsNullable) {
- switch (TypeName) {
- case "bigint":
- return 8;
- case "datetime":
- return 8;
- case "float":
- return 8;
- case "int":
- return 4;
- case "real":
- return 4;
- case "smalldatetime":
- return 4;
- case "smallint":
- return 2;
- case "tinyint":
- return 1;
- }
+ switch (TypeName) {
+ case "decimal":
+ return 17;
+ case "uniqueidentifier":
+ return 16;
+ case "bigint":
+ case "datetime":
+ case "float":
+ case "money":
+ return 8;
+ case "int":
+ case "real":
+ case "smalldatetime":
+ case "smallmoney":
+ return 4;
+ case "smallint":
+ return 2;
+ case "tinyint":
+ case "bit":
+ return 1;
+ /*
+ case "nvarchar" :
+ */
+ case "nchar" :
+ case "ntext" :
+ return size*2 ;
}
return size;
}
+ internal byte[] GetBytes ()
+ {
+ byte[] result = {};
+ if (Value == DBNull.Value || Value == null)
+ return result;
+
+ switch (TypeName)
+ {
+ case "nvarchar" :
+ case "nchar" :
+ case "ntext" :
+ case "xml" :
+ return Encoding.Unicode.GetBytes ((string)Value);
+ case "varchar" :
+ case "char" :
+ case "text" :
+ return Encoding.Default.GetBytes ((string)Value);
+ default :
+ return ((byte[]) Value);
+ }
+ }
+
internal TdsColumnType GetMetaType ()
{
switch (TypeName) {
case "binary":
- return TdsColumnType.Binary;
+ return TdsColumnType.BigBinary;
case "bit":
+ if (IsNullable)
+ return TdsColumnType.BitN;
return TdsColumnType.Bit;
+ case "bigint":
+ if (IsNullable)
+ return TdsColumnType.IntN ;
+ return TdsColumnType.BigInt;
case "char":
- return TdsColumnType.Char;
+ return TdsColumnType.BigChar;
+ case "money":
+ if (IsNullable)
+ return TdsColumnType.MoneyN;
+ return TdsColumnType.Money;
+ case "smallmoney":
+ if (IsNullable)
+ return TdsColumnType.MoneyN ;
+ return TdsColumnType.SmallMoney;
case "decimal":
return TdsColumnType.Decimal;
case "datetime":
if (IsNullable)
return TdsColumnType.DateTimeN;
return TdsColumnType.DateTime;
+ case "smalldatetime":
+ if (IsNullable)
+ return TdsColumnType.DateTimeN;
+ return TdsColumnType.DateTime4;
case "float":
+ if (IsNullable)
+ return TdsColumnType.FloatN ;
return TdsColumnType.Float8;
case "image":
return TdsColumnType.Image;
return TdsColumnType.NChar;
case "ntext":
return TdsColumnType.NText;
+ case "xml":
case "nvarchar":
- return TdsColumnType.NVarChar;
+ return TdsColumnType.BigNVarChar;
case "real":
+ if (IsNullable)
+ return TdsColumnType.FloatN ;
return TdsColumnType.Real;
case "smallint":
if (IsNullable)
case "uniqueidentifier":
return TdsColumnType.UniqueIdentifier;
case "varbinary":
- return TdsColumnType.VarBinary;
+ return TdsColumnType.BigVarBinary;
case "varchar":
- return TdsColumnType.VarChar;
+ return TdsColumnType.BigVarChar;
default:
- throw new NotSupportedException ();
+ throw new NotSupportedException ("Unknown Type : " + TypeName);
+ }
+ }
+
+ public void CalculateIsVariableType()
+ {
+ switch (GetMetaType ()) {
+ case TdsColumnType.UniqueIdentifier:
+ case TdsColumnType.BigVarChar:
+ case TdsColumnType.BigVarBinary:
+ case TdsColumnType.IntN:
+ case TdsColumnType.Text:
+ case TdsColumnType.FloatN:
+ case TdsColumnType.BigNVarChar:
+ case TdsColumnType.NText:
+ case TdsColumnType.Image:
+ case TdsColumnType.Decimal:
+ case TdsColumnType.BigBinary:
+ case TdsColumnType.DateTimeN:
+ case TdsColumnType.MoneyN:
+ case TdsColumnType.BitN:
+ case TdsColumnType.Char:
+ case TdsColumnType.BigChar:
+ case TdsColumnType.NChar:
+ IsVariableSizeType = true;
+ break;
+ default:
+ IsVariableSizeType = false;
+ break;
}
}