Russian Qt Forum
Ноябрь 24, 2024, 01:49 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Открытие базы данных только для чтения  (Прочитано 6121 раз)
QCasper
Гость
« : Май 08, 2009, 11:45 »

Работаю с базой sqlite с помощью класса QSqlDatabase и прочими, применимыми для этого дела. Как открывать её только для чтения? То есть чтобы запросы типа update и прочие "пишущие" не срабатывали.
Записан
developer
Гость
« Ответ #1 : Май 08, 2009, 13:22 »

Как сделать на уровне базы данных не знаю. Но програмно попробуй просто проверить sql, если он имеет слово SELECT тогда такой запрос пропустить, иначе запретить исполнениэ запроса, слово SELECT можеш найти с помощью регекса.
Записан
QCasper
Гость
« Ответ #2 : Май 08, 2009, 17:06 »

Ага, а если он имеет слово и селект и апдейт? И ремув до кучи. Запрос вложенный может быть. Вобщем это костыль, рассматривался, не устраивает.
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #3 : Май 08, 2009, 17:33 »

не знаю можно ли задать параметры средствами Qt, но сама СУБД позволяет открывать БД в режиме "только чтение" см. тут: http://www.sqlite.org/c3ref/open.html
Записан

Юра.
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #4 : Май 08, 2009, 17:39 »

Ещё один вариант создать временные тригеры:
CREATE TEMPORARY TRIGGER ...
и в них осуществлять какую-нибудь ругань.
Они автоматически удаляются при закрытии соединения.
Записан

Юра.
QCasper
Гость
« Ответ #5 : Май 08, 2009, 17:48 »

не знаю можно ли задать параметры средствами Qt, но сама СУБД позволяет открывать БД в режиме "только чтение" см. тут: http://www.sqlite.org/c3ref/open.html

Интересно таки с помощью Qt, поэтому здесь и спрашиваю.

Ещё один вариант создать временные тригеры

А вот здесь я что-то не очень понял, можно подробнее?
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #6 : Май 08, 2009, 17:58 »

>>А вот здесь я что-то не очень понял, можно подробнее?
Я мало работал с Лайтом. Незнаю есть ли в нём возможность генерить исключения из тригера.
Но для огнептица, например так:
создается тригер на событие (в твоём случае на BEFORE UPDATE/BEFORE INSERT) на интерисующие или все таблицы. Т.к. обе операции запрещены, то в тригере сразу же генерится исключение, и следовательно опрерация вставки/обновления прерывается.
Записан

Юра.
QCasper
Гость
« Ответ #7 : Май 12, 2009, 10:00 »

создается тригер на событие (в твоём случае на BEFORE UPDATE/BEFORE INSERT) на интерисующие или все таблицы. Т.к. обе операции запрещены, то в тригере сразу же генерится исключение, и следовательно опрерация вставки/обновления прерывается.

А можно ли в одном случае прервать операцию вставки/обновления по срабатыванию триггера, а в другом случае продолжить?
Записан
QCasper
Гость
« Ответ #8 : Май 12, 2009, 14:38 »

Вобщем пока решил вот таким образом:

Код:
void setWritingAllowed(bool allowed) {
QString query = (!allowed
?
"create trigger disallow_%1_on_%2 before %1 on %2 begin select "
"case when 1=1 then raise(abort, 'writing_not_allowed') end; end"
:
"drop trigger disallow_%1_on_%2")
;

const QStringList actionList = QStringList()
<< "DELETE" << "INSERT" << "UPDATE";

foreach(QString table, c_TableNameList)
foreach(QString action, actionList)
execQuery(query.arg(action).arg(table));
}

и, соответственно в местах, где хочу защититься от записи пишу:

Код:
setWritingAllowed(false);
// здесь код выполнения запроса
setWritingAllowed(true);

Если у кого-то есть более красивое и короткое решение, буду несказанно рад о нём узнать.

В этом же решении меня особенно раздражает строчка "select case when 1=1 then raise(abort, 'writing_not_allowed') end", но как по другому заполнить пустое место между BEGIN и END я не осилил найти.
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #9 : Май 20, 2009, 02:59 »

Цитировать
Ага, а если он имеет слово и селект и апдейт? И ремув до кучи. Запрос вложенный может быть. Вобщем это костыль, рассматривался, не устраивает.

Конечно понимаю что так вам не хочется но все же - если создать массив ключевых слов меняющих метаданных и в каждом отправляемом запросе искать их (а не select)- если их нет - то пропусать если хоть одно нашлось нет.

собственно ваш список таких меняющих метаданные слов:

const QStringList actionList = QStringList()
actionList << "DELETE" << "INSERT" << "UPDATE";

может это и костыль но создание / удаление триггеров в БД это еще больший костыль - т.к. программа должна стремиться не менять метаданные бех надобности. Что например будет если ваша программа сделает setWritingAllowed(false); --- а потом вылетит с ошибкой?

Кстати как там в SQLite нет у триггеров такого понятия как "активность" - тогда уж хоть через него
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.049 секунд. Запросов: 23.