예제 #1
0
        /**
         * Generate SQL tokens.
         *
         * @param sqlStatementContext SQL statement context
         * @param parameters SQL parameters
         * @param schemaMetaData schema meta data
         * @return SQL tokens
         */
        public ICollection <SqlToken> GenerateSqlTokens(ISqlCommandContext <ISqlCommand> sqlCommandContext, ParameterContext parameterContext, SchemaMetaData schemaMetaData)
        {
            ICollection <SqlToken> result = new LinkedList <SqlToken>();

            foreach (var sqlTokenGenerator in _sqlTokenGenerators)
            {
                SetUpSqlTokenGenerator(sqlTokenGenerator, parameterContext, schemaMetaData, result);
                if (!sqlTokenGenerator.IsGenerateSqlToken(sqlCommandContext))
                {
                    continue;
                }

                if (sqlTokenGenerator is IOptionalSqlTokenGenerator optionalSqlTokenGenerator)
                {
                    SqlToken sqlToken = optionalSqlTokenGenerator.GenerateSqlToken(sqlCommandContext);
                    if (!result.Contains(sqlToken))
                    {
                        result.Add(sqlToken);
                    }
                }
                else if (sqlTokenGenerator is ICollectionSqlTokenGenerator collectionSqlTokenGenerator)
                {
                    result.AddAll(collectionSqlTokenGenerator.GenerateSqlTokens(sqlCommandContext));
                }
            }

            return(result);
        }
        private IDictionary <Column, ICollection <IRouteValue> > CreateRouteValueMap(
            ISqlCommandContext <ISqlCommand> sqlCommandContext, AndPredicateSegment andPredicate,
            ParameterContext parameterContext)
        {
            IDictionary <Column, ICollection <IRouteValue> > result = new Dictionary <Column, ICollection <IRouteValue> >();

            foreach (var predicate in andPredicate.GetPredicates())
            {
                var tableName = sqlCommandContext.GetTablesContext()
                                .FindTableName(predicate.GetColumn(), schemaMetaData);
                if (tableName == null ||
                    !shardingRule.IsShardingColumn(predicate.GetColumn().GetIdentifier().GetValue(), tableName))
                {
                    continue;
                }

                Column column     = new Column(predicate.GetColumn().GetIdentifier().GetValue(), tableName);
                var    routeValue =
                    ConditionValueGeneratorFactory.Generate(predicate.GetPredicateRightValue(), column,
                                                            parameterContext);
                if (routeValue == null)
                {
                    continue;
                }

                if (!result.ContainsKey(column))
                {
                    result.Add(column, new LinkedList <IRouteValue>());
                }

                result[column].Add(routeValue);
            }

            return(result);
        }
 public ShardingStandardRoutingEngine(string logicTableName, ISqlCommandContext <ISqlCommand> sqlCommandContext, ShardingConditions shardingConditions, ConfigurationProperties properties)
 {
     this.LogicTableName     = logicTableName;
     this.SqlCommandContext  = sqlCommandContext;
     this.ShardingConditions = shardingConditions;
     this.Properties         = properties;
 }
