Beispiel #1
0
        public RelationalDatabaseWriter(SqlEtl etl, DocumentDatabase database)
            : base(etl.Configuration.FactoryName)
        {
            _etl                         = etl;
            _database                    = database;
            _logger                      = LoggingSource.Instance.GetLogger <RelationalDatabaseWriter>(_database.Name);
            _providerFactory             = GetDbProviderFactory(etl.Configuration);
            _commandBuilder              = _providerFactory.InitializeCommandBuilder();
            _connection                  = _providerFactory.CreateConnection();
            _connection.ConnectionString = etl.Configuration.Connection.ConnectionString;

            try
            {
                _connection.Open();
            }
            catch (Exception e)
            {
                database.NotificationCenter.Add(AlertRaised.Create(
                                                    database.Name,
                                                    SqlEtl.SqlEtlTag,
                                                    $"SQL ETL could not open connection to {_connection.ConnectionString}",
                                                    AlertType.SqlEtl_ConnectionError,
                                                    NotificationSeverity.Error,
                                                    key: _connection.ConnectionString,
                                                    details: new ExceptionDetails(e)));

                throw;
            }

            _tx = _connection.BeginTransaction();

            _stringParserList = GenerateStringParsers();
        }
Beispiel #2
0
        public async Task PostScriptTest()
        {
            using (Database.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                var dbDoc = await context.ReadForMemoryAsync(RequestBodyStream(), "TestSqlEtlScript");

                var testScript = JsonDeserializationServer.TestSqlEtlScript(dbDoc);

                var result = (SqlEtlTestScriptResult)SqlEtl.TestScript(testScript, Database, ServerStore, context);

                await using (var writer = new AsyncBlittableJsonTextWriter(context, ResponseBodyStream()))
                {
                    var djv = (DynamicJsonValue)TypeConverter.ToBlittableSupportedType(result);
                    writer.WriteObject(context.ReadObject(djv, "et/sql/test"));
                }
            }
        }
Beispiel #3
0
        public Task PostSimulateSqlReplication()
        {
            using (Database.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                context.OpenReadTransaction();

                var dbDoc = context.ReadForMemory(RequestBodyStream(), "SimulateSqlReplicationResult");
                var simulateSqlReplication = JsonDeserializationServer.SimulateSqlReplication(dbDoc);
                var result = SqlEtl.SimulateSqlEtl(simulateSqlReplication, Database, ServerStore, context);

                using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                {
                    var djv = (DynamicJsonValue)TypeConverter.ToBlittableSupportedType(result);
                    writer.WriteObject(context.ReadObject(djv, "et/sql/simulate"));
                }
            }

            return(Task.CompletedTask);
        }
Beispiel #4
0
        public RelationalDatabaseWriter(SqlEtl etl, DocumentDatabase database)
            : base(etl.Configuration.Connection.FactoryName)
        {
            _etl             = etl;
            _database        = database;
            _logger          = LoggingSource.Instance.GetLogger <RelationalDatabaseWriter>(_database.Name);
            _providerFactory = GetDbProviderFactory(etl.Configuration);
            _commandBuilder  = _providerFactory.InitializeCommandBuilder();
            _connection      = _providerFactory.CreateConnection();
            var connectionString = etl.Configuration.Connection.ConnectionString;

            _connection.ConnectionString = connectionString;

            OpenConnection(database, etl.Configuration.Name, etl.Configuration.ConnectionStringName);

            _tx = _connection.BeginTransaction();

            _stringParserList = GenerateStringParsers();
        }
