Algorithm-Dependency-Source-DBI

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

    Algorithm::Dependency

SYNOPSIS
      use DBI;
      use Algorithm::Dependency;
      use Algorithm::Dependency::Source::DBI;
      
  # Load the data from a database
      my $data_source = Algorithm::Dependency::Source::DBI->new(
          dbh            => DBI->connect('dbi:SQLite:sqlite.db'),
          select_ids     => 'select name from stuff',
          select_depends => 'select from, to from m2m_deps',
      );
      
  # Create the dependency object, and indicate the items that are already
      # selected/installed/etc in the database
      my $dep = Algorithm::Dependency->new(
          source   => $data_source,
          selected => [ 'This', 'That' ]
      ) or die 'Failed to set up dependency algorithm';
      
  # For the item 'Foo', find out the other things we also have to select.
      # This WON'T include the item we selected, 'Foo'.
      my $also = $dep->depends( 'Foo' );
      print $also
            ? "By selecting 'Foo', you are also selecting the following items: "
                    . join( ', ', @$also )
            : "Nothing else to select for 'Foo'";
      
  # Find out the order we need to act on the items in.
      # This WILL include the item we selected, 'Foo'.
      my $schedule = $dep->schedule( 'Foo' );

DESCRIPTION
    The Algorithm::Dependency module has shown itself to be quite reliable
    over a long period of time, as well as relatively easy to setup and use.

    However, recently there has been an increasing use of things like
    DBD::SQLite to store and distribute structured data.

    Algorithm::Dependency::Source::DBI extends Algorithm::Dependency by
    providing a simple way to create dependency objects that pull their data
    from a database directly.

METHODS
  new
      my $simple = Algorithm::Dependency::Source::DBI->new(
          dbh            => $dbi_db_handle,
          select_ids     => 'select name from stuff',
          select_depends => 'select from, to from m2m_deps',
      );
      
  my $complex = Algorithm::Dependency::Source::DBI->new(
          dbh            => $dbi_db_handle,
          select_ids     => [ 'select name from stuff where foo = ?',         'bar' ],
          select_depends => [ 'select from, to from m2m_deps where from = ?', 'bar' ],
      );

    The "new" constructor takes three named named params.

    The "dbh" param should be a standard DBI database connection.

    The "select_ids" param is either a complete SQL string, or a reference
    to an "ARRAY" containing a SQL string with placeholders and matching
    variables.

    When executed on the database, it should return a single column
    containing the complete set of all item identifiers.

    The "select_depends" param is either a complete SQL string, or a
    reference to an "ARRAY" containing a SQL string with placeholders and
    matching variables.

    When executed on the database, it should return two columns containing
    the complete set of all dependencies, where identifiers in the
    first-column depends on identifiers in the second-column.

    Returns a new Algorithm::Dependency::Source::DBI object, or dies on
    error.

  dbh
    The "dbh" accessor returns the database handle provided to the
    constructor.

  select_ids
    The "select_ids" accessor returns the SQL statement provided to the
    constructor. If a raw string was provided, it will be returned as a
    reference to an "ARRAY" containing the SQL string and no params.

  select_depends
    The "select_depends" accessor returns the SQL statement provided to the
    constructor. If a raw string was provided, it will be returned as a
    reference to an "ARRAY" containing the SQL string and no params.

SUPPORT
    To file a bug against this module, use the CPAN bug tracking system

    <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Algorithm-Dependency-Sou
    rce-DBI>

    For other comments, contact the author.

lib/Algorithm/Dependency/Source/DBI.pm  view on Meta::CPAN


=head1 SYNOPSIS

  use DBI;
  use Algorithm::Dependency;
  use Algorithm::Dependency::Source::DBI;
  
  # Load the data from a database
  my $data_source = Algorithm::Dependency::Source::DBI->new(
      dbh            => DBI->connect('dbi:SQLite:sqlite.db'),
      select_ids     => 'select name from stuff',
      select_depends => 'select from, to from m2m_deps',
  );
  
  # Create the dependency object, and indicate the items that are already
  # selected/installed/etc in the database
  my $dep = Algorithm::Dependency->new(
      source   => $data_source,
      selected => [ 'This', 'That' ]
  ) or die 'Failed to set up dependency algorithm';
  
  # For the item 'Foo', find out the other things we also have to select.
  # This WON'T include the item we selected, 'Foo'.
  my $also = $dep->depends( 'Foo' );
  print $also
  	? "By selecting 'Foo', you are also selecting the following items: "
  		. join( ', ', @$also )
  	: "Nothing else to select for 'Foo'";
  
  # Find out the order we need to act on the items in.
  # This WILL include the item we selected, 'Foo'.
  my $schedule = $dep->schedule( 'Foo' );

=head1 DESCRIPTION

The L<Algorithm::Dependency> module has shown itself to be quite reliable
over a long period of time, as well as relatively easy to setup and use.

However, recently there has been an increasing use of things like
L<DBD::SQLite> to store and distribute structured data.

lib/Algorithm/Dependency/Source/DBI.pm  view on Meta::CPAN


#####################################################################
# Constructor and Accessors

=pod

