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 )