diff --git a/matemat/db/facade.py b/matemat/db/facade.py index 7df896a..f91bf4a 100644 --- a/matemat/db/facade.py +++ b/matemat/db/facade.py @@ -328,10 +328,11 @@ class MatematDatabase(object): the statistics table. :param user: The user buying a product. :param product: The product the user is buying. - :param count: How many instances of the product the user is buying, defaults to 1. + :param count: How many units of the product the user is buying, defaults to 1. :raises DatabaseConsistencyError: If the user or the product does not exist in the database. """ with self.db.transaction() as c: + # Retrieve the consumption entry for the (user, product) pair, if any. c.execute(''' SELECT count FROM consumption @@ -343,6 +344,7 @@ class MatematDatabase(object): }) row = c.fetchone() if row is None: + # If the entry does not exist, create a new one. c.execute(''' INSERT INTO consumption (user_id, product_id, count) VALUES (:user_id, :product_id, :count) @@ -352,6 +354,7 @@ class MatematDatabase(object): 'count': count }) else: + # If the entry exists, update the consumption count. c.execute(''' UPDATE consumption SET count = count + :count @@ -361,10 +364,12 @@ class MatematDatabase(object): 'product_id': product.id, 'count': count }) + # Make sure exactly one consumption row was updated/inserted. affected = c.execute('SELECT changes()').fetchone()[0] if affected != 1: raise DatabaseConsistencyError( f'increment_consumption should affect 1 consumption row, but affected {affected}') + # Compute the cost of the transaction and subtract it from the user's account balance. c.execute(''' UPDATE users SET balance = balance - :cost @@ -372,10 +377,12 @@ class MatematDatabase(object): 'user_id': user.id, 'cost': count * product.price_member if user.is_member else count * product.price_non_member }) + # Make sure exactly one user row was updated. affected = c.execute('SELECT changes()').fetchone()[0] if affected != 1: raise DatabaseConsistencyError( f'increment_consumption should affect 1 users row, but affected {affected}') + # Subtract the number of purchased units from the product's stock. c.execute(''' UPDATE products SET stock = stock - :count @@ -384,6 +391,7 @@ class MatematDatabase(object): 'product_id': product.id, 'count': count }) + # Make sure exactly one product row was updated. affected = c.execute('SELECT changes()').fetchone()[0] if affected != 1: raise DatabaseConsistencyError( @@ -393,7 +401,7 @@ class MatematDatabase(object): """ Update the stock of a product. :param product: The product to restock. - :param count: Number of instances of the product to add. + :param count: Number of units of the product to add. :raises DatabaseConsistencyError: If the product represented by the object does not exist. """ with self.db.transaction() as c: