예제 #1
0
        /// <summary>
        /// Set common parameters to SelectChanges Sql command
        /// </summary>
        internal void SetSelectChangesCommonParameters(SyncContext context, SyncTable syncTable, Guid?excludingScopeId, bool isNew, long?lastTimestamp, DbCommand selectIncrementalChangesCommand)
        {
            // Set the parameters
            DbSyncAdapter.SetParameterValue(selectIncrementalChangesCommand, "sync_min_timestamp", lastTimestamp);
            DbSyncAdapter.SetParameterValue(selectIncrementalChangesCommand, "sync_scope_id", excludingScopeId.HasValue ? (object)excludingScopeId.Value : DBNull.Value);

            // Check filters
            SyncFilter tableFilter = null;

            // Sqlite does not have any filter, since he can't be server side
            if (this.Provider.CanBeServerProvider)
            {
                tableFilter = syncTable.GetFilter();
            }

            var hasFilters = tableFilter != null;

            if (!hasFilters)
            {
                return;
            }

            // context parameters can be null at some point.
            var contexParameters = context.Parameters ?? new SyncParameters();

            foreach (var filterParam in tableFilter.Parameters)
            {
                var parameter = contexParameters.FirstOrDefault(p =>
                                                                p.Name.Equals(filterParam.Name, SyncGlobalization.DataSourceStringComparison));

                object val = parameter?.Value;

                DbSyncAdapter.SetParameterValue(selectIncrementalChangesCommand, filterParam.Name, val);
            }
        }
예제 #2
0
        /// <summary>
        /// Set common parameters to SelectChanges Sql command
        /// </summary>
        private void SetSelectChangesCommonParameters(SyncContext context, SyncTable syncTable, Guid?excludingScopeId, bool isNew, long lastTimestamp, DbCommand selectIncrementalChangesCommand)
        {
            // Generate the isNewScope Flag.
            var isNewScope = isNew ? 1 : 0;
            var isReinit   = context.SyncType == SyncType.Reinitialize ? 1 : 0;

            switch (context.SyncWay)
            {
            case SyncWay.Upload:
                // Overwrite if we are in Reinitialize mode (not RenitializeWithUpload)
                isNewScope    = context.SyncType == SyncType.Reinitialize ? 1 : isNewScope;
                lastTimestamp = context.SyncType == SyncType.Reinitialize ? 0 : lastTimestamp;
                isReinit      = context.SyncType == SyncType.Reinitialize ? 1 : 0;
                break;

            case SyncWay.Download:
                // Ovewrite on bot Reinitialize and ReinitializeWithUpload
                isNewScope    = context.SyncType != SyncType.Normal ? 1 : isNewScope;
                lastTimestamp = context.SyncType != SyncType.Normal ? 0 : lastTimestamp;
                isReinit      = context.SyncType != SyncType.Normal ? 1 : 0;
                break;

            default:
                break;
            }

            // Set the parameters
            DbTableManagerFactory.SetParameterValue(selectIncrementalChangesCommand, "sync_min_timestamp", lastTimestamp);
            DbTableManagerFactory.SetParameterValue(selectIncrementalChangesCommand, "sync_scope_id", excludingScopeId.HasValue ? (object)excludingScopeId.Value : DBNull.Value);

            // Check filters
            SyncFilter tableFilter = null;

            // Sqlite does not have any filter, since he can't be server side
            if (this.CanBeServerProvider)
            {
                tableFilter = syncTable.GetFilter();
            }

            var hasFilters = tableFilter != null;

            if (!hasFilters)
            {
                return;
            }

            // context parameters can be null at some point.
            var contexParameters = context.Parameters ?? new SyncParameters();

            foreach (var filterParam in tableFilter.Parameters)
            {
                var parameter = contexParameters.FirstOrDefault(p =>
                                                                p.Name.Equals(filterParam.Name, SyncGlobalization.DataSourceStringComparison));

                object val = parameter?.Value;

                DbTableManagerFactory.SetParameterValue(selectIncrementalChangesCommand, filterParam.Name, val);
            }
        }
        /// <summary>
        /// Get the correct Select changes command
        /// Can be either
        /// - SelectInitializedChanges              : All changes for first sync
        /// - SelectChanges                         : All changes filtered by timestamp
        /// - SelectInitializedChangesWithFilters   : All changes for first sync with filters
        /// - SelectChangesWithFilters              : All changes filtered by timestamp with filters
        /// </summary>
        private async Task <DbCommand> GetSelectChangesCommandAsync(SyncContext context, DbSyncAdapter syncAdapter, SyncTable syncTable, bool isNew)
        {
            DbCommand     selectIncrementalChangesCommand;
            DbCommandType dbCommandType;

            SyncFilter tableFilter = null;

            // Check if we have parameters specified

            // Sqlite does not have any filter, since he can't be server side
            if (this.CanBeServerProvider)
            {
                tableFilter = syncTable.GetFilter();
            }

            var hasFilters = tableFilter != null;

            // Determing the correct DbCommandType
            if (isNew && hasFilters)
            {
                dbCommandType = DbCommandType.SelectInitializedChangesWithFilters;
            }
            else if (isNew && !hasFilters)
            {
                dbCommandType = DbCommandType.SelectInitializedChanges;
            }
            else if (!isNew && hasFilters)
            {
                dbCommandType = DbCommandType.SelectChangesWithFilters;
            }
            else
            {
                dbCommandType = DbCommandType.SelectChanges;
            }

            // Get correct Select incremental changes command
            selectIncrementalChangesCommand = syncAdapter.GetCommand(dbCommandType, tableFilter);

            if (selectIncrementalChangesCommand == null)
            {
                throw new MissingCommandException(dbCommandType.ToString());
            }

            // Add common parameters
            await syncAdapter.SetCommandParametersAsync(dbCommandType, selectIncrementalChangesCommand, tableFilter);

            return(selectIncrementalChangesCommand);
        }
