File Coverage

lib/Workflow/Persister/DBI/ExtraData.pm
Criterion Covered Total %
statement 18 63 28.5
branch 0 14 0.0
condition 0 3 0.0
subroutine 6 10 60.0
pod 2 2 100.0
total 26 92 28.2


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