예제 #1
0
        public void Translate(DatabaseObjectType databaseObjectType = DatabaseObjectType.None)
        {
            if (this.NeedTranslate(databaseObjectType, DatabaseObjectType.TableColumn))
            {
                ColumnTranslator columnTranslator = new ColumnTranslator(this.sourceInterpreter, this.targetInerpreter, this.targetSchemaInfo.TableColumns);
                this.Translate(columnTranslator);
            }

            if (this.NeedTranslate(databaseObjectType, DatabaseObjectType.TableConstraint))
            {
                ConstraintTranslator constraintTranslator = new ConstraintTranslator(sourceInterpreter, this.targetInerpreter, this.targetSchemaInfo.TableConstraints)
                {
                    SkipError = this.SkipError
                };
                this.Translate(constraintTranslator);
            }

            if (this.NeedTranslate(databaseObjectType, DatabaseObjectType.View))
            {
                ScriptTranslator <View> viewTranslator = this.GetScriptTranslator <View>(this.targetSchemaInfo.Views);
                viewTranslator.Translate();
            }

            if (this.NeedTranslate(databaseObjectType, DatabaseObjectType.Function))
            {
                ScriptTranslator <Function> functionTranslator = this.GetScriptTranslator <Function>(this.targetSchemaInfo.Functions);
                functionTranslator.Translate();
            }

            if (this.NeedTranslate(databaseObjectType, DatabaseObjectType.Procedure))
            {
                ScriptTranslator <Procedure> procedureTranslator = this.GetScriptTranslator <Procedure>(this.targetSchemaInfo.Procedures);
                procedureTranslator.Translate();
            }

            if (this.NeedTranslate(databaseObjectType, DatabaseObjectType.TableTrigger))
            {
                ScriptTranslator <TableTrigger> triggerTranslator = this.GetScriptTranslator <TableTrigger>(this.targetSchemaInfo.TableTriggers);
                triggerTranslator.Translate();
            }

            this.TranslateOwner();
        }
