package repository import ( "reflect" "strings" "git.gdulai.com/gdulai/simpleorm" "git.gdulai.com/gdulai/simpleorm/exec" log "gitlab.com/gdulai/simpleloglvl" ) type HasPK interface { IsInsertable() bool } type Repository[T HasPK] struct { conn *simpleorm.DBConnection orm *simpleorm.ORM } func NewRepository[T HasPK](conn *simpleorm.DBConnection, orm *simpleorm.ORM) *Repository[T] { return &Repository[T]{conn: conn, orm: orm} } func (r *Repository[T]) SelectAll() []*T { selectExec, err := exec.CreateSelect[T](r.orm) if err != nil { log.LogError("Failed to create select execution: %s", err) return []*T{} } err = selectExec.Execute(r.conn) if err != nil { log.LogError("Failed to load projects: %s", err) return []*T{} } selectRes := selectExec.Results() res := make([]*T, 0, len(selectRes)) for i := range selectRes { res = append(res, &selectRes[i]) } return res } func (r *Repository[T]) SelectByPk(pks ...any) *T { table, ok := r.orm.Cache().Get(reflect.TypeFor[T]().Name()) if !ok { log.LogError("Could not get cached Table!") return nil } var whereStmtBuilder strings.Builder for _, constr := range table.Constraints { if constr.Type != "pk" { continue } for i, col := range constr.Columns { if i != 0 { whereStmtBuilder.WriteString(" AND ") } whereStmtBuilder.WriteString(col.Name + " = ?") } } selectExec, err := exec.CreateSelect[T](r.orm) if err != nil { log.LogError("Failed to create select execution: %s", err) return nil } selectExec.Where(whereStmtBuilder.String(), pks) err = selectExec.Execute(r.conn) if err != nil { log.LogError("Failed to load entity: %s", err) return nil } selectRes := selectExec.Results() if len(selectRes) != 1 { log.LogError("Invalid result number of results: %s", len(selectRes)) return nil } return &selectRes[0] } func (r *Repository[T]) Save(entity *T) error { // Insert if (*entity).IsInsertable() { insertExec, err := exec.NewInsert[T](r.orm, *entity) if err != nil { return err } err = insertExec.Execute(r.conn) if err != nil { return err } result := insertExec.Results() // Point to the new inserted result *entity = result[0] return nil } updateExec, err := exec.NewUpdate[T](r.orm, *entity) if err != nil { return err } err = updateExec.Execute(r.conn) if err != nil { return err } return nil } func (r *Repository[T]) Delete(entity *T) { deleteExec, err := exec.NewDelete[T](r.orm, []T{*entity}) if err != nil { log.LogError("Failed to create delete execution: %s", err) return } err = deleteExec.Execute(r.conn) if err != nil { log.LogError("Delete failed: %s", err) return } }