Imported Upstream version 4.2.0.179

Former-commit-id: 0a113cb3a6feb7873f632839b1307cc6033cd595
This commit is contained in:
Xamarin Public Jenkins
2015-08-26 07:17:56 -04:00
committed by Jo Shields
parent 183bba2c9a
commit 6992685b86
7507 changed files with 90259 additions and 657307 deletions

View File

@@ -3,7 +3,8 @@ SUBDIRS =
include ../../build/rules.make
LIBRARY = Mono.Data.Tds.dll
LIB_MCS_FLAGS = /r:$(corlib) /r:System.dll /r:System.Xml.dll /r:Mono.Security.dll
LIB_REFS = System System.Xml Mono.Security
LIB_MCS_FLAGS = /r:$(corlib)
TEST_MCS_FLAGS = /r:System.dll /r:System.Net.dll

View File

@@ -932,6 +932,11 @@ namespace Mono.Data.Tds.Protocol
element = new Guid (guidBytes);
}
break;
case TdsColumnType.Variant :
if (outParam)
comm.Skip (4);
element = GetVariantValue();
break;
default :
return DBNull.Value;
}
@@ -956,6 +961,40 @@ namespace Mono.Data.Tds.Protocol
return result;
}
private object GetVariantValue ()
{
uint len = (uint)comm.GetTdsInt ();
if (len == 0)
return DBNull.Value;
// VARIANT_BASETYPE
TdsColumnType colType = (TdsColumnType)comm.GetByte ();
// VARIANT_PROPBYTES
byte propbytes = comm.GetByte ();
if (propbytes != 0)
// VARIANT_PROPERTIES
comm.Skip (propbytes);
len -= (uint)propbytes + 2;
switch (colType)
{
case TdsColumnType.Int1 :
case TdsColumnType.Int2 :
case TdsColumnType.Int4 :
case TdsColumnType.BigInt :
return GetIntValue (colType);
default:
// The old code was ignoring variants
// and returning null. Should we
// throw an exception?
comm.Skip (len);
break;
}
return DBNull.Value;
}
private object GetDateTimeValue (
TdsColumnType? type
)
@@ -1291,7 +1330,7 @@ namespace Mono.Data.Tds.Protocol
internal bool IsBlobType (TdsColumnType columnType)
{
return (columnType == TdsColumnType.Text || columnType == TdsColumnType.Image || columnType == TdsColumnType.NText);
return (columnType == TdsColumnType.Text || columnType == TdsColumnType.Image || columnType == TdsColumnType.NText || columnType == TdsColumnType.Variant);
}
internal bool IsLargeType (TdsColumnType columnType)

View File

