Пример #1
0
        public Task GetTestSqlConnection()
        {
            try
            {
                var factoryName      = GetStringQueryString("factoryName", true);
                var connectionString = GetStringQueryString("connectionString", true);
                RelationalDatabaseWriter.TestConnection(factoryName, connectionString);
                HttpContext.Response.StatusCode = 204; // No Content
            }
            catch (Exception ex)
            {
                HttpContext.Response.StatusCode = 400; // Bad Request

                JsonOperationContext context;
                using (ContextPool.AllocateOperationContext(out context))
                {
                    using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                    {
                        context.Write(writer, new DynamicJsonValue
                        {
                            ["Error"]     = "Connection failed",
                            ["Exception"] = ex.ToString(),
                        });
                    }
                }
            }

            return(Task.CompletedTask);
        }
Пример #2
0
        public DynamicJsonValue Simulate(SimulateSqlReplication simulateSqlReplication, DocumentsOperationContext context, SqlReplicationScriptResult result)
        {
            if (simulateSqlReplication.PerformRolledBackTransaction)
            {
                using (var writer = new RelationalDatabaseWriter(_database, context, _predefinedSqlConnection, this))
                {
                    return(new DynamicJsonValue
                    {
                        ["Results"] = new DynamicJsonArray(writer.RolledBackExecute(result).ToArray()),
                        ["LastAlert"] = Statistics.LastAlert,
                    });
                }
            }

            var simulatedwriter     = new RelationalDatabaseWriterSimulator(_predefinedSqlConnection, this);
            var tableQuerySummaries = new List <RelationalDatabaseWriter.TableQuerySummary>
            {
                new RelationalDatabaseWriter.TableQuerySummary
                {
                    Commands = simulatedwriter.SimulateExecuteCommandText(result)
                               .Select(x => new RelationalDatabaseWriter.TableQuerySummary.CommandData
                    {
                        CommandText = x
                    }).ToArray()
                }
            }.ToArray();

            return(new DynamicJsonValue
            {
                ["Results"] = new DynamicJsonArray(tableQuerySummaries),
                ["LastAlert"] = Statistics.LastAlert,
            });
        }
Пример #3
0
        private bool ReplicateDeletionsToDestination(DocumentsOperationContext context)
        {
            var pageSize = int.MaxValue; // _database.Configuration.Indexing.MaxNumberOfTombstonesToFetch;

            var documents = _database.DocumentsStorage.GetTombstonesFrom(context, Configuration.Collection, Statistics.LastTombstonesEtag + 1, 0, pageSize).ToList();

            if (documents.Count == 0)
            {
                return(false);
            }

            Statistics.LastTombstonesEtag = documents.Last().Etag;

            var documentsKeys = documents.Select(tombstone => (string)tombstone.Key).ToList();

            using (var writer = new RelationalDatabaseWriter(_database, context, _predefinedSqlConnection, this))
            {
                foreach (var sqlReplicationTable in Configuration.SqlReplicationTables)
                {
                    writer.DeleteItems(sqlReplicationTable.TableName, sqlReplicationTable.DocumentKeyColumn, Configuration.ParameterizeDeletesDisabled, documentsKeys);
                }
                writer.Commit();
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Replicated deletes of " + string.Join(", ", documentsKeys) + " for config " + Configuration.Name);
                }
            }
            return(true);
        }
Пример #4
0
        private IEnumerable <string> GenerteInsertItemCommandText(string tableName, string pkName, List <ItemToReplicate> dataForTable)
        {
            foreach (var itemToReplicate in dataForTable)
            {
                var sb = new StringBuilder("INSERT INTO ")
                         .Append(GetTableNameString(tableName))
                         .Append(" (")
                         .Append(commandBuilder.QuoteIdentifier(pkName))
                         .Append(", ");
                foreach (var column in itemToReplicate.Columns)
                {
                    if (column.Key == pkName)
                    {
                        continue;
                    }
                    sb.Append(commandBuilder.QuoteIdentifier(column.Key)).Append(", ");
                }
                sb.Length = sb.Length - 2;


                sb.Append(") VALUES (")
                .Append(itemToReplicate.DocumentKey)
                .Append(", ");

                foreach (var column in itemToReplicate.Columns)
                {
                    if (column.Key == pkName)
                    {
                        continue;
                    }
                    DbParameter param = new SqlParameter();
                    RelationalDatabaseWriter.SetParamValue(param, column, null);
                    sb.Append("'").Append(param.Value).Append("'").Append(", ");
                }
                sb.Length = sb.Length - 2;
                sb.Append(")");
                if (IsSqlServerFactoryType && _sqlReplication.Configuration.ForceSqlServerQueryRecompile)
                {
                    sb.Append(" OPTION(RECOMPILE)");
                }

                sb.Append(";");

                yield return(sb.ToString());
            }
        }
