105 lines
1.9 KiB
Go
105 lines
1.9 KiB
Go
package models
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
)
|
|
|
|
type VoterModelInterface interface {
|
|
InsertMultiple(identities []string, electionID string) ([]int, error)
|
|
CountByElection(electionID string) (int, error)
|
|
Exists(voterIdentity string, electionID string) (bool, error)
|
|
}
|
|
|
|
type VoterModel struct {
|
|
DB *sql.DB
|
|
}
|
|
|
|
func (v *VoterModel) InsertMultiple(identities []string, electionID string) ([]int, error) {
|
|
tx, err := v.DB.Begin()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer tx.Rollback()
|
|
|
|
stmt, err := tx.Prepare(`
|
|
INSERT INTO voters (identity, election_id)
|
|
VALUES (?, ?)`)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer stmt.Close()
|
|
|
|
voterIDs := make([]int, 0, len(identities))
|
|
|
|
for _, identity := range identities {
|
|
result, err := stmt.Exec(identity, electionID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
voterID, err := result.LastInsertId()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
voterIDs = append(voterIDs, int(voterID))
|
|
}
|
|
|
|
if err = tx.Commit(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return voterIDs, nil
|
|
}
|
|
|
|
func (v *VoterModel) CountByElection(electionID string) (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 string) (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
|
|
}
|