App-Koyomi
view release on metacpan or search on metacpan
lib/App/Koyomi/DataSource/Job/Teng.pm view on Meta::CPAN
args(
my $self,
my $ctx => 'App::Koyomi::Context',
);
my @jobs = $self->teng->search('jobs' => +{})->all;
my @times = $self->teng->search('job_times' => +{})->all;
my @data;
for my $job (@jobs) {
my @_t = grep { $_->job_id == $job->id } @times;
my $d = App::Koyomi::DataSource::Job::Teng::Data->new(
ctx => $ctx,
job => $job,
times => \@_t,
);
push(@data, $d);
}
return @data;
}
sub get_by_id {
args(
my $self,
my $id => 'Int',
my $ctx => 'App::Koyomi::Context',
);
my $job = $self->teng->single('jobs' => +{ id => $id });
return unless $job;
my @times = $self->teng->search('job_times' => +{ job_id => $id })->all;
unless (@times) {
warnf(q/Job id=%d has no times records./, $id);
}
return App::Koyomi::DataSource::Job::Teng::Data->new(
ctx => $ctx,
job => $job,
times => \@times,
);
}
sub create {
args(
my $self,
my $data => 'HashRef',
my $ctx => 'App::Koyomi::Context',
my $now => +{ isa => 'DateTime', optional => 1 },
);
$now ||= $ctx->now;
my $teng = $self->teng;
# Transaction
my $txn = $teng->txn_scope;
my $now_db = DateTime::Format::MySQL->format_datetime($now);
eval {
# create jobs
my %job = map { $_ => $data->{$_} } qw/user command memo/;
$job{created_on} = $job{updated_at} = $now_db;
my $new_job = $teng->insert('jobs', \%job);
unless ($new_job) {
croakf(q/Insert jobs Failed! data=%s/, ddf(\%job));
}
# create job_times
for my $t (@{$data->{times}}) {
my %time = (
job_id => $new_job->id,
%$t,
created_on => $now_db,
updated_at => $now_db,
);
$teng->insert('job_times', \%time)
or croakf(q/Insert job_times Failed! data=%s/, ddf(\%time));
}
# Initialize semaphore
$ctx->datasource_semaphore->create(
job_id => $new_job->id, ctx => $ctx, now => $now);
};
if ($@) {
$txn->rollback;
die $@;
}
$txn->commit;
return 1;
}
sub update_by_id {
args(
my $self,
my $id => 'Int',
my $data => 'HashRef',
my $ctx => 'App::Koyomi::Context',
my $now => +{ isa => 'DateTime', optional => 1 },
);
$now ||= $ctx->now;
my $teng = $self->teng;
# Transaction
my $txn = $teng->txn_scope;
my $now_db = DateTime::Format::MySQL->format_datetime($now);
eval {
# update jobs
my %job = map { $_ => $data->{$_} } qw/user command memo/;
$job{updated_at} = $now_db;
unless ($teng->update('jobs', \%job, +{ id => $id })) {
croakf(q/Update jobs Failed! id=%d, data=%s/, $id, ddf(\%job));
}
# replace job_times
unless ($teng->delete('job_times', +{ job_id => $id })) {
croakf(q/Delete job_times Failed! id=%d/, $id);
}
for my $t (@{$data->{times}}) {
my %time = (
job_id => $id,
%$t,
created_on => $now_db,
updated_at => $now_db,
);
$teng->insert('job_times', \%time)
or croakf(q/Insert job_times Failed! data=%s/, ddf(\%time));
}
};
if ($@) {
$txn->rollback;
die $@;
}
$txn->commit;
return 1;
}
sub delete_by_id {
args(
my $self,
my $id => 'Int',
my $ctx => 'App::Koyomi::Context',
);
my $teng = $self->teng;
# Transaction
my $txn = $teng->txn_scope;
eval {
unless ($teng->delete('jobs', +{ id => $id })) {
croakf(q/Delete jobs Failed! id=%d/, $id);
}
unless ($teng->delete('job_times', +{ job_id => $id })) {
croakf(q/Delete job_times Failed! id=%d/, $id);
}
# Clean up semaphore
$ctx->datasource_semaphore->delete_by_job_id(job_id => $id, ctx => $ctx);
};
if ($@) {
$txn->rollback;
die $@;
}
$txn->commit;
return 1;
}
1;
__END__
=encoding utf-8
=head1 NAME
App::Koyomi::DataSource::Job::Teng - Teng interface as job datasource
=head1 SYNOPSIS
use App::Koyomi::DataSource::Job::Teng;
my $ds = App::Koyomi::DataSource::Job::Teng->instance(ctx => $ctx);
my @jobs = $ds->gets
( run in 0.820 second using v1.01-cache-2.11-cpan-437f7b0c052 )