Insert election with uuid instead of auto-generated id
This commit is contained in:
@ -47,7 +47,7 @@ type Election struct {
|
||||
Choices []string `json:"choices"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
ExpiresAt string `json:"expiresAt"`
|
||||
Id int `json:"id"`
|
||||
Id string `json:"id"`
|
||||
MaxVoters int `json:"maxVoters"`
|
||||
Name string `json:"name"`
|
||||
Tokens int `json:"tokens"`
|
||||
@ -89,13 +89,13 @@ type ServerInterface interface {
|
||||
CreateElection(w http.ResponseWriter, r *http.Request)
|
||||
// Get an election
|
||||
// (GET /election/{id})
|
||||
GetElection(w http.ResponseWriter, r *http.Request, id int)
|
||||
GetElection(w http.ResponseWriter, r *http.Request, id string)
|
||||
// Get the results of an election
|
||||
// (GET /election/{id}/results)
|
||||
GetElectionResults(w http.ResponseWriter, r *http.Request, id int)
|
||||
GetElectionResults(w http.ResponseWriter, r *http.Request, id string)
|
||||
// Cast your votes for an election
|
||||
// (POST /election/{id}/votes)
|
||||
CreateVotes(w http.ResponseWriter, r *http.Request, id int)
|
||||
CreateVotes(w http.ResponseWriter, r *http.Request, id string)
|
||||
}
|
||||
|
||||
// ServerInterfaceWrapper converts contexts to parameters.
|
||||
@ -129,7 +129,7 @@ func (siw *ServerInterfaceWrapper) GetElection(w http.ResponseWriter, r *http.Re
|
||||
var err error
|
||||
|
||||
// ------------- Path parameter "id" -------------
|
||||
var id int
|
||||
var id string
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "id", r.PathValue("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true})
|
||||
if err != nil {
|
||||
@ -155,7 +155,7 @@ func (siw *ServerInterfaceWrapper) GetElectionResults(w http.ResponseWriter, r *
|
||||
var err error
|
||||
|
||||
// ------------- Path parameter "id" -------------
|
||||
var id int
|
||||
var id string
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "id", r.PathValue("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true})
|
||||
if err != nil {
|
||||
@ -181,7 +181,7 @@ func (siw *ServerInterfaceWrapper) CreateVotes(w http.ResponseWriter, r *http.Re
|
||||
var err error
|
||||
|
||||
// ------------- Path parameter "id" -------------
|
||||
var id int
|
||||
var id string
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "id", r.PathValue("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true})
|
||||
if err != nil {
|
||||
|
@ -2,6 +2,7 @@ package mappers
|
||||
|
||||
import (
|
||||
"code.dlmw.ch/dlmw/qv/internal/models"
|
||||
uuid2 "github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
"time"
|
||||
@ -19,8 +20,9 @@ func TestElectionResponse(t *testing.T) {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
uuid, _ := uuid2.NewV7()
|
||||
election := models.Election{
|
||||
ID: 15,
|
||||
ID: uuid.String(),
|
||||
Name: "The best",
|
||||
Tokens: 100,
|
||||
AreVotersKnown: true,
|
||||
@ -32,7 +34,7 @@ func TestElectionResponse(t *testing.T) {
|
||||
|
||||
response := ElectionResponse(&election)
|
||||
|
||||
assert.Equal(t, 15, response.Id)
|
||||
assert.Equal(t, uuid.String(), response.Id)
|
||||
assert.Equal(t, "The best", response.Name)
|
||||
assert.Equal(t, 100, response.Tokens)
|
||||
assert.Equal(t, true, response.AreVotersKnown)
|
||||
|
@ -1,5 +1,5 @@
|
||||
CREATE TABLE elections (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT, -- TODO: try to generate a UUID
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
tokens INTEGER NOT NULL,
|
||||
are_voters_known INTEGER NOT NULL,
|
||||
|
@ -2,12 +2,13 @@ package models
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"github.com/google/uuid"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ElectionModelInterface interface {
|
||||
Insert(name string, tokens int, areVotersKnown bool, maxVoters int, Choices []string, ExpiresAt time.Time) (int, error)
|
||||
GetById(id int) (*Election, error)
|
||||
Insert(name string, tokens int, areVotersKnown bool, maxVoters int, Choices []string, ExpiresAt time.Time) (string, error)
|
||||
GetById(id string) (*Election, error)
|
||||
}
|
||||
|
||||
type ElectionModel struct {
|
||||
@ -15,7 +16,7 @@ type ElectionModel struct {
|
||||
}
|
||||
|
||||
type Election struct {
|
||||
ID int
|
||||
ID string
|
||||
Name string
|
||||
Tokens int
|
||||
AreVotersKnown bool
|
||||
@ -25,48 +26,48 @@ type Election struct {
|
||||
Choices []string
|
||||
}
|
||||
|
||||
func (e *ElectionModel) Insert(name string, tokens int, areVotersKnown bool, maxVoters int, choices []string, expiresAt time.Time) (int, error) {
|
||||
func (e *ElectionModel) Insert(name string, tokens int, areVotersKnown bool, maxVoters int, choices []string, expiresAt time.Time) (string, error) {
|
||||
tx, err := e.DB.Begin()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return "", err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
result, err := tx.Exec(`
|
||||
INSERT INTO elections (name, tokens, are_voters_known, max_voters, expires_at)
|
||||
VALUES (?, ?, ?, ?, ?)`, name, tokens, areVotersKnown, maxVoters, expiresAt)
|
||||
electionID, err := uuid.NewV7()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
electionID, err := result.LastInsertId()
|
||||
_, err = tx.Exec(`
|
||||
INSERT INTO elections (id, name, tokens, are_voters_known, max_voters, expires_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?)`, electionID, name, tokens, areVotersKnown, maxVoters, expiresAt)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
stmt, err := tx.Prepare(`
|
||||
INSERT INTO choices (text, election_id)
|
||||
VALUES (?, ?)`)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return "", err
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
for _, choice := range choices {
|
||||
_, err = stmt.Exec(choice, electionID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if err = tx.Commit(); err != nil {
|
||||
return 0, err
|
||||
return "0", err
|
||||
}
|
||||
|
||||
return int(electionID), nil
|
||||
return electionID.String(), nil
|
||||
}
|
||||
|
||||
func (e *ElectionModel) GetById(id int) (*Election, error) {
|
||||
func (e *ElectionModel) GetById(id string) (*Election, error) {
|
||||
query := `
|
||||
SELECT id, name, tokens, are_voters_known, max_voters, created_at, expires_at
|
||||
FROM elections
|
||||
|
@ -6,16 +6,16 @@ import (
|
||||
)
|
||||
|
||||
type VoterModelInterface interface {
|
||||
InsertMultiple(identities []string, electionID int) ([]int, error)
|
||||
CountByElection(electionID int) (int, error)
|
||||
Exists(voterIdentity string, electionID int) (bool, error)
|
||||
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 int) ([]int, error) {
|
||||
func (v *VoterModel) InsertMultiple(identities []string, electionID string) ([]int, error) {
|
||||
tx, err := v.DB.Begin()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -53,7 +53,7 @@ func (v *VoterModel) InsertMultiple(identities []string, electionID int) ([]int,
|
||||
return voterIDs, nil
|
||||
}
|
||||
|
||||
func (v *VoterModel) CountByElection(electionID int) (int, error) {
|
||||
func (v *VoterModel) CountByElection(electionID string) (int, error) {
|
||||
// use a transaction to prevent race conditions
|
||||
tx, err := v.DB.Begin()
|
||||
if err != nil {
|
||||
@ -82,7 +82,7 @@ func (v *VoterModel) CountByElection(electionID int) (int, error) {
|
||||
return voterCount, nil
|
||||
}
|
||||
|
||||
func (v *VoterModel) Exists(voterIdentity string, electionID int) (bool, error) {
|
||||
func (v *VoterModel) Exists(voterIdentity string, electionID string) (bool, error) {
|
||||
query := `
|
||||
SELECT EXISTS (
|
||||
SELECT 1
|
||||
|
@ -7,9 +7,9 @@ import (
|
||||
)
|
||||
|
||||
type VoteModelInterface interface {
|
||||
Insert(voterIdentity string, electionId int, choiceText string, tokens int) (int, error)
|
||||
Exists(voterIdentity string, electionID int) (bool, error)
|
||||
GetByElection(electionID int) (*[]Vote, error)
|
||||
Insert(voterIdentity string, electionId string, choiceText string, tokens int) (int, error)
|
||||
Exists(voterIdentity string, electionID string) (bool, error)
|
||||
GetByElection(electionID string) (*[]Vote, error)
|
||||
}
|
||||
|
||||
type VoteModel struct {
|
||||
@ -18,13 +18,13 @@ type VoteModel struct {
|
||||
|
||||
type Vote struct {
|
||||
VoterIdentity string
|
||||
ElectionID int
|
||||
ElectionID string
|
||||
ChoiceText string
|
||||
Tokens int
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
func (v *VoteModel) Insert(voterIdentity string, electionId int, choiceText string, tokens int) (int, error) {
|
||||
func (v *VoteModel) Insert(voterIdentity string, electionId string, choiceText string, tokens int) (int, error) {
|
||||
tx, err := v.DB.Begin()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@ -47,7 +47,7 @@ func (v *VoteModel) Insert(voterIdentity string, electionId int, choiceText stri
|
||||
return int(voteId), nil
|
||||
}
|
||||
|
||||
func (v *VoteModel) Exists(voterIdentity string, electionID int) (bool, error) {
|
||||
func (v *VoteModel) Exists(voterIdentity string, electionID string) (bool, error) {
|
||||
var exists bool
|
||||
query := `
|
||||
SELECT EXISTS (
|
||||
@ -66,7 +66,7 @@ func (v *VoteModel) Exists(voterIdentity string, electionID int) (bool, error) {
|
||||
return exists, nil
|
||||
}
|
||||
|
||||
func (v *VoteModel) GetByElection(electionID int) (*[]Vote, error) {
|
||||
func (v *VoteModel) GetByElection(electionID string) (*[]Vote, error) {
|
||||
query := `
|
||||
SELECT voter_identity, election_id, choice_text, tokens, created_at
|
||||
FROM votes
|
||||
|
Reference in New Issue
Block a user