From ca02fabb917dde893f1abbbfaf253a3d8e5dc84f Mon Sep 17 00:00:00 2001 From: Ibrahim Serdar Acikgoz Date: Fri, 17 Dec 2021 11:39:25 +0300 Subject: [PATCH] allow upsert for duplicate key --- store/sqlstore/link_metadata_store.go | 16 ++++++++++++---- store/storetest/link_metadata_store.go | 4 ++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/store/sqlstore/link_metadata_store.go b/store/sqlstore/link_metadata_store.go index bfbc173c0c..67413b31da 100644 --- a/store/sqlstore/link_metadata_store.go +++ b/store/sqlstore/link_metadata_store.go @@ -50,15 +50,23 @@ func (s SqlLinkMetadataStore) Save(metadata *model.LinkMetadata) (*model.LinkMet return nil, errors.Wrap(err, "could not serialize metadataBytes to JSON") } - query, args, err := s.getQueryBuilder(). + query := s.getQueryBuilder(). Insert("LinkMetadata"). Columns("Hash", "URL", "Timestamp", "Type", "Data"). - Values(metadata.Hash, metadata.URL, metadata.Timestamp, metadata.Type, string(metadataBytes)). - ToSql() + Values(metadata.Hash, metadata.URL, metadata.Timestamp, metadata.Type, string(metadataBytes)) + + if s.DriverName() == model.DatabaseDriverMysql { + query = query.SuffixExpr(sq.Expr("ON DUPLICATE KEY UPDATE URL = ?, Timestamp = ?, Type = ?, Data = ?", metadata.URL, metadata.Timestamp, metadata.Type, string(metadataBytes))) + } else { + query = query.SuffixExpr(sq.Expr("ON CONFLICT (hash) DO UPDATE SET URL = ?, Timestamp = ?, Type = ?, Data = ?", metadata.URL, metadata.Timestamp, metadata.Type, string(metadataBytes))) + } + + q, args, err := query.ToSql() if err != nil { return nil, errors.Wrap(err, "metadata_tosql") } - _, err = s.GetMasterX().Exec(query, args...) + + _, err = s.GetMasterX().Exec(q, args...) if err != nil && !IsUniqueConstraintError(err, []string{"PRIMARY", "linkmetadata_pkey"}) { return nil, errors.Wrap(err, "could not save link metadata") } diff --git a/store/storetest/link_metadata_store.go b/store/storetest/link_metadata_store.go index c4a7986af6..0550a56451 100644 --- a/store/storetest/link_metadata_store.go +++ b/store/storetest/link_metadata_store.go @@ -95,7 +95,7 @@ func testLinkMetadataStoreSave(t *testing.T, ss store.Store) { assert.Equal(t, *metadata, *linkMetadata) }) - t.Run("should not save with duplicate URL and timestamp, but should not return an error", func(t *testing.T) { + t.Run("should save data with duplicate URL and timestamp", func(t *testing.T) { metadata := &model.LinkMetadata{ URL: "http://example.com", Timestamp: getNextLinkMetadataTimestamp(), @@ -116,7 +116,7 @@ func testLinkMetadataStoreSave(t *testing.T, ss store.Store) { // Should return the original result, not the duplicate one linkMetadata, err = ss.LinkMetadata().Get(metadata.URL, metadata.Timestamp) require.NoError(t, err) - assert.Equal(t, &model.PostImage{}, linkMetadata.Data) + assert.NotEqual(t, &model.PostImage{}, linkMetadata.Data) }) }