code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/votes.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package sqlstore 17 18 import ( 19 "context" 20 "fmt" 21 "strings" 22 23 "code.vegaprotocol.io/vega/datanode/entities" 24 "code.vegaprotocol.io/vega/datanode/metrics" 25 v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2" 26 27 "github.com/georgysavva/scany/pgxscan" 28 ) 29 30 type Votes struct { 31 *ConnectionSource 32 } 33 34 var votesOrdering = TableOrdering{ 35 ColumnOrdering{Name: "vega_time", Sorting: ASC}, 36 } 37 38 func NewVotes(connectionSource *ConnectionSource) *Votes { 39 d := &Votes{ 40 ConnectionSource: connectionSource, 41 } 42 return d 43 } 44 45 func (vs *Votes) Add(ctx context.Context, v entities.Vote) error { 46 defer metrics.StartSQLQuery("Votes", "Add")() 47 _, err := vs.Exec(ctx, 48 `INSERT INTO votes( 49 proposal_id, 50 party_id, 51 value, 52 tx_hash, 53 vega_time, 54 initial_time, 55 total_governance_token_balance, 56 total_governance_token_weight, 57 total_equity_like_share_weight, 58 per_market_equity_like_share_weight 59 ) 60 VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) 61 ON CONFLICT (proposal_id, party_id, vega_time) DO UPDATE SET 62 value = EXCLUDED.value, 63 total_governance_token_balance =EXCLUDED.total_governance_token_balance, 64 total_governance_token_weight = EXCLUDED.total_governance_token_weight, 65 total_equity_like_share_weight = EXCLUDED.total_equity_like_share_weight, 66 per_market_equity_like_share_weight = EXCLUDED.per_market_equity_like_share_weight, 67 tx_hash = EXCLUDED.tx_hash; 68 `, 69 v.ProposalID, v.PartyID, v.Value, v.TxHash, v.VegaTime, v.InitialTime, 70 v.TotalGovernanceTokenBalance, v.TotalGovernanceTokenWeight, v.TotalEquityLikeShareWeight, v.PerMarketEquityLikeShareWeight) 71 return err 72 } 73 74 func (vs *Votes) GetYesVotesForProposal(ctx context.Context, proposalIDStr string) ([]entities.Vote, error) { 75 defer metrics.StartSQLQuery("Votes", "GetYesVotesForProposal")() 76 yes := entities.VoteValueYes 77 return vs.Get(ctx, &proposalIDStr, nil, &yes) 78 } 79 80 func (vs *Votes) GetNoVotesForProposal(ctx context.Context, proposalIDStr string) ([]entities.Vote, error) { 81 defer metrics.StartSQLQuery("Votes", "GetNoVotesForProposal")() 82 no := entities.VoteValueNo 83 return vs.Get(ctx, &proposalIDStr, nil, &no) 84 } 85 86 func (vs *Votes) GetByParty(ctx context.Context, partyIDStr string) ([]entities.Vote, error) { 87 defer metrics.StartSQLQuery("Votes", "GetByParty")() 88 return vs.Get(ctx, nil, &partyIDStr, nil) 89 } 90 91 func (vs *Votes) GetByTxHash(ctx context.Context, txHash entities.TxHash) ([]entities.Vote, error) { 92 defer metrics.StartSQLQuery("Votes", "GetByTxHash")() 93 94 var votes []entities.Vote 95 query := `SELECT * FROM votes WHERE tx_hash = $1` 96 err := pgxscan.Select(ctx, vs.ConnectionSource, &votes, query, txHash) 97 if err != nil { 98 return nil, fmt.Errorf("querying votes: %w", err) 99 } 100 return votes, nil 101 } 102 103 func (vs *Votes) GetByPartyConnection(ctx context.Context, partyIDStr string, pagination entities.CursorPagination) ([]entities.Vote, entities.PageInfo, error) { 104 args := make([]interface{}, 0) 105 query := fmt.Sprintf(`select * from votes_current where party_id=%s`, nextBindVar(&args, entities.PartyID(partyIDStr))) 106 107 var ( 108 votes []entities.Vote 109 pageInfo entities.PageInfo 110 err error 111 ) 112 113 query, args, err = PaginateQuery[entities.VoteCursor](query, args, votesOrdering, pagination) 114 if err != nil { 115 return votes, pageInfo, err 116 } 117 118 if err = pgxscan.Select(ctx, vs.ConnectionSource, &votes, query, args...); err != nil { 119 return nil, entities.PageInfo{}, err 120 } 121 122 votes, pageInfo = entities.PageEntities[*v2.VoteEdge](votes, pagination) 123 return votes, pageInfo, nil 124 } 125 126 func (vs *Votes) GetConnection( 127 ctx context.Context, 128 proposalIDStr, partyIDStr *string, 129 pagination entities.CursorPagination, 130 ) ([]entities.Vote, entities.PageInfo, error) { 131 query := `SELECT * FROM votes_current` 132 args := []interface{}{} 133 134 conditions := []string{} 135 136 if proposalIDStr != nil { 137 proposalID := entities.ProposalID(*proposalIDStr) 138 conditions = append(conditions, fmt.Sprintf("proposal_id=%s", nextBindVar(&args, proposalID))) 139 } 140 141 if partyIDStr != nil { 142 partyID := entities.PartyID(*partyIDStr) 143 conditions = append(conditions, fmt.Sprintf("party_id=%s", nextBindVar(&args, partyID))) 144 } 145 146 if len(conditions) > 0 { 147 query = fmt.Sprintf("%s WHERE %s", query, strings.Join(conditions, " AND ")) 148 } 149 150 var ( 151 votes []entities.Vote 152 pageInfo entities.PageInfo 153 err error 154 ) 155 156 query, args, err = PaginateQuery[entities.VoteCursor](query, args, votesOrdering, pagination) 157 if err != nil { 158 return votes, pageInfo, err 159 } 160 161 if err = pgxscan.Select(ctx, vs.ConnectionSource, &votes, query, args...); err != nil { 162 return nil, entities.PageInfo{}, err 163 } 164 165 votes, pageInfo = entities.PageEntities[*v2.VoteEdge](votes, pagination) 166 return votes, pageInfo, nil 167 } 168 169 func (vs *Votes) Get(ctx context.Context, 170 proposalIDStr *string, 171 partyIDStr *string, 172 value *entities.VoteValue, 173 ) ([]entities.Vote, error) { 174 query := `SELECT * FROM votes_current` 175 args := []interface{}{} 176 177 conditions := []string{} 178 179 if proposalIDStr != nil { 180 proposalID := entities.ProposalID(*proposalIDStr) 181 conditions = append(conditions, fmt.Sprintf("proposal_id=%s", nextBindVar(&args, proposalID))) 182 } 183 184 if partyIDStr != nil { 185 partyID := entities.PartyID(*partyIDStr) 186 conditions = append(conditions, fmt.Sprintf("party_id=%s", nextBindVar(&args, partyID))) 187 } 188 189 if value != nil { 190 conditions = append(conditions, fmt.Sprintf("value=%s", nextBindVar(&args, *value))) 191 } 192 193 if len(conditions) > 0 { 194 query = fmt.Sprintf("%s WHERE %s", query, strings.Join(conditions, " AND ")) 195 } 196 197 votes := []entities.Vote{} 198 err := pgxscan.Select(ctx, vs.ConnectionSource, &votes, query, args...) 199 if err != nil { 200 return nil, fmt.Errorf("querying votes: %w", err) 201 } 202 return votes, nil 203 }