VMXTemplate/VMX/Common.pm

234 lines
6.1 KiB
Perl
Raw Normal View History

#!/usr/bin/perl
=head1 Некоторые простые полезные функции
=cut
package VMX::Common;
use DBI;
2008-02-21 23:56:43 +03:00
use Encode;
2007-05-29 19:40:59 +04:00
use Digest::MD5;
require Exporter;
2008-02-13 04:18:50 +03:00
@EXPORT_OK = qw(min max trim htmlspecialchars strip_tags file_get_contents dbi_hacks ar1el filemd5 mysql_quote updaterow_hashref insertall_hashref);
%EXPORT_TAGS = (all => [ @EXPORT_OK ]);
our $t;
##
# Exporter-ский импорт + возможность подмены функции в DBI
##
sub import {
foreach (@_) {
2008-02-13 04:18:50 +03:00
if ($_ eq '!dbi_hacks') {
return Exporter::import(@_);
2008-02-13 04:18:50 +03:00
} elsif ($_ eq 'dbi_hacks') {
$_ = '!dbi_hacks';
}
}
*DBI::_::st::fetchall_hashref = *VMX::Common::fetchall_hashref;
*DBI::st::fetchall_hashref = *VMX::Common::fetchall_hashref;
$DBI::DBI_methods{st}{fetchall_hashref} = { U =>[1,2,'[ $key_field ]'] };
2007-09-02 15:07:58 +04:00
$DBI::DBI_methods{db}{selectall_hashref} = { U =>[2,0,'$statement [, $keyfield [, \%attr [, @bind_params ] ] ]'], O=>0x2000 };
$Exporter::ExportLevel = 1;
my $r = Exporter::import(@_);
$Exporter::ExportLevel = 0;
return $r;
}
##
# Функция возвращает минимальное из значений
# $r = min (@list)
##
sub min {
return undef if (@_ < 1);
my $r = shift;
foreach (@_) { $r = $_ if $r > $_; }
return $r;
}
2007-05-30 19:40:07 +04:00
##
# Функция возвращает максимальное из значений
# $r = max (@list)
##
sub max {
return undef if (@_ < 1);
my $r = shift;
foreach (@_) { $r = $_ if $r < $_; }
return $r;
}
2007-05-25 03:13:23 +04:00
##
# shift arrayref
##
sub ar1el {
my $a = shift;
return undef unless 'ARRAY' eq ref $a;
return shift @$a;
}
##
# Функция обрезает пробельные символы в начале и конце строки
# $r = trim ($r)
##
sub trim {
my $a = shift;
$a =~ s/^\s+|\s+$//os;
return $a;
}
##
# аналог htmlspecialchars из PHP
# $str = htmlspecialchars ($str)
##
sub htmlspecialchars {
$_ = shift;
s/&/&apos;/g;
s/</&lt;/g;
s/>/&gt;/g;
s/\"/&quot;/g;
s/\'/&apos;/g;
return $_;
}
##
# аналог strip_tags из PHP
# $str = strip_tags ($str)
##
sub strip_tags {
$_ = shift;
my $ex = join '|', (shift =~ /[a-z0-9_\-]+/giso);
s/<\/?(?!\/?($ex))([a-z0-9_\-]+)[^<>]*>//gis;
return $_;
}
##
# аналог file_get_contents из PHP
# $contents = file_get_contents ($filename)
##
sub file_get_contents {
my ($tmp, $res);
open ($tmp, '<'.$_[0]);
2007-05-25 22:14:24 +04:00
if ($tmp) {
local $/ = undef;
$res = <$tmp>;
close ($tmp);
}
return $res;
}
##
# изменённый вариант функции DBI::_::st::fetchall_hashref
##
sub fetchall_hashref {
my ($sth, $key_field) = @_;
my $hash_key_name = $sth->{FetchHashKeyName} || 'NAME';
my $names_hash = $sth->FETCH("${hash_key_name}_hash");
my @key_fields = (ref $key_field) ? @$key_field : $key_field ? ($key_field) : ();
my @key_indexes;
my $num_of_fields = $sth->FETCH('NUM_OF_FIELDS');
foreach (@key_fields) {
my $index = $names_hash->{$_}; # perl index not column
$index = $_ - 1 if !defined $index && DBI::looks_like_number($_) && $_>=1 && $_ <= $num_of_fields;
return $sth->set_err(1, "Field '$_' does not exist (not one of @{[keys %$names_hash]})")
unless defined $index;
push @key_indexes, $index;
}
my $rows = {};
$rows = [] unless @key_indexes;
my $NAME = $sth->FETCH($hash_key_name);
my @row = (undef) x $num_of_fields;
$sth->bind_columns(\(@row)) if @row;
while ($sth->fetch) {
my $ref;
if (@key_indexes) {
$ref = $rows;
$ref = $ref->{$row[$_]} ||= {} for @key_indexes;
} else {
push @$rows, {};
$ref = $rows->[@$rows-1];
}
@$ref{@$NAME} = @row;
}
return $rows;
}
2008-02-13 04:18:50 +03:00
##
# Обновить строку или несколько строк по значениям ключа
##
sub updaterow_hashref {
my ($dbh, $table, $row, $key) = @_;
return 0 unless
$dbh &&
$table && $t->{$table} &&
$row && ref($row) eq 'HASH' && %$row &&
$key && ref($key) eq 'HASH' && %$key;
my @f = keys %$row;
my @k = keys %$key;
my $sql =
'UPDATE `'.$t->{$table}.'` SET '.
join(', ', map { "`$_`=?" } @f).
2008-03-12 03:52:05 +03:00
' WHERE '.join(' AND ', map { "`$_`=?" } @k);
2008-02-13 04:18:50 +03:00
my @bind = (@$row{@f}, @$key{@k});
return $dbh->do($sql, {}, @bind);
}
##
# Вставить набор записей в таблицу
##
sub insertall_hashref {
my ($dbh, $table, $rows, $reselect) = @_;
return 0 unless
$dbh &&
$table && $t->{$table} &&
$rows && ref($rows) eq 'ARRAY' && @$rows;
if ($reselect) {
my $i = 0;
@$_{'ji','jin'} = ($dbh->{mysql_connection_id}, ++$i) foreach @$rows;
}
my @f = keys %{$rows->[0]};
my $sql =
'INSERT INTO `'.$t->{$table}.'` (`'.join('`,`',@f).'`) VALUES '.
join(',',('('.(join(',', ('?') x scalar(@f))).')') x scalar(@$rows));
my @bind = map { @$_{@f} } @$rows;
my $st = $dbh->do($sql, {}, @bind);
return $st if !$st || !$reselect;
if (ref($reselect) eq 'ARRAY') {
$reselect = '`'.join('`,`',@$reselect).'`';
} elsif ($reselect ne '*') {
$reselect = "`$reselect`";
}
2008-02-14 03:39:17 +03:00
# осуществляем reselect данных
$sql = "SELECT $reselect FROM `".$t->{$table}.'` WHERE `ji`=? ORDER BY `jin` ASC';
2008-02-13 04:18:50 +03:00
@bind = ($dbh->{mysql_connection_id});
2008-02-14 03:39:17 +03:00
my $resel = $dbh->selectall_hashref($sql, [], {}, @bind);
for (my $i = 0; $i < @$resel; $i++) {
$rows->[$i]->{$_} = $resel->[$i]->{$_} for keys %{$resel->[$i]};
}
$sql = "UPDATE `".$t->{$table}."` SET `ji`=NULL, `jin`=NULL WHERE `ji`=?";
$dbh->do($sql, {}, @bind);
return $st;
2008-02-13 04:18:50 +03:00
}
2007-05-29 19:40:59 +04:00
sub filemd5 {
my ($file) = @_;
my $f;
my $r;
if (open $f, "<$file") {
my $ctx = Digest::MD5->new;
$ctx->addfile($f);
$r = $ctx->hexdigest;
close $f;
}
return $r;
}
2007-06-07 03:09:26 +04:00
sub mysql_quote {
my ($a) = @_;
$a =~ s/\'/\'\'/gso;
2008-02-13 04:18:50 +03:00
$a =~ s/\\/\\\\/gso;
2007-06-07 03:09:26 +04:00
return "'$a'";
}
1;