DBI

 view release on metacpan or  search on metacpan

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

	    # be used to test non-select statements.
	    # Now we have DBI::DBM etc., ExampleP should be deprecated
	}

	my ($outer, $sth) = DBI::_new_sth($dbh, {
	    'Statement'     => $statement,
            examplep_private_sth_attrib => 24, # an example, for testing
	}, ['example implementors private data '.__PACKAGE__]);

	my @bad = map {
	    defined $DBD::ExampleP::statnames{$_} ? () : $_
	} @fields;
	return $dbh->set_err($DBI::stderr, "Unknown field names: @bad")
		if @bad;

	$outer->STORE('NUM_OF_FIELDS' => scalar(@fields));

	$sth->{examplep_ex_dir} = $dir if defined($dir) && $dir !~ /\?/;
	$outer->STORE('NUM_OF_PARAMS' => ($dir) ? $dir =~ tr/?/?/ : 0);

	if (@fields) {
	    $outer->STORE('NAME'     => \@fields);
	    $outer->STORE('NULLABLE' => [ (0) x @fields ]);
	    $outer->STORE('SCALE'    => [ (0) x @fields ]);
	}

	$outer;
    }


    sub table_info {
	my $dbh = shift;
	my ($catalog, $schema, $table, $type) = @_;

	my @types = split(/["']*,["']/, $type || 'TABLE');
	my %types = map { $_=>$_ } @types;

	# Return a list of all subdirectories
	my $dh = Symbol::gensym(); # "DBD::ExampleP::".++$DBD::ExampleP::gensym;
	my $dir = $catalog || File::Spec->curdir();
	my @list;
	if ($types{VIEW}) {	# for use by test harness
	    push @list, [ undef, "schema",  "table",  'VIEW', undef ];
	    push @list, [ undef, "sch-ema", "table",  'VIEW', undef ];
	    push @list, [ undef, "schema",  "ta-ble", 'VIEW', undef ];
	    push @list, [ undef, "sch ema", "table",  'VIEW', undef ];
	    push @list, [ undef, "schema",  "ta ble", 'VIEW', undef ];
	}
	if ($types{TABLE}) {
	    no strict 'refs';
	    opendir($dh, $dir)
		or return $dbh->set_err(int($!), "Failed to open directory $dir: $!");
	    while (defined(my $item = readdir($dh))) {
                if ($^O eq 'VMS') {
                    # if on VMS then avoid warnings from catdir if you use a file
                    # (not a dir) as the item below
                    next if $item !~ /\.dir$/oi;
                }
                my $file = File::Spec->catdir($dir,$item);
		next unless -d $file;
		my($dev, $ino, $mode, $nlink, $uid) = lstat($file);
		my $pwnam = undef; # eval { scalar(getpwnam($uid)) } || $uid;
		push @list, [ $dir, $pwnam, $item, 'TABLE', undef ];
	    }
	    close($dh);
	}
	# We would like to simply do a DBI->connect() here. However,
	# this is wrong if we are in a subclass like DBI::ProxyServer.
	$dbh->{'dbd_sponge_dbh'} ||= DBI->connect("DBI:Sponge:", '','')
	    or return $dbh->set_err($DBI::err,
			"Failed to connect to DBI::Sponge: $DBI::errstr");

	my $attr = {
	    'rows' => \@list,
	    'NUM_OF_FIELDS' => 5,
	    'NAME' => ['TABLE_CAT', 'TABLE_SCHEM', 'TABLE_NAME',
		    'TABLE_TYPE', 'REMARKS'],
	    'TYPE' => [DBI::SQL_VARCHAR(), DBI::SQL_VARCHAR(),
		    DBI::SQL_VARCHAR(), DBI::SQL_VARCHAR(), DBI::SQL_VARCHAR() ],
	    'NULLABLE' => [1, 1, 1, 1, 1]
	};
	my $sdbh = $dbh->{'dbd_sponge_dbh'};
	my $sth = $sdbh->prepare("SHOW TABLES FROM $dir", $attr)
	    or return $dbh->set_err($sdbh->err(), $sdbh->errstr());
	$sth;
    }


    sub type_info_all {
	my ($dbh) = @_;
	my $ti = [
	    {	TYPE_NAME	=> 0,
		DATA_TYPE	=> 1,
		COLUMN_SIZE	=> 2,
		LITERAL_PREFIX	=> 3,
		LITERAL_SUFFIX	=> 4,
		CREATE_PARAMS	=> 5,
		NULLABLE	=> 6,
		CASE_SENSITIVE	=> 7,
		SEARCHABLE	=> 8,
		UNSIGNED_ATTRIBUTE=> 9,
		FIXED_PREC_SCALE=> 10,
		AUTO_UNIQUE_VALUE => 11,
		LOCAL_TYPE_NAME	=> 12,
		MINIMUM_SCALE	=> 13,
		MAXIMUM_SCALE	=> 14,
	    },
	    [ 'VARCHAR', DBI::SQL_VARCHAR, 1024, "'","'", undef, 0, 1, 1, 0, 0,0,undef,0,0 ],
	    [ 'INTEGER', DBI::SQL_INTEGER,   10, "","",   undef, 0, 0, 1, 0, 0,0,undef,0,0 ],
	];
	return $ti;
    }


    sub ping {
	(shift->FETCH('Active')) ? 2 : 0;    # the value 2 is checked for by t/80proxy.t
    }


    sub disconnect {
	shift->STORE(Active => 0);

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

	return $sth->set_err(2, @$dbd_param." values bound when $sth->{NUM_OF_PARAMS} expected")
	    unless @$dbd_param == $sth->{NUM_OF_PARAMS};

	return 0 unless $sth->{NUM_OF_FIELDS}; # not a select

	$dir = $dbd_param->[0] || $sth->{examplep_ex_dir};
	return $sth->set_err(2, "No bind parameter supplied")
	    unless defined $dir;

	$sth->finish;

	#
	# If the users asks for directory "long_list_4532", then we fake a
	# directory with files "file4351", "file4350", ..., "file0".
	# This is a special case used for testing, especially DBD::Proxy.
	#
	if ($dir =~ /^long_list_(\d+)$/) {
	    $sth->{dbd_dir} = [ $1 ];	# array ref indicates special mode
	    $sth->{dbd_datahandle} = undef;
	}
	else {
	    $sth->{dbd_dir} = $dir;
	    my $sym = Symbol::gensym(); # "DBD::ExampleP::".++$DBD::ExampleP::gensym;
	    opendir($sym, $dir)
                or return $sth->set_err(2, "opendir($dir): $!");
	    $sth->{dbd_datahandle} = $sym;
	}
	$sth->STORE(Active => 1);
	return 1;
    }


    sub fetch {
	my $sth = shift;
	my $dir = $sth->{dbd_dir};
	my %s;

	if (ref $dir) {		# special fake-data test mode
	    my $num = $dir->[0]--;
	    unless ($num > 0) {
		$sth->finish();
		return;
	    }
	    my $time = time;
	    @s{@DBD::ExampleP::statnames} =
		( 2051, 1000+$num, 0644, 2, $>, $), 0, 1024,
	          $time, $time, $time, 512, 2, "file$num")
	}
	else {			# normal mode
            my $dh  = $sth->{dbd_datahandle}
                or return $sth->set_err($DBI::stderr, "fetch without successful execute");
	    my $f = readdir($dh);
	    unless ($f) {
		$sth->finish;
		return;
	    }
	    # untaint $f so that we can use this for DBI taint tests
	    ($f) = ($f =~ m/^(.*)$/);
	    my $file = File::Spec->catfile($dir, $f);
	    # put in all the data fields
	    @s{ @DBD::ExampleP::statnames } = (lstat($file), $f);
	}

	# return just what fields the query asks for
	my @new = @s{ @{$sth->{NAME}} };

	return $sth->_set_fbav(\@new);
    }
    *fetchrow_arrayref = \&fetch;


    sub finish {
	my $sth = shift;
	closedir($sth->{dbd_datahandle}) if $sth->{dbd_datahandle};
	$sth->{dbd_datahandle} = undef;
	$sth->{dbd_dir} = undef;
	$sth->SUPER::finish();
	return 1;
    }


    sub FETCH {
	my ($sth, $attrib) = @_;
	# In reality this would interrogate the database engine to
	# either return dynamic values that cannot be precomputed
	# or fetch and cache attribute values too expensive to prefetch.
	if ($attrib eq 'TYPE'){
	    return [ @DBD::ExampleP::stattypes{ @{ $sth->FETCH(q{NAME_lc}) } } ];
	}
	elsif ($attrib eq 'PRECISION'){
	    return [ @DBD::ExampleP::statprec{  @{ $sth->FETCH(q{NAME_lc}) } } ];
	}
	elsif ($attrib eq 'ParamValues') {
	    my $dbd_param = $sth->{dbd_param} || [];
	    my %pv = map { $_ => $dbd_param->[$_-1] } 1..@$dbd_param;
	    return \%pv;
	}
	# else pass up to DBI to handle
	return $sth->SUPER::FETCH($attrib);
    }


    sub STORE {
	my ($sth, $attrib, $value) = @_;
	# would normally validate and only store known attributes
	# else pass up to DBI to handle
	return $sth->{$attrib} = $value
	    if $attrib eq 'NAME' or $attrib eq 'NULLABLE' or $attrib eq 'SCALE' or $attrib eq 'PRECISION';
	return $sth->SUPER::STORE($attrib, $value);
    }

    *parse_trace_flag = \&DBD::ExampleP::db::parse_trace_flag;
}

1;
# vim: sw=4:ts=8



( run in 0.414 second using v1.01-cache-2.11-cpan-5b529ec07f3 )