FireBolt / mfinder /db /ban_sql.py
AngryBird-22's picture
Upload 35 files
5dc4327 verified
Raw
History Blame
3.36 kB
import threading
from sqlalchemy import create_engine, Column, BigInteger
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy.pool import QueuePool
from mfinder import DB_URL
import time
import sqlalchemy
BASE = declarative_base()
class BanList(BASE):
__tablename__ = "banlist"
user_id = Column(BigInteger, primary_key=True)
def __init__(self, user_id):
self.user_id = user_id
def start() -> scoped_session:
connect_args = {}
if DB_URL and DB_URL.startswith(("postgres://", "postgresql://")):
connect_args["sslmode"] = "require"
engine = create_engine(
DB_URL,
connect_args=connect_args,
poolclass=QueuePool,
pool_size=10,
max_overflow=20,
pool_pre_ping=True,
pool_recycle=1800 # Recycle connections every 1800 seconds (30 minutes)
)
BASE.metadata.bind = engine
BASE.metadata.create_all(engine)
return scoped_session(sessionmaker(bind=engine, autoflush=False))
SESSION = start()
INSERTION_LOCK = threading.RLock()
async def ban_user(user_id):
with INSERTION_LOCK:
try:
usr = SESSION.query(BanList).filter_by(user_id=user_id).one()
except NoResultFound:
usr = BanList(user_id=user_id)
SESSION.add(usr)
SESSION.commit()
return True
except sqlalchemy.exc.OperationalError as e:
SESSION.rollback()
raise e
finally:
SESSION.close()
async def is_banned(user_id, retries=3):
with INSERTION_LOCK:
for attempt in range(retries):
try:
usr = SESSION.query(BanList).filter_by(user_id=user_id).one()
return usr.user_id
except NoResultFound:
return False
except sqlalchemy.exc.OperationalError as e:
try:
SESSION.rollback()
except Exception:
pass
try:
SESSION.remove()
except Exception:
pass
if 'SSL connection has been closed unexpectedly' in str(e):
if attempt < retries - 1:
time.sleep(2) # wait before retrying
continue
raise e
except sqlalchemy.exc.PendingRollbackError:
try:
SESSION.rollback()
except Exception:
pass
try:
SESSION.remove()
except Exception:
pass
if attempt < retries - 1:
time.sleep(2) # wait before retrying
continue
raise
finally:
SESSION.close()
async def unban_user(user_id):
with INSERTION_LOCK:
try:
usr = SESSION.query(BanList).filter_by(user_id=user_id).one()
SESSION.delete(usr)
SESSION.commit()
return True
except NoResultFound:
return False
except sqlalchemy.exc.OperationalError as e:
SESSION.rollback()
raise e
finally:
SESSION.close()