NAME

Workflow::Persister::DBI - Persist workflow and history to DBI database

VERSION

This documentation describes version 1.54 of this package

SYNOPSIS

<persister name="MainDatabase"
           class="Workflow::Persister::DBI"
           dsn="DBI:mysql:database=workflows"
           user="wf"
           password="mypass"/>

<persister name="BackupDatabase"
           class="Workflow::Persister::DBI"
           dsn="DBI:Pg:dbname=workflows"
           user="wf"
           password="mypass"
           date_format="%Y-%m-%d %H:%M"
           autocommit="0"
           workflow_table="wf"
           workflow_sequence="wf_seq"
           history_table="wf_history"
           history_sequence="wf_history_seq"/>

<persister name="OtherDatabase"
           class="My::Persister::DBHFromElsewhere"
           driver="mysql"
           />

DESCRIPTION

Main persistence class for storing the workflow and workflow history records to a DBI-accessible datasource.

Subclassing: Getting handle from elsewhere

A common need to create a subclass is to use a database handle created with other means. For instance, OpenInteract has a central configuration file for defining datasources, and the datasource will be available in a predictable manner. So we can create a subclass to provide the database handle on demand from the CTX object available from everywhere. A sample implementation is below. (Note that in real life we would just use SPOPS for this, but it is still a good example.)

package Workflow::Persister::DBI::OpenInteractHandle;

use strict;
use base qw( Workflow::Persister::DBI );
use OpenInteract2::Context qw( CTX );

my @FIELDS = qw( datasource_name );
__PACKAGE__->mk_accessors( @FIELDS );

# override parent method, assuming that we set the 'datasource'
# parameter in the persister declaration

sub init {
   my ( $self, $params ) = @_;
   $self->datasource_name( $params->{datasource} );
   my $ds_config = CTX->lookup_datasource_config( $self->datasource_name );

   # delegate the other assignment tasks to the parent class
   $params->{driver} = $ds_config->{driver_name};
   $self->SUPER::init( $params );
}

# suppress the parent from trying to connect to the database
sub create_handle { return undef; }

sub handle {
    my ( $self ) = @_;
    return CTX->datasource( $self->datasource_name );
}

Subclassing: Changing fieldnames

Earlier versions of Workflow used the field 'user' to record in the history the user making a state change or comment. Unfortunately 'user' is a reserved word in our favorite database, PostgreSQL. (Oops.) So in addition to changing the field to an assuredly-unreserved word (workflow_user), we made the fieldnames customizable by subclasses.

Just override either or both of the methods:

get_workflow_fields()

Return list of fields in this order:

workflow_id, type, state, last_update

get_history_fields()

Return list of fields in this order:

workflow_hist_id, workflow_id, action, description,
state, workflow_user, history_date

Note that we may cache the results, so don't try and do anything weird like change the fieldnames based on the workflow user or something...

METHODS

Public Methods

All public methods are inherited from Workflow::Persister.

Private Methods

init( \%params )

Initializes the the instance by setting the connection parameters and calling create_handle. You are only required to provide 'dsn', which is the full DBI DSN you normally use as the first argument to connect().

You can set these parameters in your persister configuration file and they will be passed to init.

You may also use:

user

Name of user to login with.

password

Password for user to login with.

date_format

Date format to use when working with the database. Accepts a format string that can be processed by the DateTime module. See http://search.cpan.org/~drolsky/DateTime-0.39/lib/DateTime.pm#strftime_Specifiers for the format options.

The default is '%Y-%m-%d %H:%M' for backward compatibility.

autocommit

0 or 1 to turn autocommit off or on for the database handle.

Setting autocommit to off will run Workflow with transactions. If there is a failure somewhere and the persister supports it, Workflow will attempt to roll back all database activity in the current transaction.