예제 #2
0
        private void ProcessTokens()
        {
            ScriptTokenExtracter    tokenExtracter = new ScriptTokenExtracter(this.Script);
            IEnumerable <TokenInfo> tokens         = tokenExtracter.Extract();

            IEnumerable <string> keywords  = KeywordManager.GetKeywords(this.TargetInterpreter.DatabaseType);
            IEnumerable <string> functions = FunctionManager.GetFunctionSpecifications(this.TargetInterpreter.DatabaseType).Select(item => item.Name);

            this.columnTranslator = new ColumnTranslator(this.SourceInterpreter, this.TargetInterpreter, null);
            columnTranslator.LoadMappings();

            Func <TokenInfo, bool> changeValue = (token) =>
            {
                string oldSymbol = token.Symbol;

                bool hasChanged = false;

                if (this.TargetInterpreter.DatabaseType == DatabaseType.SqlServer)
                {
                    token.Symbol = "@" + token.Symbol.TrimStart('@');
                    hasChanged   = true;

                    if (!this.ReplacedVariables.ContainsKey(oldSymbol))
                    {
                        this.ReplacedVariables.Add(oldSymbol, token.Symbol);
                    }
                }
                else if (this.SourceInterpreter.DatabaseType == DatabaseType.SqlServer)
                {
                    token.Symbol = token.Symbol.TrimStart('@');

                    if (keywords.Contains(token.Symbol.ToUpper()) || functions.Contains(token.Symbol.ToUpper()))
                    {
                        token.Symbol = token.Symbol + "_";
                    }

                    hasChanged = true;

                    if (!this.ReplacedVariables.ContainsKey(oldSymbol))
                    {
                        this.ReplacedVariables.Add(oldSymbol, token.Symbol);
                    }
                }

                return(hasChanged);
            };

            this.ReplaceTokens(tokens);

            foreach (TokenInfo token in tokens.Where(item => item != null && (item.Type == TokenType.ParameterName || item.Type == TokenType.VariableName)))
            {
                changeValue(token);
            }

            IEnumerable <string> aliases = tokens.Where(item => item.Symbol != null && item.Type == TokenType.Alias).Select(item => item.Symbol);

            foreach (TokenInfo token in tokens)
            {
                if (token.Symbol == null)
                {
                    continue;
                }

                if (token.Type == TokenType.DataType)
                {
                    TableColumn tableColumn = this.CreateTableColumn(token.Symbol);

                    columnTranslator.ConvertDataType(tableColumn);

                    token.Symbol = this.TargetInterpreter.ParseDataType(tableColumn);
                }
                else if (token is TableName tableName)
                {
                    if (tableName.Name != null && tableName.Name.Symbol != null)
                    {
                        string alias = tableName.Alias == null ? "" : tableName.Alias.ToString();

                        token.Symbol = $"{ this.GetQuotedName(tableName.Name.ToString(), token.Type)}" + (string.IsNullOrEmpty(alias) ? "" : " " + alias);
                    }
                }
                else if (token is ColumnName columnName)
                {
                    string columnContent = "";

                    if (columnName.Name != null)
                    {
                        string strTableName = "";

                        if (columnName.TableName != null)
                        {
                            strTableName = (!aliases.Contains(columnName.TableName.Symbol) ?
                                            this.GetQuotedName(columnName.TableName.ToString().Trim('.'), token.Type) :
                                            columnName.TableName.Symbol)
                                           + ".";
                        }

                        string strColName = this.GetQuotedName(columnName.Name.ToString().Trim('.'), token.Type);

                        columnContent = $"{strTableName}{strColName}";

                        if (columnName.Alias != null && !string.IsNullOrEmpty(columnName.Alias.Symbol))
                        {
                            string alias = columnName.Alias.ToString();

                            columnContent += $" AS {this.GetQuotedName(alias, token.Type)}";
                        }

                        token.Symbol = columnContent;
                    }
                }
                else if (token.Type == TokenType.TableName || token.Type == TokenType.ColumnName)
                {
                    if (!aliases.Contains(token.Symbol))
                    {
                        token.Symbol = this.GetQuotedName(token.Symbol.Trim('.'), token.Type);
                    }
                }
                else if (token.Type == TokenType.RoutineName)
                {
                    token.Symbol = this.GetQuotedName(token.Symbol, token.Type);
                }
                else if (token.Type == TokenType.Condition ||
                         token.Type == TokenType.OrderBy ||
                         token.Type == TokenType.GroupBy
                         )
                {
                    if (token.Tokens.Count == 0)
                    {
                        token.Symbol = this.GetQuotedString(token.Symbol);
                    }
                }
                else if (token.Type == TokenType.Alias)
                {
                    if (token.Symbol != null && !token.Symbol.Contains(" "))
                    {
                        token.Symbol = token.Symbol.Trim(this.TrimChars);
                    }
                }

                #region Replace parameter and variable name
                if (token.Type != TokenType.ParameterName && token.Type != TokenType.VariableName)
                {
                    if (this.ReplacedVariables.ContainsKey(token.Symbol))
                    {
                        token.Symbol = this.ReplacedVariables[token.Symbol];
                    }
                    else if (this.ReplacedVariables.Any(item => token.Symbol.Contains(item.Key)))
                    {
                        foreach (var kp in this.ReplacedVariables)
                        {
                            string prefix = "";

                            foreach (var c in kp.Key)
                            {
                                if (!Regex.IsMatch(c.ToString(), "[_a-zA-Z]"))
                                {
                                    prefix += c;
                                }
                                else
                                {
                                    break;
                                }
                            }

                            string excludePattern = $@"[`""\[]\b({kp.Key})\b[`""\]]";
                            string pattern        = "";

                            if (prefix.Length == 0)
                            {
                                pattern = $@"\b({kp.Key})\b";
                            }
                            else
                            {
                                pattern = $@"([{prefix}]\b({kp.Key.Substring(prefix.Length)})\b)";
                            }

                            if (!Regex.IsMatch(token.Symbol, excludePattern))
                            {
                                foreach (Match match in Regex.Matches(token.Symbol, pattern))
                                {
                                    if (kp.Value.StartsWith("@") && token.Symbol.Contains(kp.Value))
                                    {
                                        continue;
                                    }

                                    token.Symbol = Regex.Replace(token.Symbol, pattern, kp.Value);
                                }
                            }
                        }
                    }
                }
                #endregion
            }

            #region Nested token handle
            if (this.nameWithQuotation)
            {
                var nestedTokens = tokens.Where(item => this.IsNestedToken(item));

                foreach (TokenInfo nestedToken in nestedTokens)
                {
                    List <string> replacedSymbols = new List <string>();

                    var childTokens = this.GetNestedTokenChildren(nestedToken);

                    foreach (var token in childTokens)
                    {
                        if (token.Symbol == null)
                        {
                            continue;
                        }

                        string[] items = token.Symbol.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);

                        foreach (string item in items)
                        {
                            string trimedItem = item.Trim(this.TrimChars);

                            if (aliases.Contains(trimedItem))
                            {
                                continue;
                            }

                            if (nameRegex.IsMatch(trimedItem))
                            {
                                Regex doubleQuotationRegex = new Regex($@"[""]\b({trimedItem})\b[""]");
                                Regex matchRegex           = new Regex($@"[{this.SourceInterpreter.QuotationLeftChar}]?\b({trimedItem})\b[{this.SourceInterpreter.QuotationRightChar}]?");

                                string quotedValue = $"{this.TargetInterpreter.QuotationLeftChar}{trimedItem}{this.TargetInterpreter.QuotationRightChar}";

                                if (!nestedToken.Symbol.Contains(quotedValue))
                                {
                                    bool doubleQuotationMatched = doubleQuotationRegex.IsMatch(nestedToken.Symbol);

                                    if (doubleQuotationMatched)
                                    {
                                        nestedToken.Symbol = doubleQuotationRegex.Replace(nestedToken.Symbol, trimedItem);
                                    }

                                    bool matched = matchRegex.IsMatch(nestedToken.Symbol);

                                    if (matched)
                                    {
                                        nestedToken.Symbol = matchRegex.Replace(nestedToken.Symbol, quotedValue);

                                        replacedSymbols.Add(token.Symbol);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            #endregion

            this.Script.Owner = null;

            this.Script.Name.Symbol = this.TargetInterpreter.GetQuotedString(this.DbObject.Name);
        }