private static DataTypeMappingTarget ParseTarget(XElement element) { DataTypeMappingTarget target = new DataTypeMappingTarget(element); if (!string.IsNullOrEmpty(target.Args)) { string[] items = target.Args.Split(','); foreach (string item in items) { string[] nvs = item.Split(':'); DataTypeMappingArgument arg = new DataTypeMappingArgument() { Name = nvs[0], Value = nvs[1] }; target.Arguments.Add(arg); } } return(target); }
public string GetNewDataType(List <DataTypeMapping> mappings, string dataType, bool usedForFunction = true) { dataType = dataType.Trim(); DatabaseType sourceDbType = this.sourceDbInterpreter.DatabaseType; DatabaseType targetDbType = this.targetDbInterpreter.DatabaseType; string cleanDataType = dataType.Split('(')[0].Trim(this.sourceDbInterpreter.QuotationLeftChar, this.sourceDbInterpreter.QuotationRightChar); string newDataType = cleanDataType; bool hasPrecisionScale = false; if (cleanDataType != dataType) { hasPrecisionScale = true; } string upperTypeName = newDataType.ToUpper(); DataTypeMapping mapping = this.GetDataTypeMapping(mappings, cleanDataType); if (mapping != null) { DataTypeMappingTarget targetDataType = mapping.Target; newDataType = targetDataType.Type; if (usedForFunction) { if (targetDbType == DatabaseType.MySql) { if (upperTypeName == "INT") { newDataType = "SIGNED"; } else if (upperTypeName == "FLOAT" || upperTypeName == "DOUBLE" || upperTypeName == "NUMBER") { newDataType = "DECIMAL"; } else if (DataTypeHelper.IsCharType(newDataType)) { newDataType = "CHAR"; } } else if (targetDbType == DatabaseType.Oracle) { if (DataTypeHelper.IsCharType(newDataType) && this.GetType() == typeof(FunctionTranslator)) { return(newDataType); } } } if (!hasPrecisionScale && !string.IsNullOrEmpty(targetDataType.Precision) && !string.IsNullOrEmpty(targetDataType.Scale)) { newDataType += $"({targetDataType.Precision},{targetDataType.Scale})"; } else if (hasPrecisionScale) { newDataType += "(" + dataType.Split('(')[1]; } } else { if (usedForFunction) { if (sourceDbType == DatabaseType.MySql) { if (upperTypeName == "SIGNED") { if (targetDbType == DatabaseType.SqlServer) { newDataType = "DECIMAL"; } else if (targetDbType == DatabaseType.Oracle) { newDataType = "NUMBER"; } } } } } return(newDataType); }
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; } } } }