Skip to content

Commit

Permalink
implement sqlite3
Browse files Browse the repository at this point in the history
This patch completes a working implementation of sqlite support. MySQL also still works, so nothing should have regressed.

Signed-off-by: Amy Parker <[email protected]>
amyipdev committed Jul 26, 2023

Verified

This commit was signed with the committer’s verified signature.
kraj Khem Raj
1 parent 28595ac commit 312ad24
Showing 6 changed files with 110 additions and 32 deletions.
2 changes: 1 addition & 1 deletion srv/db-setup-mysql.sql
Original file line number Diff line number Diff line change
@@ -47,5 +47,5 @@ create table ssvp_events (
eventDescription text,
startTime datetime not null,
endTime datetime,
severity integer
severity integer not null
);
26 changes: 26 additions & 0 deletions srv/db-setup-sqlite3.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
-- SPDX-License-Identifier: AGPL-3.0-or-later
--
-- ssvp: server statistics viewer project
-- Copyright (C) 2023 Amy Parker <[email protected]>
--
-- This program is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Affero General Public License as published
-- by the Free Software Foundation; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program; if not, write to the Free Software Foundation, Inc.,
-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA or visit the
-- GNU Project at https:--gnu.org/licenses. The GNU Affero General Public
-- License version 3 is available at, for your convenience,
-- https:--www.gnu.org/licenses/agpl-3.0.en.html.

create table ssvp_day_logs ( logDate date not null, serverName text not null, serverStatus integer not null );
create table ssvp_interval_logs ( logDate datetime not null, serverName text not null, serverStatus boolean not null );
create table ssvp_cached_stats ( monthlyUptime double not null, yearlyUptime double not null, allTimeUptime double not null, serverName text not null, currentStatus integer not null );
create table ssvp_events ( eventID integer not null, serverName text not null, eventName text not null, eventDescription text, startTime datetime not null, endTime datetime, severity integer not null );
40 changes: 31 additions & 9 deletions srv/dbhandle.py
Original file line number Diff line number Diff line change
@@ -60,17 +60,39 @@ def update_cached_stats(self, srv: str, st: int) -> None:
unimplemented()


# TODO: create a database of pre-treated SQL on initialization
class DBAPIAbstracted(DBAbstract):
def __init__(self, config: dict, prefix: str) -> None:
super().__init__(config=config)
self.p = prefix

def _get_ups(self, srv: str, conn) -> dict:
def _generate_connection(self):
unimplemented()

def _treat_sql(self, sql: str) -> str:
return ""

def _fetch_daily_data(self, srv: str) -> dict:
return self._fdd(srv=srv, conn=self._generate_connection())

def handle_daily_record(self, srv: str, st: int) -> int:
return self._hdr(srv=srv, st=st, conn=self._generate_connection())

def insert_interval_log(self, srv: str, status: int) -> None:
self._iil(srv=srv, status=status, conn=self._generate_connection())

def update_cached_stats(self, srv: str, st: int) -> None:
self._ucs(srv=srv, st=st, conn=self._generate_connection())

def get_uptime_stats(self, srv: str) -> dict:
return self._ups(srv=srv, conn=self._generate_connection())

def _ups(self, srv: str, conn) -> dict:
curr = conn.cursor()
sql = f"select monthlyUptime, yearlyUptime, allTimeUptime, currentStatus \
from {self.p}cached_stats \
where serverName = %s;"
curr.execute(sql, (srv,))
curr.execute(self._treat_sql(sql), (srv,))
row = curr.fetchone()
if row is None:
curr.close()
@@ -89,7 +111,7 @@ def _fdd(self, srv: str, conn) -> dict:
sql = f"select logDate, serverStatus \
from {self.p}day_logs \
where logDate between (current_date() - interval 3 month) and current_date() and serverName = %s;"
curr.execute(sql, (srv,))
curr.execute(self._treat_sql(sql), (srv,))
res = {}
for row in curr.fetchall():
res[row[0]] = row[1]
@@ -106,7 +128,7 @@ def _hdr(self, srv: str, st: int, conn) -> int:
where serverName = %s \
and logDate = %s \
);"
curr.execute(sql, (srv, day))
curr.execute(self._treat_sql(sql), (srv, day))
rc_exists = curr.fetchone()[0]
sql = f"select max( \
select severity \
@@ -116,7 +138,7 @@ def _hdr(self, srv: str, st: int, conn) -> int:
);"
mx = None
try:
curr.execute(sql, (srv,))
curr.execute(self._treat_sql(sql), (srv,))
mx = max(st, curr.fetchone()[0])
# we can ignore the pep violation
except:
@@ -125,13 +147,13 @@ def _hdr(self, srv: str, st: int, conn) -> int:
sql = f"insert into {self.p}day_logs \
(logDate, serverName, serverStatus) values \
(%s, %s, %s);"
curr.execute(sql, (day, srv, mx))
curr.execute(self._treat_sql(sql), (day, srv, mx))
else:
sql = f"update {self.p}day_logs \
set serverStatus = %s \
where logDate = %s \
and serverName = %s;"
curr.execute(sql, (mx, day, srv))
curr.execute(self._treat_sql(sql), (mx, day, srv))
curr.fetchall()
conn.commit()
curr.close()
@@ -143,7 +165,7 @@ def _iil(self, srv: str, status: int, conn) -> None:
sql = f"insert into {self.p}interval_logs \
(logDate, serverName, serverStatus) values \
(%s, %s, %s);"
curr.execute(sql, (datetime.datetime.now(), srv, status))
curr.execute(self._treat_sql(sql), (datetime.datetime.now(), srv, status))
curr.fetchall()
conn.commit()
curr.close()
@@ -170,7 +192,7 @@ def _ucs(self, srv: str, st: int, conn) -> None:
where serverName = %s), \
currentStatus = %s\
where serverName = %s;"
curr.execute(sql, (srv, srv, srv, st, srv))
curr.execute(self._treat_sql(sql), (srv, srv, srv, st, srv))
curr.fetchall()
conn.commit()
curr.close()
4 changes: 3 additions & 1 deletion srv/getdb.py
Original file line number Diff line number Diff line change
@@ -21,9 +21,11 @@
# https://www.gnu.org/licenses/agpl-3.0.en.html.

