public async Task <CommitsLoad> LoadCommitsAsync(string streamId) { Expect.NotDisposed(isDisposed); Expect.NotEmpty(streamId, "streamId"); var routingInfo = routing.CreateRoutingInfo(streamId); return(await Execute(async() => { var result = new List <Commit>(); var conn = await GetOrCreateOpenedConnection(routingInfo).ConfigureAwait(false); using (var cmd = SqlCommands.Load(streamId, routingInfo.Partition, schema)) { cmd.Connection = conn; using (var reader = await cmd.ExecuteReaderAsync().ConfigureAwait(false)) { while (reader.Read()) { var commit = ReadRowAsCommit(reader); result.Add(commit); } } } var commits = result.OrderBy(c => c.Version).ToArray(); return commits.Length > 0 ? new CommitsLoad(commits, commits.Last().Version) : CommitsLoad.Empty; }).ConfigureAwait(false)); }
internal static string EnsureStorageForTests(string connectionString, PartitionMap partitionMap) { var schema = "test" + Guid.NewGuid().ToString("N").Substring(0, 8); var source = partitionMap.Hosts.Select(x => { var cb = new NpgsqlConnectionStringBuilder(connectionString) { Host = x.Host, Port = x.Port, Enlist = false, }; return(Builder: cb, x.Partitions); }); Parallel.ForEach(source, src => { using (var conn = new NpgsqlConnection(src.Builder.ToString())) { conn.Open(); using (var cmd = SqlCommands.EnsureSchema(schema, src.Builder.Username)) { cmd.Connection = conn; cmd.ExecuteNonQuery(); } using (var cmd = SqlCommands.EnsureStorage(src.Partitions, schema)) { cmd.Connection = conn; cmd.ExecuteNonQuery(); } } }); return(schema); }
public async Task <bool> SaveAsync(Commit commit) { Expect.NotDisposed(isDisposed); Expect.NotNull(commit, "commit"); commit.ThrowIfContainsInvalidData(); var routingInfo = routing.CreateRoutingInfo(commit.StreamId); return(await Execute(async() => { var conn = await GetOrCreateOpenedConnection(routingInfo).ConfigureAwait(false); using (var cmd = SqlCommands.Save(commit, routingInfo.Partition, schema)) { cmd.Connection = conn; try { var affected = await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); return affected == 1; } catch (PostgresException ex) { if (ex.SqlState == PgsqlCodeOnDuplicateRec) { throw ToVersionConflict(ex); } throw; } } }).ConfigureAwait(false)); }
/// <summary> /// Creates partition (table) in the host if it does not exists. /// It also creates database schema if it is missing (before it creates the table). /// </summary> /// <param name="connection">database connection string</param> /// <param name="schema">database schema name</param> /// <param name="partition">partition number</param> public async ValueTask <bool> EnsureStorageIsReadyAsync(NpgsqlConnection connection, string schema, int partition = 0) { var key = $"{connection.Host}:{connection.Port}/{schema}/{partition}"; if (FinishedInits.Contains(key)) { return(false); } try { await InitLock.WaitAsync().ConfigureAwait(false); if (FinishedInits.Contains(key)) { return(false); } try { // Initialization of internal database tables needs to be created in new dedicated connection // which doesn't enlist to any ambient transactions. var connBuilder = new NpgsqlConnectionStringBuilder(connection.ConnectionString) { Enlist = false, }; var owner = connection.GetUserId(); using (var conn = new NpgsqlConnection(connBuilder.ToString())) using (var cmd = SqlCommands.EnsureStorage(partition, owner, schema)) { await conn.OpenAsync().ConfigureAwait(false); cmd.Connection = conn; await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); } } catch (PostgresException ex) { if (ex.SqlState != "42P07") // 42P07 = duplicate table { throw; } } FinishedInits.Add(key); return(true); } finally { InitLock.Release(); } }
internal static void DeleteStorageAfterTests(string connectionString, string schema) { var connBuilder = new NpgsqlConnectionStringBuilder(connectionString) { Enlist = false, }; using (var conn = new NpgsqlConnection(connBuilder.ToString())) using (var cmd = SqlCommands.DropSchemaIfExists(schema)) { conn.Open(); cmd.Connection = conn; cmd.ExecuteNonQuery(); } }
public async Task <bool> DeleteAsync(string streamId) { Expect.NotDisposed(isDisposed); Expect.NotEmpty(streamId, "streamId"); var routingInfo = routing.CreateRoutingInfo(streamId); return(await Execute(async() => { var conn = await GetOrCreateOpenedConnection(routingInfo).ConfigureAwait(false); using (var cmd = SqlCommands.Delete(streamId, routingInfo.Partition, schema)) { cmd.Connection = conn; var affected = await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); return affected == 1; } }).ConfigureAwait(false)); }
internal static string EnsureStorageForTests(string connectionString, string schema = null) { schema ??= "test" + Guid.NewGuid().ToString("N").Substring(0, 8); var cb = new NpgsqlConnectionStringBuilder(connectionString) { Enlist = false, }; try { using (var conn = new NpgsqlConnection(cb.ToString())) { conn.Open(); using (var cmd = SqlCommands.EnsureSchema(schema, cb.Username)) { cmd.Connection = conn; cmd.ExecuteNonQuery(); } using (var cmd = SqlCommands.EnsureStorage(schema)) { cmd.Connection = conn; cmd.ExecuteNonQuery(); } } } catch (PostgresException ex) { if (!IsThrownBecauseItAlreadyExists(ex)) { throw; } } return(schema); }