DBD::Gofer middleware thoughts (was Idea for a Gofer transport for translating SQL - primarily intended for testing)

2011-09-09 Thread Andrew Ford
If we have a DBD::Gofer middleware feature then it would be helpful to 
add a new passthrough (or "passthru") transport.  This would be based on 
the null transport, but without the serialization/deserialization, i.e. 
something as simple as:


   package DBD::Gofer::Transport::passthrough;

   #   $Id: null.pm 10087 2007-10-16 12:42:37Z timbo
   $   

   # 


   #   Copyright (c) 2007, Tim Bunce,
   Ireland

   # 


   #   You may distribute under the terms of either the GNU General
   Public   


   #   License or the Artistic License, as specified in the Perl README
   file.



   use strict;
   use warnings;

   use base qw(DBD::Gofer::Transport::Base);

   use DBI::Gofer::Execute;

   our $VERSION = sprintf("0.%06d", q$Revision: 10087 $ =~ /(\d+)/o);

   my $executor = DBI::Gofer::Execute->new();

   sub transmit_request_by_transport {
   my ($self, $request) = @_;
   


   return $executor->execute_request( $request );
   }

   1;

This would be suitable for middleware modules to wrap.

Andrew


Re: Fwd: Idea for a Gofer transport for translating SQL - primarily intended for testing

2011-09-09 Thread Andrew Ford
Thinking about how middleware could be implemented in DBD::Gofer - see 
below ...


Tim Bunce wrote:

On Thu, Sep 08, 2011 at 01:19:17PM +0100, Andrew Ford wrote:
  

   and I would quite like to get this module onto CPAN and would like some 
feedback as to
   whether "the expert" thinks it is a bad idea.  I think it would be a useful 
addition to the testing
   armoury, but then I am obviously biased.



The general idea is certainly useful. I'd like to generalise it though.

There's a conceptual similarity with PSGI/Plack middlewares that I'd
like to build on.  Specifically, rather than creating a new transport,
I'd like to see DBD/Gofer/Transport/Base.pm extended to call one or more
'Gofer client middlewares' just before it calls transmit_request_by_transport().

The calling code could be something like:

+   my $mw = $self->middleware;
my $transmit_sub = sub {
my $response = eval {
...
-  $self->transmit_request_by_transport($request)
+  $mw->($self, $request);
}
...
}

The middleware attribute would default to:

sub { shift->transmit_request_by_transport(@_) }

new middleware layer would be added by doing:

my $mw = $self->middleware;
$self->middleware( sub {
my ($self, $request) = @_;
...do something with $request...
my $response = $mw->($self, $request);
...do something with $response...
return $response;
} );

[This is all off-the-top-of-my-head, and I'm not very familar with Plack
internals so I may well be missing important issues.]

Then we just need a way to add middlewares via the environment.
  
I'd be delighted if you would work up a patch to add that to the DBI.
  

