@@ -322,22 +322,61 @@ func (r *AssetRepository) getByVersion(
322
322
return ast .toVersionedAsset (latest )
323
323
}
324
324
325
+ // UpsertPatch creates a new asset if it does not exist yet.
326
+ // It updates if asset does exist.
327
+ // Checking existence is done using "urn", "type", and "service" fields
328
+ // And will revalidate again with additional: "data" and "name" fields.
325
329
func (r * AssetRepository ) UpsertPatch (ctx context.Context , ast * asset.Asset , patchData map [string ]interface {}) (asset.Asset , error ) {
326
- return r .upsertWithPatchOption (ctx , ast , patchData )
327
- }
330
+ var upsertedAsset asset.Asset
331
+ err := r .client .RunWithinTx (ctx , func (tx * sqlx.Tx ) error {
332
+ fetchedAsset , err := r .GetByURNWithTx (ctx , tx , ast .URN )
333
+ if errors .As (err , new (asset.NotFoundError )) {
334
+ err = nil
335
+ }
336
+ if err != nil {
337
+ return fmt .Errorf ("error getting asset by URN: %w" , err )
338
+ }
328
339
329
- func (r * AssetRepository ) Upsert (ctx context.Context , ast * asset.Asset ) (asset.Asset , error ) {
330
- return r .upsertWithPatchOption (ctx , ast , nil )
340
+ if fetchedAsset .ID == "" {
341
+ // insert flow
342
+ upsertedAsset , err = r .insert (ctx , tx , ast )
343
+ if err != nil {
344
+ return fmt .Errorf ("error inserting asset to DB: %w" , err )
345
+ }
346
+ return nil
347
+ }
348
+
349
+ // update flow
350
+ if err := copier .CopyWithOption (& ast , & fetchedAsset , copier.Option {DeepCopy : true }); err != nil {
351
+ return err
352
+ }
353
+ ast .Patch (patchData )
354
+ if err := r .validateAsset (* ast ); err != nil {
355
+ return err
356
+ }
357
+ changelog , err := fetchedAsset .Diff (ast )
358
+ if err != nil {
359
+ return fmt .Errorf ("error diffing two assets: %w" , err )
360
+ }
361
+
362
+ upsertedAsset , err = r .update (ctx , tx , ast , & fetchedAsset , changelog )
363
+ if err != nil {
364
+ return fmt .Errorf ("error updating asset to DB: %w" , err )
365
+ }
366
+
367
+ return nil
368
+ })
369
+ if err != nil {
370
+ return asset.Asset {}, err
371
+ }
372
+
373
+ return upsertedAsset , nil
331
374
}
332
375
333
376
// Upsert creates a new asset if it does not exist yet.
334
377
// It updates if asset does exist.
335
- // Checking existence is done using "urn", "type", and "service" fields.
336
- func (r * AssetRepository ) upsertWithPatchOption ( //nolint:gocognit
337
- ctx context.Context ,
338
- ast * asset.Asset ,
339
- patchData map [string ]interface {},
340
- ) (asset.Asset , error ) {
378
+ // Checking existence is done using "urn", "type", "name", "data", and "service" fields.
379
+ func (r * AssetRepository ) Upsert (ctx context.Context , ast * asset.Asset ) (asset.Asset , error ) {
341
380
var upsertedAsset asset.Asset
342
381
err := r .client .RunWithinTx (ctx , func (tx * sqlx.Tx ) error {
343
382
fetchedAsset , err := r .GetByURNWithTx (ctx , tx , ast .URN )
@@ -347,27 +386,17 @@ func (r *AssetRepository) upsertWithPatchOption( //nolint:gocognit
347
386
if err != nil {
348
387
return fmt .Errorf ("error getting asset by URN: %w" , err )
349
388
}
350
- if err := r .validateAsset (fetchedAsset ); err != nil {
351
- return err
352
- }
353
389
354
390
if fetchedAsset .ID == "" {
355
391
// insert flow
356
392
upsertedAsset , err = r .insert (ctx , tx , ast )
357
393
if err != nil {
358
394
return fmt .Errorf ("error inserting asset to DB: %w" , err )
359
395
}
396
+
360
397
return nil
361
398
}
362
399
363
- // update flow
364
- if patchData != nil {
365
- err := copier .CopyWithOption (& ast , & fetchedAsset , copier.Option {DeepCopy : true })
366
- if err != nil {
367
- return err
368
- }
369
- ast .Patch (patchData )
370
- }
371
400
changelog , err := fetchedAsset .Diff (ast )
372
401
if err != nil {
373
402
return fmt .Errorf ("error diffing two assets: %w" , err )
@@ -614,6 +643,7 @@ func (r *AssetRepository) insert(ctx context.Context, tx *sqlx.Tx, ast *asset.As
614
643
"created_at" , "updated_by" , "updated_at" , "refreshed_at" , "version" ).
615
644
Values (ast .URN , ast .Type , ast .Service , ast .Name , ast .Description , ast .Data , ast .URL , ast .Labels ,
616
645
ast .CreatedAt , ast .UpdatedBy .ID , ast .UpdatedAt , currentTime , asset .BaseVersion ).
646
+ Suffix ("RETURNING \" id\" " ).
617
647
PlaceholderFormat (sq .Dollar ).
618
648
ToSql ()
619
649
if err != nil {
@@ -622,9 +652,12 @@ func (r *AssetRepository) insert(ctx context.Context, tx *sqlx.Tx, ast *asset.As
622
652
623
653
ast .Version = asset .BaseVersion
624
654
625
- if err := r .execContext (ctx , tx , query , args ... ); err != nil {
655
+ var id string
656
+ err = tx .QueryRowContext (ctx , query , args ... ).Scan (& id )
657
+ if err != nil {
626
658
return asset.Asset {}, fmt .Errorf ("run insert query: %w" , err )
627
659
}
660
+ ast .ID = id
628
661
629
662
users , err := r .createOrFetchUsers (ctx , tx , ast .Owners )
630
663
if err != nil {
0 commit comments