DB.py 4.16 KiB
# -*- coding: utf-8 -*-

import os
import sqlite3
import logging

from pathlib import Path

from tools import SQL
from Model.Except import NotImplementedMethodeError

logger = logging.getLogger()

# Top level model class
class SQLModel(SQL):
    _sub_classes = []

    def _init_db_file(self, db, is_new = True):
        exists = Path(db).exists()

        if exists and is_new:
            os.remove(db)

        self._db = sqlite3.connect(db)
        self._cur = self._db.cursor()

        if is_new:
            logger.info("Create database")
            self._create()      # Create db
            # self._save()        # Save
        else:
            self._update()      # Update db scheme if necessary
            # self._load()        # Load data


    def __init__(self, filename = None):
        self._db = None

    def _create_submodel(self):
        fn = lambda sql: self.execute(
            sql,
            fetch_one = False,
            commit = False
        )

        for cls in self._sub_classes:
            requests = cls._sql_create(fn)

        self.commit()
        return True

    def _create(self):
        raise NotImplementedMethodeError(self, self._create)

    def _update_submodel(self, version):
        fn = lambda sql: self.execute(
            sql,
            fetch_one = False,
            commit = False
        )

        ok = True
        for cls in self._sub_classes:
            ok &= cls._sql_update(fn, version)

        self.commit()
        return ok

    def _update(self):
        raise NotImplementedMethodeError(self, self._update)

    def _save_submodel(self, objs, data = None):
        fn = lambda sql: self.execute(
            sql,
            fetch_one = False,
            commit = False
        )

        ok = True
        for obj in objs:
            ok &= obj._sql_save(fn)

        self.commit()
        return ok

    def _save(self):
        raise NotImplementedMethodeError(self, self._save)

    @classmethod
    def _load(cls, filename = None):
        raise NotImplementedMethodeError(cls, cls._load)

# Sub model class
class SQLSubModel(object):
    _sub_classes = []

    def _sql_format(self, value):
        # Replace ''' by ''' to preserve SQL injection
        if type(value) == str:
            value = value.replace("'", "'")
        elif type(value) == bool:
            value = 'TRUE' if value else 'FALSE'
        return value

    @classmethod
    def _create_submodel(cls, execute):
        for sc in cls._sub_classes:
            sc._sql_create(execute)

    @classmethod
    def _sql_create(cls, execute):
        """Create data base scheme

        Args:
            execute: Function to exec SQL resquest

        Returns:
            Return true, otherelse false if an issue appear
        """
        raise NotImplementedMethodeError(cls, cls._sql_create)

    @classmethod
    def _update_submodel(cls, execute, version):
        for sc in cls._sub_classes:
            sc._sql_update(execute, version)

    @classmethod
    def _sql_update(cls, execute, version):
        """Update data base scheme

        Args:
            execute: Function to exec SQL resquest
            version: Current database version

        Returns:
            Return true, otherelse false if an issue appear
        """
        raise NotImplementedMethodeError(cls, cls._sql_update)

    @classmethod
    def _sql_load(cls, execute, data = None):
        """Load instance of this class from SQL data base

        Args:
            execute: Function to exec SQL request
            data: Optional data for the class constructor

        Returns:
            Return new instance of class
        """
        raise NotImplementedMethodeError(cls, cls._sql_load)

    def _save_submodel(self, execute, objs, data = None):
        for o in objs:
            o._sql_save(execute, data = data)

    def _sql_save(self, execute, data = None):
        """Save class data to data base

        Args:
            execute: Function to exec SQL resquest
            data: Optional additional information for save

        Returns:
            Return true, otherelse false if an issue appear during
            save
        """
        raise NotImplementedMethodeError(self, self._sql_save)