App-SD

 view release on metacpan or  search on metacpan

lib/App/SD/Replica/trac/PullEncoder.pm  view on Meta::CPAN

after transaction $num.

=cut

sub find_matching_transactions {
    my $self = shift;
    my %args = validate( @_, { ticket => 1, starting_transaction => 1 } );
    my @raw_txns = @{$args{ticket}->history->entries};

    my @txns;
    # XXX TODO make this one loop.
    for my $txn ( sort { $a->date cmp $b->date} @raw_txns) {
        my $txn_date = $txn->date->epoch;
        # Skip things we know we've already pulled
        next if $txn_date < ( $args{'starting_transaction'} ||0 );
        # Skip things we've pushed
        next if ($self->sync_source->foreign_transaction_originated_locally($txn_date, $args{'ticket'}->id) );

        # ok. it didn't originate locally. we might want to integrate it
        push @txns, { timestamp => $txn->date,
                      serial => $txn->date->epoch,
                      object => $txn};
    }
    $self->sync_source->log_debug('Done looking at pulled txns');
    return \@txns;
}

sub build_initial_ticket_state {
    my $self          = shift;
    my $final_state   = shift;
    my $ticket_object = shift;

    my %initial_state = %{$final_state};

    for my $txn ( reverse @{ $ticket_object->history->entries } ) {
        for my $pc ( values %{ $txn->prop_changes } ) {
            unless ( $initial_state{ $pc->property } eq $pc->new_value ) {
                warn "I was expecting "
                    . $pc->property
                    . " to be "
                    . $pc->new_value
                    . " but it was actually "
                    . $initial_state{ $pc->property };
            }
            $initial_state{ $pc->property } = $pc->old_value;

        }
    }
    return \%initial_state;
}

sub transcode_create_txn {
    my $self        = shift;
    my $txn         = shift;
    my $create_data = shift;
    my $final_data = shift;
    my $ticket      = $txn->ticket;
    # this sequence_no only works because trac tickets only allow one update
    # per ticket per second.
    # we decrement by 1 on the off chance that someone created and
    # updated the ticket in the first second
    my $changeset = Prophet::ChangeSet->new(
        {   original_source_uuid => $self->sync_source->uuid_for_remote_id( $ticket->id ),
            original_sequence_no => ( $ticket->created->epoch-1),
            creator => $self->resolve_user_id_to( email_address => $create_data->{reporter} ),
            created => $ticket->created->ymd ." ".$ticket->created->hms
        }
    );

    my $change = Prophet::Change->new(
        {   record_type => 'ticket',
            record_uuid => $self->sync_source->uuid_for_remote_id( $ticket->id ),
            change_type => 'add_file'
        }
    );

    for my $prop ( keys %$create_data ) {
        next unless defined $create_data->{$prop};
        next if $prop =~ /^(?:patch)$/;
        $change->add_prop_change( name => $prop, old => '', new => $create_data->{$prop} );
    }

    $changeset->add_change( { change => $change } );

    if ( my $att = $txn->attachment ) {
        $self->_recode_attachment_create(
            ticket     => $ticket,
            txn        => $txn,
            changeset  => $changeset,
            attachment => $att,
        );
    }
    return $changeset;
}

            # we might get return:
            # 0 changesets if it was a null txn
            # 1 changeset if it was a normal txn
            # 2 changesets if we needed to to some magic fixups.
sub transcode_one_txn {
    my ( $self, $txn_wrapper, $ticket, $ticket_final ) = (@_);

    my $txn = $txn_wrapper->{object};

    if ($txn->is_create) {
        return $self->transcode_create_txn($txn,$ticket,$ticket_final);
    }

    my $ticket_uuid = $self->sync_source->uuid_for_remote_id( $ticket->{ $self->sync_source->uuid . '-id' } );

    my $changeset = Prophet::ChangeSet->new(
        {   original_source_uuid => $ticket_uuid,
            original_sequence_no => $txn->date->epoch,    # see comment on ticket
                                                          # create changeset
            creator => $self->resolve_user_id_to( email_address => $txn->author ),
            created => $txn->date->ymd . " " . $txn->date->hms
        }
    );

    my $change = Prophet::Change->new(
        {   record_type => 'ticket',



( run in 1.185 second using v1.01-cache-2.11-cpan-39bf76dae61 )