예제 #4
0
 public TableToken(int startIndex, int stopIndex, IdentifierValue identifier, ISqlCommandContext <ISqlCommand> sqlCommandContext, ShardingRule shardingRule) : base(startIndex)
 {
     this.stopIndex         = stopIndex;
     this.identifier        = identifier;
     this.sqlCommandContext = sqlCommandContext;
     this.shardingRule      = shardingRule;
 }
 public ShardingComplexRoutingEngine(ICollection <string> logicTables, ISqlCommandContext <ISqlCommand> sqlStatementContext, ShardingConditions shardingConditions, ConfigurationProperties properties)
 {
     this.logicTables         = logicTables;
     this.sqlStatementContext = sqlStatementContext;
     this.shardingConditions  = shardingConditions;
     this.properties          = properties;
 }
        /**
         * Create sharding conditions.
         *
         * @param sqlStatementContext SQL statement context
         * @param parameters SQL parameters
         * @return sharding conditions
         */
        public List <ShardingCondition> CreateShardingConditions(ISqlCommandContext <ISqlCommand> sqlCommandContext,
                                                                 ParameterContext parameterContext)
        {
            if (sqlCommandContext is IWhereAvailable whereAvailable)
            {
                var whereSegment = whereAvailable.GetWhere();
                if (whereSegment != null)
                {
                    var shardingConditions = CreateShardingConditions(sqlCommandContext,
                                                                      whereSegment.GetAndPredicates(), parameterContext);
                    return(new List <ShardingCondition>(shardingConditions));
                }
            }

            return(new List <ShardingCondition>(0));

            // FIXME process subquery
            //        ICollection<SubqueryPredicateSegment> subqueryPredicateSegments = sqlStatementContext.findSQLSegments(SubqueryPredicateSegment.class);
            //        for (SubqueryPredicateSegment each : subqueryPredicateSegments) {
            //            ICollection<ShardingCondition> subqueryShardingConditions = createShardingConditions((WhereSegmentAvailable) sqlStatementContext, each.getAndPredicates(), parameters);
            //            if (!result.containsAll(subqueryShardingConditions)) {
            //                result.addAll(subqueryShardingConditions);
            //            }
            //        }
        }
 private static bool IsDCLForSingleTable(ISqlCommandContext <ISqlCommand> sqlCommandContext)
 {
     if (sqlCommandContext is ITableAvailable tableAvailable)
     {
         return(1 == tableAvailable.GetAllTables().Count&& !"*".Equals(tableAvailable.GetAllTables().First().GetTableName().GetIdentifier().GetValue()));
     }
     return(false);
 }
 private static IShardingRouteEngine GetDCLRoutingEngine(ISqlCommandContext <ISqlCommand> sqlCommandContext, ShardingConnectorMetaData metaData)
 {
     if (IsDCLForSingleTable(sqlCommandContext))
     {
         return(new ShardingTableBroadcastRoutingEngine(metaData.Schema, sqlCommandContext));
     }
     return(new ShardingMasterInstanceBroadcastRoutingEngine(metaData.DataSources));
 }
예제 #9
0
        public ICollection <SqlToken> GenerateSqlTokens(ISqlCommandContext <ISqlCommand> sqlCommandContext)
        {
            if (sqlCommandContext is ITableAvailable tableAvailable)
            {
                return(GenerateSqlTokens(tableAvailable));
            }

            return(new List <SqlToken>(0));
        }
예제 #10
0
        public void Rewrite(IParameterBuilder parameterBuilder, ISqlCommandContext <ISqlCommand> sqlCommandContext, ParameterContext parameterContext)
        {
            var selectCommandContext = ((SelectCommandContext)sqlCommandContext);
            var pagination           = selectCommandContext.GetPaginationContext();

            pagination.GetOffsetParameterIndex().IfPresent(offsetParameterIndex => RewriteOffset(pagination, offsetParameterIndex.Value, (StandardParameterBuilder)parameterBuilder));
            pagination.GetRowCountParameterIndex().IfPresent(
                rowCountParameterIndex => rewriteRowCount(pagination, rowCountParameterIndex.Value, (StandardParameterBuilder)parameterBuilder, selectCommandContext));
        }
예제 #11
0
 private IStreamDataReader Merge(List <IStreamDataReader> streamDataReaders, ISqlCommandContext <ISqlCommand> sqlCommandContext)
 {
     foreach (var engineEntry in _engines)
     {
         if (engineEntry.Value is IResultMergerEngine resultMergerEngine)
         {
             var resultMerger = resultMergerEngine.NewInstance(_databaseType, engineEntry.Key, _properties, sqlCommandContext);
             return(resultMerger.Merge(streamDataReaders, sqlCommandContext, _schemaMetaData));
         }
     }
     return(null);
 }
        protected MemoryMergedDataReader(T rule, SchemaMetaData schemaMetaData,
                                         ISqlCommandContext <ISqlCommand> sqlCommandContext, List <IStreamDataReader> streamDataReaders)
        {
            // ReSharper disable once VirtualMemberCallInConstructor
            var memoryQueryResultRowList = Init(rule, schemaMetaData, sqlCommandContext, streamDataReaders);

            _memoryResultSetRows = memoryQueryResultRowList.GetEnumerator();
            if (memoryQueryResultRowList.Any())
            {
                _currentSetResultRow = memoryQueryResultRowList.First();
            }
        }
