Implement parsing and persisting notes
This commit is contained in:
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GuildService struct {
|
type GuildService struct {
|
||||||
@@ -39,6 +40,7 @@ func (gs *GuildService) Query(query GuildServiceQuery) ([]Guild, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gs *GuildService) Create(name string) (Guild, error) {
|
func (gs *GuildService) Create(name string) (Guild, error) {
|
||||||
|
log.Printf("Creating guild %s", name)
|
||||||
guild := Guild{}
|
guild := Guild{}
|
||||||
res, err := gs.db.writeConn.Exec("insert into guild (name) values (?)", name)
|
res, err := gs.db.writeConn.Exec("insert into guild (name) values (?)", name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -49,6 +51,7 @@ func (gs *GuildService) Create(name string) (Guild, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return guild, fmt.Errorf("failed to get last insert id: %v", err)
|
return guild, fmt.Errorf("failed to get last insert id: %v", err)
|
||||||
}
|
}
|
||||||
|
log.Printf("Created guild %s with id %d", name, id)
|
||||||
|
|
||||||
qres, err := gs.Query(GuildServiceQuery{ID: &id})
|
qres, err := gs.Query(GuildServiceQuery{ID: &id})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -64,14 +67,17 @@ func (gs *GuildService) Create(name string) (Guild, error) {
|
|||||||
func (gs *GuildService) GetOrCreate(name string) (Guild, error) {
|
func (gs *GuildService) GetOrCreate(name string) (Guild, error) {
|
||||||
guild := Guild{}
|
guild := Guild{}
|
||||||
guilds, err := gs.Query(GuildServiceQuery{Name: &name})
|
guilds, err := gs.Query(GuildServiceQuery{Name: &name})
|
||||||
if err != nil {
|
if len(guilds) > 1 {
|
||||||
if len(guilds) > 1 {
|
return guild, fmt.Errorf("more than one guild found for name %s", name)
|
||||||
return guild, fmt.Errorf("more than one guild found for name %s", name)
|
}
|
||||||
}
|
if err != nil || len(guilds) == 0 {
|
||||||
guild, err = gs.Create(name)
|
guild, err = gs.Create(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return guild, fmt.Errorf("failed creating guild: %v", err)
|
return guild, fmt.Errorf("failed creating guild: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(guilds) == 1 {
|
||||||
|
guild = guilds[0]
|
||||||
|
}
|
||||||
return guild, nil
|
return guild, nil
|
||||||
}
|
}
|
||||||
|
49
main.go
49
main.go
@@ -6,9 +6,6 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var Error *log.Logger
|
var Error *log.Logger
|
||||||
@@ -36,6 +33,7 @@ var db DB
|
|||||||
var gs GuildService
|
var gs GuildService
|
||||||
var ps PlayerService
|
var ps PlayerService
|
||||||
var ns NoteService
|
var ns NoteService
|
||||||
|
var as AssociationService
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
inputFile := flag.String("if", "input", "Input file")
|
inputFile := flag.String("if", "input", "Input file")
|
||||||
@@ -55,6 +53,7 @@ func main() {
|
|||||||
gs = GuildService{db: &db}
|
gs = GuildService{db: &db}
|
||||||
ps = PlayerService{db: &db}
|
ps = PlayerService{db: &db}
|
||||||
ns = NoteService{db: &db}
|
ns = NoteService{db: &db}
|
||||||
|
as = AssociationService{db: &db}
|
||||||
|
|
||||||
inputData, err := os.ReadFile(*inputFile)
|
inputData, err := os.ReadFile(*inputFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -68,44 +67,12 @@ func main() {
|
|||||||
Error.Printf("Failed parsing note: %v", err)
|
Error.Printf("Failed parsing note: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Printf("%#v", note)
|
|
||||||
}
|
|
||||||
|
|
||||||
var associationRe = regexp.MustCompile(`r:(\w+)(?:\(([^)]+)\))?`)
|
dbnote, ass, err := PersistNoteData(note)
|
||||||
func ParseNote(data string) (NoteData, error) {
|
if err != nil {
|
||||||
res := NoteData{}
|
Error.Printf("Failed persisting note: %v", err)
|
||||||
lines := strings.Split(data, "\n")
|
return
|
||||||
note := []string{}
|
|
||||||
for _, line := range lines {
|
|
||||||
line = strings.TrimSpace(line)
|
|
||||||
if line == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
parts := strings.Split(line, ":")
|
|
||||||
switch parts[0] {
|
|
||||||
case "p":
|
|
||||||
res.Player = parts[1]
|
|
||||||
case "d":
|
|
||||||
var err error
|
|
||||||
res.Date, err = time.Parse(time.DateOnly, parts[1])
|
|
||||||
if err != nil {
|
|
||||||
return res, fmt.Errorf("failed to parse date: %v", err)
|
|
||||||
}
|
|
||||||
case "g":
|
|
||||||
res.Guild = parts[1]
|
|
||||||
default:
|
|
||||||
note = append(note, line)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
res.Note = strings.Join(note, "\n")
|
log.Printf("%#v", dbnote)
|
||||||
|
log.Printf("%#v", ass)
|
||||||
matches := associationRe.FindAllStringSubmatch(res.Note, -1)
|
|
||||||
for _, match := range matches {
|
|
||||||
res.Associations = append(res.Associations, NoteAssociationData{
|
|
||||||
Player: match[1],
|
|
||||||
Note: match[2],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -30,10 +31,15 @@ func (ns *NoteService) Query(query NoteServiceQuery) ([]Note, error) {
|
|||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
note := Note{}
|
note := Note{}
|
||||||
err := rows.Scan(¬e.ID, ¬e.Content, ¬e.Timestamp, ¬e.Player.ID)
|
var ts string
|
||||||
|
err := rows.Scan(¬e.ID, ¬e.Content, &ts, ¬e.Player.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, fmt.Errorf("failed scanning note: %v", err)
|
return res, fmt.Errorf("failed scanning note: %v", err)
|
||||||
}
|
}
|
||||||
|
note.Timestamp, err = time.Parse(time.RFC3339, ts)
|
||||||
|
if err != nil {
|
||||||
|
return res, fmt.Errorf("failed parsing timestamp: %v", err)
|
||||||
|
}
|
||||||
res = append(res, note)
|
res = append(res, note)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,8 +47,9 @@ func (ns *NoteService) Query(query NoteServiceQuery) ([]Note, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ns *NoteService) Create(content string, timestamp time.Time, player Player) (Note, error) {
|
func (ns *NoteService) Create(content string, timestamp time.Time, player Player) (Note, error) {
|
||||||
|
log.Printf("Creating note %q with timestamp %s and player %d", content, timestamp, player.ID)
|
||||||
note := Note{}
|
note := Note{}
|
||||||
res, err := ns.db.writeConn.Exec("insert into note (content, timestamp, player) values (?, ?, ?)", content, timestamp, player.ID)
|
res, err := ns.db.writeConn.Exec("insert into note (content, timestamp, player) values (?, ?, ?)", content, timestamp.Format(time.RFC3339), player.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return note, fmt.Errorf("failed to insert note: %v", err)
|
return note, fmt.Errorf("failed to insert note: %v", err)
|
||||||
}
|
}
|
||||||
@@ -51,6 +58,7 @@ func (ns *NoteService) Create(content string, timestamp time.Time, player Player
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return note, fmt.Errorf("failed to get last insert id: %v", err)
|
return note, fmt.Errorf("failed to get last insert id: %v", err)
|
||||||
}
|
}
|
||||||
|
log.Printf("Created note %q with timestamp %s and player %d with id %d", content, timestamp, player.ID, id)
|
||||||
|
|
||||||
qres, err := ns.Query(NoteServiceQuery{ID: &id})
|
qres, err := ns.Query(NoteServiceQuery{ID: &id})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -1,6 +1,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
type PlayerService struct {
|
type PlayerService struct {
|
||||||
db *DB
|
db *DB
|
||||||
@@ -37,6 +40,7 @@ func (ps *PlayerService) Query(query PlayerServiceQuery) ([]Player, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ps *PlayerService) Create(name string, guild Guild) (Player, error) {
|
func (ps *PlayerService) Create(name string, guild Guild) (Player, error) {
|
||||||
|
log.Printf("Creating player %s in guild %s", name, guild.Name)
|
||||||
player := Player{}
|
player := Player{}
|
||||||
res, err := ps.db.writeConn.Exec("insert into player (name, guild) values (?, ?)", name, guild.ID)
|
res, err := ps.db.writeConn.Exec("insert into player (name, guild) values (?, ?)", name, guild.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -47,6 +51,7 @@ func (ps *PlayerService) Create(name string, guild Guild) (Player, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return player, fmt.Errorf("failed to get last insert id: %v", err)
|
return player, fmt.Errorf("failed to get last insert id: %v", err)
|
||||||
}
|
}
|
||||||
|
log.Printf("Created player %s in guild %s with id %d", name, guild.Name, id)
|
||||||
|
|
||||||
qres, err := ps.Query(PlayerServiceQuery{ID: &id})
|
qres, err := ps.Query(PlayerServiceQuery{ID: &id})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -62,14 +67,17 @@ func (ps *PlayerService) Create(name string, guild Guild) (Player, error) {
|
|||||||
func (ps *PlayerService) GetOrCreate(name string, guild Guild) (Player, error) {
|
func (ps *PlayerService) GetOrCreate(name string, guild Guild) (Player, error) {
|
||||||
player := Player{}
|
player := Player{}
|
||||||
players, err := ps.Query(PlayerServiceQuery{Name: &name})
|
players, err := ps.Query(PlayerServiceQuery{Name: &name})
|
||||||
if err != nil {
|
if len(players) > 1 {
|
||||||
if len(players) > 1 {
|
return player, fmt.Errorf("more than one player found for name %s", name)
|
||||||
return player, fmt.Errorf("more than one player found for name %s", name)
|
}
|
||||||
}
|
if err != nil || len(players) == 0 {
|
||||||
player, err = ps.Create(name, guild)
|
player, err = ps.Create(name, guild)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return player, fmt.Errorf("failed creating player: %v", err)
|
return player, fmt.Errorf("failed creating player: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(players) == 1 {
|
||||||
|
player = players[0]
|
||||||
|
}
|
||||||
return player, nil
|
return player, nil
|
||||||
}
|
}
|
||||||
|
79
utils.go
79
utils.go
@@ -3,7 +3,9 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BuildWhereQuery(params interface{}) string {
|
func BuildWhereQuery(params interface{}) string {
|
||||||
@@ -35,3 +37,80 @@ func BuildWhereQuery(params interface{}) string {
|
|||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var associationRe = regexp.MustCompile(`r:(\w+)(?:\(([^)]+)\))?`)
|
||||||
|
func ParseNote(data string) (NoteData, error) {
|
||||||
|
res := NoteData{}
|
||||||
|
lines := strings.Split(data, "\n")
|
||||||
|
note := []string{}
|
||||||
|
for _, line := range lines {
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if line == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
parts := strings.Split(line, ":")
|
||||||
|
switch parts[0] {
|
||||||
|
case "p":
|
||||||
|
res.Player = parts[1]
|
||||||
|
case "d":
|
||||||
|
var err error
|
||||||
|
res.Date, err = time.Parse(time.DateOnly, parts[1])
|
||||||
|
if err != nil {
|
||||||
|
return res, fmt.Errorf("failed to parse date: %v", err)
|
||||||
|
}
|
||||||
|
case "g":
|
||||||
|
res.Guild = parts[1]
|
||||||
|
default:
|
||||||
|
note = append(note, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.Note = strings.Join(note, "\n")
|
||||||
|
|
||||||
|
matches := associationRe.FindAllStringSubmatch(res.Note, -1)
|
||||||
|
for _, match := range matches {
|
||||||
|
res.Associations = append(res.Associations, NoteAssociationData{
|
||||||
|
Player: match[1],
|
||||||
|
Note: match[2],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func PersistNoteData(note NoteData) (Note, []Association, error) {
|
||||||
|
res := Note{}
|
||||||
|
ass := []Association{}
|
||||||
|
|
||||||
|
res.Content = note.Note
|
||||||
|
res.Timestamp = note.Date
|
||||||
|
guild, err := gs.GetOrCreate(note.Guild)
|
||||||
|
if err != nil {
|
||||||
|
return res, ass, fmt.Errorf("failed getting guild for %s: %v", note.Guild, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
player, err := ps.GetOrCreate(note.Player, guild)
|
||||||
|
if err != nil {
|
||||||
|
return res, ass, fmt.Errorf("failed getting player for %s: %v", note.Player, err)
|
||||||
|
}
|
||||||
|
res.Player = player
|
||||||
|
player.Guild = guild
|
||||||
|
|
||||||
|
for _, assoc := range note.Associations {
|
||||||
|
assocPlayer, err := ps.GetOrCreate(assoc.Player, guild)
|
||||||
|
if err != nil {
|
||||||
|
return res, ass, fmt.Errorf("failed getting player for %s: %v", assoc.Player, err)
|
||||||
|
}
|
||||||
|
association, err := as.Create(player, assocPlayer, assoc.Note)
|
||||||
|
if err != nil {
|
||||||
|
return res, ass, fmt.Errorf("failed creating association: %v", err)
|
||||||
|
}
|
||||||
|
ass = append(ass, association)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err = ns.Create(res.Content, res.Timestamp, res.Player)
|
||||||
|
if err != nil {
|
||||||
|
return res, ass, fmt.Errorf("failed creating note: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, ass, nil
|
||||||
|
}
|
Reference in New Issue
Block a user