107 lines
3.5 KiB
Python
107 lines
3.5 KiB
Python
"""
|
||
Databaseverbindingen.
|
||
|
||
- execute_query / get_db_connection → de database van de HUIDIGE school
|
||
- central_query / get_central_connection → de centrale database (Scholen, Gebruikers, rechten, Logs, Bugs)
|
||
|
||
Per database wordt lui een connection pool aangemaakt.
|
||
"""
|
||
import threading
|
||
|
||
import mysql.connector
|
||
from mysql.connector import pooling
|
||
|
||
from config import Config
|
||
|
||
_pools = {}
|
||
_lock = threading.Lock()
|
||
POOL_SIZE = Config.DB_POOL_SIZE # config.ini › [database] › pool_size (standaard 3)
|
||
|
||
|
||
def _pool(host, user, password, database, port=None):
|
||
key = (host, port or Config.DB_PORT, user, database)
|
||
pool = _pools.get(key)
|
||
if pool is None:
|
||
with _lock:
|
||
pool = _pools.get(key)
|
||
if pool is None:
|
||
naam = f"p{len(_pools)}_{database}"[:60]
|
||
pool = pooling.MySQLConnectionPool(
|
||
pool_name=naam, pool_size=POOL_SIZE,
|
||
host=host, port=port or Config.DB_PORT, user=user, password=password, database=database,
|
||
connection_timeout=10,
|
||
# zelfde collatie als de tabellen (sql/*.sql); anders geeft MySQL 8 bij vergelijkingen
|
||
# "Illegal mix of collations (utf8mb4_0900_ai_ci / utf8mb4_unicode_ci)"
|
||
charset='utf8mb4', collation='utf8mb4_unicode_ci',
|
||
# autocommit: elke query ziet meteen de laatste gegevens (ook na wijzigingen via een
|
||
# andere verbinding uit de pool). Wie meerdere statements samen wil, gebruikt
|
||
# conn.start_transaction() ... conn.commit().
|
||
autocommit=True)
|
||
_pools[key] = pool
|
||
return pool
|
||
|
||
|
||
def vergeet_pools(database=None):
|
||
"""Na het wijzigen van de DB-gegevens van een school: pools opnieuw laten opbouwen."""
|
||
with _lock:
|
||
for k in [k for k in _pools if database is None or k[3] == database]:
|
||
_pools.pop(k, None)
|
||
|
||
|
||
def get_db_connection():
|
||
"""Verbinding met de database van de huidige school."""
|
||
from tenancy import huidige_school
|
||
cfg = huidige_school().db_config()
|
||
return _pool(cfg['host'], cfg['user'], cfg['password'], cfg['database']).get_connection()
|
||
|
||
|
||
def get_central_connection():
|
||
return _pool(Config.DB_HOST, Config.DB_USER, Config.DB_PASSWORD, Config.DB_CENTRAAL).get_connection()
|
||
|
||
|
||
def _run(conn, query, params, commit):
|
||
cursor = conn.cursor(dictionary=True)
|
||
try:
|
||
cursor.execute(query, params)
|
||
if commit:
|
||
conn.commit()
|
||
return cursor.rowcount
|
||
return cursor.fetchall()
|
||
finally:
|
||
cursor.close()
|
||
conn.close() # terug naar de pool
|
||
|
||
|
||
def execute_query(query, params=(), commit=False):
|
||
return _run(get_db_connection(), query, params, commit)
|
||
|
||
|
||
def execute_insert(query, params=()):
|
||
"""INSERT in de database van de huidige school; geeft het nieuwe AUTO_INCREMENT-id terug."""
|
||
conn = get_db_connection()
|
||
cursor = conn.cursor()
|
||
try:
|
||
cursor.execute(query, params)
|
||
conn.commit()
|
||
return cursor.lastrowid
|
||
finally:
|
||
cursor.close()
|
||
conn.close()
|
||
|
||
|
||
def central_query(query, params=(), commit=False):
|
||
return _run(get_central_connection(), query, params, commit)
|
||
|
||
|
||
def central_insert(query, params=()):
|
||
"""INSERT in de centrale database; geeft het nieuwe AUTO_INCREMENT-id terug."""
|
||
conn = get_central_connection()
|
||
cursor = conn.cursor()
|
||
try:
|
||
cursor.execute(query, params)
|
||
conn.commit()
|
||
return cursor.lastrowid
|
||
finally:
|
||
cursor.close()
|
||
conn.close()
|