Implements full player get
This commit is contained in:
@@ -23,5 +23,4 @@ create table note (
|
|||||||
content text,
|
content text,
|
||||||
timestamp string,
|
timestamp string,
|
||||||
player integer references player(id)
|
player integer references player(id)
|
||||||
);
|
);
|
||||||
create unique index idx_note_content on note(timestamp, player);
|
|
@@ -6,6 +6,8 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
_ "embed"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Error *log.Logger
|
var Error *log.Logger
|
||||||
@@ -35,6 +37,15 @@ var ps PlayerService
|
|||||||
var ns NoteService
|
var ns NoteService
|
||||||
var as AssociationService
|
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() {
|
func main() {
|
||||||
db = DB{
|
db = DB{
|
||||||
path: "data/db.db",
|
path: "data/db.db",
|
||||||
@@ -54,6 +65,8 @@ func main() {
|
|||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
app.Post("/note/new", CreateNote)
|
app.Post("/note/new", CreateNote)
|
||||||
|
app.Get("/player/:name", GetPlayer)
|
||||||
|
app.Get("/player", GetPlayers)
|
||||||
|
|
||||||
log.Fatal(app.Listen(":3000"))
|
log.Fatal(app.Listen(":3000"))
|
||||||
}
|
}
|
||||||
@@ -89,3 +102,37 @@ func CreateNote(c fiber.Ctx) error {
|
|||||||
res.Message = "OK"
|
res.Message = "OK"
|
||||||
return c.Status(200).JSON(res)
|
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
|
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;
|
@@ -8,9 +8,9 @@ type (
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
Player struct {
|
Player struct {
|
||||||
ID int64
|
ID int64
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Guild Guild `json:"guild"`
|
Guild Guild `json:"guild,omitempty"`
|
||||||
}
|
}
|
||||||
Association struct {
|
Association struct {
|
||||||
ID int64
|
ID int64
|
||||||
|
Reference in New Issue
Block a user