package App::RemoteDownload::Queue; use strict; use DBI; use vars qw'$VERSION'; $VERSION = '0.01'; sub dbh { $_[0]->{dbh} }; sub new { my ($class,%args) = @_; $args{dsn} ||= 'DBI:SQLite:dbname=remotedownload.sqlite'; $args{dbh} ||= DBI->connect( delete $args{dsn}, undef,undef, {RaiseError => 1, PrintError => 0, AutoCommit => 1} ); my $self = bless \%args, $class; if (delete $args{create}) { eval { $self->create; }; }; $self; }; sub create { my ($self) = @_; my $res = $self->dbh->do(<<""); CREATE TABLE queue ( job_id VARCHAR(32) PRIMARY KEY UNIQUE NOT NULL, owner VARCHAR(256), pid INTEGER, url VARCHAR(4096) NOT NULL, destination VARCHAR(1024) NOT NULL, status VARCHAR(16), position INTEGER, size INTEGER ); }; sub get_pending_job { my ($self,$count) = @_; $count ||= 1; my $sth_lock = $self->dbh->prepare(<<""); UPDATE queue SET pid = ? WHERE job_id IN ( SELECT job_id FROM queue WHERE pid IS NULL AND status IS NULL LIMIT $count ) if ($sth_lock->execute($$) > 0) { $sth_lock->finish; my $sth_items = $self->dbh->prepare(<<""); SELECT job_id FROM queue WHERE pid = ? AND status IS NULL if (! $sth_items->execute($$)) { die "DB error. Couldn't find locked jobs for '$$'."; }; my $jobs = $sth_items->fetchall_arrayref; return map { @$_ } @$jobs; } else { $sth_lock->finish; return () }; }; sub running_jobs { my ($self) = @_; my $running_jobs = $self->dbh->selectall_arrayref(<<""); SELECT count(*) FROM queue WHERE pid IS NOT NULL AND pid <> 0 $running_jobs->[0]->[0] }; sub pending_jobs { my ($self) = @_; my $running_jobs = $self->dbh->selectall_arrayref(<<""); SELECT count(*) FROM queue WHERE pid IS NULL AND status IS NULL $running_jobs->[0]->[0] }; 1;