RevMapDB.pm #3

  • //
  • guest/
  • perforce_software/
  • revml/
  • lib/
  • VCP/
  • RevMapDB.pm
  • View
  • Commits
  • Open Download .zip Download (5 KB)
package VCP::RevMapDB;

=head1 NAME

VCP::RevMapDB - Persistant storage for id -> (name, rev_id) maps

=head1 SYNOPSIS

    use base qw( VCP::RevMapDB );

=head1 DESCRIPTION

By default, most VCP::Dest::* drivers keep track of the relationship
between the id field assigned by the (original) VCP::Source::* driver
and the final name and rev_id (or whatever fields are important to it)
in the destination repository so that the previous_id fields, which
refer to the original id, may be resolved when backfilling or branching.

The VCP::*::revml drivers do not do this; they do not need to resolve id
fields.

The intent for this file is to serve as a base class so that individual
sites may write their own RevMapDB plugins to, for instance, store this
state in a RDBMS table.  This is not quite offered at this time; we need
to add an option to the appropriate VCP::Dest::* modules to allow the
appropriate RevMapDB file to be loaded.

To write your own RevMapDB file, see VCP::RevMapDB::sdbm.

=for test_script t/01revmapdb.t

=cut

$VERSION = 1 ;

use strict ;
use VCP::Debug qw( :debug );
use VCP::Utils qw( start_dir );

use fields (
   'StoreLoc',   ## Where the data should be kept.
);

=head2 Methods

=over

=cut

=item new

   VCP::RevMapDB::foo->new(
      StoreLoc => $dir,  ## path to a dir to keep the state store in
   );

The C<Store> field indicates where the RevMapDB should be stored, for
instance a DBI specification string or a directory to place a
"revmap.db" file in.  There is no control over the filename, as
different storage modes may need different conventions.

=cut

sub new {
   my $class = shift ;
   $class = ref $class || $class ;

   my $self ;

   {
      no strict 'refs' ;
      $self = bless [ \%{"$class\::FIELDS"} ], $class ;
   }

   while ( @_ ) {
      my ( $key, $value ) = ( shift, shift );
      $self->{$key} = $value;
   }

   $self->{StoreLoc} = File::Spec->catfile( "vcp_state", "vcp_rev_map" )
      unless defined $self->{StoreLoc};

   $self->{StoreLoc} = File::Spec->rel2abs( $self->{StoreLoc}, start_dir );

   debug "vcp: storing RevMapDB in ", $self->store_loc if debugging $self;

   return $self ;
}

=item store_loc

Gets (does not set) the StoreLoc field as an absolute path.

=cut

sub store_loc {
   my VCP::RevMapDB $self = shift;
   return $self->{StoreLoc};
}

=item delete_db

   $db->delete_db;

Deletes the persitent store.  This should remove all files, lock files,
etc.  for filesystem stores and drop any tables for RDBMS stores.

Default action is to call close_db; subclasses should

(subclasses should call C<$self->SUPER::delete_db before doing anything
else in their delete_db() overrides).

=cut

sub delete_db {
   my VCP::RevMapDB $self = shift;

   $self->close_db;
   debug "vcp: deleting RevMapDB in ", $self->store_loc if debugging $self;
}


=item open_db

   $db->open_db;

Creates a new or opens an existing db.

(subclasses should call C<$self->SUPER::open_db before doing anything
else in their open_db() overrides).

=cut

sub open_db {
   my VCP::RevMapDB $self = shift;
   debug "vcp: opening RevMapDB in ", $self->store_loc if debugging $self;
}

=item close_db

   $db->close_db;

(subclasses should call C<$self->SUPER::close_db before doing anything
else in their close_db() overrides).

=cut

sub close_db {
   my VCP::RevMapDB $self = shift;
   debug "vcp: closing RevMapDB in ", $self->store_loc if debugging $self;
}

=item set

   $db->set( $key, @values );

Sets the values for $key.

=cut

=item get

   my @values = $db->get( $key );

Gets the values for $key.

=cut

=back

=head1 HELPER METHODS

These are provided to make subclassing a tad easier

=over

=cut

=item mkdir_store_loc

   $self->mkdir_store_loc;

A helper method for subclasses' open_db()s to create the directory
referred to by store_loc and any missing parent dirs.

=cut

sub mkdir_store_loc {
   my VCP::RevMapDB $self = shift;

   return if -e $self->store_loc;

   require File::Path;
   File::Path::mkpath( [ $self->store_loc ] );
}

=item rmdir_store_loc

   $self->rmdir_store_loc;

A helper method for subclasses' delete_db()s to remove the directory
referred to by store_loc.

=cut

sub rmdir_store_loc {
   my VCP::RevMapDB $self = shift;

   return unless -e $self->store_loc;

   require File::Path;
   File::Path::rmtree( [ $self->store_loc ] );
}

=item pack_values

   my $v = $self->pack_values( @values );

Combines the parameters in to a single string.

=cut

sub pack_values {
   shift;
   join ";", map { my $v = $_; $v =~ s/%/%%/g; $v =~ s/;/%,/; $v } @_;
}

=item upack_values

   my @v = $self->unpack_values( $v );

=cut

sub unpack_values {
   shift;
   map { s/%%/%/g; s/%,/;/g; $_ } split ";", $_[0];
}

=back

=head1 AUTHOR

Barrie Slaymaker <barries@slaysys.com>

=head1 COPYRIGHT

Copyright (c) 2000, 2001, 2002 Perforce Software, Inc.
All rights reserved.

See L<VCP::License|VCP::License> (C<vcp help license>) for the terms of use.

=cut

1
# Change User Description Committed
#12 4021 Barrie Slaymaker - Remove all phashes and all base & fields pragmas
- Work around SWASHGET error
#11 3155 Barrie Slaymaker Convert to logging using VCP::Logger to reduce stdout/err spew.
       Simplify & speed up debugging quite a bit.
       Provide more verbose information in logs.
       Print to STDERR progress reports to keep users from wondering
       what's going on.
       Breaks test; halfway through upgrading run3() to an inline
       function for speed and for VCP specific features.
#10 2807 Barrie Slaymaker Clean up debugging messages
#9 2802 John Fetkovich Added a source_repo_id to each revision, and repo_id to each
Source and Dest.  The repo_ids include repository type
(cvs,p4,revml,vss,...) and the repo_server fields.  Changed the
$self->...->set() and $self->...->get() lines in VCP::Dest::* to
pass in a conglomerated key value, by passing in the key as an
ARRAY ref.  Also various restructuring in VCP::DB.pm,
VCP::DB_file.pm and VCP::DB_file::sdbm.pm related to this
change.
#8 2787 Barrie Slaymaker fix buglet
#7 2786 Barrie Slaymaker Differentiate RevMapDB (which confesses when an undefined
       value is returned) from HeadRevsDB (which doesn't).
#6 2769 Barrie Slaymaker Suppress extraneous stale db warning, demote the stale
       state db detection to RevMapDB, allow the head revs db
       to be dumped.
#5 2723 Barrie Slaymaker Finish generalizing DB_File, implement HeadRevsDB
#4 2722 Barrie Slaymaker Generalize DB_File for reuse.
#3 2706 Barrie Slaymaker Interim checkin
#2 2703 Barrie Slaymaker use the new RevMapDB in VCP::Dest::cvs
#1 2702 Barrie Slaymaker Create the RevMapDB classes & tests