Example #1
0
        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;
                    }
                }
            }
        }
Example #2
0
        public void CompletelyRemove(Type documentType)
        {
            var mapping = _options.Storage.MappingFor(documentType);

            using (var conn = _tenant.CreateConnection())
            {
                conn.Open();

                mapping.RemoveAllObjects(_options.DdlRules, conn);
            }
        }
Example #3
0
        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();
                }
            }
        }
Example #4
0
        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));
        }
Example #5
0
        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();
            }
        }
Example #6
0
        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);
            }
        }
Example #7
0
 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();
         }
 }
Example #8
0
        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();
        }
Example #9
0
        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));
            }
        }
Example #10
0
        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();
            }
        }
Example #11
0
        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();
            }
        }
Example #12
0
        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();
                }
            }
        }
Example #13
0
        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();
                }
            }
        }
Example #14
0
        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));
            }
        }
Example #15
0
        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();
                }
            }
        }
Example #16
0
        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);
        }
Example #18
0
 public NpgsqlConnection CreateConnection()
 {
     return(_inner.CreateConnection());
 }