Skip to content

Commit

Permalink
Refactor certificate/workflow search, clenaup workflow table naming
Browse files Browse the repository at this point in the history
Use SQL COUNT to get the number of results (instead of loading and
counting them in perl)
Remove ambigous use of parameters for workflow table names
  • Loading branch information
oliwel committed Feb 7, 2015
1 parent fde1c12 commit 28f3a7a
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 99 deletions.
98 changes: 62 additions & 36 deletions core/server/OpenXPKI/Server/API/Object.pm
Original file line number Diff line number Diff line change
Expand Up @@ -526,21 +526,6 @@ sub get_crl_list {
}



sub search_cert_count {
##! 1: 'start'
my $self = shift;
my $arg_ref = shift;

my $result = $self->search_cert($arg_ref);

if ( defined $result && ref $result eq 'ARRAY' ) {
##! 1: 'array result with ' . scalar @{$result} . ' elements'
return scalar @{$result};
}
return 0;
}

=head2 search_cert
supports a facility to search certificates. It supports the following parameters:
Expand Down Expand Up @@ -578,8 +563,68 @@ of the database to reduce the transport costs an avoid parser implementations
on the client.
=cut
sub search_cert {

my $self = shift;
my $args = shift;

my $params = $self->__search_cert( $args );

##! 16: 'certificate search arguments: ' . Dumper $params

my $result = CTX('dbi_backend')->select(%{$params});
if ( ref $result ne 'ARRAY' ) {
OpenXPKI::Exception->throw(
message => 'I18N_OPENXPKI_SERVER_API_OBJECT_SEARCH_CERT_SELECT_RESULT_NOT_ARRAY',
params => { 'TYPE' => ref $result, },
);
}

##! 1: 'Result ' . Dumper $result

foreach my $item ( @{$result} ) {

# remove leading table name from result columns
map {
my $col = substr( $_, index( $_, '.' ) + 1 );
$item->{$col} = $item->{$_};
delete $item->{$_};
} keys %{$item};
}

##! 1: "finished"
return $result;

}

