Skip to content

Latest commit

 

History

History
110 lines (82 loc) · 3.04 KB

File metadata and controls

110 lines (82 loc) · 3.04 KB

data

Tier: Platform · Status: Full · Java original: firefly-common-data (R2DBC) · .NET project: FireflyFramework.Data

Overview

data provides the persistence abstractions every Firefly service shares — a generic filter DSL that renders to parameterised SQL, a canonical Page[T] paged-result envelope, and a typed Repository[T,K] contract with an in-memory implementation for tests. A pgx-backed implementation is on the v26.06 roadmap; until then, services that talk to PostgreSQL define their own typed repository conforming to the Repository[T, K] interface.

Public surface

Page[T]

type Page[T any] struct {
    Content       []T
    Number        int    // zero-based page index
    Size          int
    TotalElements int64
    TotalPages    int
}

func NewPage[T any](content []T, number, size int, total int64) Page[T]
func Empty[T any]() Page[T]

The wire-shape is identical to the Java/.NET Page<T> so SDK clients dispatch on the same JSON.

Filter DSL

type Op string  // OpEq | OpNe | OpLt | OpLte | OpGt | OpGte | OpLike | OpILike | OpIn | OpIsNil

type Predicate struct { Field string; Op Op; Value any }
type Sort struct { Field string; Direction Direction } // Asc | Desc

type Filter struct {
    Predicates []Predicate
    Sorts      []Sort
    Page       int
    Size       int
}

func (*Filter) Where(field, value) *Filter
func (*Filter) Add(Predicate) *Filter
func (*Filter) OrderBy(field, dir) *Filter
func (*Filter) Paged(page, size) *Filter
func (Filter) ToSQL() (string, []any)  // -> " WHERE …", []any{…}

ToSQL renders a parameterised PostgreSQL fragment using $1, $2, … argument placeholders. Identifier quoting is double-quoted.

Repository contract

type Repository[T any, K comparable] interface {
    FindByID(ctx context.Context, id K) (T, error)
    Find(ctx context.Context, f Filter) (Page[T], error)
    Save(ctx context.Context, entity T) (T, error)
    Delete(ctx context.Context, id K) error
}

var ErrNotFound = errors.New("firefly/data: not found")

MemoryRepository

In-process implementation of Repository, parameterised on a user-supplied keyer func(T) K. Honours paging; does not honour predicates (use a SQL-backed Repository for filtering).

Quick start

import (
    "context"
    "github.com/fireflyframework/fireflyframework-go/data"
)

type User struct { ID, Name string }

repo := data.NewMemoryRepository[User, string](func(u User) string { return u.ID })
_, _ = repo.Save(ctx, User{ID: "u1", Name: "alice"})

f := data.Filter{}
f.Where("name", "alice").OrderBy("id", data.Asc).Paged(0, 10)
page, _ := repo.Find(ctx, f)

For a real Postgres-backed repository, implement the Repository interface against pgx.Conn / *sql.DB, using f.ToSQL() to render the WHERE / ORDER BY / LIMIT clauses.

Testing

cd data
go test ./...

Covers Page total-pages math, every Op rendering correctly, predicate ↔ argument index mapping with OpIsNil skipping arg slots, and the in-memory repository's CRUD + paging.