// This is a modified version of SmiMetaDataFromSchemaTableRow above // Since CoreCLR doesn't have GetSchema, we need to infer the MetaData from the CLR Type alone internal static SmiExtendedMetaData SmiMetaDataFromType(string colName, Type colType) { // Determine correct SqlDbType. SqlDbType colDbType = InferSqlDbTypeFromType_Katmai(colType); if (InvalidSqlDbType == colDbType) { // Unknown through standard mapping, use VarBinary for columns that are Object typed, otherwise we error out. if (typeof(object) == colType) { colDbType = SqlDbType.VarBinary; } else { throw SQL.UnsupportedColumnTypeForSqlProvider(colName, colType.ToString()); } } // Determine metadata modifier values per type (maxlength, precision, scale, etc) long maxLength = 0; byte precision = 0; byte scale = 0; switch (colDbType) { case SqlDbType.BigInt: case SqlDbType.Bit: case SqlDbType.DateTime: case SqlDbType.Float: case SqlDbType.Image: case SqlDbType.Int: case SqlDbType.Money: case SqlDbType.NText: case SqlDbType.Real: case SqlDbType.UniqueIdentifier: case SqlDbType.SmallDateTime: case SqlDbType.SmallInt: case SqlDbType.SmallMoney: case SqlDbType.Text: case SqlDbType.Timestamp: case SqlDbType.TinyInt: case SqlDbType.Variant: case SqlDbType.Xml: case SqlDbType.Date: // These types require no metadata modifiers break; case SqlDbType.Binary: case SqlDbType.VarBinary: // source isn't specifying a size, so assume the Maximum if (SqlDbType.Binary == colDbType) { maxLength = SmiMetaData.MaxBinaryLength; } else { maxLength = SmiMetaData.UnlimitedMaxLengthIndicator; } break; case SqlDbType.Char: case SqlDbType.VarChar: // source isn't specifying a size, so assume the Maximum if (SqlDbType.Char == colDbType) { maxLength = SmiMetaData.MaxANSICharacters; } else { maxLength = SmiMetaData.UnlimitedMaxLengthIndicator; } break; case SqlDbType.NChar: case SqlDbType.NVarChar: // source isn't specifying a size, so assume the Maximum if (SqlDbType.NChar == colDbType) { maxLength = SmiMetaData.MaxUnicodeCharacters; } else { maxLength = SmiMetaData.UnlimitedMaxLengthIndicator; } break; case SqlDbType.Decimal: // Decimal requires precision and scale precision = SmiMetaData.DefaultDecimal.Precision; scale = SmiMetaData.DefaultDecimal.Scale; break; case SqlDbType.Time: case SqlDbType.DateTime2: case SqlDbType.DateTimeOffset: // requires scale scale = SmiMetaData.DefaultTime.Scale; break; case SqlDbType.Udt: case SqlDbType.Structured: default: // These types are not supported from SchemaTable throw SQL.UnsupportedColumnTypeForSqlProvider(colName, colType.ToString()); } return(new SmiExtendedMetaData( colDbType, maxLength, precision, scale, CultureInfo.CurrentCulture.LCID, SmiMetaData.GetDefaultForType(colDbType).CompareOptions, false, // no support for multi-valued columns in a TVP yet null, // no support for structured columns yet null, colName, null, null, null)); }
// Map SmiMetaData from a schema table. // DEVNOTE: Since we're using SchemaTable, we can assume that we aren't directly using a SqlDataReader // so we don't support the Sql-specific stuff, like collation. internal static SmiExtendedMetaData SmiMetaDataFromSchemaTableRow(DataRow schemaRow) { string colName = ""; object temp = schemaRow[SchemaTableColumn.ColumnName]; if (DBNull.Value != temp) { colName = (string)temp; } // Determine correct SqlDbType. temp = schemaRow[SchemaTableColumn.DataType]; if (DBNull.Value == temp) { throw SQL.NullSchemaTableDataTypeNotSupported(colName); } Type colType = (Type)temp; SqlDbType colDbType = InferSqlDbTypeFromType_Katmai(colType); if (InvalidSqlDbType == colDbType) { // Unknown through standard mapping, use VarBinary for columns that are Object typed, otherwise error if (typeof(object) == colType) { colDbType = SqlDbType.VarBinary; } else { throw SQL.UnsupportedColumnTypeForSqlProvider(colName, colType.ToString()); } } // Determine metadata modifier values per type (maxlength, precision, scale, etc) long maxLength = 0; byte precision = 0; byte scale = 0; switch (colDbType) { case SqlDbType.BigInt: case SqlDbType.Bit: case SqlDbType.DateTime: case SqlDbType.Float: case SqlDbType.Image: case SqlDbType.Int: case SqlDbType.Money: case SqlDbType.NText: case SqlDbType.Real: case SqlDbType.UniqueIdentifier: case SqlDbType.SmallDateTime: case SqlDbType.SmallInt: case SqlDbType.SmallMoney: case SqlDbType.Text: case SqlDbType.Timestamp: case SqlDbType.TinyInt: case SqlDbType.Variant: case SqlDbType.Xml: case SqlDbType.Date: // These types require no metadata modifies break; case SqlDbType.Binary: case SqlDbType.VarBinary: // These types need a binary max length temp = schemaRow[SchemaTableColumn.ColumnSize]; if (DBNull.Value == temp) { // source isn't specifying a size, so assume the worst if (SqlDbType.Binary == colDbType) { maxLength = SmiMetaData.MaxBinaryLength; } else { maxLength = SmiMetaData.UnlimitedMaxLengthIndicator; } } else { // We (should) have a valid maxlength, so use it. maxLength = Convert.ToInt64(temp, null); // Max length must be 0 to MaxBinaryLength or it can be UnlimitedMAX if type is varbinary. // If it's greater than MaxBinaryLength, just promote it to UnlimitedMAX, if possible. if (maxLength > SmiMetaData.MaxBinaryLength) { maxLength = SmiMetaData.UnlimitedMaxLengthIndicator; } if ((maxLength < 0 && (maxLength != SmiMetaData.UnlimitedMaxLengthIndicator || SqlDbType.Binary == colDbType))) { throw SQL.InvalidColumnMaxLength(colName, maxLength); } } break; case SqlDbType.Char: case SqlDbType.VarChar: // These types need an ANSI max length temp = schemaRow[SchemaTableColumn.ColumnSize]; if (DBNull.Value == temp) { // source isn't specifying a size, so assume the worst if (SqlDbType.Char == colDbType) { maxLength = SmiMetaData.MaxANSICharacters; } else { maxLength = SmiMetaData.UnlimitedMaxLengthIndicator; } } else { // We (should) have a valid maxlength, so use it. maxLength = Convert.ToInt64(temp, null); // Max length must be 0 to MaxANSICharacters or it can be UnlimitedMAX if type is varbinary. // If it's greater than MaxANSICharacters, just promote it to UnlimitedMAX, if possible. if (maxLength > SmiMetaData.MaxANSICharacters) { maxLength = SmiMetaData.UnlimitedMaxLengthIndicator; } if ((maxLength < 0 && (maxLength != SmiMetaData.UnlimitedMaxLengthIndicator || SqlDbType.Char == colDbType))) { throw SQL.InvalidColumnMaxLength(colName, maxLength); } } break; case SqlDbType.NChar: case SqlDbType.NVarChar: // These types need a unicode max length temp = schemaRow[SchemaTableColumn.ColumnSize]; if (DBNull.Value == temp) { // source isn't specifying a size, so assume the worst if (SqlDbType.NChar == colDbType) { maxLength = SmiMetaData.MaxUnicodeCharacters; } else { maxLength = SmiMetaData.UnlimitedMaxLengthIndicator; } } else { // We (should) have a valid maxlength, so use it. maxLength = Convert.ToInt64(temp, null); // Max length must be 0 to MaxUnicodeCharacters or it can be UnlimitedMAX if type is varbinary. // If it's greater than MaxUnicodeCharacters, just promote it to UnlimitedMAX, if possible. if (maxLength > SmiMetaData.MaxUnicodeCharacters) { maxLength = SmiMetaData.UnlimitedMaxLengthIndicator; } if ((maxLength < 0 && (maxLength != SmiMetaData.UnlimitedMaxLengthIndicator || SqlDbType.NChar == colDbType))) { throw SQL.InvalidColumnMaxLength(colName, maxLength); } } break; case SqlDbType.Decimal: // Decimal requires precision and scale temp = schemaRow[SchemaTableColumn.NumericPrecision]; if (DBNull.Value == temp) { precision = SmiMetaData.DefaultDecimal.Precision; } else { precision = Convert.ToByte(temp, null); } temp = schemaRow[SchemaTableColumn.NumericScale]; if (DBNull.Value == temp) { scale = SmiMetaData.DefaultDecimal.Scale; } else { scale = Convert.ToByte(temp, null); } if (precision < SmiMetaData.MinPrecision || precision > SqlDecimal.MaxPrecision || scale < SmiMetaData.MinScale || scale > SqlDecimal.MaxScale || scale > precision) { throw SQL.InvalidColumnPrecScale(); } break; case SqlDbType.Time: case SqlDbType.DateTime2: case SqlDbType.DateTimeOffset: // requires scale temp = schemaRow[SchemaTableColumn.NumericScale]; if (DBNull.Value == temp) { scale = SmiMetaData.DefaultTime.Scale; } else { scale = Convert.ToByte(temp, null); } if (scale > SmiMetaData.MaxTimeScale) { throw SQL.InvalidColumnPrecScale(); } else if (scale < 0) { scale = SmiMetaData.DefaultTime.Scale; } break; case SqlDbType.Udt: case SqlDbType.Structured: default: // These types are not supported from SchemaTable throw SQL.UnsupportedColumnTypeForSqlProvider(colName, colType.ToString()); } return(new SmiExtendedMetaData( colDbType, maxLength, precision, scale, System.Globalization.CultureInfo.CurrentCulture.LCID, SmiMetaData.GetDefaultForType(colDbType).CompareOptions, null, // no support for UDTs from SchemaTable false, // no support for multi-valued columns in a TVP yet null, // no support for structured columns yet null, // no support for structured columns yet colName, null, null, null)); }
internal static SmiExtendedMetaData SmiMetaDataFromSchemaTableRow(DataRow schemaRow) { string columnName = ""; object obj2 = schemaRow[SchemaTableColumn.ColumnName]; if (DBNull.Value != obj2) { columnName = (string)obj2; } obj2 = schemaRow[SchemaTableColumn.DataType]; if (DBNull.Value == obj2) { throw SQL.NullSchemaTableDataTypeNotSupported(columnName); } Type type2 = (Type)obj2; SqlDbType dbType = InferSqlDbTypeFromType_Katmai(type2); if (~SqlDbType.BigInt == dbType) { if (typeof(object) != type2) { throw SQL.UnsupportedColumnTypeForSqlProvider(columnName, type2.ToString()); } dbType = SqlDbType.VarBinary; } long maxLength = 0L; byte precision = 0; byte scale = 0; switch (dbType) { case SqlDbType.BigInt: case SqlDbType.Bit: case SqlDbType.DateTime: case SqlDbType.Float: case SqlDbType.Image: case SqlDbType.Int: case SqlDbType.Money: case SqlDbType.NText: case SqlDbType.Real: case SqlDbType.UniqueIdentifier: case SqlDbType.SmallDateTime: case SqlDbType.SmallInt: case SqlDbType.SmallMoney: case SqlDbType.Text: case SqlDbType.Timestamp: case SqlDbType.TinyInt: case SqlDbType.Variant: case SqlDbType.Xml: case SqlDbType.Date: goto Label_0302; case SqlDbType.Binary: case SqlDbType.VarBinary: obj2 = schemaRow[SchemaTableColumn.ColumnSize]; if (DBNull.Value != obj2) { maxLength = Convert.ToInt64(obj2, null); if (maxLength > 0x1f40L) { maxLength = -1L; } if ((maxLength < 0L) && ((maxLength != -1L) || (SqlDbType.Binary == dbType))) { throw SQL.InvalidColumnMaxLength(columnName, maxLength); } } else if (SqlDbType.Binary != dbType) { maxLength = -1L; } else { maxLength = 0x1f40L; } goto Label_0302; case SqlDbType.Char: case SqlDbType.VarChar: obj2 = schemaRow[SchemaTableColumn.ColumnSize]; if (DBNull.Value != obj2) { maxLength = Convert.ToInt64(obj2, null); if (maxLength > 0x1f40L) { maxLength = -1L; } if ((maxLength < 0L) && ((maxLength != -1L) || (SqlDbType.Char == dbType))) { throw SQL.InvalidColumnMaxLength(columnName, maxLength); } } else if (SqlDbType.Char != dbType) { maxLength = -1L; } else { maxLength = 0x1f40L; } goto Label_0302; case SqlDbType.Decimal: obj2 = schemaRow[SchemaTableColumn.NumericPrecision]; if (DBNull.Value != obj2) { precision = Convert.ToByte(obj2, null); break; } precision = SmiMetaData.DefaultDecimal.Precision; break; case SqlDbType.NChar: case SqlDbType.NVarChar: obj2 = schemaRow[SchemaTableColumn.ColumnSize]; if (DBNull.Value != obj2) { maxLength = Convert.ToInt64(obj2, null); if (maxLength > 0xfa0L) { maxLength = -1L; } if ((maxLength < 0L) && ((maxLength != -1L) || (SqlDbType.NChar == dbType))) { throw SQL.InvalidColumnMaxLength(columnName, maxLength); } } else if (SqlDbType.NChar != dbType) { maxLength = -1L; } else { maxLength = 0xfa0L; } goto Label_0302; case SqlDbType.Time: case SqlDbType.DateTime2: case SqlDbType.DateTimeOffset: obj2 = schemaRow[SchemaTableColumn.NumericScale]; if (DBNull.Value != obj2) { scale = Convert.ToByte(obj2, null); } else { scale = SmiMetaData.DefaultTime.Scale; } if (scale > 7) { throw SQL.InvalidColumnPrecScale(); } if (scale < 0) { scale = SmiMetaData.DefaultTime.Scale; } goto Label_0302; default: throw SQL.UnsupportedColumnTypeForSqlProvider(columnName, type2.ToString()); } obj2 = schemaRow[SchemaTableColumn.NumericScale]; if (DBNull.Value == obj2) { scale = SmiMetaData.DefaultDecimal.Scale; } else { scale = Convert.ToByte(obj2, null); } if (((precision < 1) || (precision > SqlDecimal.MaxPrecision)) || (((scale < 0) || (scale > SqlDecimal.MaxScale)) || (scale > precision))) { throw SQL.InvalidColumnPrecScale(); } Label_0302: return(new SmiExtendedMetaData(dbType, maxLength, precision, scale, (long)CultureInfo.CurrentCulture.LCID, SmiMetaData.GetDefaultForType(dbType).CompareOptions, null, false, null, null, columnName, null, null, null)); }