예제 #4
0
        /// <summary>
        /// Validates, that all column filters do refer to a an existing column of the target table
        /// </summary>
        /// <param name="filters"></param>
        /// <param name="tableDescription"></param>
        public static void ValidateColumnFilters(this SyncFilter filter, SyncTable tableDescription)
        {
            if (filter == null)
            {
                return;
            }

            // TODO : Validate column filters
            //foreach (var c in filters)
            //{
            //    if (c.IsVirtual)
            //        continue;

            //    var columnFilter = tableDescription.Columns[c.ColumnName];

            //    if (columnFilter == null)
            //        throw new InvalidExpressionException($"Column {c.ColumnName} does not exist in Table {tableDescription.TableName}");
            //}
        }
예제 #5
0
        /// <summary>
        /// Get the correct Select changes command
        /// Can be either
        /// - SelectInitializedChanges              : All changes for first sync
        /// - SelectChanges                         : All changes filtered by timestamp
        /// - SelectInitializedChangesWithFilters   : All changes for first sync with filters
        /// - SelectChangesWithFilters              : All changes filtered by timestamp with filters
        /// </summary>
        internal async Task <DbCommand> GetSelectChangesCommandAsync(SyncContext context, SyncTable syncTable, SyncSetup setup, bool isNew, DbConnection connection, DbTransaction transaction)
        {
            DbCommand     command;
            DbCommandType dbCommandType;

            SyncFilter tableFilter = null;

            var syncAdapter = this.GetSyncAdapter(syncTable, setup);

            // Check if we have parameters specified

            // Sqlite does not have any filter, since he can't be server side
            if (this.Provider.CanBeServerProvider)
            {
                tableFilter = syncTable.GetFilter();
            }

            var hasFilters = tableFilter != null;

            // Determing the correct DbCommandType
            if (isNew && hasFilters)
            {
                dbCommandType = DbCommandType.SelectInitializedChangesWithFilters;
            }
            else if (isNew && !hasFilters)
            {
                dbCommandType = DbCommandType.SelectInitializedChanges;
            }
            else if (!isNew && hasFilters)
            {
                dbCommandType = DbCommandType.SelectChangesWithFilters;
            }
            else
            {
                dbCommandType = DbCommandType.SelectChanges;
            }

            // Get correct Select incremental changes command
            command = await syncAdapter.GetCommandAsync(dbCommandType, connection, transaction, tableFilter);

            return(command);
        }
