Initial Commit

This commit is contained in:
Florian Sylvain
2025-05-02 01:30:37 +02:00
commit e6f9e96c8f
8 changed files with 369 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
package store
import (
"encoding/json"
"github.com/dgraph-io/badger/v4"
"github.com/google/uuid"
)
type Address struct {
ID string
UserID string
Line1 string
City string
ZipCode string
}
const addressPrefix = "addr:"
func AddAddressToUser(userID, line1, city, zip string) (*Address, error) {
addr := &Address{
ID: uuid.NewString(),
UserID: userID,
Line1: line1,
City: city,
ZipCode: zip,
}
data, err := json.Marshal(addr)
if err != nil {
return nil, err
}
err = GetDB().Update(func(txn *badger.Txn) error {
return txn.Set([]byte(addressPrefix+addr.ID), data)
})
return addr, err
}
func ListAddressesByUserID(userID string) ([]*Address, error) {
addresses := []*Address{}
err := GetDB().View(func(txn *badger.Txn) error {
it := txn.NewIterator(badger.DefaultIteratorOptions)
defer it.Close()
for it.Seek([]byte(addressPrefix)); it.ValidForPrefix([]byte(addressPrefix)); it.Next() {
item := it.Item()
err := item.Value(func(v []byte) error {
var a Address
if err := json.Unmarshal(v, &a); err == nil && a.UserID == userID {
addresses = append(addresses, &a)
}
return nil
})
if err != nil {
return err
}
}
return nil
})
return addresses, err
}
+35
View File
@@ -0,0 +1,35 @@
package store
import (
"log"
"sync"
"github.com/dgraph-io/badger/v4"
)
var (
db *badger.DB
once sync.Once
dbPath = "./data"
)
func InitDB() {
once.Do(func() {
opts := badger.DefaultOptions(dbPath).WithLogger(nil)
var err error
db, err = badger.Open(opts)
if err != nil {
log.Fatal(err)
}
})
}
func CloseDB() {
if db != nil {
db.Close()
}
}
func GetDB() *badger.DB {
return db
}
+115
View File
@@ -0,0 +1,115 @@
package store
import (
"encoding/json"
"errors"
"github.com/dgraph-io/badger/v4"
"github.com/google/uuid"
)
type User struct {
ID string
Name string
Email string
Password string
}
const (
userPrefix = "user:"
emailIndexPref = "email:"
)
var (
ErrEmailExists = errors.New("email already registered")
)
func CreateUser(name, email, password string) (*User, error) {
// Enforce uniqueness
if _, err := findUserIDByEmail(email); err == nil {
return nil, ErrEmailExists
}
user := &User{
ID: uuid.NewString(),
Name: name,
Email: email,
Password: password,
}
data, err := json.Marshal(user)
if err != nil {
return nil, err
}
err = GetDB().Update(func(txn *badger.Txn) error {
if err := txn.Set([]byte(userPrefix+user.ID), data); err != nil {
return err
}
return txn.Set([]byte(emailIndexPref+email), []byte(user.ID))
})
return user, err
}
func FindUserByID(id string) (*User, error) {
var user User
err := GetDB().View(func(txn *badger.Txn) error {
item, err := txn.Get([]byte(userPrefix + id))
if err != nil {
return err
}
return item.Value(func(val []byte) error {
return json.Unmarshal(val, &user)
})
})
if err != nil {
return nil, err
}
return &user, nil
}
func findUserIDByEmail(email string) (string, error) {
var id string
err := GetDB().View(func(txn *badger.Txn) error {
item, err := txn.Get([]byte(emailIndexPref + email))
if err != nil {
return err
}
return item.Value(func(v []byte) error {
id = string(v)
return nil
})
})
return id, err
}
func FindUserByEmail(email string) (*User, error) {
id, err := findUserIDByEmail(email)
if err != nil {
return nil, err
}
return FindUserByID(id)
}
func ListUsers() ([]*User, error) {
users := []*User{}
err := GetDB().View(func(txn *badger.Txn) error {
it := txn.NewIterator(badger.DefaultIteratorOptions)
defer it.Close()
for it.Seek([]byte(userPrefix)); it.ValidForPrefix([]byte(userPrefix)); it.Next() {
item := it.Item()
err := item.Value(func(v []byte) error {
var u User
if err := json.Unmarshal(v, &u); err == nil {
users = append(users, &u)
}
return nil
})
if err != nil {
return err
}
}
return nil
})
return users, err
}