Skip to content

Commit

Permalink
Refactor gorm tables
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholaspcr committed Jun 1, 2024
1 parent d036387 commit 3beaa29
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 66 deletions.
14 changes: 0 additions & 14 deletions internal/store/gorm/base_model.go

This file was deleted.

22 changes: 11 additions & 11 deletions internal/store/gorm/gorm.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,41 @@ import (
"gorm.io/gorm"
)

// MemoryEnabled defines if the database should be in memory or not, useful for
// memoryEnabled defines if the database should be in memory or not, useful for
// testing and debugging. Can be enabled by in configuration.
//
// TODO: Make this an environment option and disabled by default.
var MemoryEnabled = true
var memoryEnabled = true

// GormStore is the main store for the application. It contains implementations
// gormStore is the main store for the application. It contains implementations
// of all the interfaces defined in the store package.
type GormStore struct {
type gormStore struct {
db *gorm.DB
*userStore
}

// New returns a new GormStore.
func New(_ context.Context) (*GormStore, error) {
sqlitePath := ".env/sqlite.db"
if MemoryEnabled {
func New(_ context.Context) (*gormStore, error) {
sqlitePath := ".dev/sqlite.db"
if memoryEnabled {
sqlitePath = ":memory:"
}
db, err := gorm.Open(sqlite.Open(sqlitePath), &gorm.Config{})
if err != nil {
return nil, err
}

store := &GormStore{
store := &gormStore{
db: db,
userStore: newUserStore(db),
}

return store, nil
}

func (s *GormStore) AutoMigrate() error {
func (s *gormStore) AutoMigrate() error {
return s.db.AutoMigrate(
&TenantModel{},
&UserModel{},
&tenantModel{},
&userModel{},
)
}
20 changes: 12 additions & 8 deletions internal/store/gorm/tenant.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,34 @@ package gorm

import (
"context"
"time"

"github.com/nicholaspcr/GoDE/pkg/api/v1"
"gorm.io/gorm"
)

// Tenant is a model for the tenant table.
type TenantModel struct {
ID string `gorm:"primary_key,size:50"`
// tenantModel wraps the tenant_id column into a separate type.
type tenantModel struct {
ID string `gorm:"primary_key,size:50"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}

type tenantStore struct{ *gorm.DB }

func newTenantStore(db *gorm.DB) *tenantStore { return &tenantStore{db} }

func (st *tenantStore) Create(ctx context.Context, tnt *api.Tenant) error {
tenant := TenantModel{ID: tnt.GetIds().TenantId}
st.DB.Create(&tenant)
t := tenantModel{ID: tnt.GetIds().TenantId}
st.DB.Create(&t)
return nil
}

func (st *tenantStore) Get(
ctx context.Context, tntIDs *api.TenantIDs,
) (*api.Tenant, error) {
var tnt TenantModel
var tnt tenantModel
tx := st.First(&tnt, "id = ?", tntIDs.TenantId)
if tx.Error != nil {
return nil, tx.Error
Expand All @@ -34,8 +38,8 @@ func (st *tenantStore) Get(
}

func (st *tenantStore) Delete(ctx context.Context, tntIDs *api.TenantIDs) error {
var tenant TenantModel
tx := st.First(&tenant, "id = ?", tntIDs.TenantId)
var tnt tenantModel
tx := st.First(&tnt, "id = ?", tntIDs.TenantId)
if tx.Error != nil {
return tx.Error
}
Expand Down
83 changes: 50 additions & 33 deletions internal/store/gorm/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,81 +9,98 @@ import (
"gorm.io/gorm"
)

type UserModel struct {
BaseModel

ID string `gorm:"primary_key"`
Tenant TenantModel `gorm:"foreignKey:ID"`

type userModel struct {
gorm.Model
TenantID string `gorm:"index:user_tenant_index,unique,not null,size:50"`
Email string `gorm:"index:user_email_index,unique,not null,size:255"`
Password string `gorm:"not null,size:255"`
Name string `gorm:"size:64"`
}

func (u *userModel) fillTenantID(tx *gorm.DB) error {
ctx := tx.Statement.Context

tnt := tenant.FromContext(ctx)
u.TenantID = tnt.GetIds().TenantId

return nil
}

func (u *userModel) BeforeCreate(tx *gorm.DB) error {
return u.fillTenantID(tx)
}

func (u *userModel) BeforeUpdate(tx *gorm.DB) error {
return u.fillTenantID(tx)
}

func (u *userModel) BeforeDelete(tx *gorm.DB) error {
return u.fillTenantID(tx)
}

type userStore struct{ *gorm.DB }

func newUserStore(db *gorm.DB) *userStore { return &userStore{db} }

func (st *userStore) Create(ctx context.Context, usr *api.User) error {
tnt := tenant.FromContext(ctx)
user := UserModel{
ID: usr.GetIds().UserId,
Tenant: TenantModel{ID: tnt.GetIds().TenantId},
Email: usr.Email,
user := userModel{
Email: usr.GetIds().Email,
Password: usr.Password,
Name: usr.Name,
}
st.DB.Create(&user)
st.DB.WithContext(ctx).Create(&user)
return nil
}

func (st *userStore) Get(
ctx context.Context, usrIDs *api.UserIDs,
) (*api.User, error) {
var usr UserModel
tx := st.First(&usr, "id = ?", usrIDs.UserId)
var usr userModel

tx := st.First(&usr, "email = ?", usrIDs.Email)
if tx.Error != nil {
return nil, tx.Error
}
return &api.User{
Ids: &api.UserIDs{UserId: usr.ID},
Email: usr.Email,
Ids: &api.UserIDs{Email: usr.Email},
Password: usr.Password,
Name: usr.Name,
}, nil
}

func (st *userStore) Update(ctx context.Context, usr *api.User, fields ...string) error {
tnt := tenant.FromContext(ctx)
model := UserModel{
ID: usr.GetIds().UserId,
Tenant: TenantModel{ID: tnt.GetIds().TenantId},
func (st *userStore) Update(
ctx context.Context, usr *api.User, fields ...string,
) error {
var model userModel

tx := st.First(&model, "email = ?", usr.GetIds().Email)
if tx.Error != nil {
return tx.Error
}

columns := make(map[string]any)
for _, field := range fields {
switch field {
default:
return errors.ErrUnsupportedFieldMask
case "email":
model.Email = usr.Email
columns[field] = usr.GetIds().Email
case "password":
model.Password = usr.Password
columns[field] = usr.Password
case "name":
columns[field] = usr.Name
}
}

tx := st.DB.Model(&model).Updates(model)
tx = st.DB.Model(&model).Updates(columns)
if tx.Error != nil {
return tx.Error
}
return nil
}

func (st *userStore) Delete(ctx context.Context, usrIDs *api.UserIDs) error {
tnt := tenant.FromContext(ctx)
model := UserModel{
ID: usrIDs.UserId,
Tenant: TenantModel{ID: tnt.GetIds().TenantId},
}
model := userModel{Email: usrIDs.Email}
tx := st.DB.Delete(&model)
if tx.Error != nil {
return tx.Error
}
return nil
return tx.Error
}

0 comments on commit 3beaa29

Please sign in to comment.