line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Workflow::Persister::DBI::ExtraData; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
22427
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
37
|
|
4
|
1
|
|
|
1
|
|
5
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
26
|
|
5
|
1
|
|
|
1
|
|
6
|
use base qw( Workflow::Persister::DBI ); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
498
|
|
6
|
1
|
|
|
1
|
|
7
|
use Log::Log4perl qw( get_logger ); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
5
|
|
7
|
1
|
|
|
1
|
|
61
|
use Workflow::Exception qw( configuration_error persist_error ); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
64
|
|
8
|
1
|
|
|
1
|
|
6
|
use English qw( -no_match_vars ); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
6
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
$Workflow::Persister::DBI::ExtraData::VERSION = '1.62'; |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
my @FIELDS = qw( table data_field context_key ); |
13
|
|
|
|
|
|
|
__PACKAGE__->mk_accessors(@FIELDS); |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
sub init { |
16
|
0
|
|
|
0
|
1
|
|
my ( $self, $params ) = @_; |
17
|
0
|
|
|
|
|
|
$self->SUPER::init($params); |
18
|
|
|
|
|
|
|
|
19
|
0
|
|
|
|
|
|
my @not_found = (); |
20
|
0
|
|
|
|
|
|
foreach (qw( table data_field )) { |
21
|
0
|
0
|
|
|
|
|
push @not_found, $_ unless ( $params->{"extra_$_"} ); |
22
|
|
|
|
|
|
|
} |
23
|
0
|
0
|
|
|
|
|
if ( scalar @not_found ) { |
24
|
0
|
|
|
|
|
|
$self->log->error( "Required configuration fields not found: ", |
25
|
|
|
|
|
|
|
join ', ', @not_found ); |
26
|
0
|
|
|
|
|
|
configuration_error |
27
|
|
|
|
|
|
|
"To fetch extra data with each workflow with this implementation ", |
28
|
|
|
|
|
|
|
"you must specify: ", join ', ', @not_found; |
29
|
|
|
|
|
|
|
} |
30
|
|
|
|
|
|
|
|
31
|
0
|
|
|
|
|
|
$self->table( $params->{extra_table} ); |
32
|
0
|
|
|
|
|
|
my $data_field = $params->{extra_data_field}; |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# If multiple data fields specified we don't allow the user to |
35
|
|
|
|
|
|
|
# specify a context key |
36
|
|
|
|
|
|
|
|
37
|
0
|
0
|
|
|
|
|
if ( $data_field =~ /,/ ) { |
38
|
0
|
|
|
|
|
|
$self->data_field( [ split /\s*,\s*/, $data_field ] ); |
39
|
|
|
|
|
|
|
} else { |
40
|
0
|
|
|
|
|
|
$self->data_field($data_field); |
41
|
0
|
|
0
|
|
|
|
my $context_key = $params->{extra_context_key} || $data_field; |
42
|
0
|
|
|
|
|
|
$self->context_key($context_key); |
43
|
|
|
|
|
|
|
} |
44
|
0
|
0
|
|
|
|
|
$self->log->info( "Configured extra data fetch with: ", |
45
|
|
|
|
|
|
|
join( '; ', $self->table, $data_field, |
46
|
|
|
|
|
|
|
( defined $self->context_key |
47
|
|
|
|
|
|
|
? $self->context_key : '' ) ) ); |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub fetch_extra_workflow_data { |
51
|
0
|
|
|
0
|
1
|
|
my ( $self, $wf ) = @_; |
52
|
|
|
|
|
|
|
|
53
|
0
|
|
|
|
|
|
$self->log->debug( "Fetching extra workflow data for '", $wf->id, "'" ); |
54
|
|
|
|
|
|
|
|
55
|
0
|
|
|
|
|
|
my $sql = q{SELECT %s FROM %s WHERE workflow_id = ?}; |
56
|
0
|
|
|
|
|
|
my $data_field = $self->data_field; |
57
|
|
|
|
|
|
|
my $select_data_fields |
58
|
|
|
|
|
|
|
= ( ref $data_field ) |
59
|
|
|
|
|
|
|
? join( ', ', |
60
|
0
|
0
|
|
|
|
|
map { $self->handle->quote_identifier($_) } @{$data_field} ) |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
: $self->handle->quote_identifier($data_field); |
62
|
0
|
|
|
|
|
|
$sql = sprintf $sql, $select_data_fields, |
63
|
|
|
|
|
|
|
$self->handle->quote_identifier( $self->table ); |
64
|
0
|
|
|
|
|
|
$self->log->debug( "Using SQL: ", $sql); |
65
|
0
|
|
|
|
|
|
$self->log->debug( "Bind parameters: ", $wf->id ); |
66
|
|
|
|
|
|
|
|
67
|
0
|
|
|
|
|
|
my ($sth); |
68
|
0
|
|
|
|
|
|
local $EVAL_ERROR = undef; |
69
|
0
|
|
|
|
|
|
eval { |
70
|
0
|
|
|
|
|
|
$sth = $self->handle->prepare($sql); |
71
|
0
|
|
|
|
|
|
$sth->execute( $wf->id ); |
72
|
|
|
|
|
|
|
}; |
73
|
0
|
0
|
|
|
|
|
if ($EVAL_ERROR) { |
74
|
0
|
|
|
|
|
|
persist_error "Failed to retrieve extra data from table ", |
75
|
|
|
|
|
|
|
$self->table, ": $EVAL_ERROR"; |
76
|
|
|
|
|
|
|
} else { |
77
|
0
|
|
|
|
|
|
$self->log->debug("Prepared/executed extra data fetch ok"); |
78
|
0
|
|
|
|
|
|
my $row = $sth->fetchrow_arrayref; |
79
|
0
|
0
|
|
|
|
|
if ( ref $data_field ) { |
80
|
0
|
|
|
|
|
|
foreach my $i ( 0 .. $#{$data_field} ) { |
|
0
|
|
|
|
|
|
|
81
|
0
|
|
|
|
|
|
$wf->context->param( $data_field->[$i], $row->[$i] ); |
82
|
|
|
|
|
|
|
$self->log->info( |
83
|
0
|
|
|
0
|
|
|
sub { sprintf "Set data from %s.%s into context key %s ok", |
84
|
|
|
|
|
|
|
$self->table, $data_field->[$i], |
85
|
0
|
|
|
|
|
|
$data_field->[$i] } ); |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
} else { |
88
|
0
|
|
|
|
|
|
my $value = $row->[0]; |
89
|
0
|
|
|
|
|
|
$wf->context->param( $self->context_key, $value ); |
90
|
|
|
|
|
|
|
$self->log->info( |
91
|
0
|
|
|
0
|
|
|
sub { sprintf "Set data from %s.%s into context key %s ok", |
92
|
|
|
|
|
|
|
$self->table, $self->data_field, |
93
|
0
|
|
|
|
|
|
$self->context_key } ); |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
1; |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
__END__ |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=pod |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=head1 NAME |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
Workflow::Persister::DBI::ExtraData - Fetch extra data with each workflow and put it into the context |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=head1 VERSION |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
This documentation describes version 1.62 of this package |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=head1 SYNOPSIS |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
<persister name="MyPersister" |
115
|
|
|
|
|
|
|
class="Workflow::Persister::DBI::ExtraData" |
116
|
|
|
|
|
|
|
dsn="DBI:mysql:database=workflows" |
117
|
|
|
|
|
|
|
user="wf" |
118
|
|
|
|
|
|
|
password="mypass" |
119
|
|
|
|
|
|
|
extra_table="workflow_ticket" |
120
|
|
|
|
|
|
|
extra_data_field="ticket_id" |
121
|
|
|
|
|
|
|
extra_context_key="ticket_id"/> |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
=head1 DESCRIPTION |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=head2 Overview |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
Simple subclass of L<Workflow::Persister::DBI> to allow you to declare |
128
|
|
|
|
|
|
|
an extra table and data field(s) from which to fetch data whenever you |
129
|
|
|
|
|
|
|
fetch a workflow. There is a simple restriction: the table must have a |
130
|
|
|
|
|
|
|
field 'workflow_id' of the same datatype as the 'workflow_id' field in |
131
|
|
|
|
|
|
|
the 'workflow' table. |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=head2 Examples |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
# Specify a single field 'ticket_id' from the table 'workflow_ticket' |
136
|
|
|
|
|
|
|
# and store it in the context using the same key: |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
<persister |
139
|
|
|
|
|
|
|
... |
140
|
|
|
|
|
|
|
extra_table="workflow_ticket" |
141
|
|
|
|
|
|
|
extra_data_field="ticket_id" |
142
|
|
|
|
|
|
|
... |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
# How you would use this: |
145
|
|
|
|
|
|
|
my $wf = FACTORY->fetch_workflow( 'Ticket', 55 ); |
146
|
|
|
|
|
|
|
print "Workflow is associated with ticket: ", |
147
|
|
|
|
|
|
|
$wf->context->param( 'ticket_id' ); |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
# Specify a single field 'ticket_id' from the table 'workflow_ticket' |
150
|
|
|
|
|
|
|
# and store it in the context using a different key |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
<persister |
153
|
|
|
|
|
|
|
... |
154
|
|
|
|
|
|
|
extra_table="workflow_ticket" |
155
|
|
|
|
|
|
|
extra_data_field="ticket_id" |
156
|
|
|
|
|
|
|
extra_context_key="THE_TICKET_ID" |
157
|
|
|
|
|
|
|
... |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
# How you would use this: |
160
|
|
|
|
|
|
|
my $wf = FACTORY->fetch_workflow( 'Ticket', 55 ); |
161
|
|
|
|
|
|
|
print "Workflow is associated with ticket: ", |
162
|
|
|
|
|
|
|
$wf->context->param( 'THE_TICKET_ID' ); |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
# Specify multiple fields ('ticket_id', 'last_viewer', |
165
|
|
|
|
|
|
|
# 'last_view_date') to pull from the 'workflow_ticket' table: |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
<persister |
168
|
|
|
|
|
|
|
... |
169
|
|
|
|
|
|
|
extra_table="workflow_ticket" |
170
|
|
|
|
|
|
|
extra_data_field="ticket_id,last_viewer,last_view_date" |
171
|
|
|
|
|
|
|
... |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
# How you would use this: |
174
|
|
|
|
|
|
|
my $wf = FACTORY->fetch_workflow( 'Ticket', 55 ); |
175
|
|
|
|
|
|
|
print "Workflow is associated with ticket: ", |
176
|
|
|
|
|
|
|
$wf->context->param( 'ticket_id' ), " ", |
177
|
|
|
|
|
|
|
"which was last viewed by ", |
178
|
|
|
|
|
|
|
$wf->context->param( 'last_viewer' ), " on ", |
179
|
|
|
|
|
|
|
$wf->context->param( 'last_view_date' ); |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
=head2 Configuration |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
B<extra_table> (required) |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
Table where the extra data are kept. |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
B<extra_data_field> (required) |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
Can be a single field or a comma-separated list of fields, all in the |
190
|
|
|
|
|
|
|
same table. If a single field specified you have the option of |
191
|
|
|
|
|
|
|
declaring a different C<extra_context_key> under which the value |
192
|
|
|
|
|
|
|
should be stored in the workflow context. Otherwise the values are |
193
|
|
|
|
|
|
|
stored by the field names in the workflow context. |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
B<extra_context_key> (optional) |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
Key under which to save the data from C<extra_data_field> in the |
198
|
|
|
|
|
|
|
workflow context. |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
Note: this is ignored when you specify multiple fields in |
201
|
|
|
|
|
|
|
C<extra_data_field>; we just use the fieldnames for the context keys |
202
|
|
|
|
|
|
|
in that case. And if you specify a single data field and do not |
203
|
|
|
|
|
|
|
specify a context key we also use the data field name. |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=head2 METHODS |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=head3 init ( \%params ) |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
Initializes persister for extra workflow data. |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
Throws L<Workflow::Exception> if initialization is not successful. |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
=head3 fetch_extra_workflow_data ( $wf ) |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
Fetches extra data from database and feeds this to context of given workflow. |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
Takes a single parameter, a workflow object to which extra data are feed if |
218
|
|
|
|
|
|
|
retrieved successfully. |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
Throws L<Workflow::Exception> if retrieval is not successful. |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
=head1 COPYRIGHT |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
Copyright (c) 2003-2023 Chris Winters. All rights reserved. |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
227
|
|
|
|
|
|
|
it under the same terms as Perl itself. |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
Please see the F<LICENSE> |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
=head1 AUTHORS |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
Please see L<Workflow> |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
=cut |