module Degenz.InviteTracker open System open Npgsql.FSharp let connStr = GuildEnvironment.connectionString type Invite = { Code : string Inviter : uint64 Count : int } let getInvites () = async { let! invites = connStr |> Sql.connect |> Sql.query """ SELECT code, inviter, count FROM invite WHERE created_at > (current_timestamp at time zone 'utc') - interval '3 day' """ |> Sql.executeAsync (fun read -> { Code = read.string "code" Inviter = read.string "inviter" |> uint64 Count = read.int "count" }) |> Async.AwaitTask return invites |> List.map (fun inv -> (inv.Code , (inv.Inviter , inv.Count))) |> Map.ofList } let createInvite inviter code = connStr |> Sql.connect |> Sql.parameters [ "code" , Sql.string code ; "inviter" , Sql.string (string inviter) ] |> Sql.query "INSERT INTO invite (code, inviter) VALUES (@code, @inviter)" |> Sql.executeNonQueryAsync |> Async.AwaitTask let addInvitedUser did code = connStr |> Sql.connect |> Sql.executeTransactionAsync [ """ WITH invite AS (SELECT id FROM invite WHERE code = @code) INSERT INTO invited_user (discord_id, invite_id) SELECT @discord_id, invite.id FROM invite; """ , [ [ "@discord_id" , Sql.string (string did) ] ; [ "@code" , Sql.string code ] ] "UPDATE invite SET count = count + 1 WHERE code = @code" , [ [ "@code" , Sql.string code ] ] ] |> Async.AwaitTask let getInviteAttributions userId = connStr |> Sql.connect |> Sql.parameters [ "did" , Sql.string (string userId) ] |> Sql.query "SELECT sum(count) AS total FROM invite WHERE inviter = @did" |> Sql.executeRowAsync (fun read -> read.int "total") |> Async.AwaitTask let getInvitedUsers userId = connStr |> Sql.connect |> Sql.parameters [ "did" , Sql.string (string userId) ] |> Sql.query """ WITH invite AS (SELECT id FROM invite WHERE inviter = @did) SELECT discord_id FROM invited_user, invite WHERE invite.id = invited_user.invite_id """ |> Sql.executeAsync (fun read -> read.string "discord_id" |> uint64) |> Async.AwaitTask