83 lines
1.7 KiB
Go
83 lines
1.7 KiB
Go
package database
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// Trackable interface for models that can track field changes
|
|
type Trackable interface {
|
|
GetTableName() string
|
|
GetID() int
|
|
GetDirtyFields() map[string]any
|
|
SetDirty(field string, value any)
|
|
ClearDirty()
|
|
IsDirty() bool
|
|
}
|
|
|
|
// FieldTracker provides dirty field tracking functionality
|
|
type FieldTracker struct {
|
|
dirty map[string]any
|
|
}
|
|
|
|
// SetDirty marks a field as dirty with its new value
|
|
func (ft *FieldTracker) SetDirty(field string, value any) {
|
|
if ft.dirty == nil {
|
|
ft.dirty = make(map[string]any)
|
|
}
|
|
ft.dirty[field] = value
|
|
}
|
|
|
|
// GetDirtyFields returns map of dirty fields and their values
|
|
func (ft *FieldTracker) GetDirtyFields() map[string]any {
|
|
if ft.dirty == nil {
|
|
return make(map[string]any)
|
|
}
|
|
return ft.dirty
|
|
}
|
|
|
|
// ClearDirty clears all dirty field tracking
|
|
func (ft *FieldTracker) ClearDirty() {
|
|
ft.dirty = nil
|
|
}
|
|
|
|
// IsDirty returns true if any fields have been modified
|
|
func (ft *FieldTracker) IsDirty() bool {
|
|
return len(ft.dirty) > 0
|
|
}
|
|
|
|
// UpdateDirty updates only dirty fields in the database
|
|
func UpdateDirty(model Trackable) error {
|
|
if !model.IsDirty() {
|
|
return nil // No changes to save
|
|
}
|
|
|
|
dirty := model.GetDirtyFields()
|
|
if len(dirty) == 0 {
|
|
return nil
|
|
}
|
|
|
|
// Build dynamic UPDATE query
|
|
var setParts []string
|
|
var args []any
|
|
|
|
for field, value := range dirty {
|
|
setParts = append(setParts, field+" = ?")
|
|
args = append(args, value)
|
|
}
|
|
|
|
args = append(args, model.GetID()) // Add ID for WHERE clause
|
|
|
|
query := fmt.Sprintf("UPDATE %s SET %s WHERE id = ?",
|
|
model.GetTableName(),
|
|
strings.Join(setParts, ", "))
|
|
|
|
err := Exec(query, args...)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to update %s: %w", model.GetTableName(), err)
|
|
}
|
|
|
|
model.ClearDirty()
|
|
return nil
|
|
}
|