예제 #13
0
 /// <summary>
 /// 记录sql
 /// </summary>
 /// <param name="logicSql"></param>
 /// <param name="showSimple">简单记录</param>
 /// <param name="sqlCommandContext"></param>
 /// <param name="executionUnits"></param>
 public static void LogSql(string logicSql, bool showSimple, ISqlCommandContext <ISqlCommand> sqlCommandContext, ICollection <ExecutionUnit> executionUnits)
 {
     _logger.LogInformation($"Logic SQL: {logicSql}");
     _logger.LogInformation($"SqlCommand: {sqlCommandContext.GetSqlCommand()}");
     if (showSimple)
     {
         LogSimpleMode(executionUnits);
     }
     else
     {
         LogNormalMode(executionUnits);
     }
 }
예제 #14
0
 private ShardingConditions GetShardingConditions(ParameterContext parameterContext,
                                                  ISqlCommandContext <ISqlCommand> sqlStatementContext, SchemaMetaData schemaMetaData, ShardingRule shardingRule)
 {
     if (sqlStatementContext.GetSqlCommand() is DMLCommand)
     {
         if (sqlStatementContext is InsertCommandContext insertCommandContext)
         {
             return(new ShardingConditions(new InsertClauseShardingConditionEngine(shardingRule).CreateShardingConditions(insertCommandContext, parameterContext)));
         }
         return(new ShardingConditions(new WhereClauseShardingConditionEngine(shardingRule, schemaMetaData).CreateShardingConditions(sqlStatementContext, parameterContext)));
     }
     return(new ShardingConditions(new List <ShardingCondition>(0)));
 }
        public IStreamDataReader Merge(List <IStreamDataReader> streamDataReaders, ISqlCommandContext <ISqlCommand> sqlCommandContext, SchemaMetaData schemaMetaData)
        {
            if (1 == streamDataReaders.Count)
            {
                return(new IteratorStreamMergedDataReader(streamDataReaders));
            }
            IDictionary <string, int> columnLabelIndexMap = GetColumnLabelIndexMap(streamDataReaders[0]);
            var selectCommandContext = (SelectCommandContext)sqlCommandContext;

            selectCommandContext.SetIndexes(columnLabelIndexMap);
            var mergedEnumerator = Build(streamDataReaders, selectCommandContext, columnLabelIndexMap, schemaMetaData);

            return(Decorate(streamDataReaders, selectCommandContext, mergedEnumerator));
        }
        public ICollection <SqlToken> GenerateSqlTokens(ISqlCommandContext <ISqlCommand> sqlCommandContext)
        {
            ICollection <SqlToken> result = new LinkedList <SqlToken>();

            if (sqlCommandContext is IIndexAvailable indexAvailable)
            {
                foreach (var index in indexAvailable.GetIndexes())
                {
                    result.Add(new IndexToken(index.GetStartIndex(), index.GetStopIndex(), index.Identifier, sqlCommandContext, _shardingRule));
                }
            }

            return(result);
        }
예제 #17
0
        private IStreamDataReader Decorate(IStreamDataReader streamDataReader, ISqlCommandContext <ISqlCommand> sqlCommandContext)
        {
            IStreamDataReader result = null;

            foreach (var engineEntry in _engines)
            {
                if (engineEntry.Value is IResultDecoratorEngine <IBaseRule> resultDecoratorEngine)
                {
                    var resultDecorator = resultDecoratorEngine.NewInstance(_databaseType, _schemaMetaData, engineEntry.Key, _properties, sqlCommandContext);
                    result = null == result?resultDecorator.Decorate(streamDataReader, sqlCommandContext, _schemaMetaData) : resultDecorator.Decorate(result, sqlCommandContext, _schemaMetaData);
                }
            }
            return(result ?? streamDataReader);
        }
예제 #18
0
        /**
         * Process query results.
         *
         * @param queryResults query results
         * @param sqlStatementContext SQL statement context
         * @return merged result
         * @throws SQLException SQL exception
         */
        public IStreamDataReader Process(List <IStreamDataReader> streamDataReaders, ISqlCommandContext <ISqlCommand> sqlCommandContext)
        {
            var mergedResult         = Merge(streamDataReaders, sqlCommandContext);
            IStreamDataReader result = null;

            if (mergedResult != null)
            {
                result = Decorate(mergedResult, sqlCommandContext);
            }
            else
            {
                result = Decorate(streamDataReaders[0], sqlCommandContext);
            }
            return(result ?? new TransparentMergedDataReader(streamDataReaders[0]));
        }
