@@ -2,7 +2,6 @@ package ledger
2
2
3
3
import (
4
4
"context"
5
- "database/sql"
6
5
"fmt"
7
6
. "github.com/formancehq/go-libs/v2/bun/bunpaginate"
8
7
"github.com/formancehq/ledger/pkg/features"
@@ -12,11 +11,8 @@ import (
12
11
13
12
"github.com/formancehq/go-libs/v2/metadata"
14
13
"github.com/formancehq/go-libs/v2/platform/postgres"
15
- ledgercontroller "github.com/formancehq/ledger/internal/controller/ledger"
16
- "go.opentelemetry.io/otel/attribute"
17
- "go.opentelemetry.io/otel/trace"
18
-
19
14
"github.com/formancehq/go-libs/v2/time"
15
+ ledgercontroller "github.com/formancehq/ledger/internal/controller/ledger"
20
16
21
17
"github.com/formancehq/go-libs/v2/query"
22
18
ledger "github.com/formancehq/ledger/internal"
@@ -333,45 +329,29 @@ func (s *Store) DeleteAccountMetadata(ctx context.Context, account, key string)
333
329
return err
334
330
}
335
331
336
- // todo: since we update first balances of an accounts in the transaction process, we can avoid nested sql txs
337
- // while upserting account and upsert them all in one shot
338
- func (s * Store ) UpsertAccount (ctx context.Context , account * ledger.Account ) (bool , error ) {
339
- return tracing .TraceWithMetric (
332
+ func (s * Store ) UpsertAccounts (ctx context.Context , accounts ... * ledger.Account ) error {
333
+ return tracing .SkipResult (tracing .TraceWithMetric (
340
334
ctx ,
341
- "UpsertAccount " ,
335
+ "UpsertAccounts " ,
342
336
s .tracer ,
343
- s .upsertAccountHistogram ,
344
- func (ctx context.Context ) (bool , error ) {
345
- upserted := false
346
- err := s .db .RunInTx (ctx , & sql.TxOptions {}, func (ctx context.Context , tx bun.Tx ) error {
347
- ret , err := tx .NewInsert ().
348
- Model (account ).
349
- ModelTableExpr (s .GetPrefixedRelationName ("accounts" )).
350
- On ("conflict (ledger, address) do update" ).
351
- Set ("first_usage = case when ? < excluded.first_usage then ? else excluded.first_usage end" , account .FirstUsage , account .FirstUsage ).
352
- Set ("metadata = accounts.metadata || excluded.metadata" ).
353
- Set ("updated_at = excluded.updated_at" ).
354
- Value ("ledger" , "?" , s .ledger .Name ).
355
- Returning ("*" ).
356
- Where ("(? < accounts.first_usage) or not accounts.metadata @> excluded.metadata" , account .FirstUsage ).
357
- Exec (ctx )
358
- if err != nil {
359
- return err
360
- }
361
- rowsModified , err := ret .RowsAffected ()
362
- if err != nil {
363
- return err
364
- }
365
- upserted = rowsModified > 0
366
- return nil
367
- })
368
- return upserted , postgres .ResolveError (err )
369
- },
370
- func (ctx context.Context , upserted bool ) {
371
- trace .SpanFromContext (ctx ).SetAttributes (
372
- attribute .String ("address" , account .Address ),
373
- attribute .Bool ("upserted" , upserted ),
374
- )
375
- },
376
- )
337
+ s .upsertAccountsHistogram ,
338
+ tracing .NoResult (func (ctx context.Context ) error {
339
+ _ , err := s .db .NewInsert ().
340
+ Model (& accounts ).
341
+ ModelTableExpr (s .GetPrefixedRelationName ("accounts" )).
342
+ On ("conflict (ledger, address) do update" ).
343
+ Set ("first_usage = case when excluded.first_usage < accounts.first_usage then excluded.first_usage else accounts.first_usage end" ).
344
+ Set ("metadata = accounts.metadata || excluded.metadata" ).
345
+ Set ("updated_at = excluded.updated_at" ).
346
+ Value ("ledger" , "?" , s .ledger .Name ).
347
+ Returning ("*" ).
348
+ Where ("(excluded.first_usage < accounts.first_usage) or not accounts.metadata @> excluded.metadata" ).
349
+ Exec (ctx )
350
+ if err != nil {
351
+ return fmt .Errorf ("upserting accounts: %w" , postgres .ResolveError (err ))
352
+ }
353
+
354
+ return nil
355
+ }),
356
+ ))
377
357
}
0 commit comments