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