+sub db_onconflict (&) {
+ my ($conflictproc) = @_;
+ $dbh->{HandleError}= sub {
+ my ($emsg,$dbh,$val1) = @_;
+ my $native_ecode= $dbh->err();
+ &$conflictproc($emsg) if grep { $_ == $native_ecode } qw(5 6);
+ # 5==SQLITE_BUSY, 6==SQLITE_LOCKED according to the SQLite3
+ # API documentation, .../capi3ref.html#extended-result-codes.
+ return 0; # RaiseError happens next.
+ };
+}
+
+our $writerlockh;
+
+sub db_writer () {
+ my $lockfn= "Writer.lock";
+ $writerlockh= new IO::File "$lockfn", "w" or die "$lockfn $!";
+
+ my $flockall= pack 's!s!LLLLLL', F_WRLCK, SEEK_SET, 0,0,0,0,0,0;
+ # should work everywhere to lock the whole file, provided that
+ # l_type and l_whence are `short int' and come first in that order,
+ # and that start, len and pid are no more than 64 bits each.
+
+ my $r= fcntl($writerlockh, F_SETLKW, $flockall);
+ $r or die "$lockfn fcntl $!";
+}
+