DBD-ADO

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

2011-03-22  2.99

  Patch to remove annoying warnings during global destruction,
  with tests, from Rafael Kitover.

  Implemented more_results().
  Added tests (t/26more.t).

  Small change to table_info(): no need for client-side cursors.

2011-02-04  2.98

  Fixed a 'Missing argument in sprintf at DBD/ADO/GetInfo.pm line 13'.

  Patch for supporting cygwin in Makefile.PL from Rafael Kitover.

  Added a workaround for ADO Providers that don't accept a parameter size 0,
  spotted by Jeff Picklyk.
  Added test (12bind.t).

lib/DBD/ADO.pm  view on Meta::CPAN


		$comm->{CommandTimeout} = defined $attr->{ado_commandtimeout}
      ? $attr->{ado_commandtimeout} : $conn->{CommandTimeout};
		return if DBD::ADO::Failed( $dbh,"Can't set CommandTimeout");

		my ( $outer, $sth ) = DBI::_new_sth( $dbh, { Statement => $statement } );

		$sth->{ado_cachesize}     = $dbh->{ado_cachesize};
		$sth->{ado_comm}          = $comm;
		$sth->{ado_conn}          = $conn;
		$sth->{ado_cursortype}    = $dbh->{ado_cursortype} || $attr->{CursorType};
		$sth->{ado_fields}        = undef;
		$sth->{ado_max_errors}    = $dbh->{ado_max_errors};
		$sth->{ado_refresh}       = 1;
		$sth->{ado_rownum}        = -1;
		$sth->{ado_rows}          = -1;
		$sth->{ado_rowset}        = undef;
		$sth->{ado_type}          = undef;
		$sth->{ado_usecmd}        = undef;
		$sth->{ado_users}         = undef;
		$sth->{ado_executeoption} = 0;

lib/DBD/ADO.pm  view on Meta::CPAN

        my $i = $comm->Parameters->Item( $n - ($comm->{CommandType} == $Enums->{CommandTypeEnum}{adCmdStoredProc} ? 0 : 1) );
        if ( $i->{Direction} & $Enums->{ParameterDirectionEnum}{adParamInput} ) {
          # probably don't need the ternary; creation of ado_maxlen should
          # guarantee that this will always exist
          my $attr = defined $sth->{ado_ParamRefAttrs}{$n} ? $sth->{ado_ParamRefAttrs}{$n} : undef;
          _assign_param( $sth, $n, $$vref, $attr, $i );
        }
      }
    }
		# At this point a Command is ready to Execute. To allow for different
		# type of cursors, we need to create a Recordset object.
		# However, a Recordset Open does not return affected rows. So we need to
		# determine if a Recordset Open is needed, or a Command Execute.
		my $UseRecordSet = !defined $sth->{ado_usecmd} &&
			(  defined $sth->{ado_cursortype}
			|| defined $sth->{ado_users}
			);
		my $UseResponseStream = $sth->{ado_executeoption} &&
			( $sth->{ado_executeoption} == $Enums->{ExecuteOptionEnum}{adExecuteStream} );

		if ( $UseResponseStream ) {
			$sth->trace_msg("    -- Execute: Using Response Stream\n", 5 );
			$comm->Execute( { 'Options' => $sth->{ado_executeoption} } );
			return if DBD::ADO::Failed( $sth,"Can't Execute Command '$sql'");
      _retrieve_out_params( $sth );
			return $sth->{ado_responsestream}->ReadText();
		}
		elsif ( $UseRecordSet ) {
			$rs = Win32::OLE->new('ADODB.RecordSet');
			return if DBD::ADO::Failed( $sth,"Can't create 'ADODB.RecordSet'");

			my $CursorType = $sth->{ado_cursortype} || 'adOpenForwardOnly';
			$sth->trace_msg("    -- Open Recordset using CursorType '$CursorType'\n", 5 );
			$rs->Open( $comm, undef, $Enums->{CursorTypeEnum}{$CursorType} );
			return if DBD::ADO::Failed( $sth,"Can't Open Recordset for '$sql'");
      _retrieve_out_params( $sth );
			$sth->trace_msg("    -- CursorType: $rs->{CursorType}\n", 5 );
		}
		else {
			$rs = $comm->Execute( $rows );
			return if DBD::ADO::Failed( $sth,"Can't Execute Command '$sql'");
      _retrieve_out_params( $sth );

lib/DBD/ADO.pm  view on Meta::CPAN


=head2 prepare

The B<prepare> methods allows attributes (see DBI):

  $sth = $dbh->prepare( $statement )          or die $dbh->errstr;
  $sth = $dbh->prepare( $statement, \%attr )  or die $dbh->errstr;

DBD::ADO's prepare() supports setting the CursorType, e.g.:

  $sth = $dbh->prepare( $sql, { ado_cursortype => 'adOpenForwardOnly' } ) ...
  # the CursorType attribute is deprecated:
  $sth = $dbh->prepare( $sql, { CursorType     => 'adOpenForwardOnly' } ) ...

Possible cursortypes are:

  adOpenForwardOnly (default)
  adOpenKeyset
  adOpenDynamic
  adOpenStatic

It may be necessary to prepare the statement using cursortype 'adOpenStatic'
when using a statement handle within a statement handle:

  while( my $table = $sth1->fetchrow_hashref ) {
    ...
    my $col = $sth2->fetchrow_hashref;
    ...
  }

Changing the CursorType is a solution to the following problem:

lib/DBD/ADO.pm  view on Meta::CPAN

=item SQLOLEDB may truncate inserted strings

It seems that the size of the first inserted string is sticky.
Inserted strings longer than the first one are truncated.

As a workaround, the C<ado_size> attribute for C<bind_param> was
introduced in version 2.95:

  $sth->bind_param( $p_num, $bind_value, { ado_size => $size } );

=item MSDAORA may have problems with client-side cursors

MSDAORA may throw an error, return an empty result set or loop forever
when C<CursorLocation> is set to C<adUseClient>.
This setting is used in catalog methods for sorting and filtering.

=back


=head1 AUTHORS

t/15large.t  view on Meta::CPAN

my $dbh = DBI->connect or die "Connect failed: $DBI::errstr\n";
pass('Database connection created');

my $tbl = $DBD_TEST::table_name;

my $MAX_ROWS = 200;

ok( DBD_TEST::tab_create( $dbh ),"Create table $tbl");

my $sth = $dbh->prepare("SELECT * FROM $tbl",
  { ado_cursortype => 'adOpenStatic' }
);
ok( defined $sth,"Prepared select * statement, cursortype defined");
ok( $sth->execute,"Execute select");
$sth->finish; $sth = undef;

$sth = $dbh->prepare("SELECT * FROM $tbl",
  { ado_cursortype => 'adOpenStatic' }
);
ok( defined $sth,"Prepared select * statement, cursortype defined");
ok( $sth->execute,"Execute select");
$sth->finish; $sth = undef;

$sth = $dbh->prepare("SELECT * FROM $tbl",
  {
    ado_cursortype => 'adOpenStatic'
  , ado_users      => 1
  }
);
ok( defined $sth,"Prepared select * statement, cursortype and users defined");
ok( $sth->execute,"Execute select");
$sth->finish; $sth = undef;

$sth = $dbh->prepare("SELECT * FROM $tbl",
  {
    ado_cursortype => 'adOpenStatic'
  , ado_usecmd     => 1
  }
);
ok( defined $sth, "Prepared select * statement, cursortype and usecmd defined");
ok( $sth->execute, "Execute select");
$sth->finish; $sth = undef;

$sth = $dbh->prepare("SELECT * FROM $tbl",
  {
    ado_cursortype => 'adOpenStatic'
  , ado_usecmd     => 1
  , ado_users      => 1
  }
);
ok( defined $sth,"Prepared select * statement, cursortype, users, and usecmd defined");
ok( $sth->execute,"Execute select");
$sth->finish; $sth = undef;

# for my $ac ( 0, 1 ) {
#   pass("Testing with AutoCommit $ac");
#   $dbh->{AutoCommit} = $ac;
#
#   # Time how long it takes to run the insert test.
#   my $t_beg = [gettimeofday];
#   run_insert_test( $dbh );

t/25curs.t  view on Meta::CPAN

  my $cnt = 0;
  while ( my $row = $sth2->fetch ) {
    $cnt++;
#   print "#\t", DBI::neat_list( $row ), "\n";
  }
  ok( $cnt > 0,"Rows fetched: $cnt > 0");
}
undef $sth1;
undef $sth2;

