连接到sqlite文件时强制只读

时间:2015-12-18 13:48:10

标签: perl sqlite dbi

在许多前端, 我希望使用与主服务器镜像的sqlite3文件的只读连接来强制执行我的脚本。

有没有办法说DBI这样做?

目前,我正在这样做:

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

获得完全访问权限。

  • 我不是很流利,我必须保持/发展现有的
  • (我不想处理文件权限)

2 个答案:

答案 0 :(得分:6)

按照DBD::SQLite documentation

中的说明使用sqlite_open_flags属性
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,但它只是建议

答案 1 :(得分:2)

只需设置

$dbHand ->{ReadOnly} = 1

here

所述