예제 #19
0
        private RouteContext CreateRouteContext(string sql, ParameterContext parameterContext, bool useCache)
        {
            var sqlCommand = _parserEngine.Parse(sql, useCache);

            try
            {
                ISqlCommandContext <ISqlCommand> sqlCommandContext = SqlCommandContextFactory.NewInstance(_metaData.Schema, sql, parameterContext, sqlCommand);
                return(new RouteContext(sqlCommandContext, parameterContext, new RouteResult()));
                // TODO should pass parameters for master-slave
            }
            catch (IndexOutOfRangeException ex)
            {
                return(new RouteContext(new GenericSqlCommandContext <ISqlCommand>(sqlCommand), parameterContext, new RouteResult()));
            }
        }
예제 #20
0
 public bool IsGenerateSqlToken(ISqlCommandContext <ISqlCommand> sqlCommandContext)
 {
     if (sqlCommandContext.GetSqlCommand() is ShowTablesCommand showTablesCommand)
     {
         return(showTablesCommand.GetFromSchema() != null);
     }
     if (sqlCommandContext.GetSqlCommand() is ShowTableStatusCommand showTableStatusCommand)
     {
         return(showTableStatusCommand.GetFromSchema() != null);
     }
     if (sqlCommandContext.GetSqlCommand() is ShowColumnsCommand showColumnsCommand)
     {
         return(showColumnsCommand.GetFromSchema() != null);
     }
     return(false);
 }
 public SqlRewriteContext(SchemaMetaData schemaMetaData, ISqlCommandContext <ISqlCommand> sqlCommandContext, string sql, ParameterContext parameterContext)
 {
     this._schemaMetaData    = schemaMetaData;
     this._sqlCommandContext = sqlCommandContext;
     this._sql = sql;
     this._parameterContext = parameterContext;
     AddSqlTokenGenerators(new DefaultTokenGeneratorBuilder().GetSqlTokenGenerators());
     if (sqlCommandContext is InsertCommandContext insertCommandContext)
     {
         _parameterBuilder = new GroupedParameterBuilder(insertCommandContext.GetGroupedParameters());
     }
     else
     {
         _parameterBuilder = new StandardParameterBuilder(parameterContext);
     }
 }
예제 #22
0
 private void CheckSubQueryShardingValues(ISqlCommandContext <ISqlCommand> sqlStatementContext, ShardingRule shardingRule, ShardingConditions shardingConditions)
 {
     foreach (var tableName in sqlStatementContext.GetTablesContext().GetTableNames())
     {
         var tableRule = shardingRule.FindTableRule(tableName);
         if (tableRule != null && IsRoutingByHint(shardingRule, tableRule) &&
             HintManager.GetDatabaseShardingValues(tableName).Any() && HintManager.GetTableShardingValues(tableName).Any())
         {
             return;
         }
     }
     ShardingAssert.If(shardingConditions.Conditions.IsEmpty(), "Must have sharding column with subquery.");
     if (shardingConditions.Conditions.Count > 1)
     {
         ShardingAssert.Else(IsSameShardingCondition(shardingRule, shardingConditions), "Sharding value must same with subquery.");
     }
 }
