@@ -32,6 +32,7 @@ type model struct {
3232 Quantity sql.NullInt64 `db:"quantity"`
3333 FeeType sql.NullInt32 `db:"fee_type"`
3434 State uint `db:"state"`
35+ Version int64 `db:"version"`
3536 CreatedAt time.Time `db:"created_at"`
3637}
3738
@@ -68,6 +69,7 @@ func toModel(obj *action.Record) (*model, error) {
6869 Quantity : quantity ,
6970 FeeType : feeType ,
7071 State : uint (obj .State ),
72+ Version : int64 (obj .Version ),
7173 CreatedAt : obj .CreatedAt ,
7274 }, nil
7375}
@@ -84,6 +86,7 @@ func fromModel(obj *model) *action.Record {
8486 Quantity : pointer .Uint64IfValid (obj .Quantity .Valid , uint64 (obj .Quantity .Int64 )),
8587 FeeType : (* transactionpb .FeePaymentAction_FeeType )(pointer .Int32IfValid (obj .FeeType .Valid , obj .FeeType .Int32 )),
8688 State : action .State (obj .State ),
89+ Version : uint64 (obj .Version ),
8790 CreatedAt : obj .CreatedAt ,
8891 }
8992}
@@ -94,18 +97,19 @@ func (m *model) dbUpdate(ctx context.Context, db *sqlx.DB) error {
9497 params := []interface {}{
9598 m .Intent ,
9699 m .ActionId ,
100+ m .Version ,
97101 m .State ,
98102 }
99103
100104 if m .IntentType == uint (intent .SendPublicPayment ) && m .ActionType == uint (action .NoPrivacyWithdraw ) {
101- quantityUpdateStmt = ", quantity = $4 "
105+ quantityUpdateStmt = ", quantity = $5 "
102106 params = append (params , m .Quantity )
103107 }
104108
105109 query := fmt .Sprintf (`UPDATE ` + tableName + `
106- SET state = $3%s
107- WHERE intent = $1 AND action_id = $2
108- RETURNING id, intent, intent_type, action_id, action_type, source, destination, quantity, fee_type, state, created_at
110+ SET state = $4%s, version = version + 1
111+ WHERE intent = $1 AND action_id = $2 AND version = $3
112+ RETURNING id, intent, intent_type, action_id, action_type, source, destination, quantity, fee_type, state, version, created_at
109113 ` , quantityUpdateStmt )
110114
111115 err := tx .QueryRowxContext (
@@ -114,7 +118,7 @@ func (m *model) dbUpdate(ctx context.Context, db *sqlx.DB) error {
114118 params ... ,
115119 ).StructScan (m )
116120 if err != nil {
117- return pgutil .CheckNoRows (err , action .ErrActionNotFound )
121+ return pgutil .CheckNoRows (err , action .ErrStaleVersion )
118122 }
119123
120124 return nil
@@ -124,7 +128,7 @@ func (m *model) dbUpdate(ctx context.Context, db *sqlx.DB) error {
124128func dbPutAllInTx (ctx context.Context , tx * sqlx.Tx , models []* model ) ([]* model , error ) {
125129 var res []* model
126130
127- query := `INSERT INTO ` + tableName + ` (intent, intent_type, action_id, action_type, source, destination, quantity, fee_type, state, created_at) VALUES `
131+ query := `INSERT INTO ` + tableName + ` (intent, intent_type, action_id, action_type, source, destination, quantity, fee_type, state, version, created_at) VALUES `
128132
129133 var parameters []interface {}
130134 for i , model := range models {
@@ -134,8 +138,8 @@ func dbPutAllInTx(ctx context.Context, tx *sqlx.Tx, models []*model) ([]*model,
134138
135139 baseIndex := len (parameters )
136140 query += fmt .Sprintf (
137- `($%d, $%d, $%d, $%d, $%d, $%d, $%d, $%d, $%d, $%d)` ,
138- baseIndex + 1 , baseIndex + 2 , baseIndex + 3 , baseIndex + 4 , baseIndex + 5 , baseIndex + 6 , baseIndex + 7 , baseIndex + 8 , baseIndex + 9 , baseIndex + 10 ,
141+ `($%d, $%d, $%d, $%d, $%d, $%d, $%d, $%d, $%d, $%d + 1, $%d )` ,
142+ baseIndex + 1 , baseIndex + 2 , baseIndex + 3 , baseIndex + 4 , baseIndex + 5 , baseIndex + 6 , baseIndex + 7 , baseIndex + 8 , baseIndex + 9 , baseIndex + 10 , baseIndex + 11 ,
139143 )
140144
141145 if i != len (models )- 1 {
@@ -153,11 +157,12 @@ func dbPutAllInTx(ctx context.Context, tx *sqlx.Tx, models []*model) ([]*model,
153157 model .Quantity ,
154158 model .FeeType ,
155159 model .State ,
160+ model .Version ,
156161 model .CreatedAt ,
157162 )
158163 }
159164
160- query += ` RETURNING id, intent, intent_type, action_id, action_type, source, destination, quantity, fee_type, state, created_at`
165+ query += ` RETURNING id, intent, intent_type, action_id, action_type, source, destination, quantity, fee_type, state, version, created_at`
161166
162167 err := tx .SelectContext (
163168 ctx ,
@@ -175,7 +180,7 @@ func dbPutAllInTx(ctx context.Context, tx *sqlx.Tx, models []*model) ([]*model,
175180func dbGetById (ctx context.Context , db * sqlx.DB , intent string , actionId uint32 ) (* model , error ) {
176181 res := & model {}
177182
178- query := `SELECT id, intent, intent_type, action_id, action_type, source, destination, quantity, fee_type, state, created_at
183+ query := `SELECT id, intent, intent_type, action_id, action_type, source, destination, quantity, fee_type, state, version, created_at
179184 FROM ` + tableName + `
180185 WHERE intent = $1 AND action_id = $2
181186 LIMIT 1`
@@ -190,7 +195,7 @@ func dbGetById(ctx context.Context, db *sqlx.DB, intent string, actionId uint32)
190195func dbGetAllByIntent (ctx context.Context , db * sqlx.DB , intent string ) ([]* model , error ) {
191196 res := []* model {}
192197
193- query := `SELECT id, intent, intent_type, action_id, action_type, source, destination, quantity, fee_type, state, created_at
198+ query := `SELECT id, intent, intent_type, action_id, action_type, source, destination, quantity, fee_type, state, version, created_at
194199 FROM ` + tableName + `
195200 WHERE intent = $1
196201 ORDER BY action_id ASC`
@@ -210,7 +215,7 @@ func dbGetAllByIntent(ctx context.Context, db *sqlx.DB, intent string) ([]*model
210215func dbGetAllByAddress (ctx context.Context , db * sqlx.DB , address string ) ([]* model , error ) {
211216 res := []* model {}
212217
213- query := `SELECT id, intent, intent_type, action_id, action_type, source, destination, quantity, fee_type, state, created_at
218+ query := `SELECT id, intent, intent_type, action_id, action_type, source, destination, quantity, fee_type, state, version, created_at
214219 FROM ` + tableName + `
215220 WHERE source = $1 OR destination = $1`
216221
@@ -300,7 +305,7 @@ func dbGetNetBalanceBatch(ctx context.Context, db *sqlx.DB, accounts ...string)
300305func dbGetGiftCardClaimedAction (ctx context.Context , db * sqlx.DB , giftCardVault string ) (* model , error ) {
301306 res := []* model {}
302307
303- query := `SELECT id, intent, intent_type, action_id, action_type, source, destination, quantity, fee_type, state, created_at
308+ query := `SELECT id, intent, intent_type, action_id, action_type, source, destination, quantity, fee_type, state, version, created_at
304309 FROM ` + tableName + `
305310 WHERE source = $1 AND action_type = $2 AND intent_type = $3 AND state != $4
306311 LIMIT 2`
@@ -330,7 +335,7 @@ func dbGetGiftCardClaimedAction(ctx context.Context, db *sqlx.DB, giftCardVault
330335func dbGetGiftCardAutoReturnAction (ctx context.Context , db * sqlx.DB , giftCardVault string ) (* model , error ) {
331336 res := []* model {}
332337
333- query := `SELECT id, intent, intent_type, action_id, action_type, source, destination, quantity, fee_type, state, created_at
338+ query := `SELECT id, intent, intent_type, action_id, action_type, source, destination, quantity, fee_type, state, version, created_at
334339 FROM ` + tableName + `
335340 WHERE source = $1 AND action_type = $2 AND intent_type = $3 AND state != $4
336341 LIMIT 2`
0 commit comments