diff --git a/.gitignore b/.gitignore index d698e6f..7ffaf80 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Repository specific .idea -messages.db +server.db +client.db # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/constants.py b/constants.py index d3b075e..0f21626 100644 --- a/constants.py +++ b/constants.py @@ -8,7 +8,8 @@ __BASE_DIR = os.path.dirname(os.path.abspath(__file__)) HEADER_LENGTH = 10 MINIMUM_CONTRAST = 4.65 -DATABASE = os.path.join(__BASE_DIR, 'messages.db') +CLIENT_DATABASE = os.path.join(__BASE_DIR, 'client.db') +SERVER_DATABASE = os.path.join(__BASE_DIR, 'server.db') DEFAULT_IP = "127.0.0.1" DEFAULT_PORT = 5555 diff --git a/server/db.py b/server/db.py index 5b4a6cd..267a73f 100644 --- a/server/db.py +++ b/server/db.py @@ -1,7 +1,7 @@ import logging +import os import sqlite3 import threading -from typing import List import constants @@ -12,9 +12,9 @@ lock = threading.Lock() class Database(object): - def __init__(self): - logger.debug(f"Connected to '{constants.DATABASE}'") - self.conn = sqlite3.connect(constants.DATABASE) + def __init__(self, database: str): + logger.debug(f"Connected to './{os.path.basename(database)}'") + self.conn = sqlite3.connect(database, detect_types=sqlite3.PARSE_DECLTYPES) self.__isClosed = False @property @@ -31,6 +31,38 @@ class Database(object): self.conn.close() self.__isClosed = True + def construct(self) -> None: + raise NotImplementedError + + +class ClientDatabase(Database): + def __init__(self): + super().__init__(constants.CLIENT_DATABASE) + + def construct(self) -> None: + with lock: + cur = self.conn.cursor() + try: + cur.execute('''SELECT name FROM sqlite_master WHERE type='table' AND name = '?';''', 'connection') + if cur.fetchone() is None: + self.conn.execute('''CREATE TABLE connection + (id INTEGER PRIMARY KEY, + address TEXT NOT NULL, + port INTEGER NOT NULL, + nickname TEXT NOT NULL, + password TEXT, + connections INTEGER DEFAULT 1, + favorite BOOLEAN DEFAULT FALSE, + initial_time TIMESTAMP NOT NULL, + latest_time TIMESTAMP NOT NULL);''') + finally: + cur.close() + + +class ServerDatabase(Database): + def __init__(self): + super().__init__(constants.SERVER_DATABASE) + def construct(self): with lock: cur = self.conn.cursor() @@ -71,13 +103,3 @@ class Database(object): return cur.lastrowid finally: cur.close() - - def get_messages(self, columns: List[str] = None): - with lock: - cur = self.conn.cursor() - try: - if columns is None: - cur.execute('''SELECT * FROM message''') - return cur.fetchall() - finally: - cur.close() diff --git a/server/handler.py b/server/handler.py index 94ec882..5e79032 100644 --- a/server/handler.py +++ b/server/handler.py @@ -23,12 +23,12 @@ class BaseClient(object): def __init__(self, conn: socket.socket, all_clients: List['Client'], address) -> None: self.conn, self.all_clients, self.address = conn, all_clients, address - self.db: Optional[db.Database] = None + self.db: Optional[db.ServerDatabase] = None def connect_database(self): if self.db is None: logger.debug('Connecting client to database.') - self.db = db.Database() + self.db = db.ServerDatabase() def send(self, message: bytes) -> None: """Sends a pre-encoded message to this client.""" @@ -89,7 +89,7 @@ class Client(BaseClient): def connect_database(self) -> None: if self.db is None: logger.debug(f'Connecting Client({self.id[:8]}) to the database.') - self.db = db.Database() + self.db = db.ServerDatabase() def request_nickname(self) -> None: """Send a request for the client's nickname information."""