Принудительно только чтение при подключении к файлу sqlite

На многих внешних интерфейсах я хочу применять свои сценарии, используя подключение только для чтения к файлу sqlite3, отраженному от главного сервера.

Есть ли способ сказать DBI, чтобы сделать это?

На данный момент я делаю это:

       $dbHand = DBI->connect("dbi:SQLite:dbname=$dbName", $dbUser, $dbPass, {
            PrintError => 0,
            RaiseError => 1,
            AutoCommit => 1,
    }) or die $DBI::errstr;

И получите полный доступ.

  • Я не свободно владею Perl, я должен поддерживать / развивать существующие
  • (Я не хочу иметь дело с правами доступа к файлам)

2 ответа

Решение

Использовать sqlite_open_flags атрибут, как объяснено в документации DBD:: SQLite:

use DBD::SQLite;
my $dbh = DBI->connect("dbi:SQLite:$dbfile", undef, undef, {
  sqlite_open_flags => DBD::SQLite::OPEN_READONLY,
});

Это приведет к ошибке, если вы попытаетесь открыть базу данных, которая не существует (как правило, будет создана новая база данных), или если вы попытаетесь выполнить запись в существующую базу данных.

Обратите внимание, что вы должны явно use DBD::SQLite; для того, чтобы использовать постоянную DBD::SQLite::OPEN_READONLY,


Помните, что DBI предоставляет ReadOnly обрабатывать атрибут, но DBD:: SQLite не соблюдает его до v1.49_05:

use strict;
use warnings;

use Data::Dump;
use DBI;

my $db = 'foo.db';
unlink $db if -f $db;

my $dbh = DBI->connect("dbi:SQLite:dbname=$db",'','', {
    RaiseError => 1,
    ReadOnly   => 1
});

$dbh->do( q{CREATE TABLE foo(id INTEGER, name TEXT)} );
$dbh->do( q{INSERT INTO foo VALUES(1, 'foo')} );
my $values = $dbh->selectall_arrayref( q{SELECT * FROM foo} );

dd $values;

Выходы:

[[1, "foo"]]

Переключение на sqlite_open_flags => DBD::SQLite::OPEN_READONLY вызывает ошибки.

Если база данных не существует:

DBI connect('dbname=foo.db','',...) failed: unable to open database file

Если база данных существует:

DBD::SQLite::db do failed: attempt to write a readonly database

Начиная с DBD::SQLite v1.49_05, вы также можете использовать ReadOnly атрибут, но только в качестве опции connect, Установка атрибута после подключения не работает и выдает предупреждение:

my $dbh = DBI->connect("dbi:SQLite:dbname=$db",'','', {
    RaiseError => 1
});
$dbh->{ReadOnly} = 1;

Выходы:

DBD:: SQLite:: db STORE предупреждение: ReadOnly установлен, но это только рекомендация

Просто установите

$dbHand ->{ReadOnly} = 1

как описано здесь

Другие вопросы по тегам