#!/usr/bin/perl
use lib 'lib';
use strict;
use warnings;
# WARNING: Test::More obviously gets a bit confused with the fork
# there's also Test::Fork
use Test::More;
use DBI;
use DBD::SQLite;
my $dbfile = 'abc.sqlite';
my $pid = fork();
if( not $pid ){
my $dbh = DBI->connect(
"dbi:SQLite:dbname=$dbfile",
'', '',
{
RaiseError => 0, # don't die on error
sqlite_open_flags => DBD::SQLite::OPEN_READWRITE
| DBD::SQLite::OPEN_CREATE
}
);
ok(defined $dbh, "connect()");
# this causes the driver to timeout and not to wait
# for the lock forever
$dbh->sqlite_busy_timeout(1000); # milliseconds
my $SQL = 'PRAGMA locking_mode = EXCLUSIVE';
my $ret = eval { $dbh->do($SQL) };
ok(defined $ret, "do SQL: $SQL");
$SQL = 'BEGIN EXCLUSIVE';
$ret = eval { $dbh->do($SQL) };
ok(defined $ret, "do SQL: $SQL");
# now db is locked, we have 15 seconds
# to test the locked db before unlock
sleep 15;
$dbh->disconnect();
diag("DB is now unlocked.");
exit;
}
# parent
# give some time for our child to lock the db
sleep 2; # we now have 13 seconds to finish all tests before db unlocks
# check that the db is locked
my $dbh = DBI->connect(
"dbi:SQLite:dbname=$dbfile",
'', '',
{
RaiseError => 0, # don't die
sqlite_open_flags => DBD::SQLite::OPEN_READONLY,
TraceLevel => 1,
}
);
ok(defined $dbh, "connected to db '$dbfile'.");
# set this to a short timeout (millis) because it can wait forever
# and our child will be dead soon!
$dbh->sqlite_busy_timeout(1000);
my $SQL = 'BEGIN IMMEDIATE';
my $ret = eval { $dbh->do($SQL) };
ok(!defined $ret, "database is locked and SQL must fail: '$SQL'.");
$dbh->disconnect;
wait; # for our child
done_testing();
####
use strict;
use warnings;
use Test::More tests => 1+3+2;
use Test::Fork;
use DBI;
use DBD::SQLite;
my $dbfile = 'abc.sqlite';
fork_ok(3, sub {
my $dbh = DBI->connect(
"dbi:SQLite:dbname=$dbfile",
'', '',
{
RaiseError => 0, # don't die on error
sqlite_open_flags => DBD::SQLite::OPEN_READWRITE
| DBD::SQLite::OPEN_CREATE
}
);
ok(defined $dbh, "connect()");
# this causes the driver to timeout and not to wait
# for the lock forever
$dbh->sqlite_busy_timeout(1000); # milliseconds
my $SQL = 'PRAGMA locking_mode = EXCLUSIVE';
my $ret = eval { $dbh->do($SQL) };
ok(defined $ret, "do SQL: $SQL");
$SQL = 'BEGIN EXCLUSIVE';
$ret = eval { $dbh->do($SQL) };
ok(defined $ret, "do SQL: $SQL");
# now db is locked, we have 15 seconds
# to test the locked db before unlock
sleep 15;
# TODO: how do we unlock the beast?
# ROLLBACK; or COMMIT; nothing works
$dbh->disconnect();
diag("DB is now unlocked.");
});
# parent
# give some time for our child to lock the db
sleep 2; # we now have 13 seconds to finish all tests before db unlocks
# check that the db is locked
my $dbh = DBI->connect(
"dbi:SQLite:dbname=$dbfile",
'', '',
{
RaiseError => 0, # don't die
sqlite_open_flags => DBD::SQLite::OPEN_READONLY,
TraceLevel => 1,
}
);
ok(defined $dbh, "connected to db '$dbfile'.");
# set this to a short timeout (millis) because it can wait forever
# and our child will be dead soon!
$dbh->sqlite_busy_timeout(1000);
my $SQL = 'BEGIN IMMEDIATE';
my $ret = eval { $dbh->do($SQL) };
ok(!defined $ret, "database is locked and SQL must fail: '$SQL'.");
$dbh->disconnect;
#wait; # for our child, this is handled by fork_ok
#done_testing(); not needed
##
##
use strict;
use warnings;
use Test::More;
use DBI;
use DBD::SQLite;
my $dbfile = 'abc.sqlite';
# we are opening the same database and at some point
# we have the same DB opened with 2 different handles
# First time here to lock it
my $dbh_locked = DBI->connect(
"dbi:SQLite:dbname=$dbfile",
'', '',
{
RaiseError => 0, # don't die on error
sqlite_open_flags => DBD::SQLite::OPEN_READWRITE
| DBD::SQLite::OPEN_CREATE
}
);
ok(defined $dbh_locked, "connect()");
# this causes the driver to timeout and not to wait
# for the lock forever
$dbh_locked->sqlite_busy_timeout(1000); # milliseconds
my $SQL = 'PRAGMA locking_mode = EXCLUSIVE';
my $ret = eval { $dbh_locked->do($SQL) };
ok(defined $ret, "do SQL: $SQL");
$SQL = 'BEGIN EXCLUSIVE';
$ret = eval { $dbh_locked->do($SQL) };
ok(defined $ret, "do SQL: $SQL");
# now db is locked, we have 15 seconds
# to test the locked db before unlock
diag("DB is now locked.");
# Second time, we open the DB here to check if it's locked
# check that the db is locked
my $dbh = DBI->connect(
"dbi:SQLite:dbname=$dbfile",
'', '',
{
RaiseError => 0, # don't die
sqlite_open_flags => DBD::SQLite::OPEN_READONLY,
TraceLevel => 1,
}
);
ok(defined $dbh, "connected to db '$dbfile'.");
# set this to a short timeout (millis) because it can wait forever
# and our child will be dead soon!
$dbh->sqlite_busy_timeout(1000);
$SQL = 'BEGIN IMMEDIATE';
$ret = eval { $dbh->do($SQL) };
ok(!defined $ret, "database is locked and SQL must fail: '$SQL'.");
$dbh->disconnect;
$dbh_locked->disconnect;
done_testing();