⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbi.pm

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 PM
📖 第 1 页 / 共 5 页
字号:
	    my $ti = $dbh->type_info($data_type);	    $lp = $prefixes->{$data_type} = $ti ? $ti->{LITERAL_PREFIX} || "" : "'";	    $ls = $suffixes->{$data_type} = $ti ? $ti->{LITERAL_SUFFIX} || "" : "'";	}	return $str unless $lp || $ls; # no quoting required	# XXX don't know what the standard says about escaping	# in the 'general case' (where $lp != "'").	# So we just do this and hope:	$str =~ s/$lp/$lp$lp/g		if $lp && $lp eq $ls && ($lp eq "'" || $lp eq '"');	return "$lp$str$ls";    }    sub rows { -1 }	# here so $DBI::rows 'works' after using $dbh    sub do {	my($dbh, $statement, $attr, @params) = @_;	my $sth = $dbh->prepare($statement, $attr) or return undef;	$sth->execute(@params) or return undef;	my $rows = $sth->rows;	($rows == 0) ? "0E0" : $rows;    }    sub _do_selectrow {	my ($method, $dbh, $stmt, $attr, @bind) = @_;	my $sth = ((ref $stmt) ? $stmt : $dbh->prepare($stmt, $attr))	    or return;	$sth->execute(@bind)	    or return;	my $row = $sth->$method()	    and $sth->finish;	return $row;    }    sub selectrow_hashref {  return _do_selectrow('fetchrow_hashref',  @_); }    # XXX selectrow_array/ref also have C implementations in Driver.xst    sub selectrow_arrayref { return _do_selectrow('fetchrow_arrayref', @_); }    sub selectrow_array {	my $row = _do_selectrow('fetchrow_arrayref', @_) or return;	return $row->[0] unless wantarray;	return @$row;    }    # XXX selectall_arrayref also has C implementation in Driver.xst    # which fallsback to this if a slice is given    sub selectall_arrayref {	my ($dbh, $stmt, $attr, @bind) = @_;	my $sth = (ref $stmt) ? $stmt : $dbh->prepare($stmt, $attr)	    or return;	$sth->execute(@bind) || return;	my $slice = $attr->{Slice}; # typically undef, else hash or array ref	if (!$slice and $slice=$attr->{Columns}) {	    if (ref $slice eq 'ARRAY') { # map col idx to perl array idx		$slice = [ @{$attr->{Columns}} ];	# take a copy		for (@$slice) { $_-- }	    }	}	my $rows = $sth->fetchall_arrayref($slice, my $MaxRows = $attr->{MaxRows});	$sth->finish if defined $MaxRows;	return $rows;    }    sub selectall_hashref {	my ($dbh, $stmt, $key_field, $attr, @bind) = @_;	my $sth = (ref $stmt) ? $stmt : $dbh->prepare($stmt, $attr);	return unless $sth;	$sth->execute(@bind) || return;	return $sth->fetchall_hashref($key_field);    }    sub selectcol_arrayref {	my ($dbh, $stmt, $attr, @bind) = @_;	my $sth = (ref $stmt) ? $stmt : $dbh->prepare($stmt, $attr);	return unless $sth;	$sth->execute(@bind) || return;	my @columns = ($attr->{Columns}) ? @{$attr->{Columns}} : (1);	my @values  = (undef) x @columns;	my $idx = 0;	for (@columns) {	    $sth->bind_col($_, \$values[$idx++]) || return;	}	my @col;	if (my $max = $attr->{MaxRows}) {	    push @col, @values while @col<$max && $sth->fetch;	}	else {	    push @col, @values while $sth->fetch;	}	return \@col;    }    sub prepare_cached {	my ($dbh, $statement, $attr, $if_active) = @_;	# Needs support at dbh level to clear cache before complaining about	# active children. The XS template code does this. Drivers not using	# the template must handle clearing the cache themselves.	my $cache = $dbh->{CachedKids} ||= {};	my @attr_keys = ($attr) ? sort keys %$attr : ();	my $key = ($attr) ? join("~~", $statement, @attr_keys, @{$attr}{@attr_keys}) : $statement;	my $sth = $cache->{$key};	if ($sth) {	    return $sth unless $sth->FETCH('Active');	    Carp::carp("prepare_cached($statement) statement handle $sth still Active")		unless ($if_active ||= 0);	    $sth->finish if $if_active <= 1;	    return $sth  if $if_active <= 2;	}	$sth = $dbh->prepare($statement, $attr);	$cache->{$key} = $sth if $sth;	return $sth;    }    sub ping {	my $dbh = shift;	$dbh->_not_impl('ping');	# "0 but true" is a special kind of true 0 that is used here so	# applications can check if the ping was a real ping or not	($dbh->FETCH('Active')) ?  "0 but true" : 0;    }    sub begin_work {	my $dbh = shift;	return $dbh->set_err($DBI::stderr, "Already in a transaction")		unless $dbh->FETCH('AutoCommit');	$dbh->STORE('AutoCommit', 0); # will croak if driver doesn't support it	$dbh->STORE('BegunWork',  1); # trigger post commit/rollback action	return 1;    }    sub primary_key {	my ($dbh, @args) = @_;	my $sth = $dbh->primary_key_info(@args) or return;	my ($row, @col);	push @col, $row->[3] while ($row = $sth->fetch);	Carp::croak("primary_key method not called in list context")		unless wantarray; # leave us some elbow room	return @col;    }    sub tables {	my ($dbh, @args) = @_;	my $sth    = $dbh->table_info(@args[0,1,2,3,4]) or return;	my $tables = $sth->fetchall_arrayref or return;	my @tables;	if ($dbh->get_info(29)) { # SQL_IDENTIFIER_QUOTE_CHAR	    @tables = map { $dbh->quote_identifier( @{$_}[0,1,2] ) } @$tables;	}	else {		# temporary old style hack (yeach)	    @tables = map {		my $name = $_->[2];		if ($_->[1]) {		    my $schema = $_->[1];		    # a sad hack (mostly for Informix I recall)		    my $quote = ($schema eq uc($schema)) ? '' : '"';		    $name = "$quote$schema$quote.$name"		}		$name;	    } @$tables;	}	return @tables;    }    sub type_info {	# this should be sufficient for all drivers	my ($dbh, $data_type) = @_;	my $idx_hash;	my $tia = $dbh->{dbi_type_info_row_cache};	if ($tia) {	    $idx_hash = $dbh->{dbi_type_info_idx_cache};	}	else {	    my $temp = $dbh->type_info_all;	    return unless $temp && @$temp;	    # we cache here because type_info_all may be expensive to call	    # (and we take a copy so the following shift can't corrupt	    # the data that may be returned by future calls to type_info_all)	    $tia      = $dbh->{dbi_type_info_row_cache} = [ @$temp ];	    $idx_hash = $dbh->{dbi_type_info_idx_cache} = shift @$tia;	}	my $dt_idx   = $idx_hash->{DATA_TYPE} || $idx_hash->{data_type};	Carp::croak("type_info_all returned non-standard DATA_TYPE index value ($dt_idx != 1)")	    if $dt_idx && $dt_idx != 1;	# --- simple DATA_TYPE match filter	my @ti;	my @data_type_list = (ref $data_type) ? @$data_type : ($data_type);	foreach $data_type (@data_type_list) {	    if (defined($data_type) && $data_type != DBI::SQL_ALL_TYPES()) {		push @ti, grep { $_->[$dt_idx] == $data_type } @$tia;	    }	    else {	# SQL_ALL_TYPES		push @ti, @$tia;	    }	    last if @ti;	# found at least one match	}	# --- format results into list of hash refs	my $idx_fields = keys %$idx_hash;	my @idx_names  = map { uc($_) } keys %$idx_hash;	my @idx_values = values %$idx_hash;	Carp::croak "type_info_all result has $idx_fields keys but ".(@{$ti[0]})." fields"		if @ti && @{$ti[0]} != $idx_fields;	my @out = map {	    my %h; @h{@idx_names} = @{$_}[ @idx_values ]; \%h;	} @ti;	return $out[0] unless wantarray;	return @out;    }    sub data_sources {	my ($dbh, @other) = @_;	my $drh = $dbh->{Driver}; # XXX proxy issues?	return $drh->data_sources(@other);    }}{   package		# hide from PAUSE	DBD::_::st;	# ====== STATEMENT ======    @DBD::_::st::ISA = qw(DBD::_::common);    use strict;    sub bind_param { Carp::croak("Can't bind_param, not implement by driver") }## ********************************************************##	BEGIN ARRAY BINDING##	Array binding support for drivers which don't support#	array binding, but have sufficient interfaces to fake it.#	NOTE: mixing scalars and arrayrefs requires using bind_param_array#	for *all* params...unless we modify bind_param for the default#	case...##	2002-Apr-10	D. Arnold    sub bind_param_array {	my $sth = shift;	my ($p_id, $value_array, $attr) = @_;	return $sth->set_err($DBI::stderr, "Value for parameter $p_id must be a scalar or an arrayref, not a ".ref($value_array))	    if defined $value_array and ref $value_array and ref $value_array ne 'ARRAY';	return $sth->set_err($DBI::stderr, "Can't use named placeholder '$p_id' for non-driver supported bind_param_array")	    unless DBI::looks_like_number($p_id); # because we rely on execute(@ary) here	return $sth->set_err($DBI::stderr, "Placeholder '$p_id' is out of range")	    if $p_id <= 0; # can't easily/reliably test for too big	# get/create arrayref to hold params	my $hash_of_arrays = $sth->{ParamArrays} ||= { };	# If the bind has attribs then we rely on the driver conforming to	# the DBI spec in that a single bind_param() call with those attribs	# makes them 'sticky' and apply to all later execute(@values) calls.	# Since we only call bind_param() if we're given attribs then	# applications using drivers that don't support bind_param can still	# use bind_param_array() so long as they don't pass any attribs.	$$hash_of_arrays{$p_id} = $value_array;	return $sth->bind_param($p_id, undef, $attr)		if $attr;	1;    }    sub bind_param_inout_array {	my $sth = shift;	# XXX not supported so we just call bind_param_array instead	# and then return an error	my ($p_num, $value_array, $attr) = @_;	$sth->bind_param_array($p_num, $value_array, $attr);	return $sth->set_err($DBI::stderr, "bind_param_inout_array not supported");    }    sub bind_columns {	my $sth = shift;	my $fields = $sth->FETCH('NUM_OF_FIELDS') || 0;	if ($fields <= 0 && !$sth->{Active}) {	    return $sth->set_err($DBI::stderr, "Statement has no result columns to bind"		    ." (perhaps you need to successfully call execute first)");	}	# Backwards compatibility for old-style call with attribute hash	# ref as first arg. Skip arg if undef or a hash ref.	my $attr;	$attr = shift if !defined $_[0] or ref($_[0]) eq 'HASH';	my $idx = 0;	$sth->bind_col(++$idx, shift, $attr) or return	    while (@_ and $idx < $fields);	return $sth->set_err($DBI::stderr, "bind_columns called with ".($idx+@_)." values but $fields are needed")	    if @_ or $idx != $fields;	return 1;    }    sub execute_array {	my $sth = shift;	my ($attr, @array_of_arrays) = @_;	my $NUM_OF_PARAMS = $sth->FETCH('NUM_OF_PARAMS'); # may be undef at this point	# get tuple status array or hash attribute	my $tuple_sts = $attr->{ArrayTupleStatus};	return $sth->set_err($DBI::stderr, "ArrayTupleStatus attribute must be an arrayref")		if $tuple_sts and ref $tuple_sts ne 'ARRAY';	# bind all supplied arrays	if (@array_of_arrays) {	    $sth->{ParamArrays} = { };	# clear out old params	    return $sth->set_err($DBI::stderr,		    @array_of_arrays." bind values supplied but $NUM_OF_PARAMS expected")		if defined ($NUM_OF_PARAMS) && @array_of_arrays != $NUM_OF_PARAMS;	    $sth->bind_param_array($_, $array_of_arrays[$_-1]) or return		foreach (1..@array_of_arrays);	}	my $fetch_tuple_sub;	if ($fetch_tuple_sub = $attr->{ArrayTupleFetch}) {	# fetch on demand	    return $sth->set_err($DBI::stderr,		    "Can't use both ArrayTupleFetch and explicit bind values")		if @array_of_arrays; # previous bind_param_array calls will simply be ignored	    if (UNIVERSAL::isa($fetch_tuple_sub,'DBI::st')) {		my $fetch_sth = $fetch_tuple_sub;		return $sth->set_err($DBI::stderr,			"ArrayTupleFetch sth is not Active, need to execute() it first")		    unless $fetch_sth->{Active};		# check column count match to give more friendly message		my $NUM_OF_FIELDS = $fetch_sth->{NUM_OF_FIELDS};		return $sth->set_err($DBI::stderr,			"$NUM_OF_FIELDS columns from ArrayTupleFetch sth but $NUM_OF_PARAMS expected")		    if defined($NUM_OF_FIELDS) && defined($NUM_OF_PARAMS)		    && $NUM_OF_FIELDS != $NUM_OF_PARAMS;		$fetch_tuple_sub = sub { $fetch_sth->fetchrow_arrayref };	    }	    elsif (!UNIVERSAL::isa($fetch_tuple_sub,'CODE')) {		return $sth->set_err($DBI::stderr, "ArrayTupleFetch '$fetch_tuple_sub' is not a code ref or statement handle");	    }	}	else {	    my $NUM_OF_PARAMS_given = keys %{ $sth->{ParamArrays} || {} };	    return $sth->set_err($DBI::stderr,		    "$NUM_OF_PARAMS_given bind values supplied but $NUM_OF_PARAMS expected")		if defined($NUM_OF_PARAMS) && $NUM_OF_PARAMS != $NUM_OF_PARAMS_given;	    # get the length of a bound array	    my $maxlen;	    my %hash_of_arrays = %{$sth->{ParamArrays}};	    foreach (keys(%hash_of_arrays)) {		my $ary = $hash_of_arrays{$_};		next unless ref $ary eq 'ARRAY';		$maxlen = @$ary if !$maxlen || @$ary > $maxlen;	    }	    # if there are no arrays then execute scalars once	    $maxlen = 1 unless defined $maxlen;	    my @bind_ids = 1..keys(%hash_of_arrays);	    my $tuple_idx = 0;	    $fetch_tuple_sub = sub {		return if $tuple_idx >= $maxlen;		my @tuple = map {		    my $a = $hash_of_arrays{$_};		    ref($a) ? $a->[$tuple_idx] : $a		} @bind_ids;		++$tuple_idx;		return \@tuple;	    };	}	# pass thru the callers scalar or list context	return $sth->execute_for_fetch($fetch_tuple_sub, $tuple_sts);    }    sub execute_for_fetch {	my ($sth, $fetch_tuple_sub, $tuple_status) = @_;	# start with empty status array	($tuple_status) ? @$tuple_status = () : $tuple_status = [];        my $rc_total = 0;	my 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -