diff --git a/internal/repository/base_repository.go b/internal/repository/base_repository.go new file mode 100644 index 0000000..06195c9 --- /dev/null +++ b/internal/repository/base_repository.go @@ -0,0 +1,76 @@ +package repository + +import ( + "database/sql" + "fmt" +) + +type baseRepository[T any] struct { + db *sql.DB + tableName string +} + +func NewBaseRepository[T any](db *sql.DB, tableName string) Repository[T] { + return &baseRepository[T]{ + db: db, + tableName: tableName, + } +} + +func (r *baseRepository[T]) BuildQuery(baseQuery string) string { + return fmt.Sprintf(baseQuery, r.tableName) +} + +func (r *baseRepository[T]) GetDB() *sql.DB { + return r.db +} + +func (r *baseRepository[T]) GetByID(id int) (*T, error) { + var entity T + + query := r.BuildQuery("SELECT * FROM %s WHERE id = ?") + err := r.db.QueryRow( + query, + id, + ).Scan(entity) + + if err != nil { + if err == sql.ErrNoRows { + return nil, nil + } + return nil, err + } + + return &entity, nil +} + +func (r *baseRepository[T]) GetAll() ([]T, error) { + query := r.BuildQuery("SELECT * FROM %s ORDER BY id DESC") + + rows, err := r.db.Query(query) + if err != nil { + return nil, err + } + defer rows.Close() + + entities := make([]T, 0) + for rows.Next() { + var entity T + if err := rows.Scan(entity); err != nil { + return nil, err + } + entities = append(entities, entity) + } + + if err = rows.Err(); err != nil { + return nil, err + } + + return entities, nil +} + +func (r *baseRepository[T]) Delete(id int) error { + query := r.BuildQuery("DELETE %s WHERE id = ? LIMIT 1") + _, err := r.db.Exec(query, id) + return err +} diff --git a/internal/repository/contact_repository.go b/internal/repository/contact_repository.go new file mode 100644 index 0000000..9f34a5b --- /dev/null +++ b/internal/repository/contact_repository.go @@ -0,0 +1,57 @@ +package repository + +import ( + "database/sql" + + "gitea.gabilandia.com/gabdlr/agenda-web-go/internal/models" +) + +type ContactRepository struct { + baseRepository[models.Contact] +} + +func NewContactRepository(db *sql.DB) *ContactRepository { + return &ContactRepository{ + baseRepository[models.Contact]{ + db: db, + tableName: "contacts", + }} +} + +func (r *ContactRepository) Create(contact *models.Contact) (int64, error) { + query := r.BuildQuery("INSERT INTO %s (name, company, phone) VALUES (?, ?, ?)") + + result, err := r.db.Exec( + query, + contact.Name, contact.Company, contact.Phone, + ) + if err != nil { + return 0, err + } + + id, err := result.LastInsertId() + if err != nil { + return 0, err + } + + contact.ID = int(id) + return id, nil +} + +func (r *ContactRepository) Update(contact *models.Contact) (int64, error) { + query := r.BuildQuery("UPDATE %s SET name = ?, company = ?, phone = ? WHERE id = ?") + result, err := r.db.Exec(query, + contact.Name, contact.Company, contact.Phone, contact.ID, + ) + + if err != nil { + return 0, err + } + + rowsAffected, err := result.RowsAffected() + if err != nil { + return 0, err + } + + return rowsAffected, nil +} diff --git a/internal/repository/interfaces.go b/internal/repository/interfaces.go new file mode 100644 index 0000000..6e2cea8 --- /dev/null +++ b/internal/repository/interfaces.go @@ -0,0 +1,8 @@ +package repository + +type Repository[T any] interface { + BuildQuery(s string) string + GetByID(id int) (*T, error) + GetAll() ([]T, error) + Delete(id int) error +}