Open1
CSVファイルをDB代わりにデータ保存用に使うための方法
モデル
package model
import (
"errors"
"fmt"
"os"
"github.com/jszwec/csvutil"
)
type User struct {
UserID string `csv:"user_id"`
UserName string `csv:"user_name"`
LimitAt string `csv:"limit_at"`
SessionID string `csv:"session_id"`
}
// Users はmodel.Userのスライスです.
type Users []*User
// NewUsers はユーザーデータを読み込みます.
func NewUsers() (Users, error) {
var users Users
fileName := "/app/data/users.csv"
b, err := os.ReadFile(fileName)
if err != nil {
file, err := os.Create(fileName)
if err != nil {
fmt.Println("ファイルの作成に失敗しました:", err.Error())
return nil, err
}
defer file.Close() // 関数が終了する前にファイルを閉じる
}
if err = csvutil.Unmarshal(b, &users); err != nil {
return nil, err
}
return users, nil
}
// Filter はmodel.Users型に対する絞り込み処理を行います.
func (u Users) Filter(fn ...func(*User) bool) Users {
newUsers := make(Users, 0, len(u))
for _, v := range u {
ok := true
for _, f := range fn {
if !f(v) {
ok = false
break
}
}
if ok {
newUsers = append(newUsers, v)
}
}
return newUsers
}
// Usersの各要素に処理を適用します。
func (u Users) Apply(fn ...func(*User) *User) Users {
newUsers := make(Users, 0, len(u))
for _, v := range u {
m := v
for _, f := range fn {
m = f(m)
}
newUsers = append(newUsers, m)
}
return newUsers
}
// ユーザーデータを追加
// 最後にSaveを呼び出すことで、CSVファイルに記録されます。
func (u Users) Add(user *User) (Users, error) {
sameUser := u.Filter(func(v *User) bool {
return v.UserID == user.UserID
})
if len(sameUser) > 0 {
return nil, errors.New("user_idが重複しています")
}
v := append(u, user)
return v, nil
}
// 指定したuserIDのユーザーデータを削除
// 最後にSaveを呼び出すことで、CSVファイルに記録されます。
func (u Users) Delete(userID string) (Users, error) {
newUsers := u.Filter(func(v *User) bool {
return v.UserID != userID
})
if len(u) == len(newUsers) {
return nil, errors.New("ユーザーが存在しません")
}
return newUsers, nil
}
// ユーザーデータをCSVファイルに記録
func (u Users) Save() error {
b, err := csvutil.Marshal(u)
if err != nil {
return err
}
return os.WriteFile("/app/data/users.csv", b, 0666)
}
使う側
// ユーザーを取得する
users, err := model.NewUsers()
// 該当のユーザー情報を取得する
searchedUser := users.Filter(func(v *model.User) bool {
return input.UserID == v.UserID
})
// ユーザーが存在しない場合
if len(searchedUser) == 0 {
// ・・・
}
// セッションIDを更新し、保存する
sessionID := uuid.New()
err = users.Apply(func(v *model.User) *model.User {
if input.UserID == v.UserID {
v.SessionID = sessionID.String()
}
return v
}).Save()