import mysqlh
import sqliteh

dblookup = {
"mysql": mysqlh.MySQLHandler
"mysql": mysqlh.MySQLHandler,
"sqlite3": sqliteh.SQLite3Handler
}


15 changes: 0 additions & 15 deletions srv/mysqlh.py
Original file line number Diff line number Diff line change
@@ -32,24 +32,9 @@ def __init__(self, config: dict) -> None:
self.login = config["username"]
self.pw = config["password"]
self.db = config["database"]

def get_uptime_stats(self, srv: str) -> dict:
return self._get_ups(srv=srv, conn=self._generate_connection())

def _generate_connection(self):
return mysql.connector.connect(user=self.login,
password=self.pw,
host=self.host,
database=self.db)

def _fetch_daily_data(self, srv: str) -> dict:
return self._fdd(srv=srv, conn=self._generate_connection())

def handle_daily_record(self, srv: str, st: int) -> int:
return self._hdr(srv=srv, st=st, conn=self._generate_connection())

def insert_interval_log(self, srv: str, status: int) -> None:
self._iil(srv=srv, status=status, conn=self._generate_connection())

def update_cached_stats(self, srv: str, st: int) -> None:
self._ucs(srv=srv, st=st, conn=self._generate_connection())
55 changes: 49 additions & 6 deletions srv/sqliteh.py
Original file line number Diff line number Diff line change
@@ -22,15 +22,58 @@

import dbhandle
import sqlite3

import datetime


class SQLite3Handler(dbhandle.DBAbstract):
class SQLite3Handler(dbhandle.DBAPIAbstracted):
def __init__(self, config: dict) -> None:
super().__init__(config=config)
super().__init__(config=config, prefix=config["prefix"])
self.filename = config["host"]
self.db = config["database"]
self.p = config["prefix"]


def _generate_connection(self):
# TODO: have filename search the current directory, not the cwd
return sqlite3.connect(self.filename)

def _treat_sql(self, sql: str):
return sql.replace("%s", "?")

def _fetch_daily_data(self, srv: str) -> dict:
conn = self._generate_connection()
curr = conn.cursor()
sql = f"select logDate, serverStatus \
from {self.p}day_logs \
where logDate > date('now', '-3 months')\
and serverName = ?;"
curr.execute(sql, (srv,))
res = {}
for row in curr.fetchall():
res[datetime.datetime.strptime(row[0], "%Y-%m-%d").date()] = row[1]
curr.close()
conn.close()
return res

def update_cached_stats(self, srv: str, st: int) -> None:
conn = self._generate_connection()
curr = conn.cursor()
sql = f"update {self.p}cached_stats \
set monthlyUptime = \
(select AVG(NOT serverStatus) \
from {self.p}interval_logs \
where logDate > date('now', '-1 month') \
and serverName = %s), \
yearlyUptime = \
(select AVG(NOT serverStatus) \
from {self.p}interval_logs \
where logDate > date('now', '-1 year') \
and serverName = %s), \
allTimeUptime = \
(select AVG(NOT serverStatus) \
from {self.p}interval_logs \
where serverName = %s), \
currentStatus = %s\
where serverName = %s;"
curr.execute(self._treat_sql(sql), (srv, srv, srv, st, srv))
curr.fetchall()
conn.commit()
curr.close()
conn.close()

0 comments on commit 312ad24

Please sign in to comment.