diff --git a/helios/models.py b/helios/models.py index d0625ad6936b56285f498facf1a12f1e8784df40..c315635924e82793b7be2c2b1446c8d8681b2857 100644 --- a/helios/models.py +++ b/helios/models.py @@ -102,6 +102,17 @@ class Election(models.Model, electionalgs.Election): def num_voters(self): return self.voter_set.count() + @property + def last_alias_num(self): + """ + FIXME: we should be tracking alias number, not the V* alias which then + makes things a lot harder + """ + if not self.use_voter_aliases: + return None + + return heliosutils.one_val_raw_sql("select max(cast(substring(alias, 2) as integer)) from " + Voter._meta.db_table + " where election_id = %s", [self.id]) or 0 + @property def encrypted_tally_hash(self): if not self.encrypted_tally: @@ -441,7 +452,7 @@ class VoterFile(models.Model): election = self.election reader = unicode_csv_reader(self.voter_file) - num_voters_before = election.num_voters + last_alias_num = election.last_alias_num num_voters = 0 voter_uuids = [] @@ -476,7 +487,7 @@ class VoterFile(models.Model): voter.save() if election.use_voter_aliases: - voter_alias_integers = range(num_voters_before+1, num_voters_before+1+num_voters) + voter_alias_integers = range(last_alias_num+1, last_alias_num+1+num_voters) random.shuffle(voter_alias_integers) for i, voter_uuid in enumerate(voter_uuids): voter = Voter.get_by_election_and_uuid(election, voter_uuid) @@ -516,7 +527,7 @@ class Voter(models.Model, electionalgs.Voter): # do we need to generate an alias? if election.use_voter_aliases: heliosutils.lock_row(Election, election.id) - alias_num = election.num_voters + 1 + alias_num = election.last_alias_num + 1 voter.alias = "V%s" % alias_num voter.save() diff --git a/helios/utils.py b/helios/utils.py index fe332977dcd1bdc66e04936e925aa3691c2c6cec..3d8d4dadd7260356947210bacf1ca98bd0f09ff5 100644 --- a/helios/utils.py +++ b/helios/utils.py @@ -162,6 +162,16 @@ def send_email(sender, recpt_lst, subject, body): ## raw SQL and locking ## +def one_val_raw_sql(raw_sql, values=[]): + """ + for a simple aggregate + """ + from django.db import connection, transaction + cursor = connection.cursor() + + cursor.execute(raw_sql, values) + return cursor.fetchone()[0] + def lock_row(model, pk): """ you almost certainly want to use lock_row inside a commit_on_success function