Generic Repository
Overview
The Repository[T] interface is the primary data access API. It’s parameterized with Go generics for compile-time type safety — every operation returns the concrete type, not interface{}.
Creating Repositories
// From the provider registry (recommended)
userRepo := gpagorm.GetRepository[User]()
postRepo := gpagorm.GetRepository[Post]()
// From a specific provider instance
provider := gpa.MustGet[*gpagorm.Provider]("primary")
userRepo := gpagorm.GetRepository[User](provider)CRUD Operations
Create
user := &User{Name: "John", Email: "john@example.com"}
err := userRepo.Create(ctx, user)
// user.ID is now populatedCreate Batch
users := []*User{
{Name: "Alice"},
{Name: "Bob"},
}
err := userRepo.CreateBatch(ctx, users)Find By ID
user, err := userRepo.FindByID(ctx, 1)
// user is *User, not interface{}Find All
users, err := userRepo.FindAll(ctx)
// users is []*UserUpdate
user.Name = "Jane"
err := userRepo.Update(ctx, user)Partial Update
err := userRepo.UpdatePartial(ctx, 1, map[string]interface{}{
"status": "inactive",
"age": 31,
})Delete
err := userRepo.Delete(ctx, 1)Delete by Condition
err := userRepo.DeleteByCondition(ctx, gpa.Where("status", gpa.OpEqual, "inactive"))Query Operations
// Find with conditions
users, err := userRepo.Query(ctx,
gpa.Where("age", gpa.OpGreaterThan, 18),
gpa.Where("status", gpa.OpEqual, "active"),
)
// Find single result
user, err := userRepo.QueryOne(ctx,
gpa.Where("email", gpa.OpEqual, "user@example.com"),
)
// Count
count, err := userRepo.Count(ctx, gpa.Where("active", gpa.OpEqual, true))
// Check existence
exists, err := userRepo.Exists(ctx, gpa.Where("email", gpa.OpEqual, "user@example.com"))Repository Interface
type Repository[T any] interface {
// Basic CRUD
Create(ctx context.Context, entity *T) error
CreateBatch(ctx context.Context, entities []*T) error
FindByID(ctx context.Context, id interface{}) (*T, error)
FindAll(ctx context.Context, opts ...QueryOption) ([]*T, error)
Update(ctx context.Context, entity *T) error
UpdatePartial(ctx context.Context, id interface{}, updates map[string]interface{}) error
Delete(ctx context.Context, id interface{}) error
DeleteByCondition(ctx context.Context, condition Condition) error
// Query
Query(ctx context.Context, opts ...QueryOption) ([]*T, error)
QueryOne(ctx context.Context, opts ...QueryOption) (*T, error)
Count(ctx context.Context, opts ...QueryOption) (int64, error)
Exists(ctx context.Context, opts ...QueryOption) (bool, error)
// Advanced
Transaction(ctx context.Context, fn TransactionFunc[T]) error
RawQuery(ctx context.Context, query string, args []interface{}) ([]*T, error)
RawExec(ctx context.Context, query string, args []interface{}) (Result, error)
// Metadata
GetEntityInfo() (*EntityInfo, error)
Close() error
}SQL-Specific Repositories
SQL providers support additional operations through specialized interfaces:
SQLRepository[T]
type SQLRepository[T any] interface {
Repository[T]
FindBySQL(ctx, sql string, args []interface{}) ([]*T, error)
ExecSQL(ctx, sql string, args ...interface{}) (Result, error)
FindWithRelations(ctx, relations []string, opts ...QueryOption) ([]*T, error)
FindByIDWithRelations(ctx, id interface{}, relations []string) (*T, error)
CreateTable(ctx) error
DropTable(ctx) error
CreateIndex(ctx, fields []string, unique bool) error
DropIndex(ctx, indexName string) error
}MigratableRepository[T]
type MigratableRepository[T any] interface {
SQLRepository[T]
MigrateTable(ctx) error
GetMigrationStatus(ctx) (MigrationStatus, error)
GetTableInfo(ctx) (TableInfo, error)
}KV-Specific Repositories
Redis and other key-value stores use specialized interfaces:
// Basic KV operations
type BasicKeyValueRepository[T any] interface {
Get(ctx, key) (*T, error)
Set(ctx, key, value *T) error
DeleteKey(ctx, key) error
KeyExists(ctx, key) (bool, error)
}
// TTL support
type TTLKeyValueRepository[T any] interface {
SetWithTTL(ctx, key, value, ttl) error
TTL(ctx, key) (time.Duration, error)
SetTTL(ctx, key, ttl) error
RemoveTTL(ctx, key) error
}Document-Specific Repositories
MongoDB and other document databases:
type DocumentRepository[T any] interface {
Repository[T]
FindByDocument(ctx, doc map[string]interface{}) ([]*T, error)
TextSearch(ctx, query string, opts ...QueryOption) ([]*T, error)
FindNear(ctx, field string, point []float64, maxDistance float64) ([]*T, error)
Aggregate(ctx, pipeline []map[string]interface{}) ([]map[string]interface{}, error)
CreateCollection(ctx) error
DropCollection(ctx) error
}