예제 #6
0
 /// <summary>
 /// Set parameters on a command
 /// </summary>
 public abstract Task SetCommandParametersAsync(DbCommandType commandType, DbCommand command, SyncFilter filter = null);
예제 #7
0
 /// <summary>
 /// Gets a command from the current adapter
 /// </summary>
 public abstract DbCommand GetCommand(DbCommandType commandType, SyncFilter filter = null);
 /// <summary>
 /// Add parameters to a command
 /// </summary>
 public abstract Task AddCommandParametersAsync(DbCommandType commandType, DbCommand command, DbConnection connection, DbTransaction transaction, SyncFilter filter = null);
 /// <summary>
 /// Gets a command from the current adapter
 /// </summary>
 public abstract (DbCommand Command, bool IsBatchCommand) GetCommand(DbCommandType commandType, SyncFilter filter = null);
        /// <summary>
        /// Get the command from provider, check connection is opened, affect connection and transaction
        /// Prepare the command parameters and add scope parameters
        /// </summary>
        public async Task <(DbCommand Command, bool IsBatch)> GetCommandAsync(DbCommandType commandType, DbConnection connection, DbTransaction transaction, SyncFilter filter = null)
        {
            // Create the key
            var commandKey = $"{connection.DataSource}-{connection.Database}-{this.TableDescription.GetFullName()}-{commandType}";

            var(command, isBatch) = GetCommand(commandType, filter);

            if (command == null)
            {
                return(null, false);
            }

            // Add Parameters
            await this.AddCommandParametersAsync(commandType, command, connection, transaction, filter).ConfigureAwait(false);

            if (command == null)
            {
                throw new MissingCommandException(commandType.ToString());
            }

            if (connection == null)
            {
                throw new MissingConnectionException();
            }

            if (connection.State != ConnectionState.Open)
            {
                throw new ConnectionClosedException(connection);
            }

            command.Connection  = connection;
            command.Transaction = transaction;

            // Get a lazy command instance
            var lazyCommand = commands.GetOrAdd(commandKey, k => new Lazy <SyncCommand>(() =>
            {
                var syncCommand = new SyncCommand(commandKey);
                return(syncCommand);
            }));

            // lazyCommand.Metadata is a boolean indicating if the command is already prepared on the server
            if (lazyCommand.Value.IsPrepared == true)
            {
                return(command, isBatch);
            }

            // Testing The Prepare() performance increase
            command.Prepare();

            // Adding this command as prepared
            lazyCommand.Value.IsPrepared = true;

            commands.AddOrUpdate(commandKey, lazyCommand, (key, lc) => new Lazy <SyncCommand>(() => lc.Value));

            return(command, isBatch);
        }
예제 #11
0
        /// <summary>
        /// Get the command from provider, check connection is opened, affect connection and transaction
        /// Prepare the command parameters and add scope parameters
        /// </summary>
        internal async Task <DbCommand> PrepareCommandAsync(DbCommandType commandType, DbConnection connection, DbTransaction transaction, SyncFilter filter = null)
        {
            // Create the key
            var commandKey = $"{connection.DataSource}-{connection.Database}-{this.TableDescription.GetFullName()}-{commandType}";

            // Get a lazy command instance
            var lazyCommand = commands.GetOrAdd(commandKey, k => new Lazy <DbCommand>(() => GetCommand(commandType, filter)));

            // Get the concrete instance
            var command = lazyCommand.Value;

            if (command == null)
            {
                throw new MissingCommandException(commandType.ToString());
            }

            if (connection == null)
            {
                throw new MissingConnectionException();
            }

            if (connection.State != ConnectionState.Open)
            {
                throw new ConnectionClosedException(connection);
            }

            command.Connection = connection;

            if (transaction != null)
            {
                command.Transaction = transaction;
            }

            // Add Parameters
            await this.AddCommandParametersAsync(commandType, command, connection, transaction, filter).ConfigureAwait(false);

            // Testing The Prepare() performance increase
            command.Prepare();

            return(command);
        }
예제 #12
0
 /// <summary>
 /// Set parameters on a command
 /// </summary>
 public abstract void SetCommandParameters(DbCommandType commandType, DbCommand command, SyncFilter filter = null);