atomicity fixes
This commit is contained in:
@@ -85,6 +85,7 @@ class WordleDb:
|
|||||||
return list(User.select())
|
return list(User.select())
|
||||||
|
|
||||||
def get_users_by_round(self, round_no=None, round_id=None):
|
def get_users_by_round(self, round_no=None, round_id=None):
|
||||||
|
with db.atomic():
|
||||||
query = (
|
query = (
|
||||||
User.select(User, Player.user_id, Game.game)
|
User.select(User, Player.user_id, Game.game)
|
||||||
.join(Player, on=(Player.user_id == User.user_id))
|
.join(Player, on=(Player.user_id == User.user_id))
|
||||||
@@ -97,27 +98,33 @@ class WordleDb:
|
|||||||
return list(query)
|
return list(query)
|
||||||
|
|
||||||
def get_user_id(self, username):
|
def get_user_id(self, username):
|
||||||
|
with db.atomic():
|
||||||
user = self.get_user(username)
|
user = self.get_user(username)
|
||||||
return user.twitter_id if user else None
|
return user.twitter_id if user else None
|
||||||
|
|
||||||
def add_user(self, username, user_id, check_twitter=True):
|
def add_user(self, username, user_id, check_twitter=True):
|
||||||
|
with db.atomic():
|
||||||
return User.create(
|
return User.create(
|
||||||
username=username, twitter_id=user_id, check_twitter=check_twitter
|
username=username, twitter_id=user_id, check_twitter=check_twitter
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_rounds(self):
|
def get_rounds(self):
|
||||||
|
with db.atomic():
|
||||||
return list(sorted(Game.select(), key=lambda d: d.start_date))
|
return list(sorted(Game.select(), key=lambda d: d.start_date))
|
||||||
|
|
||||||
def get_or_create_round(self, round_no, start_date=None):
|
def get_or_create_round(self, round_no, start_date=None):
|
||||||
|
with db.atomic():
|
||||||
try:
|
try:
|
||||||
return Game.get(Game.game == round_no)
|
return Game.get(Game.game == round_no)
|
||||||
except peewee.DoesNotExist:
|
except peewee.DoesNotExist:
|
||||||
start_date = (
|
start_date = (
|
||||||
start_date or wordlinator.utils.WORDLE_GOLF_ROUND_DATES[round_no - 1]
|
start_date
|
||||||
|
or wordlinator.utils.WORDLE_GOLF_ROUND_DATES[round_no - 1]
|
||||||
)
|
)
|
||||||
return Game.create(game=round_no, start_date=start_date)
|
return Game.create(game=round_no, start_date=start_date)
|
||||||
|
|
||||||
def get_or_create_hole(self, round_no, hole_no):
|
def get_or_create_hole(self, round_no, hole_no):
|
||||||
|
with db.atomic():
|
||||||
round = self.get_or_create_round(round_no)
|
round = self.get_or_create_round(round_no)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -126,22 +133,26 @@ class WordleDb:
|
|||||||
return Hole.create(hole=hole_no, game_id=round.game_id)
|
return Hole.create(hole=hole_no, game_id=round.game_id)
|
||||||
|
|
||||||
def get_holes(self, round_no, ensure_all=False):
|
def get_holes(self, round_no, ensure_all=False):
|
||||||
|
with db.atomic():
|
||||||
round = self.get_or_create_round(round_no)
|
round = self.get_or_create_round(round_no)
|
||||||
if ensure_all:
|
if ensure_all:
|
||||||
self.create_round_holes(round_no)
|
self.create_round_holes(round_no)
|
||||||
return list(Hole.select().filter(game_id=round.game_id))
|
return list(Hole.select().filter(game_id=round.game_id))
|
||||||
|
|
||||||
def create_round_holes(self, round_no):
|
def create_round_holes(self, round_no):
|
||||||
|
with db.atomic():
|
||||||
for hole_no in range(1, 19):
|
for hole_no in range(1, 19):
|
||||||
self.get_or_create_hole(round_no, hole_no)
|
self.get_or_create_hole(round_no, hole_no)
|
||||||
|
|
||||||
def get_or_create_player_round(self, user_id, game_id):
|
def get_or_create_player_round(self, user_id, game_id):
|
||||||
|
with db.atomic():
|
||||||
try:
|
try:
|
||||||
return Player.get(Player.user_id == user_id, Player.game_id == game_id)
|
return Player.get(Player.user_id == user_id, Player.game_id == game_id)
|
||||||
except peewee.DoesNotExist:
|
except peewee.DoesNotExist:
|
||||||
return Player.create(user_id=user_id, game_id=game_id)
|
return Player.create(user_id=user_id, game_id=game_id)
|
||||||
|
|
||||||
def add_user_to_round(self, username, round_no):
|
def add_user_to_round(self, username, round_no):
|
||||||
|
with db.atomic():
|
||||||
user = self.get_user(username)
|
user = self.get_user(username)
|
||||||
if not user:
|
if not user:
|
||||||
raise ValueError(f"No user found with username {username}")
|
raise ValueError(f"No user found with username {username}")
|
||||||
@@ -149,6 +160,7 @@ class WordleDb:
|
|||||||
return self.get_or_create_player_round(user.user_id, round.game_id)
|
return self.get_or_create_player_round(user.user_id, round.game_id)
|
||||||
|
|
||||||
def remove_user_from_round(self, username, round_no):
|
def remove_user_from_round(self, username, round_no):
|
||||||
|
with db.atomic():
|
||||||
user = self.get_user(username)
|
user = self.get_user(username)
|
||||||
if not user:
|
if not user:
|
||||||
raise ValueError(f"No user found with username {username}")
|
raise ValueError(f"No user found with username {username}")
|
||||||
@@ -160,12 +172,14 @@ class WordleDb:
|
|||||||
return
|
return
|
||||||
|
|
||||||
def copy_players_from_round(self, from_round_no, to_round_no):
|
def copy_players_from_round(self, from_round_no, to_round_no):
|
||||||
|
with db.atomic():
|
||||||
to_round = self.get_or_create_round(to_round_no)
|
to_round = self.get_or_create_round(to_round_no)
|
||||||
|
|
||||||
for user in self.get_users_by_round(from_round_no):
|
for user in self.get_users_by_round(from_round_no):
|
||||||
self.get_or_create_player_round(user.user_id, to_round.game_id)
|
self.get_or_create_player_round(user.user_id, to_round.game_id)
|
||||||
|
|
||||||
def add_score(self, username, game, hole, score):
|
def add_score(self, username, game, hole, score):
|
||||||
|
with db.atomic():
|
||||||
if not score:
|
if not score:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -192,6 +206,7 @@ class WordleDb:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def get_scores(self, round_no=None, round_id=None):
|
def get_scores(self, round_no=None, round_id=None):
|
||||||
|
with db.atomic():
|
||||||
if round_no:
|
if round_no:
|
||||||
round = self.get_or_create_round(round_no)
|
round = self.get_or_create_round(round_no)
|
||||||
elif round_id:
|
elif round_id:
|
||||||
@@ -213,12 +228,12 @@ class WordleDb:
|
|||||||
.filter(Player.game_id == round.game_id)
|
.filter(Player.game_id == round.game_id)
|
||||||
.filter(Score.game_id == round.game_id)
|
.filter(Score.game_id == round.game_id)
|
||||||
)
|
)
|
||||||
return list(res)
|
return list(res) if res else []
|
||||||
|
|
||||||
def bulk_insert_scores(self, scores: typing.List[typing.Dict]):
|
def bulk_insert_scores(self, scores: typing.List[typing.Dict]):
|
||||||
with db.atomic():
|
with db.atomic() as txn:
|
||||||
for batch in peewee.chunked(scores, 50):
|
for batch in peewee.chunked(scores, 50):
|
||||||
Score.insert_many(batch).execute()
|
Score.insert_many(batch).execute(txn)
|
||||||
|
|
||||||
def bulk_update_scores(self, scores: typing.List[Score]):
|
def bulk_update_scores(self, scores: typing.List[Score]):
|
||||||
with db.atomic():
|
with db.atomic():
|
||||||
@@ -226,6 +241,7 @@ class WordleDb:
|
|||||||
score.save()
|
score.save()
|
||||||
|
|
||||||
def get_users_without_score(self, round_no, hole_no, tweetable=True):
|
def get_users_without_score(self, round_no, hole_no, tweetable=True):
|
||||||
|
with db.atomic() as txn:
|
||||||
hole = self.get_or_create_hole(round_no, hole_no)
|
hole = self.get_or_create_hole(round_no, hole_no)
|
||||||
# Find users who *have* played in this round,
|
# Find users who *have* played in this round,
|
||||||
# but have no score on the current hole
|
# but have no score on the current hole
|
||||||
@@ -245,5 +261,5 @@ class WordleDb:
|
|||||||
# Restrict to users who post scores on twitter
|
# Restrict to users who post scores on twitter
|
||||||
query_str += " AND u.check_twitter = true"
|
query_str += " AND u.check_twitter = true"
|
||||||
|
|
||||||
res = db.execute_sql(query_str)
|
res = txn.execute_sql(query_str)
|
||||||
return [r[0] for r in res]
|
return [r[0] for r in res]
|
||||||
|
|||||||
Reference in New Issue
Block a user