118 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package main
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"log"
 | 
						|
	"reflect"
 | 
						|
	"regexp"
 | 
						|
	"strings"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
func BuildWhereQuery(params interface{}) string {
 | 
						|
	conditions := []string{}
 | 
						|
	v := reflect.ValueOf(params)
 | 
						|
	t := v.Type()
 | 
						|
 | 
						|
	for i := 0; i < v.NumField(); i++ {
 | 
						|
		field := v.Field(i)
 | 
						|
		if field.Kind() == reflect.Ptr && !field.IsNil() {
 | 
						|
			dbTag := t.Field(i).Tag.Get("db")
 | 
						|
			if dbTag != "" {
 | 
						|
				switch field.Elem().Kind() {
 | 
						|
				case reflect.String:
 | 
						|
					conditions = append(conditions, fmt.Sprintf("%s = '%s'", dbTag, field.Elem().String()))
 | 
						|
				case reflect.Bool:
 | 
						|
					conditions = append(conditions, fmt.Sprintf("%s = %t", dbTag, field.Elem().Bool()))
 | 
						|
				case reflect.Int:
 | 
						|
					conditions = append(conditions, fmt.Sprintf("%s = %d", dbTag, field.Elem().Int()))
 | 
						|
				case reflect.Int64:
 | 
						|
					conditions = append(conditions, fmt.Sprintf("%s = %d", dbTag, field.Elem().Int()))
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if len(conditions) > 0 {
 | 
						|
		return "WHERE " + strings.Join(conditions, " AND ")
 | 
						|
	}
 | 
						|
	return ""
 | 
						|
}
 | 
						|
 | 
						|
var associationRe = regexp.MustCompile(`r:(\w+)(?:\(([^)]+)\))?`)
 | 
						|
func ParseNote(data string) (NoteData, error) {
 | 
						|
	log.Printf("Parsing note: %q", data)
 | 
						|
	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
 | 
						|
} |