You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
3.6 KiB

# vim: fileencoding=utf-8
#
from ..template_engine import ParametersContainer
from .base_format import Format, FormatError
from sqlite3 import connect, Connection, OperationalError, IntegrityError
import os
class SqliteFormat(Format):
FORMAT = 'sqlite'
EXECUTABLE = True
FORMAT_PARAMETERS = {'execsql'}
def __init__(self, template_text: str,
template_path: str,
parameters: ParametersContainer = ParametersContainer(),
**kwargs):
self._template_text = template_text
if parameters.execsql:
self._mode = parameters.execsql
else:
self._mode = "rollback"
self._executor = self.__getattribute__(f"_execute_{self._mode}")
# Измененные файлы.
self.changed_files = dict()
# Предупреждения.
self._warnings: list = []
def execute_format(self, target_path: str,
chroot_path: str = '/') -> dict:
'''Метод для запуска работы формата.'''
if os.path.exists(target_path) and os.path.isdir(target_path):
raise FormatError(f"directory on target path: {target_path}")
status = "N"
if os.path.exists(target_path):
status = "M"
connection = connect(target_path)
self._executor(connection, self._template_text)
connection.close()
self.changed_files[target_path] = status
return self.changed_files
def _execute_continue(self, connection: Connection, template_text: str):
"""Метод для выполнения sql-команд при значения параметра
execsql = continue. В этом случае после обнаружения ошибки в скрипте
выполнение команд будет продолжено."""
cursor = connection.cursor()
commands = template_text.split(";\n")
for command in commands:
try:
cursor.execute(command.strip())
connection.commit()
except (OperationalError, IntegrityError) as error:
self._warnings.append(str(error))
def _execute_rollback(self, connection: Connection, template_text: str):
"""Метод для выполнения sql-команд при значения параметра
execsql = rollback. В этом случае после обнаружения ошибки в скрипте
результат выполнения команд будет сброшен."""
commands = template_text.split(";\n")
cursor = connection.cursor()
cursor.execute("BEGIN TRANSACTION;")
try:
for command in commands:
cursor.execute(command)
connection.commit()
except (OperationalError, IntegrityError) as error:
self._warnings.append(str(error))
connection.rollback()
def _execute_stop(self, connection: Connection, template_text: str):
"""Метод для выполнения sql-команд при значения параметра
execsql = stop. В этом случае после обнаружения ошибки в скрипте
выполнение команд будет остановлено."""
cursor = connection.cursor()
try:
cursor.executescript(template_text)
except (OperationalError, IntegrityError) as error:
self._warnings.append(str(error))
finally:
connection.commit()
@property
def warnings(self):
return self._warnings