def __init__(self, dbtype=None) -> None: self.dbtype = dbtype dbexists = True if self.dbtype is "sqlite": cfg.DATABASE += ".db" if not os.path.isfile(cfg.DATABASE): dbexists = False try: self.store = sqlite3.connect(cfg.DATABASE) except sqlite3.Error as err: raise cfg.ExitException( err + "\nERROR: Cannot create or connect to " + cfg.DATABASE) self.store.row_factory = lambda cursor, row: row[0] elif self.dbtype is "mysql": try: self.store = mysql.connect(host=cfg.MYSQL_HOST, user=cfg.MYSQL_USER, password=cfg.MYSQL_PW, db=cfg.DATABASE, charset='utf8') except mysql.Error as err: raise cfg.ExitException( err + "\nERROR: Cannot create or connect to " + cfg.DATABASE) self.store.row_factory = lambda cursor, row: row[0] cur = self.store.cursor() cur.execute("SHOW TABLES LIKE '" + cfg.VISITED_STORE + "'") result = cur.fetchone() if result is None: dbexists = False cur.close() elif self.dbtype is "memcache": try: self.store = memcache.Client(['localhost:11211'], debug=1) if cfg.DEBUG: self.getMemcacheStats() except: raise cfg.ExitException( "ERROR: Unable to initialize memcache.") self.createDB() else: raise cfg.ExitException("Database type " + dbtype + " not supported.") if not dbexists: self.createDB() print("Database created. Please import all tables required.") exit() cfg.already_visited = self.readVisited()
def createDB(self) -> None: """ Create the database and tables. """ if self.dbtype is "memcache": keys = [cfg.KOAN_STORE, cfg.HAIKU_STORE, cfg.REPLY_STORE] for key in keys: try: dataf = open(key + ".txt", "r", encoding=cfg.ENCODING) except: raise cfg.ExitException("ERROR: Data file " + key + ".txt does not exist.") data = dataf.read().split("|") dataf.close() self.store.set(key, data) else: stmts = [ "CREATE TABLE " + cfg.VISITED_STORE + " (visited VARCHAR(16) NOT NULL)", "CREATE TABLE " + cfg.VISITED_STORE + "_debug (dv VARCHAR(16) NOT NULL)", "CREATE TABLE " + cfg.KOAN_STORE + " (koan TEXT NOT NULL)", "CREATE TABLE " + cfg.HAIKU_STORE + " (haiku TEXT NOT NULL)", "CREATE TABLE " + cfg.REPLY_STORE + " (reply TEXT NOT NULL)", "CREATE TABLE " + cfg.TEMPLATE_STORE + " (template TEXT NOT NULL)" ] for stmt in stmts: self.executeStmt(stmt) self.store.commit()
def checkDB(self) -> None: """ Checks that the required tables are populated. """ keys = [ cfg.KOAN_STORE, cfg.HAIKU_STORE, cfg.REPLY_STORE, cfg.TEMPLATE_STORE, cfg.RANT_TABLE ] for key in keys: if self.dbtype is "memcache": if self.store.get(key) is None: raise cfg.ExitException("ERROR: Need to load " + key + " data before running.") else: result = self.checkTable(key) if int(result) < 1: raise cfg.ExitException("ERROR: Need to import " + key + " before running.")
def executeStmt(self, stmt) -> None: """ Executes an atomic database operation. """ try: cur = self.store.cursor() cur.execute(stmt) except Exception as err: raise cfg.ExitException(err + "\nERROR: Cannot execute " + stmt) finally: cur.close()
def fetchStmt(self, stmt) -> list: """ Executes a SELECT statement and returns fetched results. """ try: cur = self.store.cursor() cur.execute("SELECT " + stmt) data = cur.fetchall() except Exception as err: raise cfg.ExitException(err + "\nERROR: Cannot execute SELECT " + stmt) finally: cur.close() return (data)
def readRandom(self, name) -> str: """ Returns a random entry from a table/store. """ if self.dbtype is "memcache": return (random.choice(self.store.get(name))) else: if self.dbtype is "sqlite": rand = "RANDOM()" else: rand = "RAND()" data = self.fetchStmt("* FROM " + name + " ORDER BY " + rand + " LIMIT 7") if data is None: raise cfg.ExitException("ERROR: Please import " + name + " into database.") entry = random.choice(data) return (entry.replace("''", "'"))
import os, re, random import config as cfg if cfg.STORE_TYPE is "memcache": import memcache elif cfg.STORE_TYPE is "sqlite": import sqlite3 elif cfg.STORE_TYPE is "mysql": import pymysql as mysql else: raise cfg.ExitException("ERROR: store type not supported.") class DB: """ Database class. Supports SQLite and MySQL. """ def __init__(self, dbtype=None) -> None: self.dbtype = dbtype dbexists = True if self.dbtype is "sqlite": cfg.DATABASE += ".db" if not os.path.isfile(cfg.DATABASE): dbexists = False try: self.store = sqlite3.connect(cfg.DATABASE) except sqlite3.Error as err: raise cfg.ExitException( err + "\nERROR: Cannot create or connect to " + cfg.DATABASE) self.store.row_factory = lambda cursor, row: row[0]