sub search_cert {
=head2 search_cert_count
Same as cert_search, returns the number of matching rows
=cut
sub search_cert_count {
##! 1: 'start'
my $self = shift;
my $arg_ref = shift;

my $params = $self->__search_cert( $arg_ref );

$params->{COLUMNS} = [{ COLUMN => 'CERTIFICATE.IDENTIFIER', AGGREGATE => 'COUNT' }];

my $result = CTX('dbi_backend')->select(%{$params});

if (!(defined $result && ref $result eq 'ARRAY' && scalar @{$result} == 1)) {
OpenXPKI::Exception->throw(
message => 'I18N_OPENXPKI_SERVER_API_OBJECT_SEARCH_CERT_COUNT_SELECT_RESULT_NOT_ARRAY',
params => { 'TYPE' => ref $result, },
);
}

return $result->[0]->{'CERTIFICATE.IDENTIFIER'};

}

sub __search_cert {
##! 1: "start"
my $self = shift;
my $args = shift;
Expand Down Expand Up @@ -734,27 +779,8 @@ sub search_cert {

}

##! 16: 'certificate search arguments: ' . Dumper \%params

my $result = CTX('dbi_backend')->select(%params);
if ( ref $result ne 'ARRAY' ) {
OpenXPKI::Exception->throw(
message => 'I18N_OPENXPKI_SERVER_API_OBJECT_SEARCH_CERT_SELECT_RESULT_NOT_ARRAY',
params => { 'TYPE' => ref $result, },
);
}
foreach my $item ( @{$result} ) {

# remove leading table name from result columns
map {
my $col = substr( $_, index( $_, '.' ) + 1 );
$item->{$col} = $item->{$_};
delete $item->{$_};
} keys %{$item};
}
return \%params;

##! 1: "finished"
return $result;
}

=head2 private_key_exists_for_cert
Expand Down
117 changes: 70 additions & 47 deletions core/server/OpenXPKI/Server/API/Workflow.pm
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ use OpenXPKI::Server::Workflow::Observer::AddExecuteHistory;
use OpenXPKI::Server::Workflow::Observer::Log;
use OpenXPKI::Serialization::Simple;

my $workflow_table = 'WORKFLOW';
my $context_table = 'WORKFLOW_CONTEXT';
my $workflow_history_table = 'WORKFLOW_HISTORY';

sub START {
# somebody tried to instantiate us, but we are just an
# utility class with static methods
Expand Down Expand Up @@ -153,7 +149,7 @@ sub list_workflow_instances {
##! 16: 'start: ' . $start

my $instances = $dbi->select(
TABLE => $workflow_table,
TABLE => 'WORKFLOW',
DYNAMIC => {
PKI_REALM => {VALUE => CTX('session')->get_pki_realm()},
},
Expand Down Expand Up @@ -183,7 +179,7 @@ sub get_number_of_workflow_instances {
# TODO - wait for someone to implement aggregates without joins
# and then use a simpler query (cf. feature request #1675572)
my $instances = $dbi->select(
TABLE => [ $workflow_table ],
TABLE => [ 'WORKFLOW' ],
JOIN => [ [ 'WORKFLOW_SERIAL'] ],
DYNAMIC => {
PKI_REALM => {VALUE => CTX('session')->get_pki_realm()},
Expand Down Expand Up @@ -217,20 +213,20 @@ sub list_context_keys {
$arg_ref->{'WORKFLOW_TYPE'} = '%';
}
my $context_keys = $dbi->select(
TABLE => [ $workflow_table, $context_table ],
TABLE => [ 'WORKFLOW', 'WORKFLOW_CONTEXT' ],
COLUMNS => [
$context_table . '.WORKFLOW_CONTEXT_KEY',
'WORKFLOW_CONTEXT.WORKFLOW_CONTEXT_KEY',
],
DYNAMIC => {
"$workflow_table.WORKFLOW_TYPE" => {VALUE => $arg_ref->{'WORKFLOW_TYPE'}},
"$workflow_table.PKI_REALM" => {VALUE => CTX('session')->get_pki_realm()},
"WORKFLOW.WORKFLOW_TYPE" => {VALUE => $arg_ref->{'WORKFLOW_TYPE'}},
"WORKFLOW.PKI_REALM" => {VALUE => CTX('session')->get_pki_realm()},
},
JOIN => [ [ 'WORKFLOW_SERIAL', 'WORKFLOW_SERIAL' ] ],
DISTINCT => 1,
);
##! 16: 'context_keys: ' . Dumper $context_keys

my @context_keys = map { $_->{$context_table.'.WORKFLOW_CONTEXT_KEY'} } @{$context_keys};
my @context_keys = map { $_->{'WORKFLOW_CONTEXT.WORKFLOW_CONTEXT_KEY'} } @{$context_keys};
return \@context_keys;
}

Expand All @@ -254,7 +250,7 @@ sub get_workflow_type_for_id {
$dbi->commit();

my $db_result = $dbi->first(
TABLE => $workflow_table,
TABLE => 'WORKFLOW',
DYNAMIC => {
'WORKFLOW_SERIAL' => {VALUE => $id},
},
Expand Down Expand Up @@ -438,7 +434,7 @@ sub get_workflow_history {
my $wf_id = $arg_ref->{ID};

my $history = CTX('dbi_workflow')->select(
TABLE => $workflow_history_table,
TABLE => 'WORKFLOW_HISTORY',
DYNAMIC => {
WORKFLOW_SERIAL => {VALUE => $wf_id},
},
Expand Down Expand Up @@ -677,28 +673,60 @@ sub get_workflow_activities {
}

sub search_workflow_instances_count {
my $self = shift;
my $arg_ref = shift;

my $result = $self->search_workflow_instances($arg_ref);

if (defined $result && ref $result eq 'ARRAY') {
return scalar @{$result};
my $self = shift;
my $arg_ref = shift;

my $params = $self->__search_workflow_instances( $arg_ref );

$params->{COLUMNS} = [{ COLUMN => 'WORKFLOW.WORKFLOW_SERIAL', AGGREGATE => 'COUNT' }];

my $dbi = CTX('dbi_workflow');
$dbi->commit();

my $result = $dbi->select( %{$params} );

if (!(defined $result && ref $result eq 'ARRAY' && scalar @{$result} == 1)) {
OpenXPKI::Exception->throw(
message => 'I18N_OPENXPKI_SERVER_API_WORKFLOW_SEARCH_WORKFLOW_RESULT_COUNT_NOT_ARRAY',
params => { 'TYPE' => ref $result, },
);
}
return 0;

##! 16: 'result: ' . Dumper $result
return $result->[0]->{'WORKFLOW.WORKFLOW_SERIAL'};

}

sub search_workflow_instances {

my $self = shift;
my $arg_ref = shift;
my $re_alpha_string = qr{ \A [ \w \- \. : \s ]* \z }xms;


my $param = $self->__search_workflow_instances( $arg_ref );

my $dbi = CTX('dbi_workflow');
# commit to get a current snapshot of the database in the
# highest isolation level.
# Without this, we will only see old data, especially if
# other processes are writing to the database at the same time
$dbi->commit();

my $result = $dbi->select( %{$param} );

if (!(defined $result && ref $result eq 'ARRAY')) {
OpenXPKI::Exception->throw(
message => 'I18N_OPENXPKI_SERVER_API_WORKFLOW_SEARCH_WORKFLOW_RESULT_NOT_ARRAY',
params => { 'TYPE' => ref $result, },
);
}

##! 16: 'result: ' . Dumper $result
return $result;

}

sub __search_workflow_instances {

my $self = shift;
my $arg_ref = shift;
my $re_alpha_string = qr{ \A [ \w \- \. : \s ]* \z }xms;

my $realm = CTX('session')->get_pki_realm();

Expand Down Expand Up @@ -750,9 +778,9 @@ sub search_workflow_instances {
push @joins, 'WORKFLOW_SERIAL';
$i++;
}
push @tables, $workflow_table;
push @tables, 'WORKFLOW';
push @joins, 'WORKFLOW_SERIAL';
$dynamic->{$workflow_table . '.PKI_REALM'} = {VALUE => $realm};
$dynamic->{'WORKFLOW.PKI_REALM'} = {VALUE => $realm};

if (defined $arg_ref->{TYPE}) {
# do parameter validation (here instead of the API because
Expand All @@ -779,7 +807,7 @@ sub search_workflow_instances {
}
}
}
$dynamic->{$workflow_table . '.WORKFLOW_TYPE'} = {VALUE => $arg_ref->{TYPE}};
$dynamic->{'WORKFLOW.WORKFLOW_TYPE'} = {VALUE => $arg_ref->{TYPE}};
}
if (defined $arg_ref->{STATE}) {
if (! ref $arg_ref->{STATE}) {
Expand All @@ -804,7 +832,7 @@ sub search_workflow_instances {
}
}
}
$dynamic->{$workflow_table . '.WORKFLOW_STATE'} = {VALUE => $arg_ref->{STATE}};
$dynamic->{'WORKFLOW.WORKFLOW_STATE'} = {VALUE => $arg_ref->{STATE}};
}
my %limit;
if (defined $arg_ref->{LIMIT} && !defined $arg_ref->{START}) {
Expand All @@ -819,29 +847,24 @@ sub search_workflow_instances {

##! 16: 'dynamic: ' . Dumper $dynamic
##! 16: 'tables: ' . Dumper(\@tables)
my $result = $dbi->select(
TABLE => \@tables,
my %params = (
TABLE => \@tables,
COLUMNS => [
$workflow_table . '.WORKFLOW_LAST_UPDATE',
$workflow_table . '.WORKFLOW_SERIAL',
$workflow_table . '.WORKFLOW_TYPE',
$workflow_table . '.WORKFLOW_STATE',
$workflow_table . '.WORKFLOW_PROC_STATE',
$workflow_table . '.WORKFLOW_WAKEUP_AT'
],
JOIN => [
\@joins,
],
'WORKFLOW.WORKFLOW_LAST_UPDATE',
'WORKFLOW.WORKFLOW_SERIAL',
'WORKFLOW.WORKFLOW_TYPE',
'WORKFLOW.WORKFLOW_STATE',
'WORKFLOW.WORKFLOW_PROC_STATE',
'WORKFLOW.WORKFLOW_WAKEUP_AT'
],
JOIN => [ \@joins, ],
REVERSE => 1,
DYNAMIC => $dynamic,
DISTINCT => 1,
ORDER => [
$workflow_table . '.WORKFLOW_SERIAL',
],
ORDER => [ 'WORKFLOW.WORKFLOW_SERIAL' ],
%limit,
);
##! 16: 'result: ' . Dumper $result
return $result;
return \%params;
}

###########################################################################
Expand Down

0 comments on commit 28f3a7a

Please sign in to comment.