public void BulkInsert <T>(IReadOnlyCollection <T> documents, BulkInsertMode mode = BulkInsertMode.InsertsOnly, int batchSize = 1000) { if (typeof(T) == typeof(object)) { BulkInsertDocuments(documents.OfType <object>(), mode: mode); } else { using (var conn = _tenant.CreateConnection()) { conn.Open(); var tx = conn.BeginTransaction(); try { bulkInsertDocuments(documents, batchSize, conn, mode); tx.Commit(); } catch (Exception) { tx.Rollback(); throw; } } } }
public void CompletelyRemove(Type documentType) { var mapping = _options.Storage.MappingFor(documentType); using (var conn = _tenant.CreateConnection()) { conn.Open(); mapping.RemoveAllObjects(_options.DdlRules, conn); } }
public FunctionBody DefinitionForFunction(DbObjectName function) { var sql = @" SELECT pg_get_functiondef(pg_proc.oid) FROM pg_proc JOIN pg_namespace as ns ON pg_proc.pronamespace = ns.oid WHERE ns.nspname = :schema and proname = :function; SELECT format('DROP FUNCTION %s.%s(%s);' ,n.nspname ,p.proname ,pg_get_function_identity_arguments(p.oid)) FROM pg_proc p LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE p.proname = :function AND n.nspname = :schema; "; using (var conn = _tenant.CreateConnection()) { conn.Open(); try { var cmd = conn.CreateCommand().Sql(sql) .With("schema", function.Schema) .With("function", function.Name); using (var reader = cmd.ExecuteReader()) { if (!reader.Read()) { return(null); } var definition = reader.GetString(0); reader.NextResult(); var drops = new List <string>(); while (reader.Read()) { drops.Add(reader.GetString(0)); } return(new FunctionBody(function, drops.ToArray(), definition)); } } finally { conn.Close(); } } }
public async Task <T> Query <T>(ISingleQueryHandler <T> handler, CancellationToken cancellation) { using var conn = _tenant.CreateConnection(); var command = handler.BuildCommand(); command.Connection = conn; await conn.OpenAsync(cancellation); using var reader = await command.ExecuteReaderAsync(cancellation); return(await handler.HandleAsync(reader, cancellation)); }
public void Where <T>(string transformName, Expression <Func <T, bool> > @where) { var transform = _tenant.TransformFor(transformName); var mapping = _tenant.MappingFor(typeof(T)); var whereFragment = findWhereFragment(@where, mapping); var cmd = CommandBuilder.BuildCommand(sql => { writeBasicSql(sql, mapping, transform); if (whereFragment != null) { sql.Append(" where "); whereFragment.Apply(sql); } }); using (var conn = _tenant.CreateConnection()) { conn.Open(); var tx = conn.BeginTransaction(IsolationLevel.ReadCommitted); cmd.Connection = conn; cmd.Transaction = tx; cmd.ExecuteNonQuery(); tx.Commit(); } }
private void CreateDb(ITenant tenant, TenantDatabaseCreationExpressions config) { string catalog; var maintenanceDb = _maintenanceDbConnectionString; using (var t = tenant.CreateConnection()) { catalog = t.Database; if (maintenanceDb == null) { var cstringBuilder = new NpgsqlConnectionStringBuilder(t.ConnectionString); cstringBuilder.Database = "postgres"; maintenanceDb = cstringBuilder.ToString(); } var noExistingDb = config.CheckAgainstCatalog ? new Func <bool>(() => IsNotInPgDatabase(catalog, maintenanceDb)) : (() => CannotConnectDueToInvalidCatalog(t)); if (noExistingDb()) { CreateDb(catalog, config, false, maintenanceDb); return; } } if (config.DropExistingDatabase) { CreateDb(catalog, config, true, maintenanceDb); } }
private static void CreatePlv8Extension(ITenant tenant) { using (var connection = tenant.CreateConnection()) using (var cmd = connection.CreateCommand("CREATE EXTENSION IF NOT EXISTS plv8")) { connection.Open(); cmd.ExecuteNonQuery(); connection.Close(); } }
public async Task SetFloor(long floor) { var numberOfPages = (long)Math.Ceiling((double)floor / MaxLo); var updateSql = $"update {_options.DatabaseSchemaName}.mt_hilo set hi_value = :floor where entity_name = :name"; // This guarantees that the hilo row exists await AdvanceToNextHi(); using var conn = _tenant.CreateConnection(); await conn.OpenAsync(); await conn.CreateCommand(updateSql) .With("floor", numberOfPages) .With("name", _entityName) .ExecuteNonQueryAsync(); // And again to get it where we need it to be await AdvanceToNextHi(); }
private static IManagedConnection buildManagedConnection(SessionOptions options, ITenant tenant, CommandRunnerMode commandRunnerMode) { // TODO -- this is all spaghetti code. Make this some kind of more intelligent state machine // w/ the logic encapsulated into SessionOptions // Hate crap like this, but if we don't control the transation, use External to direct // IManagedConnection not to call commit or rollback if (!options.OwnsTransactionLifecycle && commandRunnerMode != CommandRunnerMode.ReadOnly) { commandRunnerMode = CommandRunnerMode.External; } if (options.Connection != null || options.Transaction != null) { options.OwnsConnection = false; } if (options.Transaction != null) { options.Connection = options.Transaction.Connection; } #if NET46 || NETSTANDARD2_0 if (options.Connection == null && options.DotNetTransaction != null) { var connection = tenant.CreateConnection(); connection.Open(); options.OwnsConnection = true; options.Connection = connection; } if (options.DotNetTransaction != null) { options.Connection.EnlistTransaction(options.DotNetTransaction); options.OwnsTransactionLifecycle = false; } #endif if (options.Connection == null) { return(tenant.OpenConnection(commandRunnerMode, options.IsolationLevel, options.Timeout)); } else { return(new ManagedConnection(options, commandRunnerMode)); } }
internal static void RunSql(this ITenant tenant, string sql) { using var conn = tenant.CreateConnection(); conn.Open(); try { conn.CreateCommand().WithText(sql).ExecuteNonQuery(); } finally { conn.Close(); conn.Dispose(); } }
internal static async Task RunSqlAsync(this ITenant tenant, string sql) { using var conn = tenant.CreateConnection(); await conn.OpenAsync(); try { await conn.CreateCommand(sql).ExecuteNonQueryAsync(); } finally { await conn.CloseAsync(); conn.Dispose(); } }
private static void execute(this ITenant tenant, Action <NpgsqlConnection> action) { using (var conn = tenant.CreateConnection()) { conn.Open(); try { action(conn); } finally { conn.Close(); conn.Dispose(); } } }
private static T execute <T>(this ITenant tenant, Func <NpgsqlConnection, T> func) { using (var conn = tenant.CreateConnection()) { conn.Open(); try { return(func(conn)); } finally { conn.Close(); conn.Dispose(); } } }
private static IManagedConnection buildManagedConnection(SessionOptions options, ITenant tenant, CommandRunnerMode commandRunnerMode) { // Hate crap like this, but if we don't control the transation, use External to direct // IManagedConnection not to call commit or rollback if (!options.OwnsTransactionLifecycle && commandRunnerMode != CommandRunnerMode.ReadOnly) { commandRunnerMode = CommandRunnerMode.External; } if (options.Transaction != null) { options.Connection = options.Transaction.Connection; } #if NET46 || NETSTANDARD2_0 if (options.Connection == null && options.DotNetTransaction != null) { var connection = tenant.CreateConnection(); connection.Open(); options.Connection = connection; } if (options.DotNetTransaction != null) { options.Connection.EnlistTransaction(options.DotNetTransaction); options.OwnsTransactionLifecycle = false; } #endif if (options.Connection == null) { return(tenant.OpenConnection(commandRunnerMode, options.IsolationLevel, options.Timeout)); } else { return(new ManagedConnection(options, commandRunnerMode)); } }
private async Task <EventPage> fetchNextPage(long lastEncountered) { await using (var conn = _tenant.CreateConnection()) { try { await conn.OpenAsync(_token).ConfigureAwait(false); var lastPossible = lastEncountered + _options.PageSize; var cmd = conn.CreateCommand(_sql) .With("last", lastEncountered) .With("limit", lastPossible) .With("buffer", _settings.LeadingEdgeBuffer.TotalSeconds) .With("types", EventTypeNames, NpgsqlDbType.Array | NpgsqlDbType.Varchar); var page = await buildEventPage(lastEncountered, cmd).ConfigureAwait(false); if (page.Count == 0 || page.IsSequential()) { return(page); } var starting = page; await Task.Delay(250, _token).ConfigureAwait(false); page = await buildEventPage(lastEncountered, cmd).ConfigureAwait(false); while (!page.CanContinueProcessing(starting.Sequences)) { starting = page; page = await buildEventPage(lastEncountered, cmd).ConfigureAwait(false); } return(page); } finally { conn.Close(); } } }
public async Task DeleteAllDocumentsAsync() { using var conn = _tenant.CreateConnection(); await conn.OpenAsync(); var schemas = _options.Storage.AllSchemaNames(); var tables = await conn.ExistingTables("mt_%", schemas); if (!tables.Any()) { return; } var builder = new CommandBuilder(); foreach (var table in tables) { builder.Append($"truncate {table} cascade;"); } await builder.ExecuteNonQueryAsync(conn); }
private async Task <bool> tryToAttainLockAndStartShards() { bool gotLock = false; NpgsqlConnection conn = null; try { conn = _tenant.CreateConnection(); await conn.OpenAsync(_cancellation.Token); gotLock = (bool)await conn.CreateCommand("SELECT pg_try_advisory_lock(:id);") .With("id", _settings.DaemonLockId) .ExecuteScalarAsync(_cancellation.Token); if (!gotLock) { await conn.CloseAsync(); } } catch (Exception e) { conn?.SafeDispose(); _logger.LogError("Error trying to attain the async daemon lock", e); return(false); } if (gotLock) { _logger.LogInformation("Attained lock for the async daemon, attempting to start all shards"); try { await startAllProjections(conn); stopPollingForOwnership(); return(true); } catch (Exception ex) { _logger.LogError("Failure while trying to start all async projection shards", ex); } } else { _logger.LogDebug("Attempted to attain lock for async projections, but could not take leadership."); } if (_timer == null || !_timer.Enabled) { startPollingForOwnership(); } else { _timer.Start(); } return(false); }
public NpgsqlConnection CreateConnection() { return(_inner.CreateConnection()); }