@@ -559,8 +559,10 @@ namespace Mono.Data.Tds.Protocol
* If the value is null, not setting the size to 0 will cause varchar
* fields to get inserted as an empty string rather than an null.
*/
if (param.Value == null || param.Value == DBNull.Value)
size = 0;
if (colType != TdsColumnType.IntN && colType != TdsColumnType.DateTimeN) {
if (param.Value == null || param.Value == DBNull.Value)
size = 0;
}
// Change colType according to the following table
/*
@@ -584,6 +586,13 @@ namespace Mono.Data.Tds.Protocol
} else if (colType == TdsColumnType.BigVarBinary) {
if (size > 8000)
colType = TdsColumnType.Image;
} else if (colType == TdsColumnType.DateTime2 ||
colType == TdsColumnType.DateTimeOffset) {
// HACK: Wire-level DateTime{2,Offset}
// require TDS 7.3, which this driver
// does not implement correctly--so we
// serialize to ASCII instead.
colType = TdsColumnType.Char;
}
// Calculation of TypeInfo field
/*
@@ -713,6 +722,8 @@ namespace Mono.Data.Tds.Protocol
case "nchar" :
case "text" :
case "ntext" :
case "datetime2":
case "datetimeoffset":
byte [] tmp = param.GetBytes ();
Comm.Append (tmp);
break;

View File

@@ -35,6 +35,8 @@ namespace Mono.Data.Tds.Protocol {
Char = 0x2f, // SYBCHAR
DateTime = 0x3d, // SYBDATETIME
DateTime4 = 0x3a, // SYBDATETIME4
DateTime2 = 0x2a, // SYBMSDATETIME2
DateTimeOffset = 0x2b, // SYBMSDATETIMEOFFSET
DateTimeN = 0x6f, // SYBDATETIMN
Decimal = 0x6a, // SYBDECIMAL
Real = 0x3b, // SYBREAL

View File

@@ -219,6 +219,9 @@ namespace Mono.Data.Tds.Protocol {
case TypeCode.Object :
if (o is byte[])
Append ((byte[]) o);
else if (o is Guid)
Append (((Guid) o).ToByteArray ());
else break;
return;
case TypeCode.Int16 :
Append ((short) o);

View File

@@ -287,18 +287,31 @@ namespace Mono.Data.Tds {
internal string Prepare ()
{
string typeName = TypeName;
if (typeName == "varbinary") {
int size = Size;
// Cf. GetDateTimeString
TdsColumnType actualType = TdsColumnType.Char;
int size;
switch (typeName) {
case "varbinary":
size = Size;
if (size <= 0) {
size = GetActualSize ();
}
if (size > 8000) {
typeName = "varbinary(max)";
}
break;
case "datetime2":
actualType = TdsColumnType.DateTime2;
typeName = "char";
break;
case "datetimeoffset":
actualType = TdsColumnType.DateTimeOffset;
typeName = "char";
break;
}
string includeAt = "@";
if (ParameterName [0] == '@')
includeAt = "";
@@ -313,7 +326,7 @@ namespace Mono.Data.Tds {
case "varchar":
case "varbinary":
//A size of 0 is not allowed in declarations.
int size = Size;
size = Size;
if (size <= 0) {
size = GetActualSize ();
if (size <= 0)
@@ -326,6 +339,14 @@ namespace Mono.Data.Tds {
result.Append (paramSize > 0 ? (paramSize > 4000 ? "(max)" : String.Format ("({0})", paramSize)) : "(4000)");
break;
case "char":
size = -1;
if (actualType != TdsColumnType.Char)
size = GetDateTimeStringLength (actualType);
else if (isSizeSet)
size = Size;
if (size > 0)
result.Append (String.Format ("({0})", size));
break;
case "nchar":
case "binary":
if (isSizeSet && Size > 0)
@@ -366,6 +387,10 @@ namespace Mono.Data.Tds {
case "float":
case "money":
return 8;
case "datetime2":
return GetDateTimeStringLength (TdsColumnType.DateTime2);
case "datetimeoffset":
return GetDateTimeStringLength (TdsColumnType.DateTimeOffset);
case "int":
case "real":
case "smalldatetime":
@@ -386,6 +411,53 @@ namespace Mono.Data.Tds {
return size;
}
private int GetDateTimePrecision ()
{
int precision = Precision;
// http://msdn.microsoft.com/en-us/library/bb677335.aspx
// says that default precision is 7. How do
// we distinguish that from zero?
if (precision == 0 || precision > 7)
precision = 7;
return precision;
}
private int GetDateTimeStringLength (TdsColumnType type)
{
int precision = GetDateTimePrecision ();
int len = precision == 0 ? 19 : 20 + precision;
if (type == TdsColumnType.DateTimeOffset)
len += 6;
return len;
}
// HACK: Wire-level DateTime{2,Offset} require TDS
// 7.3, which this driver does not implement
// correctly--so we serialize to ASCII instead.
private string GetDateTimeString (TdsColumnType type)
{
int precision = GetDateTimePrecision ();
string fmt = "yyyy-MM-dd'T'HH':'mm':'ss";
if (precision > 0)
fmt += ".fffffff".Substring(0, precision + 1);
switch (type) {
case TdsColumnType.DateTime2:
DateTime dt = (DateTime)Value;
return dt.ToString(fmt);
case TdsColumnType.DateTimeOffset:
DateTimeOffset dto = (DateTimeOffset)Value;
return dto.ToString(fmt + "zzz");
}
throw new ApplicationException("Should be unreachable");
}
internal byte[] GetBytes ()
{
byte[] result = {};
@@ -403,6 +475,10 @@ namespace Mono.Data.Tds {
case "char" :
case "text" :
return Encoding.Default.GetBytes ((string)Value);
case "datetime2":
return Encoding.Default.GetBytes (GetDateTimeString (TdsColumnType.DateTime2));
case "datetimeoffset":
return Encoding.Default.GetBytes (GetDateTimeString (TdsColumnType.DateTimeOffset));
default :
return ((byte[]) Value);
}
@@ -441,6 +517,10 @@ namespace Mono.Data.Tds {
if (IsNullable)
return TdsColumnType.DateTimeN;
return TdsColumnType.DateTime4;
case "datetime2":
return TdsColumnType.DateTime2;
case "datetimeoffset":
return TdsColumnType.DateTimeOffset;
case "float":
if (IsNullable)
return TdsColumnType.FloatN ;
@@ -480,6 +560,8 @@ namespace Mono.Data.Tds {
return TdsColumnType.BigVarBinary;
case "varchar":
return TdsColumnType.BigVarChar;
case "sql_variant":
return TdsColumnType.Variant;
default:
throw new NotSupportedException ("Unknown Type : " + TypeName);
}