Beispiel #1
0
        public async Task <IEnumerable <SwitchMembersListEntry> > GetSwitchMembersList(PKSystem system, Instant start, Instant end)
        {
            // Wrap multiple commands in a single transaction for performance
            using (var conn = await _conn.Obtain())
                using (var tx = conn.BeginTransaction())
                {
                    // Find the time of the last switch outside the range as it overlaps the range
                    // If no prior switch exists, the lower bound of the range remains the start time
                    var lastSwitch = await conn.QuerySingleOrDefaultAsync <Instant>(
                        @"SELECT COALESCE(MAX(timestamp), @Start)
                        FROM switches
                        WHERE switches.system = @System
                        AND switches.timestamp < @Start",
                        new { System = system.Id, Start = start });

                    // Then collect the time and members of all switches that overlap the range
                    var switchMembersEntries = await conn.QueryAsync <SwitchMembersListEntry>(
                        @"SELECT switch_members.member, switches.timestamp
                        FROM switches
                        LEFT JOIN switch_members
                        ON switches.id = switch_members.switch
                        WHERE switches.system = @System
                        AND (
	                        switches.timestamp >= @Start
	                        OR switches.timestamp = @LastSwitch
                        )
                        AND switches.timestamp < @End
                        ORDER BY switches.timestamp DESC",
                        new { System = system.Id, Start = start, End = end, LastSwitch = lastSwitch });

                    // Commit and return the list
                    tx.Commit();
                    return(switchMembersEntries);
                }
        }
Beispiel #2
0
        public async Task <AuxillaryProxyInformation> GetAuxillaryProxyInformation(ulong guild, PKSystem system, PKMember member)
        {
            using var conn = await _conn.Obtain();

            var args = new { Guild = guild, System = system.Id, Member = member.Id };

            var multi = await conn.QueryMultipleAsync(@"
            select servers.* from servers where id = @Guild; 
            select * from system_guild where guild = @Guild and system = @System;
            select * from member_guild where guild = @Guild and member = @Member", args);

            return(new AuxillaryProxyInformation
            {
                Guild = (await multi.ReadSingleOrDefaultAsync <DatabaseCompatibleGuildConfig>()).Into(),
                SystemGuild = await multi.ReadSingleOrDefaultAsync <SystemGuildSettings>() ?? new SystemGuildSettings(),
                MemberGuild = await multi.ReadSingleOrDefaultAsync <MemberGuildSettings>() ?? new MemberGuildSettings()
            });
        }
Beispiel #3
0
        public async Task AddSwitchesBulk(PKSystem system, IEnumerable <ImportedSwitch> switches)
        {
            // Read existing switches to enforce unique timestamps
            var priorSwitches = await GetSwitches(system);

            var lastSwitchId = priorSwitches.Any()
                ? priorSwitches.Max(x => x.Id)
                : 0;

            using (var conn = (PerformanceTrackingConnection)await _conn.Obtain())
            {
                using (var tx = conn.BeginTransaction())
                {
                    // Import switches in bulk
                    using (var importer = conn.BeginBinaryImport("COPY switches (system, timestamp) FROM STDIN (FORMAT BINARY)"))
                    {
                        foreach (var sw in switches)
                        {
                            // If there's already a switch at this time, move on
                            if (priorSwitches.Any(x => x.Timestamp.Equals(sw.Timestamp)))
                            {
                                continue;
                            }

                            // Otherwise, add it to the importer
                            importer.StartRow();
                            importer.Write(system.Id, NpgsqlTypes.NpgsqlDbType.Integer);
                            importer.Write(sw.Timestamp, NpgsqlTypes.NpgsqlDbType.Timestamp);
                        }
                        importer.Complete(); // Commits the copy operation so dispose won't roll it back
                    }

                    // Get all switches that were created above and don't have members for ID lookup
                    var switchesWithoutMembers =
                        await conn.QueryAsync <PKSwitch>(@"
                        SELECT switches.*
                        FROM switches
                        LEFT JOIN switch_members
                        ON switch_members.switch = switches.id
                        WHERE switches.id > @LastSwitchId
                        AND switches.system = @System
                        AND switch_members.id IS NULL", new { LastSwitchId = lastSwitchId, System = system.Id });

                    // Import switch_members in bulk
                    using (var importer = conn.BeginBinaryImport("COPY switch_members (switch, member) FROM STDIN (FORMAT BINARY)"))
                    {
                        // Iterate over the switches we created above and set their members
                        foreach (var pkSwitch in switchesWithoutMembers)
                        {
                            // If this isn't in our import set, move on
                            var sw = switches.Select(x => (ImportedSwitch?)x).FirstOrDefault(x => x.Value.Timestamp.Equals(pkSwitch.Timestamp));
                            if (sw == null)
                            {
                                continue;
                            }

                            // Loop through associated members to add each to the switch
                            foreach (var m in sw.Value.Members)
                            {
                                // Skip switch-outs - these don't have switch_members
                                if (m == null)
                                {
                                    continue;
                                }
                                importer.StartRow();
                                importer.Write(pkSwitch.Id, NpgsqlTypes.NpgsqlDbType.Integer);
                                importer.Write(m.Id, NpgsqlTypes.NpgsqlDbType.Integer);
                            }
                        }
                        importer.Complete(); // Commits the copy operation so dispose won't roll it back
                    }
                    tx.Commit();
                }
            }

            _logger.Information("Completed bulk import of switches for system {0}", system.Hid);
        }
Beispiel #4
0
 public async Task <IEnumerable <MemberMessageCount> > GetMemberMessageCountBulk(PKSystem system)
 {
     using (var conn = await _conn.Obtain())
         return(await conn.QueryAsync <MemberMessageCount>(
                    @"SELECT messages.member, COUNT(messages.member) messagecount
                 FROM members
                 JOIN messages
                 ON members.id = messages.member
                 WHERE members.system = @System
                 GROUP BY messages.member",
                    new { System = system.Id }));
 }
Beispiel #5
0
 public async Task <int> GetSystemMemberCount(PKSystem system)
 {
     using (var conn = await _conn.Obtain())
         return(await conn.ExecuteScalarAsync <int>("select count(*) from members where system = @Id", system));
 }
Beispiel #6
0
 public async Task <IEnumerable <PKMember> > GetSystemMembers(PKSystem system)
 {
     using (var conn = await _conn.Obtain())
         return(await conn.QueryAsync <PKMember>("select * from members where system = @SystemID", new { SystemID = system.Id }));
 }
Beispiel #7
0
 public async Task <PKMember> GetMemberByName(PKSystem system, string name)
 {
     // QueryFirst, since members can (in rare cases) share names
     using (var conn = await _conn.Obtain())
         return(await conn.QueryFirstOrDefaultAsync <PKMember>("select * from members where lower(name) = lower(@Name) and system = @SystemID", new { Name = name, SystemID = system.Id }));
 }
Beispiel #8
0
 public async Task DeleteAllSwitches(PKSystem system)
 {
     using (var conn = await _conn.Obtain())
         await conn.ExecuteAsync("delete from switches where system = @Id", system);
 }
Beispiel #9
0
 public async Task <IEnumerable <ulong> > GetSystemAccounts(PKSystem system)
 {
     using (var conn = await _conn.Obtain())
         return(await conn.QueryAsync <ulong>("select uid from accounts where system = @Id", new { Id = system.Id }));
 }
Beispiel #10
0
 public async Task DeleteSystem(PKSystem system)
 {
     using (var conn = await _conn.Obtain())
         await conn.ExecuteAsync("delete from systems where id = @Id", system);
     _logger.Information("Deleted system {System}", system.Id);
 }