using System.Text;
namespace Mono.Data.Tds {
+ public delegate object FrameworkValueGetter (object rawValue, ref bool updated);
+
public class TdsMetaParameter
{
#region Fields
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;
}
}
#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":
int len = ((string)value).Length;
- if (TypeName == "nvarchar" || TypeName == "nchar" || TypeName == "ntext")
+ if (TypeName == "nvarchar" || TypeName == "nchar"
+ || TypeName == "ntext"
+ || TypeName == "xml")
len *= 2;
return len ;
case "System.Byte[]":
case "nvarchar" :
case "nchar" :
case "ntext" :
+ case "xml" :
return Encoding.Unicode.GetBytes ((string)Value);
case "varchar" :
case "char" :
return TdsColumnType.BitN;
return TdsColumnType.Bit;
case "bigint":
- return TdsColumnType.IntN;
+ if (IsNullable)
+ return TdsColumnType.IntN ;
+ return TdsColumnType.BigInt;
case "char":
return TdsColumnType.Char;
case "money":
return TdsColumnType.NChar;
case "ntext":
return TdsColumnType.NText;
+ case "xml":
case "nvarchar":
return TdsColumnType.BigNVarChar;
case "real":