notebookvb

This commit is contained in:
Vladimir Buzalka
2026-06-15 18:07:32 +02:00
parent 8142de5216
commit 79216dfbdb
4 changed files with 74 additions and 5 deletions
+66
View File
@@ -31,6 +31,72 @@ def get_medicus_connection():
return fdb.connect(dsn=dsn, user="SYSDBA", password="masterkey", charset="win1250")
class ReconnectingConnection:
"""Obal nad fdb.Connection, který se sám znovu připojí, když spojení umře.
Dlouho běžící procesy (např. MCP server) drží jedno spojení od startu.
To se rozpadne, když:
* se notebook uspí/hibernuje (TCP socket odumře), nebo
* na serveru proběhne denní gbak restore (Firebird zabije stará spojení).
Výsledkem je `SQLCODE -902 Error writing data to the connection`.
Tato třída ověří před každým použitím, že spojení žije, a když ne,
tiše ho znovu naváže. Volající kód používá .cursor()/.commit() beze změny.
"""
def __init__(self, connect_fn=get_medicus_connection):
self._connect = connect_fn
self._conn = None
def _alive(self):
if self._conn is None:
return False
try:
cur = self._conn.cursor()
cur.execute("SELECT 1 FROM RDB$DATABASE")
cur.fetchone()
return True
except Exception:
return False
def _ensure(self):
if not self._alive():
if self._conn is not None:
try:
self._conn.close()
except Exception:
pass
self._conn = None
self._conn = self._connect()
return self._conn
def cursor(self):
return self._ensure().cursor()
def commit(self):
return self._ensure().commit()
def rollback(self):
if self._conn is not None:
return self._conn.rollback()
def close(self):
if self._conn is not None:
try:
self._conn.close()
finally:
self._conn = None
def __getattr__(self, name):
# ostatní atributy/metody proxy na živé spojení
return getattr(self._ensure(), name)
def get_medicus_connection_reconnecting():
"""Vrátí spojení s automatickým reconnectem (vhodné pro dlouho běžící procesy)."""
return ReconnectingConnection(get_medicus_connection)
def get_medicus_db():
"""Vrátí MedicusDB instanci s připojením podle názvu počítače."""
conn = get_medicus_connection()