-
Notifications
You must be signed in to change notification settings - Fork 0
/
sqlite.py
119 lines (101 loc) · 4.19 KB
/
sqlite.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
"""Klasse `DatabaseConnector`."""
from __future__ import annotations
__all__: Final[list[str]] = ["DatabaseConnector"]
import sqlite3
from contextlib import closing
from typing import Final
from nrw.database._query_result import QueryResult
class DatabaseConnector:
"""Ein Objekt der Klasse `DatabaseConnector` ermöglicht die Abfrage und
Manipulation einer `SQLite`-Datenbank.
Beim Erzeugen des Objekts wird eine Datenbankverbindung aufgebaut, so dass
anschließend SQL-Anweisungen an diese Datenbank gerichtet werden koennen.
"""
# pylint: disable=W0613, W0718, R0913
__slots__: Final[tuple[str, str, str]] = (
"_connection",
"_current_query_result",
"_message",
)
def __init__(
self,
ip: None,
port: None,
database: str,
username: None,
password: None,
) -> None:
"""Ein Objekt vom Typ `DatabaseConnector` wird erstellt, und eine Verbindung zur
Datenbank wird aufgebaut. Mit den Parametern `ip` und `port` werden die
IP-Adresse und die Port-Nummer übergeben, unter denen die Datenbank mit Namen
`database` zu erreichen ist.
Mit den Parametern `username` und `password` werden Benutzername und Passwort
für die Datenbank übergeben.
Für `SQLite` wird nur `database` benötigt.
"""
self._current_query_result: QueryResult | None = None
self._message: str | None = None
try:
self._connection: sqlite3.Connection | None = sqlite3.connect(
database,
isolation_level=None,
)
except Exception as exception:
self._connection = None
self._message = str(exception)
def execute_statement(self, sql_statement: str) -> None:
"""Der Auftrag schickt den im Parameter `sql_statement` enthaltenen SQL-Befehl
an die Datenbank ab.
Handelt es sich bei `sql_statement` um einen SQL-Befehl, der eine Ergebnismenge
liefert, so kann dieses Ergebnis anschließend mit dem Property
`current_query_result` abgerufen werden.
"""
self._current_query_result = None
self._message = None
if self._connection is None:
self._message = "No connection"
return
try:
with closing(self._connection.cursor()) as cursor:
if cursor.execute(sql_statement) is not None and (
data := cursor.fetchall()
):
assert cursor.description is not None, "No description"
column_names: tuple[str, ...] = tuple(
column[0] for column in cursor.description
)
colum_types: tuple[None, ...] = tuple(
column[1] for column in cursor.description
)
self._current_query_result = QueryResult(
data,
column_names,
colum_types,
)
except Exception as exception:
self._message = str(exception)
@property
def current_query_result(self) -> QueryResult | None:
"""Die Anfrage liefert das Ergebnis des letzten mit der Methode
`execute_statement` an die Datenbank geschickten SQL-Befehls als Objekt vom Typ
`QueryResult` zurück.
Wurde bisher kein SQL-Befehl abgeschickt oder ergab der letzte Aufruf von
`execute_statement` keine Ergebnismenge (z.B. bei einem INSERT-Befehl oder einem
Syntaxfehler), so wird `None` geliefert.
"""
return self._current_query_result
@property
def error_message(self) -> str | None:
"""Die Anfrage liefert `None` oder eine Fehlermeldung, die sich jeweils auf die
letzte zuvor ausgeführte Datenbankoperation bezieht.
"""
return self._message
def close(self) -> None:
"""Die Datenbankverbindung wird geschlossen."""
if self._connection is None:
self._message = "No connection"
return
try:
self._connection.close()
except Exception as exception:
self._message = str(exception)