예제 #23
0
 private void refreshMetaDataIfNeeded(ShardingRuntimeContext runtimeContext, ISqlCommandContext <ISqlCommand> sqlStatementContext)
 {
     if (null == sqlStatementContext)
     {
         return;
     }
     // if (sqlStatementContext instanceof CreateTableStatementContext) {
     //     refreshTableMetaData(runtimeContext, ((CreateTableStatementContext) sqlStatementContext).getSqlStatement());
     // } else if (sqlStatementContext instanceof AlterTableStatementContext) {
     //     refreshTableMetaData(runtimeContext, ((AlterTableStatementContext) sqlStatementContext).getSqlStatement());
     // } else if (sqlStatementContext instanceof DropTableStatementContext) {
     //     refreshTableMetaData(runtimeContext, ((DropTableStatementContext) sqlStatementContext).getSqlStatement());
     // } else if (sqlStatementContext instanceof CreateIndexStatementContext) {
     //     refreshTableMetaData(runtimeContext, ((CreateIndexStatementContext) sqlStatementContext).getSqlStatement());
     // } else if (sqlStatementContext instanceof DropIndexStatementContext) {
     //     refreshTableMetaData(runtimeContext, ((DropIndexStatementContext) sqlStatementContext).getSqlStatement());
     // }
 }
        private ICollection <ShardingCondition> CreateShardingConditions(
            ISqlCommandContext <ISqlCommand> sqlCommandContext, ICollection <AndPredicateSegment> andPredicates,
            ParameterContext parameterContext)
        {
            ICollection <ShardingCondition> result = new LinkedList <ShardingCondition>();

            foreach (var andPredicate in andPredicates)
            {
                var routeValueMap = CreateRouteValueMap(sqlCommandContext, andPredicate, parameterContext);
                if (routeValueMap.IsEmpty())
                {
                    return(new List <ShardingCondition>(0));
                }

                result.Add(CreateShardingCondition(routeValueMap));
            }

            return(result);
        }
예제 #25
0
        // public ICollection<SqlToken> GenerateSqlTokens(ISqlCommandContext<ISqlCommand> sqlCommandContext)
        // {
        //     if (sqlCommandContext.GetSqlCommand() is ShowTablesStatement) {
        //         Preconditions.checkState(((ShowTablesStatement) sqlStatementContext.getSqlStatement()).getFromSchema().isPresent());
        //         RemoveAvailable removeAvailable = ((ShowTablesStatement) sqlStatementContext.getSqlStatement()).getFromSchema().get();
        //         return Collections.singletonList(new RemoveToken(removeAvailable.getStartIndex(), removeAvailable.getStopIndex()));
        //     }
        //     if (sqlStatementContext.getSqlStatement() instanceof ShowTableStatusStatement) {
        //         Preconditions.checkState(((ShowTableStatusStatement) sqlStatementContext.getSqlStatement()).getFromSchema().isPresent());
        //         RemoveAvailable removeAvailable = ((ShowTableStatusStatement) sqlStatementContext.getSqlStatement()).getFromSchema().get();
        //         return Collections.singletonList(new RemoveToken(removeAvailable.getStartIndex(), removeAvailable.getStopIndex()));
        //     }
        //     if (sqlStatementContext.getSqlStatement() instanceof ShowColumnsStatement) {
        //         Preconditions.checkState(((ShowColumnsStatement) sqlStatementContext.getSqlStatement()).getFromSchema().isPresent());
        //         RemoveAvailable removeAvailable = ((ShowColumnsStatement) sqlStatementContext.getSqlStatement()).getFromSchema().get();
        //         return Collections.singletonList(new RemoveToken(removeAvailable.getStartIndex(), removeAvailable.getStopIndex()));
        //     }
        //     return Collections.emptyList();
        // }
        //
        // public bool IsGenerateSqlToken(ISqlCommandContext<ISqlCommand> sqlCommandContext)
        // {if (sqlStatementContext.getSqlStatement() instanceof ShowTablesStatement) {
        //         return ((ShowTablesStatement) sqlStatementContext.getSqlStatement()).getFromSchema().isPresent();
        //     }
        //     if (sqlStatementContext.getSqlStatement() instanceof ShowTableStatusStatement) {
        //         return ((ShowTableStatusStatement) sqlStatementContext.getSqlStatement()).getFromSchema().isPresent();
        //     }
        //     if (sqlStatementContext.getSqlStatement() instanceof ShowColumnsStatement) {
        //         return ((ShowColumnsStatement) sqlStatementContext.getSqlStatement()).getFromSchema().isPresent();
        //     }
        //     return false;
        // }
        public ICollection <SqlToken> GenerateSqlTokens(ISqlCommandContext <ISqlCommand> sqlCommandContext)
        {
            if (sqlCommandContext.GetSqlCommand() is ShowTablesCommand showTablesCommand)
            {
                if (showTablesCommand.GetFromSchema() == null)
                {
                    throw new ArgumentNullException("showTablesCommand.GetFromSchema");
                }

                var removeAvailable = showTablesCommand.GetFromSchema();
                return(new List <SqlToken>()
                {
                    new RemoveToken(removeAvailable.GetStartIndex(), removeAvailable.GetStopIndex())
                });
            }
            if (sqlCommandContext.GetSqlCommand() is ShowTableStatusCommand showTableStatusCommand)
            {
                if (showTableStatusCommand.GetFromSchema() == null)
                {
                    throw new ArgumentNullException("showTableStatusCommand.GetFromSchema");
                }
                var removeAvailable = showTableStatusCommand.GetFromSchema();
                return(new List <SqlToken>()
                {
                    new RemoveToken(removeAvailable.GetStartIndex(), removeAvailable.GetStopIndex())
                });
            }
            if (sqlCommandContext.GetSqlCommand() is ShowColumnsCommand showColumnsCommand)
            {
                if (showColumnsCommand.GetFromSchema() == null)
                {
                    throw new ArgumentNullException("showColumnsCommand.GetFromSchema");
                }
                var removeAvailable = showColumnsCommand.GetFromSchema();
                return(new List <SqlToken>()
                {
                    new RemoveToken(removeAvailable.GetStartIndex(), removeAvailable.GetStopIndex())
                });
            }
            return(new List <SqlToken>(0));
        }
