annotate variant_effect_predictor/Bio/EnsEMBL/Utils/SqlHelper.pm @ 0:1f6dce3d34e0

Uploaded
author mahtabm
date Thu, 11 Apr 2013 02:01:53 -0400
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1 =head1 LICENSE
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
2
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
3 Copyright (c) 1999-2012 The European Bioinformatics Institute and
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
4 Genome Research Limited. All rights reserved.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
5
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
6 This software is distributed under a modified Apache license.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
7 For license details, please see
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
8
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
9 http://www.ensembl.org/info/about/code_licence.html
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
10
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
11 =head1 CONTACT
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
12
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
13 Please email comments or questions to the public Ensembl
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
14 developers list at <dev@ensembl.org>.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
15
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
16 Questions may also be sent to the Ensembl help desk at
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
17 <helpdesk@ensembl.org>.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
18
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
19 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
20
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
21 =head1 NAME
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
22
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
23 Bio::EnsEMBL::Utils::SqlHelper
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
24
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
25 =head1 VERSION
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
26
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
27 $Revision: 1.25 $
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
28
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
29 =head1 SYNOPSIS
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
30
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
31 use Bio::EnsEMBL::Utils::SqlHelper;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
32
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
33 my $helper =
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
34 Bio::EnsEMBL::Utils::SqlHelper->new( -DB_CONNECTION => $dbc );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
35
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
36 my $arr_ref = $helper->execute(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
37 -SQL => 'select name, age from tab where col =?',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
38 -CALLBACK => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
39 my @row = @{ shift @_ };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
40 return { name => $row[0], age => $row[1] };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
41 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
42 -PARAMS => ['A'] );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
43
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
44 use Data::Dumper;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
45 print Dumper($arr_ref), "\n";
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
46 # Prints out [name=>'name', age=>1] maybe ....
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
47
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
48
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
49 # For transactional work; only works if your MySQL table
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
50 # engine/database supports transactional work (such as InnoDB)
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
51
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
52 $helper->transaction(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
53 -CALLBACK => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
54 if ( $helper->execute_single_result(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
55 -SQL => 'select count(*) from tab'
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
56 ) )
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
57 {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
58 return $helper->execute_update('delete from tab');
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
59 } else {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
60 return
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
61 $helper->batch( -SQL => 'insert into tab (?,?)',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
62 -DATA => [ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ] ] );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
63 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
64 } );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
65
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
66 =head1 DESCRIPTION
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
67
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
68 Easier database interaction
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
69
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
70 =head1 METHODS
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
71
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
72 See subrotuines.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
73
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
74 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
75
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
76 package Bio::EnsEMBL::Utils::SqlHelper;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
77
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
78 use warnings;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
79 use strict;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
80
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
81 use Bio::EnsEMBL::Utils::Argument qw(rearrange);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
82 use Bio::EnsEMBL::Utils::Scalar qw(assert_ref check_ref);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
83 use Bio::EnsEMBL::Utils::Exception qw(throw);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
84 use Bio::EnsEMBL::Utils::Iterator;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
85 use English qw( -no_match_vars ); #Used for $PROCESS_ID
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
86 use Scalar::Util qw(weaken); #Used to not hold a strong ref to DBConnection
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
87
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
88 =pod
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
89
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
90 =head2 new()
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
91
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
92 Arg [DB_CONNECTION] : Bio::EnsEMBL::DBSQL::DBConnection $db_connection
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
93 Returntype : Instance of helper
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
94 Exceptions : If the object given as a DBConnection is not one or it
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
95 was undefined
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
96 Status : Stable
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
97
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
98 Creates a new instance of this object.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
99
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
100 my $dba = get_dba('mydb'); # New DBAdaptor from somewhere
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
101 my $helper = Bio::EnsEMBL::Utils::SqlHelper->new(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
102 -DB_CONNECTION => $dba->dbc() );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
103
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
104 $helper->execute_update( -SQL => 'update tab set flag=?',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
105 -PARAMS => [1] );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
106
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
107 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
108
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
109 sub new {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
110 my ( $class, @args ) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
111
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
112 my ($db_connection) = rearrange([qw(db_connection)], @args);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
113
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
114 my $self = bless( {}, ref($class) || $class );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
115 throw('-DB_CONNECTION construction parameter was undefined.')
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
116 unless defined $db_connection;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
117 $self->db_connection($db_connection);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
118
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
119 return $self;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
120 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
121
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
122 =pod
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
123
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
124 =head2 db_connection()
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
125
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
126 Arg [1] : Bio::EnsEMBL::DBSQL::DBConnection $db_connection
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
127 Description : Sets and retrieves the DBConnection
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
128 Returntype : Bio::EnsEMBL::DBSQL::DBConnection
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
129 Exceptions : If the object given as a DBConnection is not one or if an
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
130 attempt is made to set the value more than once
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
131 Status : Stable
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
132
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
133 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
134
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
135 sub db_connection {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
136 my ($self, $db_connection) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
137 if(defined $db_connection) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
138 if(exists $self->{db_connection}) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
139 throw('Cannot reset the DBConnection object; already defined ');
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
140 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
141 assert_ref($db_connection, 'Bio::EnsEMBL::DBSQL::DBConnection', 'db_connection');
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
142 $self->{db_connection} = $db_connection;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
143 weaken $self->{db_connection};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
144 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
145 return $self->{db_connection};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
146 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
147
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
148 # --------- SQL Methods
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
149
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
150 =pod
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
151
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
152 =head2 execute() - Execute a SQL statement with a custom row handler
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
153
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
154 Arg [SQL] : string SQL to execute
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
155 Arg [CALLBACK] : CodeRef; The callback to use for mapping a row to a data
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
156 point; leave blank for a default mapping to a 2D array
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
157 Arg [USE_HASHREFS] : boolean If set to true will cause HashRefs to be returned
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
158 to the callback & not ArrayRefs
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
159 Arg [PARAMS] : ArrayRef The binding parameters to the SQL statement
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
160 Arg [PREPARE_PARAMS] : boolean Parameters to be passed onto the Statement Handle
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
161 prepare call
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
162 Arg [ITERATOR] : boolean Request a L<Bio::EnsEMBL::Utils::Iterator>
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
163 rather than a 2D array
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
164 Returntype : ArrayRef/L<Bio::EnsEMBL::Utils::Iterator>
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
165 Exceptions : If errors occur in the execution of the SQL
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
166 Status : Stable
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
167
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
168 my $arr_ref = $helper->execute(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
169 -SQL => 'select a,b,c from tab where col =?',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
170 -CALLBACK => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
171 my @row = @{ shift @_ };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
172 return { A => $row[0], B => $row[1], C => $row[2] };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
173 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
174 -PARAMS => ['A'] );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
175
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
176 #Or with hashrefs
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
177 my $arr_ref = $helper->execute(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
178 -SQL => 'select a,b,c from tab where col =?',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
179 -USE_HASHREFS => 1,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
180 -CALLBACK => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
181 my $row = shift @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
182 return { A => $row->{a}, B => $row->{b}, C => $row->{c} };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
183 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
184 -PARAMS => ['A'] );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
185
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
186 Uses a callback defined by the C<sub> decalaration. Here we specify how
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
187 the calling code will deal with each row of a database's result set. The
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
188 sub can return any type of Object/hash/data structure you require.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
189
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
190 Should you not specify a callback then a basic one will be assigned to
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
191 you which will return a 2D array structure e.g.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
192
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
193 my $arr_ref = $helper->execute(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
194 -SQL => 'select a,b,c from tab where col =?',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
195 -PARAMS => ['A'] );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
196
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
197 This is equivalent to DBI's c<selectall_arrayref()> subroutine.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
198
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
199 As an extension to this method you can write a closure subroutine which
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
200 takes in two parameters. The first is the array/hash reference & the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
201 second is the statement handle used to execute. 99% of the time you will
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
202 not need it but there are occasions where you do need it. An example of
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
203 usage would be:
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
204
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
205 my $conn = get_conn(); #From somwewhere
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
206 my $arr_ref = $conn->execute(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
207 -SQL => 'select a,b,c from tab where col =?',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
208 -USE_HASHREFS => 1,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
209 -CALLBACK => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
210 my ( $row, $sth ) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
211 #Then do something with sth
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
212 return { A => $row->[0], B => $row->[1], C => $row->[2] };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
213 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
214 -PARAMS => ['A'] );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
215
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
216 Any arguments to bind to the incoming statement. This can be a set of scalars
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
217 or a 2D array if you need to specify any kind of types of sql objects i.e.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
218
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
219 use DBI qw(:sql_types);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
220
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
221 my $conn = get_conn();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
222 my $arr_ref = $conn->execute(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
223 -SQL =>
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
224 'select a,b,c from tab where col =? and num_col=? and other=?',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
225 -USE_HASHREFS => 1,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
226 -CALLBACK => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
227 my @row = @{ shift @_ };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
228 return { A => $row[0], B => $row[1], C => $row[2] };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
229 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
230 -PARAMS => [ '1', SQL_VARCHAR ],
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
231 [ 2, SQL_INTEGER ],
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
232 'hello' );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
233
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
234 Here we import DBI's sql types into our package and then pass in
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
235 multiple anonymous array references as parameters. Each param is
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
236 tested in the input and if it is detected to be an ARRAY reference we
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
237 dereference the array and run DBI's bind_param method. In fact you can
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
238 see each part of the incoming paramaters array as the contents to call
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
239 C<bind_param> with. The only difference is the package tracks the bind
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
240 position for you.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
241
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
242 We can get back a L<Bio::EnsEMBL::Utils::Iterator> object which can be used
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
243 to iterate over the results set without first materializing the data into
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
244 memory. An example would be:
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
245
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
246 my $iterator = $helper->execute(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
247 -SQL => 'select a,b,c from tab where col =?',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
248 -PARAMS => ['A']
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
249 -ITERATOR => 1);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
250 while($iterator->has_next()) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
251 my $row = $iterator->next();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
252 #Do something
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
253 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
254
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
255 This is very useful for very large datasets.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
256
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
257 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
258
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
259 sub execute {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
260 my ( $self, @args ) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
261 my ($sql, $callback, $use_hashrefs, $params, $prepare_params, $iterator) =
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
262 rearrange([qw(sql callback use_hashrefs params prepare_params iterator)], @args);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
263 my $has_return = 1;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
264
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
265 #If no callback then we execute using a default one which returns a 2D array
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
266 if(!defined $callback) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
267 throw('Cannot use fetchrow_hashref() with default mappers. Turn off this option') if $use_hashrefs;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
268 $callback = $self->_mappers()->{array_ref};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
269 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
270
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
271 return $self->_execute( $sql, $callback, $has_return, $use_hashrefs, $params, $prepare_params, $iterator );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
272 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
273
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
274 =pod
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
275
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
276 =head2 execute_simple()
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
277
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
278 Arg [SQL] : string $sql
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
279 Arg [PARAMS] : ArrayRef $params
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
280 Arg [CALLBACK] : CodeRef $callback
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
281 Returntype : ArrayRef of 1D elements
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
282 Exceptions : If errors occur in the execution of the SQL
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
283 Status : Stable
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
284
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
285 my $classification =
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
286 $helper->execute_simple(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
287 -SQL =>
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
288 'select meta_val from meta where meta_key =? order by meta_id',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
289 -PARAMS => ['species.classification'] );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
290
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
291 Identical to C<execute> except you do not specify a sub-routine reference.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
292 Using this code assumes you want an array of single scalar values as returned
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
293 by the given SQL statement.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
294
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
295 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
296
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
297 sub execute_simple {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
298 my ( $self, @args ) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
299 my ($sql, $params, $callback) = rearrange([qw(sql params callback)], @args);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
300 my $has_return = 1;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
301 my $use_hashrefs = 0;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
302 $callback ||= $self->_mappers()->{first_element};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
303 return $self->_execute($sql, $callback, $has_return, $use_hashrefs, $params);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
304 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
305
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
306 =pod
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
307
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
308 =head2 execute_no_return()
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
309
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
310 Arg [SQL] : string sql
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
311 Arg [CALLBACK] : CodeRef The callback to use for mapping a row to a data point;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
312 we assume you are assigning into a data structure which
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
313 has requirements other than simple translation into an
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
314 array
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
315 Arg [USE_HASHREFS] : boolean If set to true will cause HashRefs to be returned
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
316 to the callback & not ArrayRefs
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
317 Arg [PARAMS] : ArrayRef The binding parameters to the SQL statement
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
318 Returntype : None
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
319 Exceptions : If errors occur in the execution of the SQL
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
320 Status : Stable
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
321
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
322 Whilst all other execute methods will return something; this assumes that the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
323 given mapper subroutine will be performing the business of placing values
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
324 somewhere or doing something with them.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
325
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
326 There is a huge temptation to nest queries using this method; do not! Execute
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
327 the values into an array using one of the other methods then run your subqueries
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
328 on them; or make a better first query. SQL is flexible; so use it.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
329
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
330 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
331
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
332 sub execute_no_return {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
333 my ( $self, @args ) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
334 my ($sql, $callback, $use_hashrefs, $params) = rearrange([qw(sql callback use_hashrefs params)], @args);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
335 throw('No callback defined but this is a required parameter for execute_no_return()') if ! $callback;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
336 my $has_return = 0;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
337 my $prepare_params = [];
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
338 $self->_execute( $sql, $callback, $has_return, $use_hashrefs, $params);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
339 return;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
340 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
341
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
342 =pod
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
343
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
344 =head2 execute_into_hash()
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
345
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
346 Arg [SQL] : string $sql
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
347 Arg [CALLBACK] : CodeRef The callback to use for mapping to a value in a hash
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
348 keyed by the first element in your result set;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
349 leave blank for a default mapping to a scalar value
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
350 of the second element
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
351 Arg [PARAMS] : The binding parameters to the SQL statement
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
352 Returntype : HashRef keyed by column 1 & value is the return of callback
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
353 Exceptions : If errors occur in the execution of the SQL
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
354 Status : Stable
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
355
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
356 A variant of the execute methods but rather than returning a list of
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
357 mapped results this will assume the first column of a returning map &
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
358 the calling subroutine will map the remainder of your return as the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
359 hash's key.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
360
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
361 B<This code can handle simple queries to hashes, complex value mappings
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
362 and repeated mappings for the same key>.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
363
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
364 For example:
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
365
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
366 my $sql = 'select key, one, two from table where something =?';
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
367 my $mapper = sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
368 my ( $row, $value ) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
369 #Ignore field 0 as that is being used for the key
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
370 my $obj = Some::Obj->new( one => $row->[1], two => $row->[2] );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
371 return $obj;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
372 };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
373
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
374 my $hash =
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
375 $helper->execute_into_hash( -SQL => $sql,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
376 -CALLBACK => $mapper,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
377 -PARAMS => ['val'] );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
378
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
379 #Or for a more simple usage
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
380 my $sql = 'select biotype, count(gene_id) from gene group by biotype';
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
381 my $biotype_hash = $conn->execute_into_hash( -SQL => $sql );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
382 print $biotype_hash->{protein_coding} || 0, "\n";
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
383
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
384 The basic pattern assumes a scenario where you are mapping in a one
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
385 key to one value. For more advanced mapping techniques you can use the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
386 second value passed to the subroutine paramater set. This is shown as
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
387 C<$value> in the above examples. This value is what is found in the HASH
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
388 being populated in the background. So on the first time you encounter it
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
389 for the given key it will be undefined. For future invocations it will
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
390 be set to the value you gave it. This allows us to setup code like the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
391 following
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
392
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
393 my %args = ( -SQL => 'select meta_key, meta_value from meta '
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
394 . 'where meta_key =? order by meta_id',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
395 -PARAMS => ['species.classification'] );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
396
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
397 my $hash = $helper->execute_into_hash(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
398 %args,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
399 -CALLBACK => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
400 my ( $row, $value ) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
401 $value = [] if !defined $value;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
402 push( @{$value}, $row->[1] );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
403 return $value;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
404 } );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
405
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
406 #OR
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
407
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
408 $hash = $helper->execute_into_hash(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
409 %args,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
410 -CALLBACK => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
411 my ( $row, $value ) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
412 if ( defined $value ) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
413 push( @{$value}, $row->[1] );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
414 return;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
415 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
416 my $new_value = [ $row->[1] ];
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
417 return $new_value;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
418 } );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
419
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
420 The code understands that returning a defined value means to push this
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
421 value into the background hash. In example one we keep on re-inserting
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
422 the Array of classifications into the hash. Example two shows an early
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
423 return from the callback which indicates to the code we do not have any
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
424 value to re-insert into the hash. Of the two methods example one is
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
425 clearer but is possibliy slower.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
426
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
427 B<Remember that the row you are given is the full row & not a view of
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
428 the reminaing fields.> Therefore indexing for the data you are concerned
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
429 with begins at position 1.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
430
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
431 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
432
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
433 sub execute_into_hash {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
434 my ( $self, @args ) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
435 my ($sql, $callback, $params) = rearrange([qw(sql callback params)], @args);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
436 my $hash = {};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
437
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
438 #If no callback then we execute using a default one which sets value to 2nd element
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
439 if(!defined $callback) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
440 $callback = $self->_mappers()->{second_element};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
441 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
442
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
443 #Default mapper uses the 1st key + something else from the mapper
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
444 my $mapper = sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
445 my $row = shift @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
446 my $key = $row->[0];
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
447 my $value = $hash->{$key};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
448 my $new_value = $callback->($row, $value);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
449 if(defined $new_value) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
450 $hash->{ $key } = $new_value;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
451 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
452 return;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
453 };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
454
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
455 $self->execute_no_return(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
456 -SQL => $sql,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
457 -CALLBACK => $mapper,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
458 -PARAMS => $params
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
459 );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
460
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
461 return $hash;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
462 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
463
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
464 =pod
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
465
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
466 =head2 execute_single_result()
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
467
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
468 Arg [SQL] : string $sql
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
469 Arg [CALLBACK] : CodeRef The callback to use for mapping a row to a data point;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
470 leave blank for a default scalar mapping
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
471 Arg [USE_HASHREFS] : boolean If set to true will cause HashRefs to be returned
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
472 to the callback & not ArrayRefs
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
473 Arg [PARAMS] : ArrayRef The binding parameters to the SQL statement
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
474 Returntype : Scalar
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
475 Exceptions : If errors occur in the execution of the SQL, if the query
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
476 returned more than 1 row and if we found no rows.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
477 Status : Stable
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
478
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
479 my $meta_count =
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
480 $helper->execute_single_result(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
481 -SQL => 'select count(*) from meta where species_id =?',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
482 -PARAMS => [1] );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
483
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
484 Very similar to C<execute()> except it will raise an exception if we have more
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
485 or less than one row returned
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
486
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
487 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
488
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
489 sub execute_single_result {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
490 my ( $self, @args ) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
491 my ($sql, $callback, $use_hashrefs, $params) = rearrange(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
492 [qw(sql callback use_hashrefs params)], @args);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
493
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
494 my $results = $self->execute_simple(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
495 -SQL => $sql,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
496 -CALLBACK => $callback,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
497 -USE_HASHREFS => $use_hashrefs,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
498 -PARAMS => $params
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
499 );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
500
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
501 my $result_count = scalar(@{$results});
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
502 if($result_count != 1) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
503 $params = [] if ! $params;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
504 my $type = ($result_count == 0) ? 'No' : 'Too many';
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
505 my $msg = "${type} results returned. Expected 1 but got $result_count for query '${sql}' with params [";
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
506 $msg .= join( ',', map {(defined $_) ? $_ : '-undef-';} @{$params} );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
507 $msg .= ']';
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
508 throw($msg);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
509 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
510 return $results->[0];
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
511 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
512
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
513 =pod
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
514
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
515 =head2 transaction()
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
516
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
517 Arg [CALLBACK] : CodeRef The callback used for transaction isolation; once
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
518 the subroutine exists the code will decide on rollback
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
519 or commit. Required
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
520 Arg [RETRY] : integer the number of retries to attempt with this
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
521 transactional block. Defaults to 0.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
522 Arg [PAUSE] : integer the time in seconds to pause in-between retries.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
523 Defaults to 1.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
524 Arg [CONDITION] : CodeRef allows you to inspect the exception raised
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
525 and should your callback return true then the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
526 retry will be attempted. If not given then all
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
527 exceptions mean attempt a retry (if specified)
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
528 Returntype : Return of the callback
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
529 Exceptions : If errors occur in the execution of the SQL
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
530 Status : Stable
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
531
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
532 my $val = $helper->transaction(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
533 -CALLBACK => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
534 my ($dbc) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
535 #Do something
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
536 return 1;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
537 } );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
538
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
539 #Or because of the arguments method we use
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
540 my $val = $helper->transaction(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
541 sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
542 my ($dbc) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
543 #Do something
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
544 return 1;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
545 } );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
546
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
547 Creates a transactional block which will ensure that the connection is
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
548 committed when your submmited subroutine has finished or will rollback
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
549 in the event of an error occuring in your block.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
550
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
551 The code will always force AutoCommit off but will restore it to its
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
552 previous setting. If your DBI/DBD driver does not support manual
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
553 commits then this code will break. The code will turn off the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
554 C<disconnect_when_idle()> method to allow transactions to work as
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
555 expected.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
556
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
557 An effect of using REPEATABLE READ transaction isolation (InnoDB's
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
558 default) is that your data is as fresh as when you started your current
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
559 transaction. To ensure the freshest data use C<SELECT ... from ... LOCK
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
560 IN SHARE MODE> or C<SELECT ... from ... LOCK FOR UPDATE> if you are
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
561 going to issue updates.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
562
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
563 Creating a transaction within a transaction results in the commit
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
564 rollback statements occuring in the top level transaction. That way any
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
565 block of code which is meant to to be transaction can be wrapped in
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
566 this block ( assuming the same instance of SQLHelper is passed around &
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
567 used).
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
568
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
569 You can also request the retry of a transactional block of code which is
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
570 causing problems. This is not a perfect solution as it indicates your
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
571 programming model is broken. This mode can be specified as such:
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
572
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
573 my $val = $helper->transaction(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
574 -RETRY => 3, -PAUSE => 2,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
575 -CALLBACK => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
576 my ($dbc) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
577 #Do something
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
578 return 1;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
579 } );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
580
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
581 The C<-RETRY> argument indicates the number of times we attempt the transaction
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
582 and C<-PAUSE> indicates the time in-between attempts. These retries will
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
583 only occur in the root transaction block i.e. you cannot influence the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
584 retry system in a sub transaction. You can influence if the retry is done with
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
585 the C<-CONDITION> argument which accepts a Code reference (same as the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
586 C<-CALLBACK> parameter). This allows you to inspect the error thrown to
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
587 retry only in some situations e.g.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
588
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
589 my $val = $helper->transaction(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
590 -RETRY => 3, -PAUSE => 2,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
591 -CALLBACK => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
592 my ($dbc) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
593 #Do something
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
594 return 1;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
595 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
596 -CONDITION => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
597 my ($error) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
598 return ( $error =~ /deadlock/ ) ? 1 : 0;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
599 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
600 );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
601
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
602 Here we attempt a transaction and will B<only> retry when we have an error
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
603 with the phrase deadlock.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
604
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
605 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
606
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
607 sub transaction {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
608 my ($self, @args) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
609
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
610 my ($callback, $retry, $pause, $condition) = rearrange([qw(callback retry pause condition)], @args);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
611
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
612 throw('-CALLBACK was not a CodeRef. Got a reference of type ['.ref($callback).']. Check your parameters')
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
613 unless check_ref($callback, 'CODE');
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
614
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
615 #Setup defaults
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
616 $retry = 0 unless defined $retry;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
617 $pause = 1 unless defined $pause;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
618 if(! defined $condition) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
619 $condition = sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
620 return 1;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
621 };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
622 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
623
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
624 assert_ref($condition, 'CODE', '-CONDITION');
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
625
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
626 my $dbc = $self->db_connection();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
627 my $original_dwi;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
628 my $ac;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
629
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
630 my $error;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
631 my $result;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
632
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
633 #If we were already in a transaction then we do not do any management of the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
634 #session & wait for the parent transaction(s) to finish
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
635 my $perform_transaction = $self->_perform_transaction_code();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
636 if($perform_transaction) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
637 ($original_dwi, $ac) = $self->_enable_transaction();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
638 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
639 else {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
640 #If we were in a transaction then ignore any attempts at retry here
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
641 $retry = 0;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
642 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
643
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
644 for(my $iteration = 0; $iteration <= $retry; $iteration++) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
645 eval {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
646 $result = $callback->($dbc);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
647 $dbc->db_handle()->commit() if $perform_transaction;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
648 };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
649 $error = $@;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
650 #If we were allowed to deal with the error then we apply rollbacks & then
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
651 #retry or leave to the remainder of the code to throw
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
652 if($perform_transaction && $error) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
653 eval { $dbc->db_handle()->rollback(); };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
654 #If we were not on our last iteration then warn & allow the retry
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
655 if($iteration != $retry) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
656 if($condition->($error)) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
657 warn("Encountered error on attempt ${iteration} of ${retry} and have issued a rollback. Will retry after sleeping for $pause second(s): $error");
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
658 sleep $pause;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
659 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
660 else {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
661 last; #break early if condition of error was not matched
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
662 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
663 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
664 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
665
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
666 #Always break the loop if we had a successful attempt
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
667 last if ! $error;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
668 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
669
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
670 if($perform_transaction) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
671 $self->_disable_transaction($original_dwi, $ac);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
672 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
673
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
674 throw("ABORT: Transaction aborted because of error: ${error}") if $error;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
675
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
676 return $result;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
677 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
678
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
679 =pod
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
680
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
681 =head2 execute_update()
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
682
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
683 Arg [SQL] : string $sql
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
684 Arg [CALLBACK] : CodeRef The callback to use for calling methods on the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
685 DBI statement handle or DBConnection object after an
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
686 update command
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
687 Arg [PARAMS] : ArrayRef The binding parameters to the SQL statement
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
688 Arg [PREPARE_PARAMS] : ArrayRef Parameters to bind to the prepare() StatementHandle call
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
689 Returntype : Number of rows affected
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
690 Exceptions : If errors occur in the execution of the SQL
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
691 Status : Stable
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
692
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
693 Used for performing updates but conforms to the normal execute statement
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
694 subroutines.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
695
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
696 use DBI qw(:sql_types);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
697 $helper->execute_update(-SQL => 'update tab set name = ? where id =?',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
698 -PARAMS => [ 'andy', [ 1, SQL_INTEGER ] ] );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
699
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
700 If you need to do something a bit more advanced with your DML then you can
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
701 give the method a closure and this will be called after the execute has been
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
702 issued i.e.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
703
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
704 my $obj;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
705 $helper->execute_update(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
706 -SQL => 'insert into tab (name) values(?)',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
707 -CALLBACK => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
708 my ( $sth, $dbh ) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
709 $obj->{id} = $dbh->{mysql_insertid};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
710 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
711 -PARAMS => [ $obj->name() ] );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
712
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
713 This lets us access the statement handle & database handle to access other
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
714 properties such as the last identifier inserted.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
715
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
716 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
717
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
718 sub execute_update {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
719 my ($self, @args) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
720 my ($sql, $callback, $params, $prepare_params) = rearrange([qw(sql callback params prepare_params)], @args);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
721 my $rv = 0;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
722 my $sth;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
723 eval {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
724 my @prepare_params;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
725 @prepare_params = @{$prepare_params} if check_ref($prepare_params, 'ARRAY');
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
726 $sth = $self->db_connection()->prepare($sql, @prepare_params);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
727 $self->_bind_params($sth, $params);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
728 $rv = $sth->execute();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
729 $callback->($sth, $self->db_connection()->db_handle()) if $callback;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
730 };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
731 my $error = $@;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
732 $self->_finish_sth($sth);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
733 if($error) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
734 my $params = join ' ', map { (defined $_) ? $_ : q{undef} } @{$params};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
735 throw("Cannot apply sql '${sql}' with params '${params}': ${error}");
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
736 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
737 return $rv;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
738 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
739
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
740 =head2 execute_with_sth()
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
741
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
742 Arg [SQL] : string $sql
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
743 Arg [CALLBACK] : CodeRef The callback to use for working with the statement
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
744 handle once returned. This is B<not> a mapper.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
745 Arg [PARAMS] : ArrayRef The binding parameters to the SQL statement
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
746 Arg [PREPARE_PARAMS] : ArrayRef Used to pass parameters to the statement handle
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
747 prepare method
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
748 Description : A subrotuine which abstracts resource handling and statement
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
749 preparing leaving the developer to define how to handle
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
750 and process the statement.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
751 Returntype : Anything you wish to return from the callback
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
752 Exceptions : If errors occur in the execution of the SQL
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
753 Status : Stable
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
754
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
755 my $meta_count = $helper->execute_with_sth(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
756 -SQL => 'select count(*) from meta where species_id =?',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
757 -PARAMS => [1],
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
758 -CALLBACK => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
759 my ($sth) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
760 my $count;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
761 $sth->bind_columns( \$count );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
762 while ( $sth->fetch ) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
763 print $count, "\n";
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
764 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
765 return $count;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
766 } );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
767
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
768 Very similar to C<execute()> except this gives you full control over the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
769 lifecycle of the statement handle & how you wish to proceed with working
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
770 with a statement handle. This is for situations where you believe going through
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
771 the mappers causes too much of a slow-down (since we have to execute a
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
772 subroutine for every row in order to map it correctly).
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
773
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
774 However please benchmark before adopting this method as it increases the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
775 complexity of your code and the mapper slow down only becomes apparent when
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
776 working with very large numbers of rows.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
777
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
778 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
779
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
780 sub execute_with_sth {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
781 my ($self, @args) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
782 my ($sql, $callback, $params, $prepare_params) = rearrange([qw(sql callback params prepare_params)], @args);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
783 my $sth = $self->_base_execute( $sql, $params, $prepare_params, $callback );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
784 my $result = eval {$callback->($sth)};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
785 my $error = $@;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
786 $self->_finish_sth($sth);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
787 die $error if $error;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
788 return $result;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
789 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
790
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
791 =pod
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
792
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
793 =head2 batch()
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
794
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
795 Arg [SQL] : string $sql
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
796 Arg [CALLBACK] : CodeRef The callback to use for working with the statement
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
797 handle once returned; specify this or -DATA
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
798 Arg [DATA] : ArrayRef The data to insert; specify this or -CALLBACK
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
799 Arg [COMMIT_EVERY] : Integer defines the rate at which to issue commits to
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
800 the DB handle. This is important when working with
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
801 InnoDB databases since it affects the speed of rollback
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
802 (larger gaps inbetween commits means more to rollback).
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
803
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
804 Ignored if using the callback version.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
805 Arg [PREPARE_PARAMS] : ArrayRef Used to pass parameters to the statement handle
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
806 prepare method
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
807 Returntype : integer rows updated
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
808 Exceptions : If errors occur in the execution of the SQL
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
809 Status : Stable
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
810
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
811 my $alotofdata = getitfromsomewhere();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
812 $helper->batch(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
813 -SQL => 'insert into table (one,two) values(?,?)',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
814 -CALLBACk => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
815 my ( $sth, $dbc ) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
816 foreach my $data (@alotofdata) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
817 $sth->execute( @{$data} );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
818 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
819 } );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
820
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
821 #Or for a 2D array data driven approach
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
822 $helper->batch( -SQL => 'insert into table (one,two) values(?,?)',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
823 -DATA => $alotofdata );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
824
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
825 Takes in a sql statement & a code reference. Your SQL is converted into a
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
826 prepared statement & then given as the first parameter to the closure. The
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
827 second parameter is the DBH which created the statement. This is intended
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
828 to let you do mass insertion into a database without the need to
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
829 re-preparing the same statement.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
830
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
831 This can be combined with the transaction() code to provide a construct
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
832 which does batch insertion & is transactionally aware.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
833
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
834 We can also use data based batch insertions i.e.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
835
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
836 #Needs to be like:
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
837 # [ [1,2], [3,4] ]
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
838 #Or if using the DBI types:
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
839 # [ [ [ 1, SQL_INTEGER ], [ 2, SQL_INTEGER ] ],
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
840 # [ [ 3, SQL_INTEGER ], [ 4, SQL_INTEGER ] ] ];
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
841
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
842 my $alotofdata = getitfromsomewhere();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
843 $helper->batch( -SQL => 'insert into table (one,two) values(?,?)',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
844 -DATA => $alotofdata );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
845
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
846 This does exactly what the previous example.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
847
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
848 All batch statements will return the value the callback computes. If you are
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
849 using the previous example with a data array then the code will return the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
850 number affected rows by the query.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
851
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
852 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
853
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
854 sub batch {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
855 my ($self, @args) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
856 my ($sql, $callback, $data, $commit_every, $prepare_params) =
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
857 rearrange([qw(sql callback data commit_every prepare_params)], @args);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
858
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
859 if(! defined $callback && ! defined $data) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
860 throw('You need to define a callback for insertion work or the 2D data array');
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
861 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
862
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
863 my $result;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
864 if(defined $callback) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
865 $result = $self->_callback_batch($sql, $callback, $prepare_params);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
866 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
867 else {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
868 $result = $self->_data_batch($sql, $data, $commit_every, $prepare_params);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
869 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
870 return $result if defined $result;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
871 return;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
872 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
873
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
874 #------- Internal methods
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
875
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
876 my $default_mappers = {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
877 first_element => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
878 my ($row) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
879 return $row->[0];
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
880 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
881 second_element => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
882 my ($row) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
883 return $row->[1];
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
884 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
885 array_ref => sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
886 my $row = shift @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
887 return [@{$row}];
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
888 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
889 };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
890
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
891 sub _mappers {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
892 my ($self) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
893 return $default_mappers;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
894 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
895
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
896 sub _perform_transaction_code {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
897 my ($self) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
898 return $self->{_transaction_active}->{$PROCESS_ID} ? 0 : 1;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
899 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
900
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
901 sub _enable_transaction {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
902 my ($self) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
903 my $dbc = $self->db_connection();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
904 my $original_dwi = $dbc->disconnect_when_inactive();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
905 $dbc->disconnect_when_inactive(0);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
906 my $ac = $dbc->db_handle()->{'AutoCommit'};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
907 $dbc->db_handle()->{'AutoCommit'} = 0;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
908 $self->{_transaction_active}->{$PROCESS_ID} = 1;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
909 return ($original_dwi, $ac);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
910 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
911
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
912 sub _disable_transaction {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
913 my ($self, $original_dwi, $ac) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
914 my $dbc = $self->db_connection();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
915 $dbc->db_handle()->{'AutoCommit'} = $ac;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
916 $dbc->disconnect_when_inactive($original_dwi);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
917 delete $self->{_transaction_active}->{$PROCESS_ID};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
918 return;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
919 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
920
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
921 sub _bind_params {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
922 my ( $self, $sth, $params ) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
923
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
924 return if ! defined $params; #Return quickly if we had no data
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
925
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
926 if(! check_ref($params, 'ARRAY')) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
927 throw(qq{The given parameters reference '${params}' is not an ARRAY; wrap in an ArrayRef});
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
928 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
929
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
930 my $count = 1;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
931 foreach my $param (@{$params}) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
932 if ( check_ref($param, 'ARRAY') ) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
933 $sth->bind_param( $count, @{$param} );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
934 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
935 else {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
936 $sth->bind_param( $count, $param );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
937 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
938 $count++;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
939 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
940 return;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
941 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
942
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
943 sub _execute {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
944 my ( $self, $sql, $callback, $has_return, $use_hashrefs, $params, $prepare_params, $iterator ) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
945
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
946 throw('Not given a mapper. _execute() must always been given a CodeRef') unless check_ref($callback, 'CODE');
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
947
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
948 my $sth = $self->_base_execute($sql, $params, $prepare_params);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
949
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
950 my $sth_processor;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
951 if($use_hashrefs) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
952 $sth_processor = sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
953 while( my $row = $sth->fetchrow_hashref() ) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
954 my $v = $callback->($row, $sth);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
955 return $v if $has_return;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
956 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
957 $self->_finish_sth($sth);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
958 return undef;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
959 };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
960 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
961 else {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
962 $sth_processor = sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
963 while( my $row = $sth->fetchrow_arrayref() ) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
964 my $v = $callback->($row, $sth);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
965 return $v if $has_return;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
966 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
967 $self->_finish_sth($sth);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
968 return undef;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
969 };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
970 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
971
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
972 my $iter = Bio::EnsEMBL::Utils::Iterator->new($sth_processor);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
973 if($has_return) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
974 return $iter if $iterator;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
975 return $iter->to_arrayref();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
976 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
977 else {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
978 #Force iteration if we had no return since the caller is expecting this
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
979 $iter->each(sub {});
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
980 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
981 return;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
982 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
983
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
984 sub _base_execute {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
985 my ( $self, $sql, $params, $prepare_params) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
986
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
987 $params = [] unless $params;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
988
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
989 my $conn = $self->db_connection;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
990
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
991 my $sth;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
992 eval {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
993 my @prepare_params;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
994 @prepare_params = @{$prepare_params} if check_ref($prepare_params, 'ARRAY');
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
995 $sth = $conn->prepare($sql, @prepare_params);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
996 throw("Cannot continue as prepare() did not return a handle with prepare params '@prepare_params'")
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
997 unless $sth;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
998 $self->_bind_params( $sth, $params );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
999 $sth->execute();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1000 };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1001
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1002 my $error = $@;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1003 if($error) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1004 throw("Cannot run '${sql}' with params '@{$params}' due to error: $error") if $error;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1005 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1006
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1007 return $sth;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1008 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1009
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1010 sub _finish_sth {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1011 my ($self, $sth) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1012 eval { $sth->finish() if defined $sth; };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1013 warn('Cannot finish() the statement handle: $@') if $@;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1014 return;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1015 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1016
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1017 sub _callback_batch {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1018 my ($self, $sql, $callback, $prepare_params) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1019 my $error;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1020 my $sth;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1021 my $closure_return;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1022 eval {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1023 my @prepare_params;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1024 @prepare_params = @{$prepare_params} if check_ref($prepare_params, 'ARRAY');
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1025 $sth = $self->db_connection()->prepare($sql, @prepare_params);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1026 $closure_return = $callback->($sth, $self->db_connection());
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1027 };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1028 $error = $@;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1029 $self->_finish_sth($sth);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1030 throw("Problem detected during batch work: $error") if $error;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1031
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1032 return $closure_return if defined $closure_return;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1033 return;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1034 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1035
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1036 sub _data_batch {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1037 my ($self, $sql, $data, $commit_every, $prepare_params) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1038
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1039 #Input checks
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1040 assert_ref($data, 'ARRAY', '-DATA');
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1041 my $data_length = scalar(@{$data});
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1042 return 0 unless $data_length > 0;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1043 my $first_row = $data->[0];
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1044 throw('I expect to work with a 2D ArrayRef but this is not one') unless check_ref($first_row, 'ARRAY');
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1045
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1046 my $callback = sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1047 my ($sth, $dbc) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1048 my $total_affected = 0;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1049 #Iterate over each data point
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1050 for(my $data_index = 0; $data_index < $data_length; $data_index++) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1051 my $row = $data->[$data_index];
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1052 $self->_bind_params($sth, $row);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1053 my $affected = eval {$sth->execute()};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1054 if($@) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1055 throw("Problem working with $sql with params @{$row}: $@");
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1056 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1057 my $num_affected = ($affected) ? $affected : 0; #Get around DBI's 0E0
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1058 $total_affected += $num_affected;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1059
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1060 #Lets us do a commit once every x rows apart from 0. We also finish
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1061 #off with a commit if the code told us we were doing it
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1062 if($commit_every) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1063 if( ($data_index % $commit_every == 0) && $data_index != 0) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1064 $dbc->db_handle()->commit();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1065 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1066 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1067 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1068
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1069 #finish off with a commit if the code told us we were doing it
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1070 if($commit_every) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1071 $dbc->db_handle()->commit();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1072 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1073
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1074 return $total_affected || 0;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1075 };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1076
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1077 return $self->_callback_batch($sql, $callback, $prepare_params)
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1078 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1079
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1080 1;