Currently DBD::Gofer::dr:connect() contains code to set up the transport:

   my $transport_class = delete $go_attr{go_transport}
   or return $drh->set_err($DBI::stderr, "No transport=
   argument in '$orig_dsn'");
   $transport_class = "DBD::Gofer::Transport::$transport_class"
   unless $transport_class =~ /::/;
   _load_class($transport_class)
   or return $drh->set_err($DBI::stderr, "Can't load
   $transport_class: $@");
   my $go_transport = eval { $transport_class->new(\%go_attr) }
   or return $drh->set_err($DBI::stderr, "Can't instanciate
   $transport_class: $@");


I would imagine that we could have a "middleware" keyword that was a 
comma-separated list of names that were assumed to be in the 
DBDx::GoferMiddleware namespace - these would be installed in sequence 
with a similar block of code that follows on from the snippet above, 
looking something like:


   my $middleware_classes = delete $go_attr{go_middleware};
   foreach my $middleware_class (split /,/,
   $middleware_classes) {  
   $middleware_class =

   "DBDx::GoferMiddleware::$middleware_class"
   unless $middleware_class =~ /::/;
   _load_class($middleware_class)
   or return $drh->set_err($DBI::stderr, "Can't load
   $middleware_class: $@");
   $go_transport->middleware( sub { return
   $middleware_class->HANDLER(shift, $go_transport->middleware) } );
   }

Each middleware handler would take a request object and a reference to 
the next handler in the chain.


We would need to have a default method name for the middleware handler 
(I've used the placeholder HANDLER in the pseudo-code above).


The DSNs would then look like:


dbi:Gofer:transport=null;middleware=adaptor;transform=MyMapper;dsn=dbi:XXX...

There are a few holes in this that I can think of:

   * We might want to instantiate a middleware object for each
 component and use that in installing the middleware handler
   * I am not sure how we could specify a handler name other than the
 default for individual middleware components
   * Also not sure how attributes for each middleware component could
 be specified such that the component for which the attribute is
 intended could be specified - the example DSN above assumes that
 the attribute (transform in the example DSN) is just dumped into
 the general "go_" attribute hash)
   * The go_middleware attribute could be set in the DBI connect
 attribute hash to a list of subroutine references (code would need
 to differentiate between a comma-separated list value and a list
 reference value)
   * Should the middleware components be listed innermost first (as
 implemented in the pseudo-code above) or outermost first?
   * We might want to add some convenience methods to the request class
 to build response objects (as suggested in my
 DBD::Gofer::Transport::adaptor code)


I'll have a go at getting this coded over the next few days, but it 
looks as if the changes required to implement middleware are relatively 
trivial.



Your module could then use this mechanism. If you wanted to release it
to CPAN then 

Try to Contact SQL::Library Author Doug Gorley

2011-09-09 Thread tiger peng
Hello,

Is Doug Gorley in this group?


I try to contact SQL::Library Author Doug Gorley but failed by the email listed 
in the module. Could any one help?

Thanks,


Ge Peng

Re: Fwd: Idea for a Gofer transport for translating SQL - primarily intended for testing

2011-09-09 Thread Andrew Ford

Tim Bunce wrote:

On Thu, Sep 08, 2011 at 01:19:17PM +0100, Andrew Ford wrote:
  

   and I would quite like to get this module onto CPAN and would like some 
feedback as to
   whether "the expert" thinks it is a bad idea.  I think it would be a useful 
addition to the testing
   armoury, but then I am obviously biased.



The general idea is certainly useful. I'd like to generalise it though.

  
OK  - I have got Gofer::DBD::Transport::adaptor written and tested 
(attached to this mail).  I will hang off on uploading to CPAN and will 
look at Plack middleware and how the functionality could be refactored 
to give patches to DBD::Gofer for installing middleware, plus the rump 
of my adaptor module as a DBDx::MiddleWare::XXX module.


Andrew




DBD-Gofer-Transport-adaptor-0.001.tar.gz
Description: application/gzip


Re: Fwd: Idea for a Gofer transport for translating SQL - primarily intended for testing

2011-09-09 Thread Tim Bunce
On Thu, Sep 08, 2011 at 01:19:17PM +0100, Andrew Ford wrote:
>Hi Tim
> 
>Sorry for mailing you directly, but I don't know whether my emails
>are getting through to the dbi-users mailing list,

[CC'd to dbi-users]

>and I would quite like to get this module onto CPAN and would like some 
> feedback as to
>whether "the expert" thinks it is a bad idea.  I think it would be a 
> useful addition to the testing
>armoury, but then I am obviously biased.

The general idea is certainly useful. I'd like to generalise it though.

There's a conceptual similarity with PSGI/Plack middlewares that I'd
like to build on.  Specifically, rather than creating a new transport,
I'd like to see DBD/Gofer/Transport/Base.pm extended to call one or more
'Gofer client middlewares' just before it calls transmit_request_by_transport().

The calling code could be something like:

+   my $mw = $self->middleware;
my $transmit_sub = sub {
my $response = eval {
...
-  $self->transmit_request_by_transport($request)
+  $mw->($self, $request);
}
...
}

The middleware attribute would default to:

sub { shift->transmit_request_by_transport(@_) }

new middleware layer would be added by doing:

my $mw = $self->middleware;
$self->middleware( sub {
my ($self, $request) = @_;
...do something with $request...
my $response = $mw->($self, $request);
...do something with $response...
return $response;
} );

[This is all off-the-top-of-my-head, and I'm not very familar with Plack
internals so I may well be missing important issues.]

Then we just need a way to add middlewares via the environment.

I'd be delighted if you would work up a patch to add that to the DBI.

Your module could then use this mechanism. If you wanted to release it
to CPAN then a name like DBDx::GoferMiddleware::FOO would be good.
(Note the DBDx not DBIx since this is client-side. We may well end up
with server-side gofer middlewares as well.)

Tim.

>I have attached the current version of the module file with some 
> documentation from my intial post
>included below (I've changed my mind about the attribute naming and 
> currently am going for
>transform=modulename and method=methodname for the module/method that 
> implements the transformation).  I
>will of course add unit tests and everything that goes with a proper CPAN 
> release, but I would be
>grateful for some quick feedback.
> 
>Regards
>Andrew
> 
> Original Message 
> 
>Subject: Idea for a Gofer transport for translating SQL - primarily 
> intended for testing
>   Date: Thu, 08 Sep 2011 11:16:41 +0100
>   From: Andrew Ford [1]
> To: [2]dbi-users@perl.org
> 
>I have a software system that I have to test that uses a very large 
> database accessed exclusively with
>stored procedures.  It is a pain setting up a test database for simple 
> unit tests of the Perl code (I am
>not trying to test the stored procedures).
> 
>What I want is to be able to do is set up a simple database (SQLite) 
> quickly to use instead, but of
>course there is the issue of the stored procedures being database-specific 
> - but then for testing
>purposes most of the stored procedures could be represented by simple SQL 
> statements.
> 
>What I have done as a proof of concept is to take the 
> DBD::Gofer::Transport::null and create a new
>module that maps the stored procedures into simple SQL statements and then 
> executes them in-process
>against the test database
> 
>The code is pretty simple and included below.  Currently it has a map of 
> stored procedure
>transformations hard-coded in the code and assumes ODBC style stored 
> procedure call syntax, but I was
>thinking of allowing a mapping module to be specified as an attribute in 
> the DSN so that the DSN would
>be specified like:
> 
>  
> dbi:Gofer:transport=adaptor;mapper=My::Mapping::Module;dsn=dbi:SQLite:test.db
> 
>Overriding the system's DSN then causes the system to use my test 
> database, transparently doing the
>appropriate mappings.
> 
>I would appreciate any comments, suggestions, and thoughts as to whether 
> this would be a useful addition
>to CPAN.
> 
>The immediate issue that I see is: what would the interface to the mapping 
> module be (probably the
>module should provide a single function that takes a request object and 
> either modifies it or returns a
>new request object).
> 
>Andrew
> 
>current proof-of-concept code:
> 
>  package DBD::Gofer::Transport::adaptor;
> 
>  use strict;
>  use warnings;
> 
>  use DBI::Gofer::Execute;
> 
>  use base qw(DBD::Gofer::Transport::Base);
> 
>  __PACKAGE__->mk_accessors( qw( pending_response transmit_count ) );
> 
>  # Lookup table for stored procedure transformations
> 
>  my %stored_proc_transform
>  

problems install DBD::DB2

2011-09-09 Thread Marco Avvisano

Hi,
i'm tryng to install DBD::DB2 on my linux box but it fails:


install DBD::DB2
Going to read '/root/.cpan/Metadata'
  Database was generated on Thu, 08 Sep 2011 09:28:48 GMT
Running install for module 'DBD::DB2'
Running make for I/IB/IBMTORDB2/DBD-DB2-1.81.tar.gz
Checksum for 
/root/.cpan/sources/authors/id/I/IB/IBMTORDB2/DBD-DB2-1.81.tar.gz ok

Scanning cache /root/.cpan/build for sizes
..--DONE
DEL(1/2): /root/.cpan/build/SOAP-Lite-0.712-CNzvW5
DEL(2/2): /root/.cpan/build/SOAP-Lite-0.712-CNzvW5.yml

  CPAN.pm: Going to build I/IB/IBMTORDB2/DBD-DB2-1.81.tar.gz

Legacy library flush.pl will be removed from the Perl core distribution 
in the next major release. Please install it from the CPAN distribution 
Perl4::CoreLibs. It is being used at Makefile.PL, line 11.


Configuring DBD::DB2...
Remember to actually read the README and CAVEATS files!

Using DB2 in "/opt/ibm/db2/V9.7"
System: perl5.014001 DBI1.616 linux monitor.regione.toscana.it 
2.6.32-131.6.1.el6.x86_64 #1 smp mon jun 20 14:15:38 edt 2011 x86_64 
x86_64 x86_64 gnulinux  x86_64-linux dl_dlopen.xs
Compiler: cc -O2 -fno-strict-aliasing -pipe -fstack-protector 
-I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
Includes:  -I"/opt/ibm/db2/V9.7/include" 
-I"/opt/perl5/lib/site_perl/5.14.1/x86_64-linux/auto/DBI" 
-I"/opt/perl5/lib/5.14.1/x86_64-linux/auto/DBI" 
-I"/opt/perl5/lib/site_perl/5.14.1/x86_64-linux/auto/DBI"

Libraries: -L/opt/ibm/db2/V9.7/lib64 -ldb2

Checking if your kit is complete...
Looks good
Checking if your kit is complete...
Looks good
Writing Makefile for DBD::DB2::Constants
Writing MYMETA.yml
Writing Makefile for DBD::DB2
Writing MYMETA.yml
cp DB2.pm blib/lib/DBD/DB2.pm
cp lib/Bundle/DBD/DB2.pm blib/lib/Bundle/DBD/DB2.pm
cp DB2.pod blib/lib/DBD/DB2.pod
make[1]: Entering directory 
`/root/.cpan/build/DBD-DB2-1.81-xaPjeE/Constants'

cp Constants.pm ../blib/lib/DBD/DB2/Constants.pm
AutoSplitting ../blib/lib/DBD/DB2/Constants.pm 
(../blib/lib/auto/DBD/DB2/Constants)
/opt/perl5/bin/perl /opt/perl5/lib/5.14.1/ExtUtils/xsubpp  -typemap 
/opt/perl5/lib/5.14.1/ExtUtils/typemap  Constants.xs > Constants.xsc && 
mv Constants.xsc Constants.c
cc -c  -I"/opt/ibm/db2/V9.7/include" -fno-strict-aliasing -pipe 
-fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE 
-D_FILE_OFFSET_BITS=64 -O2   -DVERSION=\"1.81\" -DXS_VERSION=\"1.81\" 
-fPIC "-I/opt/perl5/lib/5.14.1/x86_64-linux/CORE"   Constants.c

Running Mkbootstrap for DBD::DB2::Constants ()
chmod 644 Constants.bs
rm -f ../blib/arch/auto/DBD/DB2/Constants/Constants.so
cc  -shared -O2 -L/usr/local/lib -fstack-protector Constants.o  -o 
../blib/arch/auto/DBD/DB2/Constants/Constants.so \

\

chmod 755 ../blib/arch/auto/DBD/DB2/Constants/Constants.so
cp Constants.bs ../blib/arch/auto/DBD/DB2/Constants/Constants.bs
chmod 644 ../blib/arch/auto/DBD/DB2/Constants/Constants.bs
make[1]: Leaving directory `/root/.cpan/build/DBD-DB2-1.81-xaPjeE/Constants'
/opt/perl5/bin/perl /opt/perl5/lib/5.14.1/ExtUtils/xsubpp  -typemap 
/opt/perl5/lib/5.14.1/ExtUtils/typemap  DB2.xs > DB2.xsc && mv DB2.xsc DB2.c
cc -c  -I"/opt/ibm/db2/V9.7/include" 
-I"/opt/perl5/lib/site_perl/5.14.1/x86_64-linux/auto/DBI" 
-I"/opt/perl5/lib/5.14.1/x86_64-linux/auto/DBI" 
-I"/opt/perl5/lib/site_perl/5.14.1/x86_64-linux/auto/DBI"  
-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include 
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2   -DVERSION=\"1.81\" 
-DXS_VERSION=\"1.81\" -fPIC "-I/opt/perl5/lib/5.14.1/x86_64-linux/CORE"  
-DDB2_CACHE_FIX  DB2.c

DB2.xs: In function âXS_DBD__DB2__dr_disconnect_allâ:
DB2.xs:49: error: âdirtyâ undeclared (first use in this function)
DB2.xs:49: error: (Each undeclared identifier is reported only once
DB2.xs:49: error: for each function it appears in.)
DB2.xs: In function âXS_DBD__DB2__db__loginâ:
DB2.xs:92: error: âsv_yesâ undeclared (first use in this function)
DB2.xs:92: error: âsv_noâ undeclared (first use in this function)
DB2.xs: In function âXS_DBD__DB2__db_commitâ:
DB2.xs:103: error: âsv_yesâ undeclared (first use in this function)
DB2.xs:103: error: âsv_noâ undeclared (first use in this function)
DB2.xs: In function âXS_DBD__DB2__db_rollbackâ:
DB2.xs:112: error: âsv_yesâ undeclared (first use in this function)
DB2.xs:112: error: âsv_noâ undeclared (first use in this function)
DB2.xs: In function âXS_DBD__DB2__db_disconnectâ:
DB2.xs:134: error: âdirtyâ undeclared (first use in this function)
DB2.xs:141: error: âsv_yesâ undeclared (first use in this function)
DB2.xs:141: error: âsv_noâ undeclared (first use in this function)
DB2.xs: In function âXS_DBD__DB2__db_STOREâ:
DB2.xs:156: error: âsv_yesâ undeclared (first use in this function)
DB2.xs:159: error: âsv_noâ undeclared (first use in this function)
DB2.xs: In function âXS_DBD__DB2__db_DESTROYâ:
DB2.xs:178: error: âsv_yesâ undeclared (first use in this function)
DB2.xs:181: error: âdirtyâ undeclared