github.com/kaleido-io/firefly@v0.0.0-20210622132723-8b4b6aacb971/internal/database/sqlcommon/pin_sql.go (about) 1 // Copyright © 2021 Kaleido, Inc. 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 package sqlcommon 18 19 import ( 20 "context" 21 "database/sql" 22 23 sq "github.com/Masterminds/squirrel" 24 "github.com/kaleido-io/firefly/internal/i18n" 25 "github.com/kaleido-io/firefly/internal/log" 26 "github.com/kaleido-io/firefly/pkg/database" 27 "github.com/kaleido-io/firefly/pkg/fftypes" 28 ) 29 30 var ( 31 pinColumns = []string{ 32 "masked", 33 "hash", 34 "batch_id", 35 "idx", 36 "dispatched", 37 "created", 38 } 39 pinFilterTypeMap = map[string]string{ 40 "batch": "batch_id", 41 "index": "idx", 42 } 43 ) 44 45 func (s *SQLCommon) UpsertPin(ctx context.Context, pin *fftypes.Pin) (err error) { 46 ctx, tx, autoCommit, err := s.beginOrUseTx(ctx) 47 if err != nil { 48 return err 49 } 50 defer s.rollbackTx(ctx, tx, autoCommit) 51 52 // Do a select within the transaction to detemine if the UUID already exists 53 pinRows, err := s.queryTx(ctx, tx, 54 sq.Select(s.provider.SequenceField(""), "masked", "dispatched"). 55 From("pins"). 56 Where(sq.Eq{ 57 "hash": pin.Hash, 58 "batch_id": pin.Batch, 59 "idx": pin.Index, 60 })) 61 if err != nil { 62 return err 63 } 64 existing := pinRows.Next() 65 66 if existing { 67 err := pinRows.Scan(&pin.Sequence, &pin.Masked, &pin.Dispatched) 68 pinRows.Close() 69 if err != nil { 70 return i18n.WrapError(ctx, err, i18n.MsgDBReadErr, "pins") 71 } 72 // Pin's can only go from undispatched, to dispatched - so no update here. 73 log.L(ctx).Debugf("Existing pin returned at sequence %d", pin.Sequence) 74 } else { 75 pinRows.Close() 76 if pin.Sequence, err = s.insertTx(ctx, tx, 77 sq.Insert("pins"). 78 Columns(pinColumns...). 79 Values( 80 pin.Masked, 81 pin.Hash, 82 pin.Batch, 83 pin.Index, 84 pin.Dispatched, 85 pin.Created, 86 ), 87 ); err != nil { 88 return err 89 } 90 91 s.postCommitEvent(tx, func() { 92 s.callbacks.PinCreated(pin.Sequence) 93 }) 94 95 } 96 97 return s.commitTx(ctx, tx, autoCommit) 98 } 99 100 func (s *SQLCommon) pinResult(ctx context.Context, row *sql.Rows) (*fftypes.Pin, error) { 101 pin := fftypes.Pin{} 102 err := row.Scan( 103 &pin.Masked, 104 &pin.Hash, 105 &pin.Batch, 106 &pin.Index, 107 &pin.Dispatched, 108 &pin.Created, 109 &pin.Sequence, 110 ) 111 if err != nil { 112 return nil, i18n.WrapError(ctx, err, i18n.MsgDBReadErr, "pins") 113 } 114 return &pin, nil 115 } 116 117 func (s *SQLCommon) GetPins(ctx context.Context, filter database.Filter) (message []*fftypes.Pin, err error) { 118 119 cols := append([]string{}, pinColumns...) 120 cols = append(cols, s.provider.SequenceField("")) 121 query, err := s.filterSelect(ctx, "", sq.Select(cols...).From("pins"), filter, pinFilterTypeMap) 122 if err != nil { 123 return nil, err 124 } 125 126 rows, err := s.query(ctx, query) 127 if err != nil { 128 return nil, err 129 } 130 defer rows.Close() 131 132 pin := []*fftypes.Pin{} 133 for rows.Next() { 134 d, err := s.pinResult(ctx, rows) 135 if err != nil { 136 return nil, err 137 } 138 pin = append(pin, d) 139 } 140 141 return pin, err 142 143 } 144 145 func (s *SQLCommon) SetPinDispatched(ctx context.Context, sequence int64) (err error) { 146 147 ctx, tx, autoCommit, err := s.beginOrUseTx(ctx) 148 if err != nil { 149 return err 150 } 151 defer s.rollbackTx(ctx, tx, autoCommit) 152 153 err = s.updateTx(ctx, tx, sq. 154 Update("pins"). 155 Set("dispatched", true). 156 Where(sq.Eq{ 157 s.provider.SequenceField(""): sequence, 158 })) 159 if err != nil { 160 return err 161 } 162 163 return s.commitTx(ctx, tx, autoCommit) 164 } 165 166 func (s *SQLCommon) DeletePin(ctx context.Context, sequence int64) (err error) { 167 168 ctx, tx, autoCommit, err := s.beginOrUseTx(ctx) 169 if err != nil { 170 return err 171 } 172 defer s.rollbackTx(ctx, tx, autoCommit) 173 174 err = s.deleteTx(ctx, tx, sq.Delete("pins").Where(sq.Eq{ 175 s.provider.SequenceField(""): sequence, 176 })) 177 if err != nil { 178 return err 179 } 180 181 return s.commitTx(ctx, tx, autoCommit) 182 }