예제 #26
0
        public IStreamDataReader Merge(List <IStreamDataReader> streamDataReaders, ISqlCommandContext <ISqlCommand> sqlCommandContext, SchemaMetaData schemaMetaData)
        {
            var dalStatement = sqlCommandContext.GetSqlCommand();

            if (dalStatement is ShowDatabasesCommand showDatabasesCommand)
            {
                return(new SingleLocalDataMergedDataReader(new List <object>()
                {
                    DefaultSchema.LOGIC_NAME
                }));
            }
            if (dalStatement is ShowTablesCommand || dalStatement is ShowTableStatusCommand || dalStatement is ShowIndexCommand)
            {
                return(new LogicTablesMergedDataReader(shardingRule, schemaMetaData, sqlCommandContext, streamDataReaders));
            }
            if (dalStatement is ShowCreateTableCommand)
            {
                return(new ShowCreateTableMergedDataReader(shardingRule, schemaMetaData, sqlCommandContext, streamDataReaders));
            }
            return(new TransparentMergedDataReader(streamDataReaders[0]));
        }
        public void Rewrite(IParameterBuilder parameterBuilder, ISqlCommandContext <ISqlCommand> sqlCommandContext, ParameterContext parameterContext)
        {
            var insertCommandContext = (InsertCommandContext)sqlCommandContext;

            ShardingAssert.ShouldBeNotNull(insertCommandContext.GetGeneratedKeyContext(), "insertCommandContext.GetGeneratedKeyContext is required");
            ((GroupedParameterBuilder)parameterBuilder).SetDerivedColumnName(insertCommandContext.GetGeneratedKeyContext().GetColumnName());
            var generatedValues = insertCommandContext.GetGeneratedKeyContext().GetGeneratedValues().Reverse().GetEnumerator();
            int count           = 0;
            int parametersCount = 0;

            foreach (var groupedParameter in insertCommandContext.GetGroupedParameters())
            {
                parametersCount += insertCommandContext.GetInsertValueContexts()[count].GetParametersCount();
                var generatedValue = generatedValues.Next();
                if (!groupedParameter.IsEmpty())
                {
                    ((GroupedParameterBuilder)parameterBuilder).GetParameterBuilders()[count].AddAddedParameters(parametersCount, new List <object>()
                    {
                        generatedValue
                    });
                }
                count++;
            }
        }
예제 #28
0
 public IStreamDataReader Merge(List <IStreamDataReader> streamDataReaders, ISqlCommandContext <ISqlCommand> sqlCommandContext, SchemaMetaData schemaMetaData)
 {
     return(new TransparentMergedDataReader(streamDataReaders[0]));
 }
예제 #29
0
 public bool IsGenerateSqlToken(ISqlCommandContext <ISqlCommand> sqlCommandContext)
 {
     return(sqlCommandContext is SelectCommandContext selectCommandContext && GetDerivedProjectionTexts(selectCommandContext).Any());
 }
예제 #30
0
 public SqlToken GenerateSqlToken(ISqlCommandContext <ISqlCommand> sqlCommandContext)
 {
     return(GenerateSqlToken((SelectCommandContext)sqlCommandContext));
 }