2021-11-20 14:40:07 +00:00
import sqlite3
import pathlib
import uuid
class Database :
def __init__ ( self , filename = None ) :
filename = filename or pathlib . Path ( __file__ ) . parent . parent . absolute ( ) / " database.sqlite3 "
self . _con = sqlite3 . connect ( filename )
self . migrate ( )
def _execute ( self , query , parameters = None ) :
cur = self . getCursor ( )
cur . execute ( query , parameters )
self . commit ( )
def commit ( self ) :
return self . _con . commit ( )
def getCursor ( self ) :
return self . _con . cursor ( )
def getVersion ( self ) :
cur = self . getCursor ( )
try :
cur . execute ( " SELECT value FROM contentmonster_settings WHERE key = ' dbversion ' " )
assert ( version := cur . fetchone ( ) )
return int ( version [ 0 ] )
except ( sqlite3 . OperationalError , AssertionError ) :
return 0
def getFileUUID ( self , fileobj ) :
hash = fileobj . getHash ( )
cur = self . getCursor ( )
cur . execute ( " SELECT uuid, checksum FROM contentmonster_file WHERE directory = ? AND name = ? " , ( fileobj . directory . name , fileobj . name ) )
fileuuid = None
for result in cur . fetchall ( ) :
if result [ 1 ] == hash :
fileuuid = result [ 0 ]
else :
self . removeFileByUUID ( result [ 0 ] )
return fileuuid or self . addFile ( fileobj , hash )
def addFile ( self , fileobj , hash = None ) :
hash = hash or fileobj . getHash ( )
fileuuid = str ( uuid . uuid4 ( ) )
self . _execute ( " INSERT INTO contentmonster_file(uuid, directory, name, checksum) VALUES (?, ?, ?, ?) " , ( fileuuid , fileobj . directory . name , fileobj . name , hash ) )
return fileuuid
2021-11-22 10:14:38 +00:00
def getFileByUUID ( self , fileuuid ) :
cur = self . getCursor ( )
cur . execute ( " SELECT directory, name, checksum FROM contentmonster_file WHERE uuid = ? " , ( fileuuid , ) )
if ( result := cur . fetchone ( ) ) :
return result
2021-11-20 14:40:07 +00:00
def removeFileByUUID ( self , fileuuid ) :
self . _execute ( " DELETE FROM contentmonster_file WHERE uuid = ? " , ( fileuuid , ) )
def logCompletion ( self , file , vessel ) :
2021-11-22 10:14:38 +00:00
self . _execute ( " INSERT INTO contentmonster_file_log(file, vessel) VALUES(?, ?) " , ( file . uuid , vessel . name ) )
def getCompletionForVessel ( self , vessel ) :
cur = self . getCursor ( )
cur . execute ( " SELECT file FROM contentmonster_file_log WHERE vessel = ? " , ( vessel . name , ) )
2021-11-20 14:40:07 +00:00
def migrate ( self ) :
cur = self . getCursor ( )
if self . getVersion ( ) == 0 :
cur . execute ( " CREATE TABLE IF NOT EXISTS contentmonster_settings(key VARCHAR(64) PRIMARY KEY, value TEXT) " )
cur . execute ( " INSERT INTO contentmonster_settings(key, value) VALUES ( ' dbversion ' , ' 1 ' ) " )
self . commit ( )
if self . getVersion ( ) == 1 :
cur . execute ( " CREATE TABLE IF NOT EXISTS contentmonster_file(uuid VARCHAR(36) PRIMARY KEY, directory VARCHAR(128), name VARCHAR(128), checksum VARCHAR(64)) " )
2021-11-22 10:14:38 +00:00
cur . execute ( " CREATE TABLE IF NOT EXISTS contentmonster_file_log(file VARCHAR(36), vessel VARCHAR(128), PRIMARY KEY (file, vessel), FOREIGN KEY (file) REFERENCES contentmonster_files(uuid) ON DELETE CASCADE) " )
2021-11-20 14:40:07 +00:00
cur . execute ( " UPDATE contentmonster_settings SET value = ' 2 ' WHERE key = ' dbversion ' " )
self . commit ( )
def __del__ ( self ) :
self . _con . close ( )