Fix slow-ass code
This commit is contained in:
@ -90,12 +90,12 @@ func (app *application) CreateElection(w http.ResponseWriter, r *http.Request) {
|
|||||||
voterIdentities := make([]string, 0, request.MaxVoters) // TODO: this is way too slow
|
voterIdentities := make([]string, 0, request.MaxVoters) // TODO: this is way too slow
|
||||||
for i := 0; i < request.MaxVoters; i++ {
|
for i := 0; i < request.MaxVoters; i++ {
|
||||||
randomIdentity := randomVoterIdentity()
|
randomIdentity := randomVoterIdentity()
|
||||||
_, err := app.voters.Insert(randomIdentity, electionId)
|
|
||||||
if err != nil {
|
|
||||||
app.serverError(w, r, err)
|
|
||||||
}
|
|
||||||
voterIdentities = append(voterIdentities, randomIdentity)
|
voterIdentities = append(voterIdentities, randomIdentity)
|
||||||
}
|
}
|
||||||
|
_, err := app.voters.InsertMultiple(voterIdentities, electionId)
|
||||||
|
if err != nil {
|
||||||
|
app.serverError(w, r, err)
|
||||||
|
}
|
||||||
|
|
||||||
res, err = json.Marshal(api.CreateElectionResponse{VoterIdentities: &voterIdentities})
|
res, err = json.Marshal(api.CreateElectionResponse{VoterIdentities: &voterIdentities})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -248,7 +248,7 @@ func (app *application) createVotesHandleUnknownVotersElection(w http.ResponseWr
|
|||||||
return "", fmt.Errorf(message)
|
return "", fmt.Errorf(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = app.voters.Insert(voterIdentity, election.ID)
|
_, err = app.voters.InsertMultiple([]string{voterIdentity}, election.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.serverError(w, r, err)
|
app.serverError(w, r, err)
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -243,8 +243,8 @@ func TestCreateVotes_UnknownVotersElection(t *testing.T) {
|
|||||||
On("Exists", mock.Anything, mock.Anything).
|
On("Exists", mock.Anything, mock.Anything).
|
||||||
Return(false, nil)
|
Return(false, nil)
|
||||||
mockVoters.
|
mockVoters.
|
||||||
On("Insert", mock.Anything, mock.Anything).
|
On("InsertMultiple", mock.Anything, mock.Anything).
|
||||||
Return(1, nil)
|
Return([]int{1}, nil)
|
||||||
mockVoters.
|
mockVoters.
|
||||||
On("CountByElection", mock.Anything).
|
On("CountByElection", mock.Anything).
|
||||||
Return(0, nil)
|
Return(0, nil)
|
||||||
@ -634,8 +634,8 @@ func TestCreateVotes_UnknownVotersElectionMaxVotersReached(t *testing.T) {
|
|||||||
On("Exists", mock.Anything, mock.Anything).
|
On("Exists", mock.Anything, mock.Anything).
|
||||||
Return(false, nil)
|
Return(false, nil)
|
||||||
mockVoters.
|
mockVoters.
|
||||||
On("Insert", mock.Anything, mock.Anything).
|
On("InsertMultiple", mock.Anything, mock.Anything).
|
||||||
Return(1, nil)
|
Return([]int{1}, nil)
|
||||||
mockVoters.
|
mockVoters.
|
||||||
On("CountByElection", mock.Anything).
|
On("CountByElection", mock.Anything).
|
||||||
Return(10, nil)
|
Return(10, nil)
|
||||||
|
@ -48,7 +48,7 @@ func main() {
|
|||||||
Addr: addr,
|
Addr: addr,
|
||||||
Handler: app.routes(),
|
Handler: app.routes(),
|
||||||
ErrorLog: slog.NewLogLogger(logger.Handler(), slog.LevelError),
|
ErrorLog: slog.NewLogLogger(logger.Handler(), slog.LevelError),
|
||||||
IdleTimeout: 6 * time.Minute,
|
IdleTimeout: time.Minute,
|
||||||
ReadTimeout: 5 * time.Second,
|
ReadTimeout: 5 * time.Second,
|
||||||
WriteTimeout: 10 * time.Second,
|
WriteTimeout: 10 * time.Second,
|
||||||
}
|
}
|
||||||
|
@ -62,9 +62,9 @@ type mockVoterModel struct {
|
|||||||
mock.Mock
|
mock.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *mockVoterModel) Insert(identity string, electionID int) (int, error) {
|
func (v *mockVoterModel) InsertMultiple(identities []string, electionID int) ([]int, error) {
|
||||||
args := v.Called(identity, electionID)
|
args := v.Called(identities, electionID)
|
||||||
return args.Int(0), args.Error(1)
|
return args.Get(0).([]int), args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *mockVoterModel) CountByElection(electionID int) (int, error) {
|
func (v *mockVoterModel) CountByElection(electionID int) (int, error) {
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type VoterModelInterface interface {
|
type VoterModelInterface interface {
|
||||||
Insert(identity string, electionID int) (int, error)
|
InsertMultiple(identities []string, electionID int) ([]int, error)
|
||||||
CountByElection(electionID int) (int, error)
|
CountByElection(electionID int) (int, error)
|
||||||
Exists(voterIdentity string, electionID int) (bool, error)
|
Exists(voterIdentity string, electionID int) (bool, error)
|
||||||
}
|
}
|
||||||
@ -15,27 +15,45 @@ type VoterModel struct {
|
|||||||
DB *sql.DB
|
DB *sql.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *VoterModel) Insert(identity string, electionID int) (int, error) {
|
func (v *VoterModel) InsertMultiple(identities []string, electionID int) ([]int, error) {
|
||||||
tx, err := v.DB.Begin()
|
tx, err := v.DB.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer tx.Rollback()
|
defer tx.Rollback()
|
||||||
|
|
||||||
result, err := tx.Exec(`
|
// Prepare the statement once to reuse
|
||||||
|
stmt, err := tx.Prepare(`
|
||||||
INSERT INTO voters (identity, election_id)
|
INSERT INTO voters (identity, election_id)
|
||||||
VALUES (?, ?)`,
|
VALUES (?, ?)`)
|
||||||
identity, electionID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return nil, err
|
||||||
|
}
|
||||||
|
defer stmt.Close()
|
||||||
|
|
||||||
|
// Store all voter IDs
|
||||||
|
voterIDs := make([]int, 0, len(identities))
|
||||||
|
|
||||||
|
// Execute statement for each identity
|
||||||
|
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 {
|
if err = tx.Commit(); err != nil {
|
||||||
return 0, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
voterId, err := result.LastInsertId()
|
return voterIDs, nil
|
||||||
return int(voterId), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *VoterModel) CountByElection(electionID int) (int, error) {
|
func (v *VoterModel) CountByElection(electionID int) (int, error) {
|
||||||
|
Reference in New Issue
Block a user