Пример #5
0
        private IEnumerable <string> GenerateDeleteItemsCommandText(string tableName, string pkName, bool doNotParameterize, List <string> identifiers)
        {
            const int maxParams = 1000;

            _sqlReplication.CancellationToken.ThrowIfCancellationRequested();
            for (int i = 0; i < identifiers.Count; i += maxParams)
            {
                var sb = new StringBuilder("DELETE FROM ")
                         .Append(GetTableNameString(tableName))
                         .Append(" WHERE ")
                         .Append(commandBuilder.QuoteIdentifier(pkName))
                         .Append(" IN (");

                for (int j = i; j < Math.Min(i + maxParams, identifiers.Count); j++)
                {
                    if (i != j)
                    {
                        sb.Append(", ");
                    }
                    if (doNotParameterize == false)
                    {
                        sb.Append(identifiers[j]);
                    }
                    else
                    {
                        sb.Append("'").Append(RelationalDatabaseWriter.SanitizeSqlValue(identifiers[j])).Append("'");
                    }
                }
                sb.Append(")");

                if (IsSqlServerFactoryType && _sqlReplication.Configuration.ForceSqlServerQueryRecompile)
                {
                    sb.Append(" OPTION(RECOMPILE)");
                }

                sb.Append(";");
                yield return(sb.ToString());
            }
        }
Пример #6
0
        private bool ReplicateChangesToDestination(DocumentsOperationContext context, out int countOfReplicatedItems)
        {
            countOfReplicatedItems = 0;
            var pageSize = int.MaxValue; // _database.Configuration.Indexing.MaxNumberOfDocumentsToFetchForMap;

            var documents = _database.DocumentsStorage.GetDocumentsFrom(context, Configuration.Collection, Statistics.LastReplicatedEtag + 1, 0, pageSize).ToList();

            if (documents.Count == 0)
            {
                return(false);
            }

            Statistics.LastReplicatedEtag = documents.Last().Etag;

            var scriptResult = ApplyConversionScript(documents, context);

            if (scriptResult.Keys.Count == 0)
            {
                return(true);
            }

            countOfReplicatedItems = scriptResult.Data.Sum(x => x.Value.Count);
            try
            {
                using (var writer = new RelationalDatabaseWriter(_database, context, _predefinedSqlConnection, this))
                {
                    if (writer.ExecuteScript(scriptResult))
                    {
                        if (_logger.IsInfoEnabled)
                        {
                            _logger.Info("Replicated changes of " + string.Join(", ", documents.Select(d => d.Key)) + " for replication " + Configuration.Name);
                        }
                        Statistics.CompleteSuccess(countOfReplicatedItems);
                    }
                    else
                    {
                        if (_logger.IsInfoEnabled)
                        {
                            _logger.Info("Replicated changes (with some errors) of " + string.Join(", ", documents.Select(d => d.Key)) + " for replication " + Configuration.Name);
                        }
                        Statistics.Success(countOfReplicatedItems);
                    }
                }
                return(true);
            }
            catch (Exception e)
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Failure to replicate changes to relational database for: " + Configuration.Name, e);
                }

                DateTime newTime;
                if (Statistics.LastErrorTime == null)
                {
                    newTime = SystemTime.UtcNow.AddSeconds(5);
                }
                else
                {
                    // double the fallback time (but don't cross 15 minutes)
                    var totalSeconds = (SystemTime.UtcNow - Statistics.LastErrorTime.Value).TotalSeconds;
                    newTime = SystemTime.UtcNow.AddSeconds(Math.Min(60 * 15, Math.Max(5, totalSeconds * 2)));
                }
                Statistics.RecordWriteError(e, _database, countOfReplicatedItems, newTime);
                return(false);
            }
        }