adaffc363b
Signed-off-by: Galen Charlton <gmcharlt@gmail.com>
280 lines
6.2 KiB
Perl
280 lines
6.2 KiB
Perl
package C4::SQLHelper;
|
|
|
|
# Copyright 2009 Biblibre SARL
|
|
#
|
|
# This file is part of Koha.
|
|
#
|
|
# Koha is free software; you can redistribute it and/or modify it under the
|
|
# terms of the GNU General Public License as published by the Free Software
|
|
# Foundation; either version 2 of the License, or (at your option) any later
|
|
# version.
|
|
#
|
|
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along with
|
|
# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
# Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
|
use List::MoreUtils qw(first_value);
|
|
use C4::Context;
|
|
use C4::Dates qw(format_date_in_iso);
|
|
use C4::Debug;
|
|
use strict;
|
|
use warnings;
|
|
require Exporter;
|
|
use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS);
|
|
|
|
BEGIN {
|
|
# set the version for version checking
|
|
$VERSION = 0.5;
|
|
require Exporter;
|
|
@ISA = qw(Exporter);
|
|
@EXPORT_OK=qw(
|
|
InsertInTable
|
|
SearchInTable
|
|
UpdateInTable
|
|
GetPrimaryKey
|
|
);
|
|
%EXPORT_TAGS = ( all =>[qw( InsertInTable SearchInTable UpdateInTable GetPrimaryKey)]
|
|
);
|
|
}
|
|
|
|
my $tablename;
|
|
my $hash;
|
|
|
|
=head1 NAME
|
|
|
|
C4::SQLHelper - Perl Module containing convenience functions for SQL Handling
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
use C4::SQLHelper;
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
This module contains routines for adding, modifying and Searching Data in MysqlDB
|
|
|
|
=head1 FUNCTIONS
|
|
|
|
=over 2
|
|
|
|
=back
|
|
|
|
|
|
=head2 SearchInTable
|
|
|
|
=over 4
|
|
|
|
$hashref = &SearchInTable($tablename,$data, $orderby);
|
|
|
|
=back
|
|
|
|
$data may contain
|
|
- string
|
|
- data_hashref : will be considered as an AND of all the data searched
|
|
- data_array_ref on hashrefs : Will be considered as an OR of Datahasref elements
|
|
|
|
$orderby is a hashref with fieldnames as key and 0 or 1 as values (ASCENDING or DESCENDING order)
|
|
|
|
=cut
|
|
|
|
sub SearchInTable{
|
|
my ($tablename,$filters,$orderby) = @_;
|
|
my $dbh = C4::Context->dbh;
|
|
my $sql = "SELECT * from $tablename";
|
|
my $row;
|
|
my $sth;
|
|
my ($keys,$values)=_filter_fields($filters,$tablename, "search");
|
|
if ($filters) {
|
|
$sql.= do { local $"=' AND ';
|
|
qq{ WHERE @$keys }
|
|
};
|
|
}
|
|
if ($orderby){
|
|
my @orders=map{ "$_".($$orderby{$_}? " DESC" : "") } keys %$orderby;
|
|
$sql.= do { local $"=', ';
|
|
qq{ ORDER BY @orders}
|
|
};
|
|
}
|
|
|
|
$debug && warn $sql," ",join(",",@$values);
|
|
$sth = $dbh->prepare($sql);
|
|
$sth->execute(@$values);
|
|
my $results = $sth->fetchall_arrayref( {} );
|
|
return $results;
|
|
}
|
|
|
|
=head2 InsertInTable
|
|
|
|
=over 4
|
|
|
|
$data_id_in_table = &InsertInTable($tablename,$data_hashref);
|
|
|
|
=back
|
|
|
|
Insert Data in table
|
|
and returns the id of the row inserted
|
|
=cut
|
|
|
|
sub InsertInTable{
|
|
my ($tablename,$data) = @_;
|
|
my $dbh = C4::Context->dbh;
|
|
my ($keys,$values)=_filter_fields($data,$tablename);
|
|
|
|
my $query = do { local $"=',';
|
|
qq{
|
|
INSERT $tablename
|
|
SET @$keys
|
|
};
|
|
};
|
|
|
|
$debug && warn $query, join(",",@$values);
|
|
my $sth = $dbh->prepare($query);
|
|
$sth->execute( @$values);
|
|
|
|
return $dbh->last_insert_id(undef, undef, $tablename, undef);
|
|
}
|
|
|
|
=head2 UpdateInTable
|
|
|
|
=over 4
|
|
|
|
$status = &UpdateInTable($tablename,$data_hashref);
|
|
|
|
=back
|
|
|
|
Update Data in table
|
|
and returns the status of the operation
|
|
=cut
|
|
|
|
sub UpdateInTable{
|
|
my ($tablename,$data) = @_;
|
|
my $field_id=GetPrimaryKey($tablename);
|
|
my $id=$$data{$field_id};
|
|
my $dbh = C4::Context->dbh;
|
|
my ($keys,$values)=_filter_fields($data,$tablename,0);
|
|
|
|
my $query = do { local $"=',';
|
|
qq{
|
|
UPDATE $tablename
|
|
SET @$keys
|
|
WHERE $field_id=?
|
|
};
|
|
};
|
|
$debug && warn $query, join(",",@$values,$id);
|
|
|
|
my $sth = $dbh->prepare($query);
|
|
return $sth->execute( @$values,$id);
|
|
|
|
}
|
|
|
|
=head2 GetPrimaryKey
|
|
|
|
=over 4
|
|
|
|
$primarykeyname = &GetPrimaryKey($tablename)
|
|
|
|
=back
|
|
|
|
Get the Primary Key field name of the table
|
|
=cut
|
|
|
|
sub GetPrimaryKey($) {
|
|
my $tablename=shift;
|
|
my $hash_columns=_columns($tablename);
|
|
return first_value { $$hash_columns{$_}{'Key'} =~/PRI/} keys %$hash_columns;
|
|
}
|
|
|
|
=head2 _get_columns
|
|
|
|
=over 4
|
|
|
|
_get_columns($tablename)
|
|
|
|
=back
|
|
|
|
Given a tablename
|
|
Returns a hashref of all the fieldnames of the table
|
|
With
|
|
Key
|
|
Type
|
|
Default
|
|
|
|
=cut
|
|
|
|
sub _columns($) {
|
|
my $tablename=shift;
|
|
$debug && warn $tablename;
|
|
my $dbh=C4::Context->dbh;
|
|
my $sth=$dbh->prepare(qq{SHOW COLUMNS FROM $tablename });
|
|
$sth->execute;
|
|
return $sth->fetchall_hashref(qw(Field));
|
|
}
|
|
|
|
=head2 _filter_fields
|
|
|
|
=over 4
|
|
|
|
_filter_fields
|
|
|
|
=back
|
|
|
|
Given
|
|
- a tablename
|
|
- a hashref of data
|
|
- an indicator on operation
|
|
|
|
Returns a ref of key array to use in SQL functions
|
|
and a ref to value array
|
|
|
|
=cut
|
|
|
|
sub _filter_fields{
|
|
my ($data_to_filter,$tablename,$research)=@_;
|
|
warn "$tablename research $research";
|
|
my @keys;
|
|
my @values;
|
|
my $columns= _columns($tablename);
|
|
#Filter Primary Keys of table
|
|
my $elements=join "|",grep {$$columns{$_}{'Key'} ne "PRI"} keys %$columns;
|
|
if (ref($data_to_filter) eq "HASH"){
|
|
foreach my $field (grep {/\b($elements)\b/} keys %$data_to_filter){
|
|
## supposed to be a hash of simple values, hashes of arrays could be implemented
|
|
$$data_to_filter{$field}=format_date_in_iso($$data_to_filter{$field}) if ($$columns{$field}{Type}=~/date/ && $$data_to_filter{$field} !~C4::Dates->regexp("iso"));
|
|
my $strkeys= " $field = ? ";
|
|
if ($field=~/code/ && $research){
|
|
$strkeys="( $strkeys OR $field='' OR $field IS NULL) ";
|
|
}
|
|
push @values, $$data_to_filter{$field};
|
|
push @keys, $strkeys;
|
|
}
|
|
} elsif (ref($data_to_filter) eq "ARRAY"){
|
|
foreach my $element (@$data_to_filter){
|
|
my (@localkeys,@localvalues)=_filter_fields($element);
|
|
push @keys, join(' AND ',@localkeys);
|
|
push @values, @localvalues;
|
|
}
|
|
}
|
|
else{
|
|
my @operands=split / /,$data_to_filter;
|
|
foreach my $operand (@operands){
|
|
my @localvalues=($operand,"\%$operand\%") ;
|
|
foreach my $field (keys %$columns){
|
|
my $strkeys= " ( $field = ? OR $field LIKE ? )";
|
|
if ($field=~/code/){
|
|
$strkeys="( $strkeys OR $field='' OR $field IS NULL) ";
|
|
}
|
|
push @values, @localvalues;
|
|
push @keys, $strkeys;
|
|
}
|
|
}
|
|
}
|
|
|
|
return (\@keys,\@values);
|
|
}
|
|
|
|
1;
|
|
|