Implements full player get
This commit is contained in:
@@ -24,4 +24,3 @@ create table note (
|
||||
timestamp string,
|
||||
player integer references player(id)
|
||||
);
|
||||
create unique index idx_note_content on note(timestamp, player);
|
@@ -6,6 +6,8 @@ import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
var Error *log.Logger
|
||||
@@ -35,6 +37,15 @@ var ps PlayerService
|
||||
var ns NoteService
|
||||
var as AssociationService
|
||||
|
||||
//go:embed selectPlayer.sql
|
||||
var selectPlayer string
|
||||
|
||||
//go:embed selectAssociation.sql
|
||||
var selectAssociation string
|
||||
|
||||
//go:embed selectNotes.sql
|
||||
var selectNotes string
|
||||
|
||||
func main() {
|
||||
db = DB{
|
||||
path: "data/db.db",
|
||||
@@ -54,6 +65,8 @@ func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Post("/note/new", CreateNote)
|
||||
app.Get("/player/:name", GetPlayer)
|
||||
app.Get("/player", GetPlayers)
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
@@ -89,3 +102,37 @@ func CreateNote(c fiber.Ctx) error {
|
||||
res.Message = "OK"
|
||||
return c.Status(200).JSON(res)
|
||||
}
|
||||
|
||||
func GetPlayer(c fiber.Ctx) error {
|
||||
name := c.Params("name")
|
||||
log.Printf("Getting player %s", name)
|
||||
player, err := ps.GetAllPlayerInfo(name, 10)
|
||||
if err != nil {
|
||||
Error.Printf("Failed getting player: %v", err)
|
||||
return c.Status(500).JSON(Response{
|
||||
Success: false,
|
||||
Message: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
return c.Status(200).JSON(Response{
|
||||
Success: true,
|
||||
Data: player,
|
||||
})
|
||||
}
|
||||
|
||||
func GetPlayers(c fiber.Ctx) error {
|
||||
players, err := ps.Query(PlayerServiceQuery{})
|
||||
if err != nil {
|
||||
Error.Printf("Failed getting players: %v", err)
|
||||
return c.Status(500).JSON(Response{
|
||||
Success: false,
|
||||
Message: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
return c.Status(200).JSON(Response{
|
||||
Success: true,
|
||||
Data: players,
|
||||
})
|
||||
}
|
||||
|
@@ -81,3 +81,69 @@ func (ps *PlayerService) GetOrCreate(name string, guild Guild) (Player, error) {
|
||||
}
|
||||
return player, nil
|
||||
}
|
||||
|
||||
type (
|
||||
FullPlayer struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Guild struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
} `json:"guild"`
|
||||
Associations []FullPlayerAssociation `json:"associations"`
|
||||
Notes []FullPlayerNote `json:"notes"`
|
||||
}
|
||||
|
||||
FullPlayerAssociation struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Note string `json:"note"`
|
||||
}
|
||||
|
||||
FullPlayerNote struct {
|
||||
ID int64 `json:"id"`
|
||||
Content string `json:"content"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
}
|
||||
)
|
||||
|
||||
func (ps *PlayerService) GetAllPlayerInfo(name string, nnotes int) (FullPlayer, error) {
|
||||
res := FullPlayer{}
|
||||
|
||||
err := ps.db.readConn.QueryRow(selectPlayer, name).Scan(&res.ID, &res.Name, &res.Guild.ID, &res.Guild.Name)
|
||||
if err != nil {
|
||||
return res, fmt.Errorf("failed getting player info: %v", err)
|
||||
}
|
||||
|
||||
rows, err := ps.db.readConn.Query(selectAssociation, res.ID)
|
||||
if err != nil {
|
||||
return res, fmt.Errorf("failed getting player associations: %v", err)
|
||||
}
|
||||
|
||||
for rows.Next() {
|
||||
assoc := FullPlayerAssociation{}
|
||||
err := rows.Scan(&assoc.ID, &assoc.Name, &assoc.Note)
|
||||
if err != nil {
|
||||
return res, fmt.Errorf("failed scanning association: %v", err)
|
||||
}
|
||||
res.Associations = append(res.Associations, assoc)
|
||||
}
|
||||
rows.Close()
|
||||
|
||||
rows, err = ps.db.readConn.Query(selectNotes, res.ID, nnotes)
|
||||
if err != nil {
|
||||
return res, fmt.Errorf("failed getting player notes: %v", err)
|
||||
}
|
||||
|
||||
for rows.Next() {
|
||||
note := FullPlayerNote{}
|
||||
err := rows.Scan(¬e.ID, ¬e.Content, ¬e.Timestamp)
|
||||
if err != nil {
|
||||
return res, fmt.Errorf("failed scanning note: %v", err)
|
||||
}
|
||||
res.Notes = append(res.Notes, note)
|
||||
}
|
||||
rows.Close()
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
28
backend/selectAssociation.sql
Normal file
28
backend/selectAssociation.sql
Normal file
@@ -0,0 +1,28 @@
|
||||
-- 3. Get all associations (N rows)
|
||||
with
|
||||
AllAssociations as (
|
||||
select
|
||||
lhs as PlayerID,
|
||||
rhs as AssociateID,
|
||||
note
|
||||
from
|
||||
association
|
||||
where
|
||||
lhs = $1
|
||||
union
|
||||
select
|
||||
rhs as PlayerID,
|
||||
lhs as AssociateID,
|
||||
note
|
||||
from
|
||||
association
|
||||
where
|
||||
rhs = $1
|
||||
)
|
||||
select
|
||||
p.id as AssociateID,
|
||||
p.name as AssociateName,
|
||||
coalesce(a.note, '') as AssociationNote
|
||||
from
|
||||
AllAssociations a
|
||||
join player p on a.AssociateID = p.id;
|
22
backend/selectNotes.sql
Normal file
22
backend/selectNotes.sql
Normal file
@@ -0,0 +1,22 @@
|
||||
-- 2. Get N most recent notes (10 rows)
|
||||
select
|
||||
id as NoteID,
|
||||
content as NoteContent,
|
||||
timestamp as NoteTimestamp
|
||||
from
|
||||
(
|
||||
select
|
||||
n.*,
|
||||
ROW_NUMBER() OVER (
|
||||
order by
|
||||
timestamp desc
|
||||
) as rn
|
||||
from
|
||||
note n
|
||||
where
|
||||
n.player = $1
|
||||
) ranked
|
||||
where
|
||||
rn <= $2
|
||||
order by
|
||||
timestamp desc;
|
11
backend/selectPlayer.sql
Normal file
11
backend/selectPlayer.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
-- 1. Get player and guild info (1 row)
|
||||
select
|
||||
p.id as PlayerID,
|
||||
p.name as PlayerName,
|
||||
g.id as GuildID,
|
||||
g.name as GuildName
|
||||
from
|
||||
player p
|
||||
join guild g on p.guild = g.id
|
||||
where
|
||||
p.name = $1;
|
@@ -10,7 +10,7 @@ type (
|
||||
Player struct {
|
||||
ID int64
|
||||
Name string `json:"name"`
|
||||
Guild Guild `json:"guild"`
|
||||
Guild Guild `json:"guild,omitempty"`
|
||||
}
|
||||
Association struct {
|
||||
ID int64
|
||||
|
Reference in New Issue
Block a user