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 }