public static bool ValidateDataType(DatabaseType databaseType, TableColumnDesingerInfo columnDesingerInfo, out string message) { message = ""; if (columnDesingerInfo.IsUserDefined) { return(true); } string columName = columnDesingerInfo.Name; string dataType = columnDesingerInfo.DataType; DataTypeSpecification dataTypeSpec = DataTypeManager.GetDataTypeSpecification(databaseType, dataType); if (dataTypeSpec == null) { message = $"Invalid data type:{dataType}"; return(false); } if (!string.IsNullOrEmpty(dataTypeSpec.Args)) { string length = columnDesingerInfo?.Length?.Trim(); if (string.IsNullOrEmpty(length) && dataTypeSpec.Optional) { return(true); } if (dataTypeSpec.AllowMax && !string.IsNullOrEmpty(length) && length.ToLower() == "max") { return(true); } string args = dataTypeSpec.Args; string[] argsNames = args.Split(','); string[] lengthItems = length?.Split(','); if (argsNames.Length != lengthItems?.Length) { if (argsNames.Length == 2 && lengthItems?.Length == 1) { lengthItems = new string[] { lengthItems[0], "0" }; } else { message = $"Length is invalid for column \"{columName}\", it's format should be:{args}"; return(false); } } int i = 0; foreach (string argName in argsNames) { string lengthItem = lengthItems[i]; ArgumentRange?range = DataTypeManager.GetArgumentRange(dataTypeSpec, argName); if (range.HasValue) { int lenValue; if (!int.TryParse(lengthItem, out lenValue)) { message = $"\"{lengthItem}\" is't a valid integer value"; return(false); } if (lenValue < range.Value.Min || lenValue > range.Value.Max) { message = $"The \"{argName}\"'s range of column \"{columName}\" should be between {range.Value.Min} and {range.Value.Max}"; return(false); } } i++; } } return(true); }
public void ConvertDataType(TableColumn column) { string originalDataType = column.DataType; DataTypeInfo dataTypeInfo = DataTypeHelper.GetDataTypeInfo(this.sourceDbInterpreter, originalDataType); string sourceDataType = dataTypeInfo.DataType; column.DataType = sourceDataType; DataTypeSpecification sourceDataTypeSpec = this.GetDataTypeSpecification(this.sourceDataTypeSpecs, sourceDataType); if (!string.IsNullOrEmpty(dataTypeInfo.Args)) { if (sourceDataTypeSpec.Args == "scale") { column.Scale = int.Parse(dataTypeInfo.Args); } else if (sourceDataTypeSpec.Args == "length") { if (column.MaxLength == null) { column.MaxLength = int.Parse(dataTypeInfo.Args); } } } DataTypeMapping dataTypeMapping = this.dataTypeMappings.FirstOrDefault(item => item.Source.Type?.ToLower() == column.DataType?.ToLower() || (item.Source.IsExpression && Regex.IsMatch(column.DataType, item.Source.Type, RegexOptions.IgnoreCase)) ); if (dataTypeMapping != null) { DataTypeMappingSource sourceMapping = dataTypeMapping.Source; DataTypeMappingTarget targetMapping = dataTypeMapping.Target; string targetDataType = targetMapping.Type; DataTypeSpecification targetDataTypeSpec = this.GetDataTypeSpecification(this.targetDataTypeSpecs, targetDataType); column.DataType = targetDataType; bool isChar = DataTypeHelper.IsCharType(column.DataType); bool isBinary = DataTypeHelper.IsBinaryType(column.DataType); if (isChar || isBinary) { if (isChar) { if (!string.IsNullOrEmpty(targetMapping.Length)) { column.MaxLength = int.Parse(targetMapping.Length); if (DataTypeHelper.StartWithN(targetDataType) && !DataTypeHelper.StartWithN(sourceDataType)) { column.MaxLength *= 2; } } } if (dataTypeMapping.Specials != null && dataTypeMapping.Specials.Count > 0) { DataTypeMappingSpecial special = dataTypeMapping.Specials.FirstOrDefault(item => this.IsSpecialMaxLengthMatched(item, column)); if (special != null) { column.DataType = special.Type; if (!string.IsNullOrEmpty(special.TargetMaxLength)) { column.MaxLength = int.Parse(special.TargetMaxLength); } } } if (column.MaxLength == -1) { ArgumentRange?sourceLengthRange = DataTypeManager.GetArgumentRange(sourceDataTypeSpec, "length"); if (sourceLengthRange.HasValue) { column.MaxLength = sourceLengthRange.Value.Max; } } ArgumentRange?targetLengthRange = DataTypeManager.GetArgumentRange(targetDataTypeSpec, "length"); if (targetLengthRange.HasValue) { int targetMaxLength = targetLengthRange.Value.Max; if (column.MaxLength > targetMaxLength) { if (!string.IsNullOrEmpty(targetMapping.Substitute)) { string[] substitutes = targetMapping.Substitute.Split(','); foreach (string substitute in substitutes) { DataTypeSpecification dataTypeSpec = this.GetDataTypeSpecification(this.targetDataTypeSpecs, substitute.Trim()); if (dataTypeSpec != null) { if (string.IsNullOrEmpty(dataTypeSpec.Args)) { column.DataType = substitute; break; } else { ArgumentRange?range = DataTypeManager.GetArgumentRange(dataTypeSpec, "length"); if (range.HasValue && range.Value.Max >= column.MaxLength) { column.DataType = substitute; break; } } } } } } } } else { if (dataTypeMapping.Specials != null && dataTypeMapping.Specials.Count > 0) { foreach (DataTypeMappingSpecial special in dataTypeMapping.Specials) { string name = special.Name; bool matched = false; if (name == "maxLength") { matched = this.IsSpecialMaxLengthMatched(special, column); } else if (name.Contains("precision") || name.Contains("scale")) { matched = this.IsSpecialPrecisionOrScaleMatched(special, column); } else if (name == "expression") { matched = this.IsSpecialExpressionMatched(special, originalDataType); } if (matched) { column.DataType = special.Type; } if (!string.IsNullOrEmpty(special.TargetMaxLength)) { column.MaxLength = int.Parse(special.TargetMaxLength); } } } if (string.IsNullOrEmpty(targetDataTypeSpec.Format)) { bool useConfigPrecisionScale = false; if (!string.IsNullOrEmpty(targetMapping.Precision)) { column.Precision = int.Parse(targetMapping.Precision); useConfigPrecisionScale = true; } if (!string.IsNullOrEmpty(targetMapping.Scale)) { column.Scale = int.Parse(targetMapping.Scale); useConfigPrecisionScale = true; } if (!useConfigPrecisionScale) { if (sourceDataTypeSpec.Args == "scale") { column.Precision = default(int?); } else if (sourceDataTypeSpec.Args == "precision,scale" && sourceDataTypeSpec.Args == targetDataTypeSpec.Args) { ArgumentRange?precisionRange = DataTypeManager.GetArgumentRange(targetDataTypeSpec, "precision"); ArgumentRange?scaleRange = DataTypeManager.GetArgumentRange(targetDataTypeSpec, "scale"); if (precisionRange.HasValue && column.Precision > precisionRange.Value.Max) { column.Precision = precisionRange.Value.Max; } if (scaleRange.HasValue && column.Scale > scaleRange.Value.Max) { column.Scale = scaleRange.Value.Max; } if (column.Precision.HasValue) { if (column.DataType.ToLower() == "int") { if (column.Precision.Value > 10) { column.DataType = "bigint"; } } } } } } else { string format = targetDataTypeSpec.Format; string dataType = format; string[] defaultValues = targetDataTypeSpec.Default?.Split(','); string targetMappingArgs = targetMapping.Args; int i = 0; foreach (DataTypeArgument arg in targetDataTypeSpec.Arugments) { if (arg.Name.ToLower() == "scale") { ArgumentRange?targetScaleRange = DataTypeManager.GetArgumentRange(targetDataTypeSpec, "scale"); int scale = column.Scale == null ? 0 : column.Scale.Value; if (targetScaleRange.HasValue && scale > targetScaleRange.Value.Max) { scale = targetScaleRange.Value.Max; } dataType = dataType.Replace("$scale$", scale.ToString()); } else { string defaultValue = defaultValues != null && defaultValues.Length > i ? defaultValues[i] : ""; string value = defaultValue; if (targetMapping.Arguments.Any(item => item.Name == arg.Name)) { value = targetMapping.Arguments.FirstOrDefault(item => item.Name == arg.Name).Value; } dataType = dataType.Replace($"${arg.Name}$", value); } i++; } column.DataType = dataType; } } } }