# Testing a prepare statement with different cursor types.

my @CursorTypes = qw(adOpenForwardOnly adOpenKeyset adOpenDynamic adOpenStatic);
for my $ct ( @CursorTypes ) {
  my $sth = $dbh->prepare("SELECT * FROM $tbl ORDER BY A", { ado_cursortype => $ct } );
  ok( $sth,"Prepare statement handle using CursorType => $ct");
  my $rc = $sth->execute;
  SKIP: {
    skip("CusorType: $ct, not supported by Provider", 2 )
      if defined $sth->err && $sth->err eq $non_supported;
    ok( $rc,"Execute statement handle using CursorType => $ct : $rc");

    my $cnt = 0;
    while ( my $row = $sth->fetch ) {
      $cnt++;

t/25curs.t  view on Meta::CPAN

}

# MS SQL test.
# {
#   local ($dbh->{AutoCommit});
#   $dbh->{AutoCommit} = 0;
#   $dbh->rollback;
#
# pass( "Test creating executing statement handle 2 while looping statement handle 1" );
# ok ( $sth1 = $dbh->prepare( q{select name, type from sysobjects where type = 'U '},
#   { ado_cursortype => 'adOpenStatic' } ),
#   " test prepare with CursorType => adOpenStatic");
#
# die "Undefined statement handle: \n" unless $sth1;
#
# $sth1->execute;
# # print join("\n#\t", @{$sth1->{NAME}} ), "\n";
# while( my ($name, $type) = $sth1->fetchrow_array ) {
# #   print "# Object $name, Type $type\n";
#   my $sth2;
#   ok( $sth2 = $dbh->prepare("select * from $name", { ado_cursortype => 'adOpenForwardOnly' } ),
#     " selecting data from $name CursorType => adOpenForwardOnly"
#   );
#
#   ok(!$sth2->execute, " execute second handle CursorType => adOpenForwardOnly" );
#   my $row;
#   $row = $sth2->fetchrow;
#   ok(!$sth2->err, " fetchrow: " . defined $sth2->err ? $sth2->errstr : 'no errors' );
# #   print "# Table: $name: Columns: \n", join( "\n\t", @{$sth2->{NAME}}), "\n";
#   ok( $sth2->finish, " finished second handle" );
# }



( run in 1.297 second using v1.01-cache-2.11-cpan-49f99fa48dc )