Beispiel #1
0
        private (List <ResultSetFieldMetadata>, string) ExtractResultSetMetadata(string resultSetXml)
        {
            try
            {
                var xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(SqlResultSetFieldCollection));

                resultSetXml = $"<FieldCollection>{resultSetXml}</FieldCollection>";

                using (var sr = new StringReader(resultSetXml))
                {
                    var val = (xmlSerializer.Deserialize(sr) as Settings.ObjectModel.SqlResultSetFieldCollection);

                    // look for error
                    if (val.Fields.Count > 0 && !string.IsNullOrWhiteSpace(val.Fields[0].ErrorMsg))
                    {
                        var f = val.Fields[0];
                        return(null, $"({f.ErrorDescription}) {f.ErrorMsg}");
                    }
                    else
                    {
                        return(val.Fields.Select(f => new ResultSetFieldMetadata()
                        {
                            ColumnName = f.Name,
                            DataType = RoutineParameterV2.GetCSharpDataTypeFromSqlDbType(f.Type),
                            DbDataType = f.Type,
                            ColumnSize = f.Size,
                            NumericalPrecision = f.Precision,
                            NumericalScale = f.Scale
                        }).ToList(), null);
                    }
                }
            }
            catch (Exception ex)
            {
                SessionLog.Exception(ex);
                return(null, "Failed to parse ResultSetXml:" + ex.Message);
            }
        }
Beispiel #2
0
        private static object ConvertParameterValue(string paramName, SqlDbType sqlType, string value, string udtType)
        {
            // if the expected value is a string return as is
            if (SqlStringTypes.Contains(sqlType))
            {
                return(value);
            }

            if (string.IsNullOrWhiteSpace(value))
            {
                return(DBNull.Value);
            }

            switch (sqlType)
            {
            case SqlDbType.UniqueIdentifier:
                return(new Guid((string)value));

            case SqlDbType.DateTime:
                var expectedFormat = "yyyy-MM-dd'T'HH:mm:ss.FFFK";

                // DateTimeOffset expect the Date & Time to be in LOCAL time
                if (DateTimeOffset.TryParseExact(value, expectedFormat, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out var dto))
                {
                    return(dto.DateTime);
                }
                else
                {
                    throw new JsdalServerParameterValueException(paramName, $"Invalid DateTime value of {value ?? "(null)"}. Expected format is: {expectedFormat} e.g. {DateTime.Now.ToString(expectedFormat)}");
                }

            case SqlDbType.Bit:
                return(ConvertToSqlBit(value));

            case SqlDbType.VarBinary:
                return(ConvertToSqlVarbinary(value));

            case SqlDbType.Timestamp:
                return(BitConverter.GetBytes(long.Parse(value)).Reverse().ToArray() /*have to reverse to match the endianness*/);

            case SqlDbType.Time:
                return(value);

            case SqlDbType.Float:
                return(double.Parse(value));

            case SqlDbType.Decimal:
                return(decimal.Parse(value));

            case SqlDbType.Udt:
            {
                // TODO: Refractor into separate function
                // TODO: Add support for geometry
                // TODO: Throw if unable to convert? (e.g. see DateTime section)
                if (udtType.Equals("geography", StringComparison.OrdinalIgnoreCase))
                {
                    // for geography we only support { lat: .., lng: ...} for now - in future we might support WKT strings
                    var obj  = JsonConvert.DeserializeObject <dynamic>(value);
                    int srid = 4326;

                    if (obj["srid"] != null)
                    {
                        srid = (int)obj.srid;
                    }

                    // Use NetTopologySuite until MS adds support for Geography/Geometry in dotcore sql client
                    // See https://github.com/dotnet/SqlClient/issues/30


                    var geometry = new NetTopologySuite.Geometries.Point((double)obj.lng, (double)obj.lat)
                    {
                        SRID = srid
                    };

                    var geometryWriter = new NetTopologySuite.IO.SqlServerBytesWriter {
                        IsGeography = true
                    };
                    var bytes = geometryWriter.Write(geometry);

                    return(new System.Data.SqlTypes.SqlBytes(bytes));

                    //return SqlGeography.Point((double)obj.lat, (double)obj.lng, srid);
                }

                return(value);
            }

            default:
            {
                var typeName = RoutineParameterV2.GetCSharpDataTypeFromSqlDbType(sqlType.ToString().ToLower());
                var type     = Type.GetType(typeName);

                return(Convert.ChangeType(value, type));
            }
            }
        }