Пример #1
0
        /// <summary>
        /// Stores the message with the given headers and body data, delaying it until the specified <paramref name="approximateDueTime" />
        /// </summary>
        public async Task Defer(DateTimeOffset approximateDueTime, Dictionary <string, string> headers, byte[] body)
        {
            using (var connection = await _connectionHelper.GetConnection())
            {
                using (var command = connection.CreateCommand())
                {
                    command.CommandText =
                        $@"INSERT INTO `{_tableName}` (`due_time`, `headers`, `body`) VALUES (@due_time, @headers, @body)";

                    command.Parameters.Add(command.CreateParameter("due_time", DbType.DateTime, approximateDueTime.ToUniversalTime().DateTime.AddSeconds(-1)));
                    command.Parameters.Add(command.CreateParameter("headers", DbType.String, _dictionarySerializer.SerializeToString(headers)));
                    command.Parameters.Add(command.CreateParameter("body", DbType.Binary, body));

                    await command.ExecuteNonQueryAsync().ConfigureAwait(false);
                }

                connection.Complete();
            }
        }
Пример #2
0
        /// <summary>
        /// Gets all destination addresses for the given topic
        /// </summary>
        public async Task <string[]> GetSubscriberAddresses(string topic)
        {
            using (var connection = await _connectionHelper.GetConnection())
                using (var command = connection.CreateCommand())
                {
                    command.CommandText = $@"select `address` from `{_tableName}` where `topic` = @topic";
                    command.Parameters.Add(command.CreateParameter("topic", DbType.String, topic));

                    var endpoints = new List <string>();

                    using (var reader = await command.ExecuteReaderAsync())
                    {
                        while (reader.Read())
                        {
                            endpoints.Add((string)reader["address"]);
                        }
                    }

                    return(endpoints.ToArray());
                }
        }
Пример #3
0
        private async Task CreateSchema()
        {
            using (var connection = await _connectionHelper.GetConnection())
            {
                var tableNames = connection.GetTableNames();

                if (tableNames.Contains(_tableName, StringComparer.OrdinalIgnoreCase))
                {
                    _log.Info("Database already contains a table named '{0}' - will not create anything", _tableName);
                    return;
                }

                _log.Info("Table '{0}' does not exist - it will be created now", _tableName);

                ExecuteCommands(connection, $@"
                    CREATE TABLE {_tableName}
                    (
                        `id` INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
                        `recipient` VARCHAR(200) CHARACTER SET UTF8 NOT NULL,
                        `priority` INT NOT NULL,
                        `expiration` DATETIME NOT NULL,
                        `visible` DATETIME NOT NULL,
                        `headers` MEDIUMBLOB NOT NULL,
                        `body` MEDIUMBLOB NOT NULL,
                        `process_id` CHAR(36) NULL,
                        PRIMARY KEY (`recipient`(128), `priority`, `id`)
                    );
                    ----
                    CREATE INDEX `idx_receive_{_tableName}` ON `{_tableName}`
                    (
                        `recipient`(128) ASC,
                        `priority` ASC,
                        `visible` ASC,
                        `expiration` ASC,
                        `id` ASC
                    );");

                connection.Complete();
            }
        }
        /// <summary>
        /// Archives the given saga data in MySql under its current ID and revision
        /// </summary>
        public async Task Save(ISagaData sagaData, Dictionary <string, string> sagaAuditMetadata)
        {
            using (var connection = await _connectionHelper.GetConnection())
            {
                using (var command = connection.CreateCommand())
                {
                    command.CommandText =
                        $@"
                            INSERT
                                INTO `{_tableName}` (`id`, `revision`, `data`, `metadata`)
                                VALUES (@id, @revision, @data, @metadata);

                            ";
                    command.Parameters.Add(command.CreateParameter("id", DbType.Guid, sagaData.Id));
                    command.Parameters.Add(command.CreateParameter("revision", DbType.Int32, sagaData.Revision));
                    command.Parameters.Add(command.CreateParameter("data", DbType.Binary, _objectSerializer.Serialize(sagaData)));
                    command.Parameters.Add(command.CreateParameter("metadata", DbType.String, _dictionarySerializer.SerializeToString(sagaAuditMetadata)));

                    await command.ExecuteNonQueryAsync();
                }

                connection.Complete();
            }
        }
        public static async Task DropTableIfExists(string tableName)
        {
            using (var connection = await MySqlConnectionHelper.GetConnection())
            {
                using (var comand = connection.CreateCommand())
                {
                    comand.CommandText = $@"drop table if exists `{tableName}`;";

                    try
                    {
                        comand.ExecuteNonQuery();

                        Console.WriteLine("Dropped mysql table '{0}'", tableName);
                    }
                    catch (MySqlException exception) when(exception.SqlState == TableDoesNotExist)
                    {
                    }
                }

                connection.Complete();
            }
        }
Пример #6
0
        /// <summary>
        /// Finds an already-existing instance of the given saga data type that has a property with the given <paramref name="propertyName" />
        /// whose value matches <paramref name="propertyValue" />. Returns null if no such instance could be found
        /// </summary>
        public async Task <ISagaData> Find(Type sagaDataType, string propertyName, object propertyValue)
        {
            using (var connection = await _connectionHelper.GetConnection())
            {
                using (var command = connection.CreateCommand())
                {
                    if (propertyName == IdPropertyName)
                    {
                        command.CommandText = $@"
                            SELECT s.`data`
                                FROM `{_dataTableName}` s
                                WHERE s.`id` = @id
                            ";
                        command.Parameters.Add(command.CreateParameter("id", DbType.Guid, ToGuid(propertyValue)));
                    }
                    else
                    {
                        command.CommandText =
                            $@"
                                SELECT s.`data`
                                    FROM `{_dataTableName}` s
                                    JOIN `{_indexTableName}` i on s.id = i.saga_id
                                    WHERE i.`saga_type` = @saga_type AND i.`key` = @key AND i.value = @value;
                                ";

                        command.Parameters.Add(command.CreateParameter("key", DbType.String, propertyName));
                        command.Parameters.Add(command.CreateParameter("saga_type", DbType.String, GetSagaTypeName(sagaDataType)));
                        command.Parameters.Add(command.CreateParameter("value", DbType.String, (propertyValue ?? "").ToString()));
                    }

                    var data = (byte[])await command.ExecuteScalarAsync();

                    if (data == null)
                    {
                        return(null);
                    }

                    try
                    {
                        var sagaData = (ISagaData)_objectSerializer.Deserialize(data);

                        if (!sagaDataType.GetTypeInfo().IsInstanceOfType(sagaData))
                        {
                            return(null);
                        }

                        return(sagaData);
                    }
                    catch (Exception exception)
                    {
                        var message =
                            $"An error occurred while attempting to deserialize '{data}' into a {sagaDataType}";

                        throw new RebusApplicationException(exception, message);
                    }
                    finally
                    {
                        connection.Complete();
                    }
                }
            }
        }