From ecd8ea2e6824d593315a82b4f855c75281bcaa29 Mon Sep 17 00:00:00 2001 From: Geoffrey Ragot Date: Sun, 29 Sep 2024 23:53:27 +0200 Subject: [PATCH] feat: move logs model --- internal/log.go | 61 +++++++++++++++++++-------------- internal/storage/ledger/logs.go | 57 ++++++++---------------------- 2 files changed, 50 insertions(+), 68 deletions(-) diff --git a/internal/log.go b/internal/log.go index 1ecd10379..966965035 100644 --- a/internal/log.go +++ b/internal/log.go @@ -2,8 +2,10 @@ package ledger import ( "crypto/sha256" + "database/sql/driver" "encoding/json" "fmt" + "github.com/uptrace/bun" "reflect" "strconv" "strings" @@ -14,8 +16,6 @@ import ( "github.com/pkg/errors" ) -type LogType int16 - const ( SetMetadataLogType LogType = iota // "SET_METADATA" NewTransactionLogType // "NEW_TRANSACTION" @@ -23,6 +23,32 @@ const ( DeleteMetadataLogType ) +type LogType int16 + +func (lt LogType) Value() (driver.Value, error) { + return lt.String(), nil +} + +func (lt *LogType) Scan(src interface{}) error { + *lt = LogTypeFromString(string(src.([]byte))) + return nil +} + +func (lt LogType) MarshalJSON() ([]byte, error) { + return json.Marshal(lt.String()) +} + +func (lt *LogType) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + + *lt = LogTypeFromString(s) + + return nil +} + func (l LogType) String() string { switch l { case SetMetadataLogType: @@ -53,32 +79,17 @@ func LogTypeFromString(logType string) LogType { panic(errors.New("invalid log type")) } -// Needed in order to keep the compatibility with the openapi response for -// ListLogs. -func (lt LogType) MarshalJSON() ([]byte, error) { - return json.Marshal(lt.String()) -} - -func (lt *LogType) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - - *lt = LogTypeFromString(s) - - return nil -} - // Log represents atomic actions made on the ledger. // notes(gfyrag): Keep keys ordered! the order matter when hashing the log. type Log struct { - Type LogType `json:"type"` - Data any `json:"data"` - Date time.Time `json:"date"` - IdempotencyKey string `json:"idempotencyKey"` - ID int `json:"id"` - Hash []byte `json:"hash"` + bun.BaseModel `bun:"table:logs,alias:logs"` + + Type LogType `json:"type" bun:"type,type:log_type"` + Data any `json:"data" bun:"data,type:jsonb"` + Date time.Time `json:"date" bun:"date,type:timestamptz"` + IdempotencyKey string `json:"idempotencyKey" bun:"idempotency_key,type:varchar(256),unique,nullzero"` + ID int `json:"id" bun:"id,unique,type:numeric"` + Hash []byte `json:"hash" bun:"hash,type:bytea,scanonly"` } func (l Log) WithIdempotencyKey(key string) Log { diff --git a/internal/storage/ledger/logs.go b/internal/storage/ledger/logs.go index 3ec3d4f6b..9c19be57f 100644 --- a/internal/storage/ledger/logs.go +++ b/internal/storage/ledger/logs.go @@ -12,45 +12,28 @@ import ( "github.com/formancehq/go-libs/platform/postgres" "github.com/formancehq/go-libs/pointer" "github.com/formancehq/go-libs/query" - "github.com/formancehq/go-libs/time" ledger "github.com/formancehq/ledger/internal" ledgercontroller "github.com/formancehq/ledger/internal/controller/ledger" "github.com/pkg/errors" - "github.com/uptrace/bun" ) +// Log override ledger.Log to be able to properly read/write payload which is jsonb +// on the database and 'any' on the Log structure (data column) type Log struct { - bun.BaseModel `bun:"table:logs,alias:logs"` - - Ledger string `bun:"ledger,type:varchar"` - ID int `bun:"id,unique,type:numeric"` - Type string `bun:"type,type:log_type"` - Hash []byte `bun:"hash,type:bytea,scanonly"` - Date time.Time `bun:"date,type:timestamptz"` - Data RawMessage `bun:"data,type:jsonb"` - IdempotencyKey *string `bun:"idempotency_key,type:varchar(256),unique"` + *ledger.Log `bun:",extend"` + + Ledger string `bun:"ledger,type:varchar"` + Data RawMessage `bun:"data,type:jsonb"` } func (log Log) toCore() ledger.Log { - - payload, err := ledger.HydrateLog(ledger.LogTypeFromString(log.Type), log.Data) + payload, err := ledger.HydrateLog(log.Type, log.Data) if err != nil { panic(errors.Wrap(err, "hydrating log data")) } + log.Log.Data = payload - return ledger.Log{ - Type: ledger.LogTypeFromString(log.Type), - Data: payload, - IdempotencyKey: func() string { - if log.IdempotencyKey != nil { - return *log.IdempotencyKey - } - return "" - }(), - Date: log.Date.UTC(), - ID: log.ID, - Hash: log.Hash, - } + return *log.Log } type RawMessage json.RawMessage @@ -79,22 +62,13 @@ func (s *Store) InsertLog(ctx context.Context, log *ledger.Log) error { return errors.Wrap(err, "failed to marshal log data") } - newLog := &Log{ - Ledger: s.ledger.Name, - Type: log.Type.String(), - Data: data, - Date: log.Date, - IdempotencyKey: func() *string { - if log.IdempotencyKey == "" { - return nil - } - return &log.IdempotencyKey - }(), - } - _, err = s.db. NewInsert(). - Model(newLog). + Model(&Log{ + Log: log, + Ledger: s.ledger.Name, + Data: data, + }). ModelTableExpr(s.GetPrefixedRelationName("logs")). Value("id", "nextval(?)", s.GetPrefixedRelationName(fmt.Sprintf(`"log_id_%d"`, s.ledger.ID))). Returning("*"). @@ -111,9 +85,6 @@ func (s *Store) InsertLog(ctx context.Context, log *ledger.Log) error { } } - log.ID = newLog.ID - log.Hash = newLog.Hash - return nil }))