Beispiel #5
0
        public async Task CanTestDeletion(bool performRolledBackTransaction)
        {
            using (var store = GetDocumentStore())
            {
                CreateRdbmsSchema(store);

                using (var session = store.OpenAsyncSession())
                {
                    await session.StoreAsync(new Order
                    {
                        OrderLines = new List <OrderLine>
                        {
                            new OrderLine {
                                Cost = 3, Product = "Milk", Quantity = 3
                            },
                            new OrderLine {
                                Cost = 4, Product = "Bear", Quantity = 2
                            },
                        }
                    });

                    await session.SaveChangesAsync();
                }

                var result1 = store.Maintenance.Send(new PutConnectionStringOperation <SqlConnectionString>(new SqlConnectionString()
                {
                    Name             = "simulate",
                    ConnectionString = GetConnectionString(store),
                    FactoryName      = "System.Data.SqlClient",
                }));
                Assert.NotNull(result1.RaftCommandIndex);

                var database = GetDatabase(store.Database).Result;

                using (database.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
                {
                    var result = (SqlEtlTestScriptResult)SqlEtl.TestScript(new TestSqlEtlScript
                    {
                        PerformRolledBackTransaction = performRolledBackTransaction,
                        DocumentId    = "orders/1-A",
                        IsDelete      = true,
                        Configuration = new SqlEtlConfiguration()
                        {
                            Name = "simulate",
                            ConnectionStringName = "simulate",
                            SqlTables            =
                            {
                                new SqlEtlTable {
                                    TableName = "Orders", DocumentIdColumn = "Id"
                                },
                                new SqlEtlTable {
                                    TableName = "OrderLines", DocumentIdColumn = "OrderId"
                                },
                                new SqlEtlTable {
                                    TableName = "NotUsedInScript", DocumentIdColumn = "OrderId"
                                },
                            },
                            Transforms =
                            {
                                new Transformation()
                                {
                                    Collections ={ "Orders"                   },
                                    Name        = "OrdersAndLines",
                                    Script      = defaultScript
                                }
                            }
                        }
                    }, database, database.ServerStore, context);

                    Assert.Equal(0, result.TransformationErrors.Count);
                    Assert.Equal(0, result.LoadErrors.Count);
                    Assert.Equal(0, result.SlowSqlWarnings.Count);

                    Assert.Equal(2, result.Summary.Count);

                    var orderLines = result.Summary.First(x => x.TableName == "OrderLines");

                    Assert.Equal(1, orderLines.Commands.Length); // delete

                    var orders = result.Summary.First(x => x.TableName == "Orders");

                    Assert.Equal(1, orders.Commands.Length); // delete
                }

                using (var session = store.OpenAsyncSession())
                {
                    Assert.NotNull(session.Query <Order>("orders/1-A"));
                }
            }
        }
Beispiel #6
0
        private IEnumerable <EtlProcess> GetRelevantProcesses <T, TConnectionString>(List <T> configurations, HashSet <string> uniqueNames) where T : EtlConfiguration <TConnectionString> where TConnectionString : ConnectionString
        {
            foreach (var config in configurations)
            {
                SqlEtlConfiguration   sqlConfig   = null;
                RavenEtlConfiguration ravenConfig = null;

                var connectionStringNotFound = false;

                switch (config.EtlType)
                {
                case EtlType.Raven:
                    ravenConfig = config as RavenEtlConfiguration;
                    if (_databaseRecord.RavenConnectionStrings.TryGetValue(config.ConnectionStringName, out var ravenConnection))
                    {
                        ravenConfig.Initialize(ravenConnection);
                    }
                    else
                    {
                        connectionStringNotFound = true;
                    }

                    break;

                case EtlType.Sql:
                    sqlConfig = config as SqlEtlConfiguration;
                    if (_databaseRecord.SqlConnectionStrings.TryGetValue(config.ConnectionStringName, out var sqlConnection))
                    {
                        sqlConfig.Initialize(sqlConnection);
                    }
                    else
                    {
                        connectionStringNotFound = true;
                    }

                    break;

                default:
                    ThrownUnknownEtlConfiguration(config.GetType());
                    break;
                }

                if (connectionStringNotFound)
                {
                    LogConfigurationError(config,
                                          new List <string>
                    {
                        $"Connection string named '{config.ConnectionStringName}' was not found for {config.EtlType} ETL"
                    });

                    continue;
                }

                if (config.Disabled)
                {
                    continue;
                }

                if (ValidateConfiguration(config, uniqueNames) == false)
                {
                    continue;
                }

                var processState  = GetProcessState(config.Transforms, _database, config.Name);
                var whoseTaskIsIt = _database.WhoseTaskIsIt(_databaseRecord.Topology, config, processState);
                if (whoseTaskIsIt != _serverStore.NodeTag)
                {
                    continue;
                }

                foreach (var transform in config.Transforms)
                {
                    if (transform.Disabled)
                    {
                        continue;
                    }

                    EtlProcess process = null;

                    if (sqlConfig != null)
                    {
                        process = new SqlEtl(transform, sqlConfig, _database, _serverStore);
                    }

                    if (ravenConfig != null)
                    {
                        process = new RavenEtl(transform, ravenConfig, _database, _serverStore);
                    }

                    yield return(process);
                }
            }
        }
Beispiel #7
0
        public async Task SimulationTest()
        {
            using (var store = GetDocumentStore())
            {
                CreateRdbmsSchema(store);

                using (var session = store.OpenAsyncSession())
                {
                    await session.StoreAsync(new Order
                    {
                        OrderLines = new List <OrderLine>
                        {
                            new OrderLine {
                                Cost = 3, Product = "Milk", Quantity = 3
                            },
                            new OrderLine {
                                Cost = 4, Product = "Bear", Quantity = 2
                            },
                        }
                    });

                    await session.SaveChangesAsync();
                }

                store.Maintenance.Send(new PutConnectionStringOperation <SqlConnectionString>(new SqlConnectionString()
                {
                    Name             = "simulate",
                    ConnectionString = GetConnectionString(store),
                }));

                var database = GetDatabase(store.Database).Result;

                using (database.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
                    using (context.OpenReadTransaction())
                    {
                        for (int i = 0; i < 2; i++)
                        {
                            var result = SqlEtl.SimulateSqlEtl(new SimulateSqlEtl
                            {
                                PerformRolledBackTransaction = i % 2 != 0,
                                DocumentId    = "orders/1-A",
                                Configuration = new SqlEtlConfiguration()
                                {
                                    Name = "simulate",
                                    ConnectionStringName = "simulate",
                                    FactoryName          = "System.Data.SqlClient",
                                    SqlTables            =
                                    {
                                        new SqlEtlTable {
                                            TableName = "Orders", DocumentIdColumn = "Id"
                                        },
                                        new SqlEtlTable {
                                            TableName = "OrderLines", DocumentIdColumn = "OrderId"
                                        },
                                    },
                                    Transforms =
                                    {
                                        new Transformation()
                                        {
                                            Collections ={ "Orders"                   },
                                            Name        = "OrdersAndLines",
                                            Script      = defaultScript
                                        }
                                    }
                                }
                            }, database, database.ServerStore, context);

                            Assert.Null(result.LastAlert);
                            Assert.Equal(2, result.Summary.Count);

                            var orderLines = result.Summary.First(x => x.TableName == "OrderLines");

                            Assert.Equal(3, orderLines.Commands.Length); // delete and two inserts

                            var orders = result.Summary.First(x => x.TableName == "Orders");

                            Assert.Equal(2, orders.Commands.Length); // delete and insert
                        }
                    }
            }
        }