private List <FunctionFomular> GetFunctionFomulars(string value) { List <FunctionFomular> functions = new List <FunctionFomular>(); string innerContent = value; while (parenthesesRegex.IsMatch(innerContent)) { int firstLeftParenthesesIndex = innerContent.IndexOf('('); int lastRightParenthesesIndex = -1; int leftParenthesesCount = 0; int rightParenthesesCount = 0; for (int i = 0; i < innerContent.Length; i++) { if (innerContent[i] == '(') { leftParenthesesCount++; } else if (innerContent[i] == ')') { rightParenthesesCount++; if (rightParenthesesCount == leftParenthesesCount) { lastRightParenthesesIndex = i; break; } } } if (lastRightParenthesesIndex == -1) { break; } string leftContent = innerContent.Substring(0, firstLeftParenthesesIndex); var matches = nameRegex.Matches(leftContent); Match nameMatch = matches.Cast <Match>().LastOrDefault(); if (nameMatch != null) { string name = nameMatch.Value; int startIndex = nameMatch.Index; int length = lastRightParenthesesIndex - startIndex + 1; string expression = innerContent.Substring(startIndex, length); FunctionFomular func = new FunctionFomular(name, expression) { StartIndex = startIndex, StopIndex = lastRightParenthesesIndex }; functions.Add(func); innerContent = innerContent.Substring(firstLeftParenthesesIndex + 1, (func.StopIndex - 1) - (firstLeftParenthesesIndex + 1) + 1); } else { if (functions.Count == 0 && !leftContent.Contains("(")) { string name = value.Substring(0, firstLeftParenthesesIndex); FunctionFomular func = new FunctionFomular(name, value) { StartIndex = 0, StopIndex = value.Length - 1 }; functions.Add(func); } break; } } return(functions); }
public string ParseFomular(List <FunctionSpecification> sourceFuncSpecs, List <FunctionSpecification> targetFuncSpecs, FunctionFomular fomular, MappingFunctionInfo targetFunctionInfo, out Dictionary <string, string> dictDataType) { dictDataType = new Dictionary <string, string>(); string name = fomular.Name; FunctionSpecification sourceFuncSpec = sourceFuncSpecs.FirstOrDefault(item => item.Name.ToUpper() == name.ToUpper()); FunctionSpecification targetFuncSpec = targetFuncSpecs.FirstOrDefault(item => item.Name.ToUpper() == targetFunctionInfo.Name.ToUpper()); string newExpression = fomular.Expression; if (sourceFuncSpec != null && targetFuncSpec != null) { string delimiter = sourceFuncSpec.Delimiter == "," ? "," : $" {sourceFuncSpec.Delimiter} "; fomular.Delimiter = delimiter; List <string> fomularArgs = fomular.Args; int fetchCount = string.IsNullOrEmpty(targetFunctionInfo.Args) ? fomularArgs.Count : -1; Dictionary <int, string> sourceTokens = this.GetFunctionArgumentTokens(sourceFuncSpec, null, fetchCount); Dictionary <int, string> targetTokens = this.GetFunctionArgumentTokens(targetFuncSpec, targetFunctionInfo.Args, fetchCount); bool ignore = false; if (fomularArgs.Count > 0 && (targetTokens.Count == 0 || sourceTokens.Count == 0)) { ignore = true; } if (!ignore) { List <string> args = new List <string>(); foreach (var kp in targetTokens) { int targetIndex = kp.Key; string token = kp.Value; if (sourceTokens.ContainsValue(token)) { int sourceIndex = sourceTokens.FirstOrDefault(item => item.Value == token).Key; if (fomularArgs.Count > sourceIndex) { string oldArg = fomular.Args[sourceIndex]; string newArg = oldArg; switch (token.ToUpper()) { case "TYPE": if (!dictDataType.ContainsKey(oldArg)) { newArg = this.GetNewDataType(this.dataTypeMappings, oldArg); dictDataType.Add(oldArg, newArg.Trim()); } else { newArg = dictDataType[oldArg]; } break; } args.Add(newArg); } } else if (!string.IsNullOrEmpty(targetFunctionInfo.Args)) { args.Add(token); } } string targetDelimiter = targetFuncSpec.Delimiter == "," ? "," : $" {targetFuncSpec.Delimiter} "; string strArgs = string.Join(targetDelimiter, args); newExpression = $"{targetFunctionInfo.Name}{ (targetFuncSpec.NoParenthesess ? "" : $"({strArgs})") }"; } }
protected string HandleDefinition(string definition, List <TSQLToken> tokens, out bool changed) { this.sourceFuncSpecs = FunctionManager.GetFunctionSpecifications(this.sourceDbInterpreter.DatabaseType); this.targetFuncSpecs = FunctionManager.GetFunctionSpecifications(this.targetDbInterpreter.DatabaseType); changed = false; string newDefinition = definition; foreach (TSQLToken token in tokens) { string text = token.Text; string functionExpression = null; switch (token.Type) { case TSQLTokenType.SystemIdentifier: functionExpression = this.GetFunctionExpression(token, definition); break; case TSQLTokenType.Identifier: switch (text.ToUpper()) { case "CAST": case "TO_NUMBER": functionExpression = this.GetFunctionExpression(token, definition); break; } break; case TSQLTokenType.Keyword: break; } if (!string.IsNullOrEmpty(functionExpression)) { bool useBrackets = false; MappingFunctionInfo targetFunctionInfo = this.GetMappingFunctionInfo(text, out useBrackets); FunctionFomular fomular = new FunctionFomular(functionExpression); Dictionary <string, string> dictDataType = null; string newExpression = this.ParseFomular(this.sourceFuncSpecs, this.targetFuncSpecs, fomular, targetFunctionInfo, out dictDataType); if (newExpression != fomular.Expression) { newDefinition = this.ReplaceValue(newDefinition, fomular.Expression, newExpression); changed = true; } if (dictDataType != null) { this.convertedDataTypes.AddRange(dictDataType.Values); } if (!string.IsNullOrEmpty(targetFunctionInfo.Args) && changed) { if (!this.convertedFunctions.Contains(targetFunctionInfo.Name)) { this.convertedFunctions.Add(targetFunctionInfo.Name); } } } } return(newDefinition); }