Dirty implementation of createVotes

This commit is contained in:
2025-01-08 13:57:49 +01:00
parent ca824726b4
commit 49a1df06d2
7 changed files with 223 additions and 17 deletions

View File

@ -20,8 +20,8 @@ type Election struct {
Tokens int
AreVotersKnown bool
MaxVoters int
CreatedAt string
ExpiresAt string
CreatedAt time.Time
ExpiresAt time.Time
Choices []string
}

View File

@ -2,10 +2,13 @@ package models
import (
"database/sql"
"errors"
)
type VoterModelInterface interface {
Insert(identity string, electionID int) (int, error)
CountByElection(electionID int) (int, error)
Exists(voterIdentity string, electionID int) (bool, error)
}
type VoterModel struct {
@ -34,3 +37,53 @@ func (v *VoterModel) Insert(identity string, electionID int) (int, error) {
voterId, err := result.LastInsertId()
return int(voterId), nil
}
func (v *VoterModel) CountByElection(electionID int) (int, error) {
// use a transaction to prevent race conditions
tx, err := v.DB.Begin()
if err != nil {
return 0, err
}
defer tx.Rollback()
query := `
SELECT COUNT(identity)
FROM voters
WHERE election_id = ?
GROUP BY election_id;
`
row := tx.QueryRow(query, electionID)
var voterCount int
err = row.Scan(&voterCount)
if err != nil {
return 0, err
}
tx.Commit()
return voterCount, nil
}
func (v *VoterModel) Exists(voterIdentity string, electionID int) (bool, error) {
query := `
SELECT EXISTS (
SELECT 1
FROM voters
WHERE identity = ? AND election_id = ?
)
`
var exists bool
err := v.DB.QueryRow(query, voterIdentity, electionID).Scan(&exists)
if err != nil {
if errors.Is(sql.ErrNoRows, err) {
return false, nil
}
return false, err
}
return exists, nil
}

57
internal/models/votes.go Normal file
View File

@ -0,0 +1,57 @@
package models
import (
"database/sql"
"errors"
)
type VoteModelInterface interface {
Insert(voterIdentity string, electionId int, choiceText string, tokens int) (int, error)
Exists(voterIdentity string, electionID int) (bool, error)
}
type VoteModel struct {
DB *sql.DB
}
func (v *VoteModel) Insert(voterIdentity string, electionId int, choiceText string, tokens int) (int, error) {
tx, err := v.DB.Begin()
if err != nil {
return 0, err
}
defer tx.Rollback()
result, err := tx.Exec(`
INSERT INTO votes (voter_identity, election_id, choice_text, tokens)
VALUES (?, ?, ?, ?)`,
voterIdentity, electionId, choiceText, tokens)
if err != nil {
return 0, err
}
if err = tx.Commit(); err != nil {
return 0, err
}
voteId, err := result.LastInsertId()
return int(voteId), nil
}
func (v *VoteModel) Exists(voterIdentity string, electionID int) (bool, error) {
var exists bool
query := `
SELECT EXISTS (
SELECT 1
FROM votes
WHERE voter_identity = ? AND election_id = ?
)
`
err := v.DB.QueryRow(query, voterIdentity, electionID).Scan(&exists)
if err != nil {
if errors.Is(sql.ErrNoRows, err) {
return false, nil
}
return false, err
}
return exists, nil
}