Files
PointsBot/pointsbot/database.py

108 lines
2.7 KiB
Python
Raw Normal View History

2020-01-15 11:07:13 -08:00
import functools
import os.path
import sqlite3 as sqlite
### Decorators ###
2020-01-15 17:42:49 -08:00
def transaction(func):
@functools.wraps(func)
def newfunc(self, *args, **kwargs):
created_conn = False
if not self.conn:
self.conn = sqlite.connect(self.path)
self.conn.row_factory = sqlite.Row
self.cursor = self.conn.cursor()
created_conn = True
ret = func(self, *args, **kwargs)
if self.conn.in_transaction:
self.conn.commit()
if created_conn:
self.cursor.close()
self.conn.close()
self.cursor = self.conn = None
return ret
return newfunc
2020-01-15 11:07:13 -08:00
2020-01-15 17:42:49 -08:00
### Classes ###
class Database:
SCHEMA = '''
CREATE TABLE IF NOT EXISTS redditor_points (
id TEXT UNIQUE NOT NULL,
name TEXT UNIQUE NOT NULL,
points INTEGER DEFAULT 0
)
2020-02-11 09:08:03 -08:00
'''
2020-01-15 17:42:49 -08:00
def __init__(self, dbpath):
self.path = dbpath
self.conn = None
self.cursor = None
if not os.path.exists(self.path):
self._create()
@transaction
def _create(self):
self.cursor.execute(self.SCHEMA)
@transaction
def add_redditor(self, redditor):
insert_stmt = '''
INSERT OR IGNORE INTO redditor_points (id, name)
VALUES (:id, :name)
2020-02-11 09:08:03 -08:00
'''
2020-01-15 17:42:49 -08:00
self.cursor.execute(insert_stmt, {'id': redditor.id, 'name': redditor.name})
return self.cursor.rowcount
def add_point(self, redditor):
2020-02-11 09:08:03 -08:00
return self._update_points(redditor, 1)
def remove_point(self, redditor):
return self._update_points(redditor, -1)
@transaction
def _update_points(self, redditor, points_modifier):
"""points_modifier is positive to add points, negative to subtract."""
2020-01-15 17:42:49 -08:00
points = self.get_points(redditor, add_if_none=True)
2020-02-11 09:08:03 -08:00
params = {
'id': redditor.id,
'name': redditor.name,
'points': points + points_modifier,
}
2020-01-15 17:42:49 -08:00
update_stmt = '''
UPDATE redditor_points
SET points = :points
WHERE id = :id AND name = :name
2020-02-11 09:08:03 -08:00
'''
2020-01-15 17:42:49 -08:00
self.cursor.execute(update_stmt, params)
return self.cursor.rowcount
@transaction
def get_points(self, redditor, add_if_none=False):
params = {'id': redditor.id, 'name': redditor.name}
select_stmt = '''
SELECT points
FROM redditor_points
WHERE id = :id AND name = :name
2020-02-11 09:08:03 -08:00
'''
2020-01-15 17:42:49 -08:00
self.cursor.execute(select_stmt, params)
2020-02-11 09:11:30 -08:00
row = self.cursor.fetchone()
2020-01-15 17:42:49 -08:00
if row:
points = row['points']
elif add_if_none:
points = 0
self.add_redditor(redditor)
return points