Hi Merijn,

does the attached patch looks good for you?
I decided to deal differently with lockMode, because I don't want
silently drop lock support ...

Jens
Index: lib/DBD/File.pm
===================================================================
--- lib/DBD/File.pm     (Revision 15389)
+++ lib/DBD/File.pm     (Arbeitskopie)
@@ -624,6 +624,8 @@
 {
     my ($className, $data, $attrs, $flags) = @_;
 
+    # open_file must be called before inherited new is invoked
+    # because column name mapping is initialized in constructor ...
     my ($tblnm, $meta) = $className->get_table_meta ($data->{Database}, 
$attrs->{table}, 1) or
         croak "Cannot find appropriate file for table '$attrs->{table}'";
     $className->open_file ($meta, $attrs, $flags);
Index: lib/DBI/DBD/SqlEngine.pm
===================================================================
--- lib/DBI/DBD/SqlEngine.pm    (Revision 15389)
+++ lib/DBI/DBD/SqlEngine.pm    (Arbeitskopie)
@@ -1293,6 +1293,17 @@
                 };
     $self->{command} eq "DROP" and $flags->{dropMode} = 1;
 
+    # because column name mapping is initialized in constructor ...
+    # and therefore specific opening operations might be done before
+    # reaching DBI::DBD::SqlEngine::Table->new(), we need to intercept
+    # ReadOnly here
+    my $write_op = $createMode || $lockMode || $flags->{dropMode};
+    if( $write_op ) {
+       my ( $tblnm, $table_meta ) = $class->get_table_meta( $data->{Database}, 
$table, 1 )
+         or croak "Cannot find appropriate file for table '$table'";
+       $table_meta->{readonly} and croak "Table '$table' is marked readonly - 
" . $self->{command} . " command forbidden";
+    }
+
     return $class->new( $data, { table => $table }, $flags );
 }    # open_table
 
@@ -1450,8 +1461,6 @@
     $flags->{createMode} && $data->{sql_stmt}{table_defs}
       and $meta->{table_defs} = $data->{sql_stmt}{table_defs};
 
-    my $columns = {};
-    my $array   = [];
     my $tbl = {
                 %{$attrs},
                 meta      => $meta,
Index: lib/DBI/SQL/Nano.pm
===================================================================
--- lib/DBI/SQL/Nano.pm (Revision 15387)
+++ lib/DBI/SQL/Nano.pm (Arbeitskopie)
@@ -31,7 +31,7 @@
     $VERSION = sprintf( "1.%06d", q$Revision$ =~ /(\d+)/o );
 
     $versions->{nano_version} = $VERSION;
-    if ( $ENV{DBI_SQL_NANO} || !eval { require SQL::Statement; 
$SQL::Statement::VERSION ge '1.28' } )
+    if ( $ENV{DBI_SQL_NANO} || !eval { require SQL::Statement; 
$SQL::Statement::VERSION ge '1.400' } )
     {
         @DBI::SQL::Nano::Statement::ISA = qw(DBI::SQL::Nano::Statement_);
         @DBI::SQL::Nano::Table::ISA     = qw(DBI::SQL::Nano::Table_);
Index: t/49dbd_file.t
===================================================================
--- t/49dbd_file.t      (Revision 15389)
+++ t/49dbd_file.t      (Arbeitskopie)
@@ -150,8 +150,61 @@
     $dbh->errstr and diag $dbh->errstr;
     }
 
+# ==================== ReadOnly tests =============================
+ok ($dbh = DBI->connect ("dbi:File:", undef, undef, {
+    f_ext      => ".txt",
+    f_dir      => $dir,
+    f_schema   => undef,
+    f_encoding => $encoding,
+    f_lock     => 0,
+
+    sql_meta    => {
+       $tbl => {
+           col_names => [qw(txt)],
+           }
+       },
+
+    RaiseError => 0,
+    PrintError => 0,
+    ReadOnly    => 1,
+    }), "ReadOnly connect with driver attributes in hash");
+
+ok ($sth = $dbh->prepare ("select * from $tbl"), "Prepare select * from $tbl");
+$rowidx = 0;
+SKIP: {
+    $using_dbd_gofer and skip "method intrusion didn't work with proxying", 1;
+    ok ($sth->execute, "execute on $tbl");
+    $dbh->errstr and diag $dbh->errstr;
+    }
+
+ok ($sth = $dbh->prepare ("insert into $tbl (txt) values (?)"), "prepare 
'insert into $tbl'");
+is ($sth->execute ("Perl rules"), undef, "insert failed intensionally");
+diag $dbh->errstr;
+
+ok ($sth = $dbh->prepare ("delete from $tbl"), "prepare 'delete from $tbl'");
+is ($sth->execute (), undef, "delete failed intensionally");
+diag $dbh->errstr;
+
+is ($dbh->do ("drop table $tbl"), undef, "table drop failed intensionally");
+diag $dbh->errstr;
+is (-f $tbl_file, 1, "Test table not removed");
+
+# ==================== ReadWrite again tests =============================
+ok ($dbh = DBI->connect ("dbi:File:", undef, undef, {
+    f_ext      => ".txt",
+    f_dir      => $dir,
+    f_schema   => undef,
+    f_encoding => $encoding,
+    f_lock     => 0,
+
+    RaiseError => 0,
+    PrintError => 0,
+    }), "ReadWrite for drop connect with driver attributes in hash");
+
+# XXX add a truncate test
+
 ok ($dbh->do ("drop table $tbl"), "table drop");
-is (-s "$tbl.txt", undef, "Test table removed");
+is (-s $tbl_file, undef, "Test table removed"); # -s => size test
 
 done_testing ();
 

Reply via email to