File Coverage

lib/Workflow/Persister.pm
Criterion Covered Total %
statement 67 81 82.7
branch 10 16 62.5
condition 4 7 57.1
subroutine 20 22 90.9
pod 15 15 100.0
total 116 141 82.2


line stmt bran cond sub pod time code
1             package Workflow::Persister;
2              
3 22     22   764 use warnings;
  22         41  
  22         822  
4 22     22   115 use strict;
  22         75  
  22         661  
5 22     22   114 use base qw( Workflow::Base );
  22         59  
  22         3323  
6 22     22   1618 use English qw( -no_match_vars );
  22         5332  
  22         153  
7 22     22   8340 use Log::Log4perl qw( get_logger );
  22         88  
  22         185  
8 22     22   2546 use Workflow::Exception qw( persist_error );
  22         48  
  22         1177  
9              
10 22     22   152 use constant DEFAULT_ID_LENGTH => 8;
  22         47  
  22         22274  
11              
12             $Workflow::Persister::VERSION = '1.62';
13              
14             my @FIELDS = qw( name class
15             use_random use_uuid
16             workflow_id_generator history_id_generator );
17             __PACKAGE__->mk_accessors(@FIELDS);
18              
19             sub init {
20 16     16 1 51 my ( $self, $params ) = @_;
21 16         67 for (@FIELDS) {
22 96 100       994 $self->$_( $params->{$_} ) if ( $params->{$_} );
23             }
24 16 50       121 unless ( $self->use_random ) {
25 16         320 $self->use_random('no');
26             }
27 16 50       292 unless ( $self->use_uuid ) {
28 16         249 $self->use_uuid('no');
29             }
30 16         259 $self->log->info( "Initializing persister '", $self->name, "'" );
31             }
32              
33             ########################################
34             # COMMON GENERATOR ASSIGNMENTS
35              
36             sub assign_generators {
37 16     16 1 67 my ( $self, $params ) = @_;
38 16   50     69 $params ||= {};
39              
40 16         58 my ( $wf_gen, $history_gen );
41 16 50       99 if ( $self->use_uuid eq 'yes' ) {
    100          
42 0         0 $self->log->debug("Assigning UUID generators by request");
43 0         0 ( $wf_gen, $history_gen ) = $self->init_uuid_generators($params);
44             } elsif ( $self->use_random eq 'yes' ) {
45 2         56 $self->log->debug("Assigning random ID generators by request");
46 2         682 ( $wf_gen, $history_gen ) = $self->init_random_generators($params);
47             }
48 16 100 66     508 if ( $wf_gen and $history_gen ) {
49 2         12 $self->workflow_id_generator($wf_gen);
50 2         97 $self->history_id_generator($history_gen);
51             }
52             }
53              
54             sub init_random_generators {
55 14     14 1 49 my ( $self, $params ) = @_;
56 14   50     123 my $length = $params->{id_length} || DEFAULT_ID_LENGTH;
57              
58 14         37 local $EVAL_ERROR = undef;
59 14         32 eval { require Workflow::Persister::RandomId };
  14         113  
60 14 50       90 if (my $msg = $EVAL_ERROR) {
61 0         0 $msg =~ s/\\n/ /g;
62 0         0 $self->log->error($msg);
63             }
64 14         171 my $generator
65             = Workflow::Persister::RandomId->new( { id_length => $length } );
66 14         73 return ( $generator, $generator );
67             }
68              
69             sub init_uuid_generators {
70 0     0 1 0 my ( $self, $params ) = @_;
71              
72 0         0 local $EVAL_ERROR = undef;
73 0         0 eval { require Workflow::Persister::UUID };
  0         0  
74 0 0       0 if (my $msg = $EVAL_ERROR) {
75 0         0 $msg =~ s/\\n/ /g;
76 0         0 $self->log->error($msg);
77             }
78 0         0 my $generator = Workflow::Persister::UUID->new();
79 0         0 return ( $generator, $generator );
80             }
81              
82             ########################################
83             # INTERFACE METHODS
84              
85             sub create_workflow {
86 1     1 1 1037 my ( $self, $wf ) = @_;
87 1         4 persist_error "Persister '", ref($self), "' must implement ",
88             "'create_workflow()'";
89             }
90              
91             sub update_workflow {
92 1     1 1 1514 my ( $self, $wf ) = @_;
93 1         4 persist_error "Persister '", ref($self), "' must implement ",
94             "'update_workflow()'";
95             }
96              
97             sub fetch_workflow {
98 1     1 1 1154 my ( $self, $wf_id ) = @_;
99 1         7 persist_error "Persister '", ref($self), "' must implement ",
100             "'fetch_workflow()'";
101             }
102              
103             # This is the only one that isn't required...
104             sub fetch_extra_workflow_data {
105 6     6 1 15 my ( $self, $wf ) = @_;
106              
107 6         18 $self->log->info("Called empty 'fetch_extra_workflow_data()' (ok)");
108 6         2096 $self->log->debug(
109             "An empty implementation is not an error as you may ",
110             "not need this extra functionality. If you do you ",
111             "should use a persister for this purpose (e.g., ",
112             "Workflow::Persister::DBI::ExtraData) or ",
113             "create your own and just implement this method."
114             );
115 6         2076 return;
116             }
117              
118             sub create_history {
119 1     1 1 1186 my ( $self, $wf, @history ) = @_;
120 1         4 persist_error "Persister '", ref($self), "' must implement ",
121             "'create_history()'";
122             }
123              
124             sub fetch_history {
125 1     1 1 1133 my ( $self, $wf ) = @_;
126 1         5 persist_error "Persister '", ref($self), "' must implement ",
127             "'fetch_history()'";
128             }
129              
130             sub get_create_user {
131 21     21 1 58 my ( $self, $wf ) = @_;
132 21         130 return 'n/a';
133             }
134              
135             sub get_create_description {
136 21     21 1 58 my ( $self, $wf ) = @_;
137 21         113 return 'Create new workflow';
138             }
139              
140             sub get_create_action {
141 21     21 1 79 my ( $self, $wf ) = @_;
142 21         129 return 'Create workflow';
143             }
144              
145             # Only required for DBI persisters.
146             sub commit_transaction {
147 4     4 1 9 return;
148             }
149              
150             sub rollback_transaction {
151 0     0 1   return;
152             }
153              
154             1;
155              
156             __END__
157              
158             =pod
159              
160             =head1 NAME
161              
162             Workflow::Persister - Base class for workflow persistence
163              
164             =head1 VERSION
165              
166             This documentation describes version 1.62 of this package
167              
168             =head1 SYNOPSIS
169              
170             # Associate a workflow with a persister
171             <workflow type="Ticket"
172             persister="MainDatabase">
173             ...
174              
175             # Declare a persister
176             <persister name="MainDatabase"
177             class="Workflow::Persister::DBI"
178             driver="MySQL"
179             dsn="DBI:mysql:database=workflows"
180             user="wf"
181             password="mypass"/>
182              
183             # Declare a separate persister
184             <persister name="FileSystem"
185             class="Workflow::Persister::File"
186             path="/path/to/my/workflow"/>
187              
188             =head1 DESCRIPTION
189              
190             This is the base class for persisting workflows. It does not implement
191             anything itself but actual implementations should subclass it to
192             ensure they fulfill the contract.
193              
194             The job of a persister is to create, update and fetch the workflow
195             object plus any data associated with the workflow. It also creates and
196             fetches workflow history records.
197              
198             =head1 SUBCLASSING
199              
200             =head2 Methods
201              
202             =head3 create_workflow( $workflow )
203              
204             Stub that warns that the method should be overwritten in the derived
205             Persister. Since this is a SUPER class.
206              
207             Generate an ID for the workflow, serialize the workflow data (ID and
208             state) and set the ID in the workflow.
209              
210             Returns the ID for the workflow.
211              
212             =head3 update_workflow( $workflow )
213              
214             Stub that warns that the method should be overwritten in the derived
215             Persister. Since this is a SUPER class.
216              
217             Update the workflow state.
218              
219             Returns nothing.
220              
221             =head3 fetch_workflow( $workflow_id )
222              
223             Stub that warns that the method should be overwritten in the derived
224             Persister. Since this is a SUPER class.
225              
226             Retrieve the workflow data corresponding to C<$workflow_id>. It not
227             found return undef, if found return a hashref with at least the keys
228             C<state> and C<last_update> (a L<DateTime> instance).
229              
230             =head3 create_history( $workflow, @history )
231              
232             Stub that warns that the method should be overwritten in the derived
233             Persister. Since this is a SUPER class.
234              
235             Serialize all objects in C<@history> for later retrieval.
236              
237             Returns C<@history>, the list of history objects, with the history
238             C<id> and C<saved> values set according to the saved results.
239              
240             =head3 fetch_history( $workflow )
241              
242             Stub that warns that the method should be overwritten in the derived
243             Persister. Since this is a SUPER class.
244              
245             The derived class method should return a list of L<Workflow::History> objects.
246              
247              
248             =head3 get_create_user( $workflow )
249              
250             When creating an initial L<Workflow::History> record to insert into the database,
251             the return value of this method is used for the value of the "user" field.
252              
253             Override this method to change the value from the default, "n/a".
254              
255             =head3 get_create_description( $workflow )
256              
257             When creating an initial L<Workflow::History> record to insert into the database,
258             the return value of this method is used for the value of the "description" field.
259              
260             Override this method to change the value from the default, "Create new workflow".
261              
262              
263             =head3 get_create_action( $workflow )
264              
265             When creating an initial L<Workflow::History> record to insert into the database,
266             the return value of this method is used for the value of the "action" field.
267              
268             Override this method to change the value from the default, "Create workflow".
269              
270              
271             =head3 assign_generators( \%params )
272              
273             Assigns proper generators based on intialization, see L</init>
274              
275             =head3 fetch_extra_workflow_data ( $workflow )
276              
277             A stub that warns that the method should be overwritten in the derived
278             Persister. Since this is a SUPER class.
279              
280             =head3 commit_transaction
281              
282             Commit the current transaction if the persister supports transactions.
283             This stub does not have to be overridden. It is not executed if
284             autocommit is on.
285              
286             =head3 rollback_transaction
287              
288             Roll back the current transaction if the persister supports transactions.
289             This stub does not have to be overridden. It is not executed if
290             autocommit is on.
291              
292             =head3 init
293              
294             Method to initialize persister based on configuration.
295              
296             =head3 init_random_generators( \%params )
297              
298             Initializes random id generators, takes the following named parameters:
299              
300             =over
301              
302             =item * length, of random id to be generated
303              
304             =back
305              
306             Returns two identical random id generator objects in list context.
307              
308             =head3 init_uuid_generators( \%params )
309              
310             Initializes UUID generators, takes no parameters
311              
312             Returns two identical UUID generator objects in list context.
313              
314             =head1 TODO
315              
316             =over
317              
318             =item * refactor init_random_generators, returns two similar objects?
319              
320             =item * refactor init_uuid_generators, returns two similar objects?
321              
322             =item * refactor init_uuid_generators, takes no parameters, even though
323             we shift parameters in?
324              
325             =back
326              
327             =head1 SEE ALSO
328              
329             =over
330              
331             =item * L<Workflow::Factory>
332              
333             =item * L<Workflow::History>
334              
335             =back
336              
337             =head1 COPYRIGHT
338              
339             Copyright (c) 2003-2023 Chris Winters. All rights reserved.
340              
341             This library is free software; you can redistribute it and/or modify
342             it under the same terms as Perl itself.
343              
344             Please see the F<LICENSE>
345              
346             =head1 AUTHORS
347              
348             Please see L<Workflow>
349              
350             =cut