Qt: ловить внешние изменения в базе данных SQLite - PullRequest
0 голосов
/ 30 мая 2018

)

Я разрабатываю программу, использующую базу данных SQLite, к которой я получаю доступ через QSqlDatabase.Я хотел бы рассмотреть (надеюсь, редкий) случай, когда в базу данных вносятся некоторые изменения, которые не вызваны программой во время ее работы (например, пользователь может удалить доступ для записи, переместить или удалить файл или изменить его вручную).

Я пытался использовать QFileSystemWatcher.Я позволил ему просмотреть файл базы данных, и во всех функциях, записывающих что-то к нему, я заблокировал его сигналы, так что только «внешние» изменения вызовут измененный сигнал.

Проблема в том, что проверка QFileSystemWatcher и / или фактическая запись на диск QSqlDatabase::commit(), кажется, не происходит в тот момент, когда я называю commit(), так что фактически сначала блокируются сигналы QFileSystemWatcher, затем я изменяю некоторые вещи, затем яразблокируйте их, а затем он сообщает об изменении файла.

Затем я попытался установить переменную bool (m_writeInProgress) равной true каждый раз, когда функция запрашивает изменение.Затем «измененный» слот проверяет, было ли запрошено действие записи, и если да, снова устанавливает m_writeInProgress в false и завершает работу.Таким образом, он будет обрабатывать только «внешние» изменения.

Проблема по-прежнему в том, что если изменение происходит именно в тот момент, когда происходит фактическая запись, оно не перехватывается.

Так что возможно,использование QFileSystemWatcher является неправильным способом реализации этого.

Как это можно сделать безопасным способом?

Спасибо за помощь!

Редактировать:

Я нашел способ решить часть проблемы.Запуск эксклюзивной блокировки файла базы данных не позволяет другим соединениям изменять его.Это довольно просто, мне просто нужно выполнить

PRAGMA locking_mode = EXCLUSIVE
BEGIN EXCLUSIVE
COMMIT

и обработать ошибку, которая возникает, если другой экземпляр моей программы пытается получить доступ к базе данных.

Осталось узнать, является ли пользователь(случайно) удалил файл во время выполнения ...

1 Ответ

0 голосов
/ 01 июня 2018

Прежде всего, для этого нет поддержки SQLITE: SQLITE поддерживает только мониторинг изменений, создаваемых через соединение с базой данных в пределах вашего прямого контроля.Что бы ни происходило в отдельном процессе одновременно с вашим процессом, или когда ваш процесс не запущен, по своему замыслу полностью вне вашего контроля.

Каноническое решение этой проблемы - шифрование базы данных ключом, специфичным дляваше приложение (и, возможно, пользователь и т. д.).Тогда ни один сторонний процесс не сможет изменить базу данных с помощью SQLITE.Конечно, любой процесс может повредить вашу базу данных или избавиться от нее - это очень плохо.Вы можете легко обнаружить повреждение с помощью криптографических подписей, возможно, даже кодов, исправляющих ошибки, чтобы иметь возможность восстановить данные в случае определенного повреждения.Вам не нужны уведомления о том, что кто-то перемещает или удаляет файл базы данных: вы узнаете, когда попытаетесь открыть базу данных, и вы получите сообщение об ошибке «файл не найден».

Конечно, всевыше требуется пользовательская реализация VFS .Это очень много для курса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...