package tests::DlfQueryTest;
use strict;
use base qw/ tests::TestStoreFixture Lire::Test::TestCase /;
use Lire::DlfQuery;
use Lire::DlfSchema;
use Lire::ExtendedSchema;
sub new {
my $self = shift()->SUPER::new( @_ );
$self->init();
$self;
}
sub set_up {
my $self = $_[0];
$self->SUPER::set_up();
$self->set_up_test_schema();
$Lire::DlfSchema::SCHEMA_CACHE{'test-extended2'}
= new Lire::ExtendedSchema( 'id' => 'test-extended2',
'base-schema' => 'test-derived',
'module' => 'MyModule' );
$self->{'query'} = new Lire::DlfQuery( 'test' );
return;
}
sub tear_down {
my $self = $_[0];
$self->SUPER::tear_down();
delete $Lire::DlfSchema::SCHEMA_CACHE{'test-extended2'};
$self->tear_down_test_store()
if $self->{'store'};
$self->{'query'}->release();
return;
}
sub test_new {
my $self = $_[0];
my $query = $self->{'query'};
$self->assert_isa( 'Lire::DlfQuery', $query );
$self->assert_num_equals( 0, $query->{'_limit'} );
$self->assert_null( $query->{'_sort_spec'},
"'_sort_spec' attribute should be undef" );
$self->assert_null( $query->{'_order_by'},
"'_order_by' attribute should be undef" );
$self->assert_deep_equals( [], $query->{'_fields'} );
$self->assert_deep_equals( {}, $query->{'_field_refs'} );
$self->assert_deep_equals( [], $query->{'_filter_params'});
$self->assert_null( $query->{'_parent'},
"new query should have NULL parent" );
$self->assert_deep_equals( [], $query->{'_nested_queries'} );
$self->assert_null( $query->{'_filter_clause'},
"filter_clause attribute should be undef" );
$self->assert_str_equals( 'test', $query->{'_stream_name'} );
}
sub test_new_bad_params {
my $self = $_[0];
$self->assert_dies( qr/missing 'stream_name' parameter/,
sub { new Lire::DlfQuery() } );
$self->assert_dies( qr/there is no schema 'wawa'/,
sub { new Lire::DlfQuery( 'wawa' ) } );
}
sub test__schema_has_field {
my $self = $_[0];
$self->assert( $self->{'query'}->_schema_has_field( 'time_start' ) );
$self->assert( ! $self->{'query'}->_schema_has_field( 'dirname' ) );
$self->{'query'}{'_joined_streams'} = [ 'test-extended' ];
$self->assert( $self->{'query'}->_schema_has_field( 'dirname' ) );
}
sub test__field_by_name {
my $self = $_[0];
my $query = $self->{'query'};
$query->_add_field ('file', 'simple');
$self->assert_deep_equals ( { 'field' => 'file', 'type' => 'simple', 'alias' => undef },
$query->_field_by_name('file') );
$query->_add_field ('sum()', 'aggr', 'count');
$self->assert_deep_equals ( { 'field' => 'sum()', 'type' => 'aggr', 'alias' => 'count' },
$query->_field_by_name('count') );
}
sub test__add_field {
my $self = $_[0];
my $query = $self->{'query'};
$query->_add_field( 'time_start', 'simple' );
$self->assert( exists $query->{'_field_refs'}{'time_start'} );
$self->assert_deep_equals( [ { 'field' => 'time_start',
'alias' => undef,
'type' => 'simple' } ],
$query->{'_fields'} );
$query->_add_field( 'count()', 'aggr', 'nrecords' );
$self->assert( exists $query->{'_field_refs'}{'nrecords'} );
$self->assert_deep_equals( [ { 'field' => 'time_start',
'alias' => undef,
'type' => 'simple' },
{ 'field' => 'count()', 'alias' => 'nrecords',
'type' => 'aggr' } ],
$query->{'_fields'} );
}
sub test__add_field_bad_params {
my $self = $_[0];
my $query = $self->{'query'};
$self->assert_dies( qr/missing 'field' parameter/,
sub { $query->_add_field() } );
$self->assert_dies( qr/missing 'type' parameter/,
sub { $query->_add_field( 'a_field' ) } );
$self->assert_dies( qr/field name should contain only alphanumeric characters: 'a field'/,
sub { $query->_add_field( 'a field', 'simple' ) } );
$self->assert_dies( qr/field name should contain only alphanumeric characters: 'sum\(\)'/,
sub { $query->_add_field( 'sum()', 'aggr' ) } );
$self->assert_dies( qr/type should be 'simple', 'group', 'aggr': 'zoinzoin'/,
sub { $query->_add_field( 'wawa', 'zoinzoin' ) } );
$self->assert_dies( qr/no field 'wawa' in 'test' schema/,
sub { $query->_add_field( 'wawa', 'simple' ) } );
$self->assert_dies( qr/'nrecords' is already defined in the query/,
sub { $query->_add_field( 'sum()', 'aggr',
'nrecords' );
$query->_add_field( 'sum()', 'aggr',
'nrecords' ) } );
}
sub test__add_field_with_nested_query {
my $self = $_[0];
my $query = $self->{'query'};
my $nested1 = $query->create_nested_query();
my $nested2 = $query->create_nested_query();
my $nested3 = $nested1->create_nested_query();
$query->_add_field( 'lr_timegroup(time_start)', 'group', 'period' );
$self->assert_dies( qr/'period' is already defined in the query/,
sub { $nested1->_add_field( 'lr_timegroup(time_start)', 'group', 'period' ) } );
$self->assert_dies( qr/'period' is already defined in the query/,
sub { $nested2->_add_field( 'lr_timegroup(time_start)', 'group', 'period' ) } );
$self->assert_dies( qr/'period' is already defined in the query/,
sub { $nested3->_add_field( 'lr_timegroup(time_start)', 'group', 'period' ) } );
$nested1->_add_field( 'connection_id', 'simple' );
$self->assert_dies( qr/'connection_id' is already defined in the query/,
sub { $query->_add_field( 'connection_id', 'simple' ) } );
$nested2->_add_field( 'connection_id', 'simple' );
$nested3->_add_field( 'file', 'simple' );
$self->assert_dies( qr/'file' is already defined in the query/,
sub { $nested1->_add_field( 'file', 'simple' ) } );
}
sub test_add_field {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_field( 'time_start' );
$self->assert_deep_equals( { 'field' => 'time_start',
'alias' => undef,
'type' => 'simple' },
$query->_field_by_name( 'time_start' ) );
$query->add_field( 'file', 'file_size/1024' );
$self->assert_deep_equals( { 'field' => 'file_size/1024',
'alias' => 'file', 'type' => 'simple' },
$query->_field_by_name( 'file' ) );
}
sub test_add_field_after_add_group {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_group_field( 'connection_id' );
$self->assert_dies( qr/calls to add_field\(\) and add_group_field\(\) can't be mixed on the same Lire::DlfQuery/,
sub { $query->add_field( 'file' ) } );
}
sub test_add_field_with_create_nested_query {
my $self = $_[0];
my $query = $self->{'query'};
my $nested = $query->create_nested_query();
$self->assert_dies( qr/can't add simple field to a query containing nested queries/,
sub { $query->add_field( 'file' ) } );
$nested->add_field( 'file' );
$self->assert( defined $nested->_field_by_name( "file" ),
"field 'file' wasn't added" );
}
sub test_no_subqueries_on_simple_queries {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_field( 'file' );
$self->assert_dies( qr/can't create a nested query on query containing simple fields/,
sub { $query->create_nested_query() } );
}
sub test__fields_of_type {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_field( 'connection_id' );
$self->assert_deep_equals( [ { 'field' => 'connection_id',
'type' => 'simple',
'alias' => undef } ],
$query->_fields_of_type('simple') );
$self->assert_deep_equals( [],
$query->_fields_of_type('group+aggr') );
$self->assert_deep_equals( [ ],
$query->_fields_of_type('group') );
$self->assert_deep_equals( [ ],
$query->_fields_of_type('aggr') );
}
sub test__fields_of_type_group {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_group_field( 'connection_id' );
$self->assert_deep_equals( [ { 'field' => 'connection_id',
'type' => 'group',
'alias' => undef } ],
$query->_fields_of_type('group') );
}
sub test__fields_of_type_group_aggr {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_aggr_field( 'nrecords', 'count(*)' );
$query->add_group_field( 'connection_id' );
$self->assert_deep_equals( [ { 'field' => 'count(*)',
'type' => 'aggr',
'alias' => 'nrecords' },
{ 'field' => 'connection_id',
'type' => 'group',
'alias' => undef }, ],
$query->_fields_of_type('group+aggr') );
}
sub test__fields_of_type_bad_params {
my $self = $_[0];
my $query = $self->{'query'};
$self->assert_dies( qr/type should be 'simple', 'group', 'aggr' or 'group\+aggr': 'nosuchtype/,
sub { $query->_fields_of_type('nosuchtype') } );
}
sub test_add_group_field {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_group_field( 'connection_id' );
$self->assert_deep_equals( { 'field' => 'connection_id',
'alias' => undef,
'type' => 'group' },
$query->_field_by_name( 'connection_id' ) );
$query->add_group_field( 'period', 'lr_timegroup(time_start)' );
$self->assert_deep_equals( { 'field' => 'lr_timegroup(time_start)',
'alias' => 'period', 'type' => 'group' },
$query->_field_by_name( 'period' ) );
}
sub test_group_fields {
my $self = $_[0];
my $query = $self->{'query'};
$self->assert_deep_equals( [], $query->group_fields() );
$query->add_group_field( 'period', 'lr_timegroup(time_start)' );
my $nested = $query->create_nested_query();
$nested->add_group_field( 'connection_id' );
$nested->add_aggr_field( 'nrecords', 'count()' );
$self->assert_deep_equals( ['period' ],
$query->group_fields() );
$self->assert_deep_equals( ['period', 'connection_id' ],
$nested->group_fields() );
}
sub test_aggr_fields {
my $self = $_[0];
my $query = $self->{'query'};
$self->assert_deep_equals( [], $query->aggr_fields() );
$query->add_group_field( 'connection_id' );
$query->add_aggr_field( 'bytes', 'sum(file_size)' );
my $nested = $query->create_nested_query();
$nested->add_aggr_field( 'nrecords', 'count()' );
$self->assert_deep_equals( [ 'bytes', 'nrecords' ],
$query->aggr_fields() );
$self->assert_deep_equals( [ 'nrecords' ],
$nested->aggr_fields() );
}
sub test_fields {
my $self = $_[0];
my $query = $self->{'query'};
$self->assert_deep_equals( [], $query->fields() );
$query->add_field( 'connection_id' );
$query->add_field( 'k', 'file_size/1024' );
$self->assert_deep_equals( [ 'connection_id', 'k' ],
$query->fields() );
}
sub test_field_def {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_group_field( 'connection_id' );
my $nested1 = $self->{'query'}->create_nested_query();
$nested1->add_aggr_field( 'nrecords', 'count()' );
my $nested2 = $self->{'query'}->create_nested_query();
$nested2->add_field( 'user' );
$nested2->add_field( 'file' );
$self->assert_dies( qr/no field 'time_start' defined in the query/,
sub { $query->field_def( 'time_start' ) } );
$self->assert_str_equals( 'user', $query->field_def( 'user' ) );
$self->assert_str_equals( 'file', $query->field_def( 'file' ) );
$self->assert_str_equals( 'connection_id',
$query->field_def( 'connection_id' ) );
$self->assert_str_equals( 'count()',
$query->field_def( 'nrecords' ) );
$self->assert_dies( qr/no field 'file' defined in the query/,
sub { $nested1->field_def( 'file' ) } );
$self->assert_str_equals( 'connection_id',
$nested1->field_def( 'connection_id' ) );
$self->assert_str_equals( 'count()',
$nested1->field_def( 'nrecords' ) );
$self->assert_dies( qr/no field 'nrecords' defined in the query/,
sub { $nested2->field_def( 'nrecords' ) } );
$self->assert_str_equals( 'connection_id',
$nested2->field_def( 'connection_id' ) );
$self->assert_str_equals( 'user', $nested2->field_def( 'user' ) );
$self->assert_str_equals( 'file', $nested2->field_def( 'file' ) );
}
sub test__query_subtree_from_root {
my $self = $_[0];
my $query = $self->{'query'};
my $nested1 = $query->create_nested_query();
my $nested2 = $query->create_nested_query();
my $nested3 = $nested1->create_nested_query();
$self->assert_deep_equals( [ $query, $nested1, $nested3, $nested2 ],
$query->_query_subtree_from_root() );
$self->assert_deep_equals( [ $query, $nested1, $nested3 ],
$nested1->_query_subtree_from_root() );
$self->assert_deep_equals( [ $query, $nested2 ],
$nested2->_query_subtree_from_root() );
$self->assert_deep_equals( [ $query, $nested1, $nested3 ],
$nested3->_query_subtree_from_root() );
}
sub test_add_group_after_add_field {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_field( 'file' );
$self->assert_dies( qr/calls to add_field\(\) and add_group_field\(\) can't be mixed on the same Lire::DlfQuery/,
sub { $query->add_group_field( 'connection_id' ) } );
}
sub test_add_aggr_field {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_aggr_field( "requests", "count()" );
$self->assert_str_equals( 'aggr',
$query->_field_by_name( 'requests' )->{'type'} );
$self->assert_dies( qr/missing 'aggregate' parameter/,
sub { $query->add_aggr_field( "requests" ) } );
}
sub test_set_sort_spec {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_group_field( 'time_start' );
$query->add_group_field( 'connection_id' );
$query->add_group_field( 'transfer-complete' );
my $nested = $query->create_nested_query();
$nested->add_aggr_field( 'downloads', "count()" );
$query->set_sort_spec( '-time_start' );
$self->assert_str_equals( '-time_start', $query->{'_sort_spec'} );
$self->assert_str_equals( 'time_start DESC', $query->{'_order_by'} );
$query->set_sort_spec( undef );
$self->assert_null( $query->{'_sort_spec'},
"'_sort_spec' attribute should have been cleared" );
$self->assert_null( $query->{'_order_by'},
"'_order_by' attribute should have been cleared" );
$query->set_sort_spec( '' );
$self->assert_null( $query->{'_sort_spec'},
"'_sort_spec' attribute should still be cleared" );
$self->assert_null( $query->{'_order_by'},
"'_order_by' attribute should still be cleared" );
$query->set_sort_spec( 'connection_id -time_start' );
$self->assert_str_equals( 'connection_id -time_start',
$query->{'_sort_spec'} );
$self->assert_str_equals( 'connection_id, time_start DESC',
$query->{'_order_by'} );
$query->set_sort_spec( 'transfer-complete' );
$self->assert_str_equals( '"transfer-complete"', $query->{'_order_by'} );
$query->set_sort_spec( '-transfer-complete' );
$self->assert_str_equals( '"transfer-complete" DESC',
$query->{'_order_by'} );
$query->set_sort_spec( '-downloads' );
$self->assert_str_equals( 'downloads DESC', $query->{'_order_by'} );
$self->assert_dies( qr/field 'bad_field' unavailable for sorting/,
sub { $query->set_sort_spec( 'bad_field' ); } );
}
sub test__is_valid_sort_field {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_group_field( 'connection_id' );
my $nested1 = $query->create_nested_query();
$nested1->add_aggr_field( 'downloads', "count()" );
my $nested2 = $nested1->create_nested_query();
$nested2->add_field( 'user' );
$self->assert_num_equals( 0, $query->_is_valid_sort_field( 'bad_field' ) );
$self->assert_num_equals( 0, $query->_is_valid_sort_field( 'user' ) );
$self->assert_num_equals( 1,
$query->_is_valid_sort_field( 'connection_id'));
$self->assert_num_equals( 1, $query->_is_valid_sort_field( 'downloads'));
$self->assert_num_equals( 0,
$nested1->_is_valid_sort_field( 'bad_field' ) );
$self->assert_num_equals( 0, $nested1->_is_valid_sort_field( 'user' ) );
$self->assert_num_equals( 1,
$nested1->_is_valid_sort_field( 'connection_id'));
$self->assert_num_equals( 1, $nested1->_is_valid_sort_field( 'downloads'));
$self->assert_num_equals( 0, $nested2->_is_valid_sort_field( 'bad_field' ) );
$self->assert_num_equals( 0, $nested2->_is_valid_sort_field( 'downloads'));
$self->assert_num_equals( 1, $nested2->_is_valid_sort_field( 'user' ) );
$self->assert_num_equals( 1,
$nested2->_is_valid_sort_field( 'connection_id'));
}
sub test_set_sort_spec_and_set_order_by_clause_interaction {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_field( 'time_start');
$query->set_sort_spec( 'time_start' );
$query->set_order_by_clause( 'connection_id' );
$self->assert_null( $query->{'_sort_spec'},
"'_sort_spec' attribute should have been cleared" );
}
sub test_set_order_by_clause {
my $self = $_[0];
my $query = $self->{'query'};
$query->set_order_by_clause( 'time_start DESC' );
$self->assert_str_equals( 'time_start DESC', $query->{'_order_by'} );
$query->set_order_by_clause( undef );
$self->assert_null( $query->{'_order_by'},
"order_by attribute should have been cleared" );
$query->set_order_by_clause( '' );
$self->assert_null( $query->{'_order_by'},
"order_by attribute should still be cleared" );
}
sub test_set_limit {
my $self = $_[0];
my $query = $self->{'query'};
$query->set_limit( 50 );
$self->assert_num_equals( 50, $query->{'_limit'} );
$query->set_limit( undef );
$self->assert_num_equals( 0, $query->{'_limit'} );
$query->set_limit( 20 );
$query->set_limit( 0 );
$self->assert_num_equals( 0, $query->{'_limit'} );
$self->assert_dies( qr/'limit' parameter should be an integer: 'some text'/,
sub { $query->set_limit( 'some text' ) } );
}
sub test_set_filter_clause {
my $self = $_[0];
my $query = $self->{'query'};
$self->assert_dies( qr/invalid number of parameters: filter clause contains 0 placeholders while 1 values provided/,
sub { $query->set_filter_clause( undef, '' ); } );
$self->assert_dies( qr/invalid number of parameters: filter clause contains 1 placeholders while 0 values provided/,
sub { $query->set_filter_clause( 'time_start > ?' ); } );
$self->assert_dies( qr/invalid number of parameters: filter clause contains 1 placeholders while 2 values provided/,
sub { $query->set_filter_clause( 'time_start > ?', 1, 2 ); } );
$query->set_filter_clause( 'time_start = 0' );
$self->assert_str_equals( 'time_start = 0', $query->{'_filter_clause'} );
$self->assert_deep_equals( [], $query->{'_filter_params'});
$query->set_filter_clause( 'time_start > ?', 0 );
$self->assert_str_equals( 'time_start > ?', $query->{'_filter_clause'} );
$self->assert_deep_equals( [ 0 ], $query->{'_filter_params'});
$query->set_filter_clause( undef );
$self->assert_null( $query->{'_filter_clause'},
"filter_clause attribute should have been cleared" );
$self->assert_deep_equals( [], $query->{'_filter_params'});
$query->set_filter_clause( '' );
$self->assert_null( $query->{'_filter_clause'},
"filter_clause attribute should still be cleared" );
$self->assert_deep_equals( [], $query->{'_filter_params'});
}
sub test_sql_params {
my $self = $_[0];
my $query = $self->{'query'};
$query->set_filter_clause( 'time_start = 0' );
$self->assert_deep_equals( [], $query->sql_params() );
$query->set_filter_clause( 'time_start = ?', '12345678' );
$self->assert_deep_equals( [ '12345678' ], $query->sql_params() );
my $nested = $query->create_nested_query();
$nested->set_filter_clause( 'user IN ?', "( 'wdankers', 'flacoste' )" );
$self->assert_deep_equals( [ '12345678', "( 'wdankers', 'flacoste' )"],
$nested->sql_params() );
my $nested2 = $nested->create_nested_query();
$nested2->set_filter_clause( 'file LIKE ? ', "%.mpg" );
$self->assert_deep_equals( [ '12345678', "( 'wdankers', 'flacoste' )",
'%.mpg' ],
$nested2->sql_params() );
}
sub test_join_stream {
my $self = $_[0];
$self->assert_deep_equals( [], $self->{'query'}{'_joined_streams'} );
$self->assert_dies( qr/there is no schema: 'bad_schema'/,
sub { $self->{'query'}->join_stream( 'bad_schema' ) } );
$self->assert_dies( qr/cannot join 'test-derived' with 'test'/,
sub { $self->{'query'}->join_stream( 'test-derived') } );
my $nested = $self->{'query'}->create_nested_query();
$self->assert_dies( qr/can only join streams on root query/,
sub { $nested->join_stream( 'test-extended' ) } );
$self->{'query'}->join_stream( 'test-extended' );
$self->assert_deep_equals( [ 'test-extended' ],
$self->{'query'}{'_joined_streams'} );
$self->assert_deep_equals( [ 'test', 'test-extended' ],
$self->{'query'}->joined_streams() );
$self->assert_dies( qr/'test-extended' is already joined/,
sub { $self->{'query'}->join_stream( 'test-extended' )});
my $query = new Lire::DlfQuery( 'test-extended' );
$self->assert_dies( qr/'test-extended' is already joined/,
sub { $query->join_stream( 'test-extended' )});
}
sub test_execute {
my $self = $_[0];
$self->set_up_test_store();
my $query = $self->{'query'};
$query->add_field( 'user' );
$query->add_field( 'file' );
$self->assert_dies( qr/missing 'store' parameter/,
sub { $query->execute () } );
my $result = $query->execute( $self->{'store'} );
$self->assert_isa( 'Lire::DlfResult', $result );
}
sub test_execute_summary {
my $self = $_[0];
$self->set_up_test_store();
my $query = $self->{'query'};
$query->add_group_field( 'user' );
$query->add_aggr_field( 'downloads', 'count()' );
$self->assert_dies( qr/missing 'store' parameter/,
sub { $query->execute_summary () } );
my $result = $query->execute_summary( $self->{'store'} );
$self->assert_isa( 'Lire::DlfResult', $result );
my $summary = $result->next_row();
$self->assert( ! $result->next_row(),
"only one row should be returned by summary on top-level query" );
}
sub test_execute_no_stream {
my $self = $_[0];
$self->set_up_test_store();
my $query = new Lire::DlfQuery( 'test' );
$query->{'_joined_streams'} = [ 'test-extended' ];
$self->assert_dies( qr/store doesn't contain a 'test-extended' stream/,
sub { $query->execute_summary( $self->{'store'} ) } );
$self->assert_dies( qr/store doesn't contain a 'test-extended' stream/,
sub { $query->execute( $self->{'store'} ) } );
}
sub test__sql_select_clause_quoting {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_group_field( "connection_id" );
$query->add_group_field( "transfer-complete" );
$query->add_group_field( "total-requests", "count()" );
$query->add_group_field( "period", "lr_timegroup(time_start)" );
$self->assert_str_equals( <<ESQL, $query->_sql_select_clause() . "\n");
SELECT connection_id,
"transfer-complete",
count() AS "total-requests",
lr_timegroup(time_start) AS period
ESQL
}
sub test__sql_from_clause {
my $self = $_[0];
my $query = $self->{'query'};
$self->assert_str_equals( "FROM dlf_test", $query->_sql_from_clause() );
$query->{'_stream_name'} = "test-extended";
$self->assert_str_equals( 'FROM dlf_test, "dlf_test-extended"',
$query->_sql_from_clause() );
$query->{'_stream_name'} = 'test';
$query->{'_joined_streams'} = [ "test-extended" ];
$self->assert_str_equals( 'FROM dlf_test, "dlf_test-extended"',
$query->_sql_from_clause() );
$query->{'_stream_name'} = 'test-derived';
$query->{'_joined_streams'} = [ "test-extended" ];
$self->assert_str_equals( 'FROM "dlf_test-derived", "dlf_test-derived_links", "dlf_test-extended"',
$query->_sql_from_clause() );
$query->{'_joined_streams'} = [ "test" ];
$self->assert_str_equals( 'FROM "dlf_test-derived", "dlf_test-derived_links", dlf_test',
$query->_sql_from_clause() );
$query->{'_joined_streams'} = [];
$self->assert_str_equals( 'FROM "dlf_test-derived"',
$query->_sql_from_clause() );
$query->{'_joined_streams'} = [ 'test-extended2' ];
$self->assert_str_equals( 'FROM "dlf_test-derived", "dlf_test-extended2"',
$query->_sql_from_clause() );
}
sub test__sql_group_by_clause_quoting {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_group_field( "connection_id" );
$query->add_group_field( "transfer-complete" );
$query->add_group_field( "total-requests", "count()" );
$query->add_group_field( "period", "lr_timegroup(time_start)" );
$self->assert_str_equals( q{GROUP BY connection_id, "transfer-complete", "total-requests", period},
$query->_sql_group_by_clause() );
}
sub test__as_sql {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_group_field( 'period', 'lr_timegroup(time_start)' );
$query->add_group_field( 'client_host' );
$query->add_aggr_field( 'requests', 'count()' );
$query->add_aggr_field( 'bytes', 'sum(file_size)' );
$query->set_order_by_clause( "period, bytes DESC" );
$query->set_filter_clause( "file = ?", "index.html" );
$query->set_limit( 5 );
$self->assert_str_equals ( <<SQLS, $query->_as_sql() );
SELECT lr_timegroup(time_start) AS period,
client_host,
count() AS requests,
sum(file_size) AS bytes
FROM dlf_test
WHERE file = ?
GROUP BY period, client_host
ORDER BY period, bytes DESC
LIMIT 5
SQLS
}
sub test__sql_select_fields {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_group_field( 'file' );
my $nquery1 = $query->create_nested_query();
$nquery1->add_group_field( 'connection_id' );
$nquery1->add_aggr_field( 'bytes', 'sum(file_size)' );
my $nquery2 = $query->create_nested_query();
$nquery2->add_aggr_field( 'requests', 'count(*)' );
$nquery2->add_field( 'connection_id' );
$self->assert_deep_equals( [ { 'field' => 'file',
'type' => 'group',
'alias' => undef },
{ 'field' => 'sum(file_size)',
'type' => 'aggr',
'alias' => 'bytes' },
{ 'field' => 'count(*)',
'type' => 'aggr',
'alias' => 'requests' }, ],
$query->_sql_select_fields() );
$self->assert_deep_equals( [ { 'field' => 'sum(file_size)',
'type' => 'aggr',
'alias' => 'bytes' },
{ 'field' => 'count(*)',
'type' => 'aggr',
'alias' => 'requests' }, ],
$query->_sql_select_fields( 1 ) );
$self->assert_deep_equals( [ { 'field' => 'connection_id',
'type' => 'simple',
'alias' => undef }, ],
$nquery2->_sql_select_fields() );
$self->assert_deep_equals( [ { 'field' => 'count(*)',
'type' => 'aggr',
'alias' => 'requests' }, ],
$nquery2->_sql_select_fields(1) );
}
sub test__sql_where_clause {
my $self = $_[0];
my $query = $self->{'query'};
$self->assert_null( $query->_sql_where_clause() );
$query->{'_filter_clause'} = 'time_stamp = ?';
$self->assert_str_equals( 'WHERE time_stamp = ?',
$query->_sql_where_clause() );
my $sub = $query->create_nested_query();
$self->assert_str_equals( 'WHERE time_stamp = ?',
$sub->_sql_where_clause() );
$sub->{'_filter_clause'} = 'connection_id LIKE ?';
$self->assert_str_equals( 'WHERE time_stamp = ?',
$query->_sql_where_clause() );
$self->assert_str_equals( 'WHERE time_stamp = ? AND connection_id LIKE ?',
$sub->_sql_where_clause() );
$query->{'_stream_name'} = 'test-extended';
$self->assert_str_equals( 'WHERE dlf_test.dlf_id = "dlf_test-extended".dlf_id AND time_stamp = ?',
$query->_sql_where_clause() );
}
sub test__sql_where_join_elements {
my $self = $_[0];
my $query = $self->{'query'};
$self->assert_deep_equals( [], $query->_sql_where_join_elements() );
$query->{'_stream_name'} = 'test-extended';
$self->assert_deep_equals( [ 'dlf_test.dlf_id = "dlf_test-extended".dlf_id' ],
$query->_sql_where_join_elements() );
$query->{'_stream_name'} = 'test';
$query->{'_joined_streams'} = [ 'test-extended' ];
$self->assert_deep_equals( [ 'dlf_test.dlf_id = "dlf_test-extended".dlf_id' ],
$query->_sql_where_join_elements() );
$query->{'_stream_name'} = 'test-derived';
$query->{'_joined_streams'} = [ 'test', 'test-extended', 'test-extended2' ];
$self->assert_deep_equals( [ '"dlf_test-derived".dlf_id = "dlf_test-derived_links".src_id',
'"dlf_test-derived_links".link_id = dlf_test.dlf_id',
'"dlf_test-derived_links".link_id = "dlf_test-extended".dlf_id',
'"dlf_test-derived".dlf_id = "dlf_test-extended2".dlf_id' ],
$query->_sql_where_join_elements() );
$query->{'_joined_streams'} = [ 'test-extended2' ];
$self->assert_deep_equals( [ '"dlf_test-derived".dlf_id = "dlf_test-extended2".dlf_id' ],
$query->_sql_where_join_elements() );
}
sub test__as_sql_with_nested_query {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_group_field( 'period', 'lr_timegroup(time_start)' );
$query->add_aggr_field( 'nrecords', 'count()' );
$query->set_filter_clause( 'time_start > ?', "123456789" );
$query->set_order_by_clause( "period" );
my $nquery1 = $query->create_nested_query();
$nquery1->add_group_field( 'connection_id' );
$nquery1->add_aggr_field( 'bytes', 'sum(file_size)' );
$nquery1->set_order_by_clause( "bytes DESC" );
my $nquery2 = $query->create_nested_query();
$nquery2->add_group_field( "file" );
$nquery2->add_aggr_field( "downloads", "count()" );
$nquery2->set_filter_clause( 'file = ?', "index.html" );
$self->assert_str_equals( <<SQLS, $query->_as_sql() );
SELECT lr_timegroup(time_start) AS period,
count() AS nrecords,
sum(file_size) AS bytes,
count() AS downloads
FROM dlf_test
WHERE time_start > ?
GROUP BY period
ORDER BY period
SQLS
$self->assert_str_equals( <<SQLS, $nquery1->_as_sql() );
SELECT lr_timegroup(time_start) AS period,
connection_id,
sum(file_size) AS bytes
FROM dlf_test
WHERE time_start > ?
GROUP BY period, connection_id
ORDER BY period, bytes DESC
SQLS
$self->assert_str_equals( <<SQLS, $nquery2->_as_sql() );
SELECT lr_timegroup(time_start) AS period,
file,
count() AS downloads
FROM dlf_test
WHERE time_start > ? AND file = ?
GROUP BY period, file
ORDER BY period
SQLS
}
sub test__as_sql_select_only {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_field( 'requests', 'count()' );
$query->add_field( 'bytes', 'sum(file_size)' );
$self->assert_str_equals ( <<SQLS, $query->_as_sql() );
SELECT count() AS requests,
sum(file_size) AS bytes
FROM dlf_test
SQLS
}
sub test__as_summary_sql {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_group_field( 'period', 'lr_timegroup(time_start)' );
$query->add_group_field( 'client_host' );
$query->add_aggr_field( 'requests', 'count()' );
$query->add_aggr_field( 'bytes', 'sum(file_size)' );
$query->set_order_by_clause( "period, bytes DESC" );
$query->set_filter_clause( "file = ?", "index.html" );
$query->set_limit( 5 );
$self->assert_str_equals ( <<SQLS, $query->_as_summary_sql() );
SELECT count() AS requests,
sum(file_size) AS bytes
FROM dlf_test
WHERE file = ?
SQLS
}
sub test__as_summary_sql_nested_query {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_group_field( 'period', 'lr_timegroup(time_start)' );
$query->add_aggr_field( 'nrecords', 'count()' );
$query->set_filter_clause( 'time_start > ?', 123456789 );
$query->set_order_by_clause( "period" );
my $nquery1 = $query->create_nested_query();
$nquery1->add_group_field( 'connection_id' );
$nquery1->add_aggr_field( 'bytes', 'sum(file_size)' );
$nquery1->set_order_by_clause( "bytes DESC" );
my $nquery2 = $query->create_nested_query();
$nquery2->add_group_field( "file" );
$nquery2->add_aggr_field( "downloads", "count()" );
$nquery2->set_filter_clause( 'file = ?', "index.html" );
$self->assert_str_equals( <<SQLS, $query->_as_summary_sql() );
SELECT count() AS nrecords,
sum(file_size) AS bytes,
count() AS downloads
FROM dlf_test
WHERE time_start > ?
SQLS
$self->assert_str_equals( <<SQLS, $nquery1->_as_summary_sql() );
SELECT lr_timegroup(time_start) AS period,
sum(file_size) AS bytes
FROM dlf_test
WHERE time_start > ?
GROUP BY period
ORDER BY period
SQLS
$self->assert_str_equals( <<SQLS, $nquery2->_as_summary_sql() );
SELECT lr_timegroup(time_start) AS period,
count() AS downloads
FROM dlf_test
WHERE time_start > ? AND file = ?
GROUP BY period
ORDER BY period
SQLS
}
sub test__as_summary_sql_no_where {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_group_field( 'period', 'lr_timegroup(time_start)' );
$query->add_group_field( 'client_host' );
$query->add_aggr_field( 'requests', 'count()' );
$query->add_aggr_field( 'bytes', 'sum(file_size)' );
$query->set_order_by_clause( "period, bytes DESC" );
$query->set_limit( 5 );
$self->assert_str_equals ( <<SQLS, $query->_as_summary_sql() );
SELECT count() AS requests,
sum(file_size) AS bytes
FROM dlf_test
SQLS
}
sub test__as_sql_simple_field_nested_query {
my $self = $_[0];
my $query = $self->{'query'};
$query->add_group_field( 'period', 'lr_timegroup(time_start)' );
$query->set_order_by_clause( 'period' );
my $nquery = $query->create_nested_query();
$nquery->add_field( 'time_start' );
$nquery->add_field( 'user' );
$nquery->add_field( 'file' );
$nquery->add_field( 'time_taken' );
$self->assert_str_equals ( <<SQLS, $nquery->_as_sql() );
SELECT lr_timegroup(time_start) AS period,
time_start,
user,
file,
time_taken
FROM dlf_test
ORDER BY period
SQLS
}
sub test_create_nested_query {
my $self = $_[0];
my $query = $self->{'query'};
$self->assert_null( $query->{'_parent'},
"new query should have NULL parent" );
$self->assert_deep_equals( [], $query->{'_nested_queries'} );
my $nested = $self->{'query'}->create_nested_query();
$self->assert_isa( 'Lire::DlfQuery', $nested );
$self->assert_str_equals( $query->{'_stream_name'},
$nested->{'_stream_name'} );
$self->assert_str_equals( $query, $nested->{'_parent'} );
$self->assert_deep_equals( [ $nested ], $query->{'_nested_queries'} );
}
sub test_release {
my $self = $_[0];
my $query = $self->{'query'};
my $nested = $query->create_nested_query();
$query->release();
$self->assert_null( $nested->{'_parent'},
"_parent attribute of nested queries should be undef" );
}
sub test__root_query {
my $self = $_[0];
$self->assert_str_equals( $self->{'query'},
$self->{'query'}->_root_query() );
my $nested = $self->{'query'}->create_nested_query();
$self->assert_str_equals( $self->{'query'}, $nested->_root_query() );
my $nested2 = $nested->create_nested_query();
$self->assert_str_equals( $self->{'query'}, $nested2->_root_query() );
}
sub test__sql_order_by_clause {
my $self = $_[0];
my $query = $self->{'query'};
my $clause = $query->_sql_order_by_clause();
$self->assert_null( $clause, '_sql_order_by_clause() should be undef' );
$query->{'_order_by'} = 'connection_id, user';
$self->assert_str_equals( 'ORDER BY connection_id, user',
$query->_sql_order_by_clause() );
my $squery = $query->create_nested_query();
$self->assert_str_equals( 'ORDER BY connection_id, user',
$squery->_sql_order_by_clause() );
$squery->{'_order_by'} = 'file DESC';
$self->assert_str_equals( 'ORDER BY connection_id, user, file DESC',
$squery->_sql_order_by_clause() );
$query->{'_order_by'} = undef;
$self->assert_str_equals( 'ORDER BY file DESC',
$squery->_sql_order_by_clause() );
}
1;
syntax highlighted by Code2HTML, v. 0.9.1