=head2 new

  my $simple = Algorithm::Dependency::Source::DBI->new(
      dbh            => $dbi_db_handle,
      select_ids     => 'select name from stuff',
      select_depends => 'select from, to from m2m_deps',
  );
  
  my $complex = Algorithm::Dependency::Source::DBI->new(
      dbh            => $dbi_db_handle,
      select_ids     => [ 'select name from stuff where foo = ?',         'bar' ],
      select_depends => [ 'select from, to from m2m_deps where from = ?', 'bar' ],
  );

The C<new> constructor takes three named named params.

The C<dbh> param should be a standard L<DBI> database connection.

The C<select_ids> param is either a complete SQL string, or a reference to
an C<ARRAY> containing a SQL string with placeholders and matching
variables.

When executed on the database, it should return a single column containing
the complete set of all item identifiers.

The C<select_depends> param is either a complete SQL string, or a reference
to an C<ARRAY> containing a SQL string with placeholders and matching
variables.

When executed on the database, it should return two columns containing
the complete set of all dependencies, where identifiers in the first-column
depends on identifiers in the second-column.

Returns a new L<Algorithm::Dependency::Source::DBI> object, or dies on
error.

=cut

sub new {
	my $class = shift;

	# Create the object
	my $self = bless { @_ }, $class;

	# Apply defaults
	if ( _STRING($self->{select_ids}) ) {
		$self->{select_ids} = [ $self->{select_ids} ];
	}
	if ( _STRING($self->{select_depends}) ) {
		$self->{select_depends} = [ $self->{select_depends} ];
	}

	# Check params
	unless ( _INSTANCE($self->dbh, 'DBI::db') ) {
		Carp::croak("The dbh param is not a DBI database handle");
	}
	unless ( _ARRAY($self->select_ids) and _STRING($self->select_ids->[0]) ) {
		Carp::croak("Missing or invalid select_ids param");
	}
	unless ( _ARRAY($self->select_depends) and _STRING($self->select_depends->[0]) ) {
		Carp::croak("Did not provide the select_depends query");
	}

	return $self;
}

=pod

=head2 dbh

The C<dbh> accessor returns the database handle provided to the constructor.

=cut

sub dbh {
	$_[0]->{dbh};
}

=pod

=head2 select_ids

The C<select_ids> accessor returns the SQL statement provided to the
constructor. If a raw string was provided, it will be returned as a
reference to an C<ARRAY> containing the SQL string and no params.

=cut

sub select_ids {
	$_[0]->{select_ids};
}

=pod

=head2 select_depends

The C<select_depends> accessor returns the SQL statement provided to
the constructor. If a raw string was provided, it will be returned as
a reference to an C<ARRAY> containing the SQL string and no params.

=cut

sub select_depends {
	$_[0]->{select_depends};
}





#####################################################################
# Main Functionality

sub _load_item_list {
	my $self = shift;

	# Get the list of ids
	my $ids  = $self->dbh->selectcol_arrayref(
		$self->select_ids->[0],
		{}, # No options
		@{$self->select_ids}[1..-1],
		);
	my %hash = map { $_ => [ ] } @$ids;

	# Get the list of links
	my $depends = $self->dbh->selectall_arrayref(
		$self->select_depends->[0],
		{}, # No options
		@{$self->select_depends}[1..-1],
		);
	foreach my $depend ( @$depends ) {
		next unless $hash{$depend->[0]};
		next unless $hash{$depend->[1]};
		push @{$hash{$depend->[0]}}, $depend->[1];
	}

	# Now convert to items
	my @items = map {
		Algorithm::Dependency::Item->new( $_, @{$hash{$_}} )

t/02_selftest.t  view on Meta::CPAN


SCOPE: {
	my $db = empty_db();
	isa_ok( $db, 'DBI::db' );
}

SCOPE: {
	my $db = create_db( $sql_file, $csv_file );
	isa_ok( $db, 'DBI::db' );

	my $data = $db->selectall_arrayref( 'select * from one order by foo' );
	is_deeply( $data, [
		[ 1, 'Hello, World!' ],
		[ 2, 'secondrow'     ],
	], 'Data in table one matches expected' );

	my $rv = $db->selectrow_arrayref( 'select count(*) from two' );
	is_deeply( $rv, [ 0 ], 'Nothing in table two' );
}

t/03_simple.t  view on Meta::CPAN





#####################################################################
# Main Tests

my $dbh = create_db(@create);
isa_ok( $dbh, 'DBI::db' );

my $select_ids     = "select id from one order by id";
my $select_depends = "select foo, bar from links";

# Create the source
my $source = Algorithm::Dependency::Source::DBI->new(
	dbh            => $dbh,
	select_ids     => $select_ids,
	select_depends => $select_depends,
);
isa_ok( $source, 'Algorithm::Dependency::Source' );
isa_ok( $source, 'Algorithm::Dependency::Source::DBI' );
isa_ok( $source->dbh, 'DBI::db' );
is_deeply( $source->select_ids,     [ $select_ids     ], '->select_ids ok'     );
is_deeply( $source->select_depends, [ $select_depends ], '->select_depends ok' );

ok( $source->load, '->load ok' );



( run in 1.181 second using v1.01-cache-2.11-cpan-49f99fa48dc )