If you turn autocommit off, you must still commit transactions for Workflow::Persister::DBI::ExtraData yourself. Also, if you are sharing the database handle, you must be careful to not pass control to the workflow engine with pending transactions as they will be committed if the workflow actions are successful.

The default autocommit value for the database handle is on.

workflow_table

Table to use for persisting workflow. Default is 'workflow'.

history_table

Table to use for persisting workflow history. Default is 'workflow_history'.

You may also use parameters for the different types of ID generators. See below under the init_*_generator for the necessary parameters for your database.

In addition to creating a database handle we parse the dsn to see what driver we are using to determine how to generate IDs. We have the ability to use automatically generated IDs for PostgreSQL, MySQL, and SQLite. If your database is not included a randomly generated ID will be used. (Default length of 8 characters, which you can modify with a id_length parameter.)

You can also create your own adapter for a different type of database. Just check out the existing Workflow::Persister::DBI::AutoGeneratedId and Workflow::Persister::DBI::SequenceId classes for examples.

assign_generators( $driver, \%params )

Given $driver and the persister parameters in \%params, assign the appropriate ID generators for both the workflow and history tables.

Returns: nothing, but assigns the object properties workflow_id_generator and history_id_generator.

assign_tables( \%params )

Assign the table names from \%params (using 'workflow_table' and 'history_table') or use the defaults 'workflow' and 'workflow_history'.

Returns: nothing, but assigns the object properties workflow_table and history_table.

init_postgres_generators( \%params )

Create ID generators for the workflow and history tables using PostgreSQL sequences. You can specify the sequences used for the workflow and history tables:

workflow_sequence

Sequence for the workflow table. Default: 'workflow_seq'

history_sequence

Sequence for the workflow history table. Default: 'workflow_history_seq'

init_mysql_generators( \%params )

Create ID generators for the workflow and history tables using the MySQL 'auto_increment' type. No parameters are necessary.

init_sqlite_generators( \%params )

Create ID generators for the workflow and history tables using the SQLite implicit increment. No parameters are necessary.

init_random_generators( \%params )

Create ID generators for the workflow and history tables using a random set of characters. You can specify:

id_length

Length of character sequence to generate. Default: 8.

init_oracle_generators

Create ID generators for the workflow and history tables using the Oracle sequences. No parameters are necessary.

create_handle

Creates a database connection using DBI's connect method and returns the resulting database handle. Override this method if you want to set different options than the hard-coded ones, or when you want to use a handle from elsewhere.

The default implementation hard-codes these database handle settings:

$dbh->{RaiseError} = 1;
$dbh->{PrintError} = 0;
$dbh->{ChopBlanks} = 1;

create_workflow

Serializes a workflow into the persistance entity configured by our workflow.

Takes a single parameter: a workflow object

Returns a single value, a id for unique identification of out serialized workflow for possible deserialization.

fetch_workflow

Deserializes a workflow from the persistance entity configured by our workflow.

Takes a single parameter: the unique id assigned to our workflow upon serialization (see "create_workflow").

Returns a hashref consisting of two keys:

  • state, the workflows current state

  • last_update, date indicating last update

update_workflow

Updates a serialized workflow in the persistance entity configured by our workflow.

Takes a single parameter: a workflow object

Returns: Nothing

create_history

Serializes history records associated with a workflow object

Takes two parameters: a workflow object and an array of workflow history objects

Returns: provided array of workflow history objects upon success

fetch_history

Deserializes history records associated with a workflow object

Takes a single parameter: a workflow object

Returns an array of workflow history objects upon success

commit_transaction ( $wf )

Commit the transaction for a workflow if autocommit is not enabled.

Returns nothing

rollback_transaction

Rollsback the transaction for a workflow if autocommit is not enabled.

Returns nothing

SEE ALSO

Workflow
Workflow::Persister
Workflow::History
DBI

COPYRIGHT

Copyright (c) 2003-2021 Chris Winters. All rights reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

Please see the LICENSE

AUTHORS

Please see Workflow