package VCP::DB_File;
=head1 NAME
VCP::DB_File - Persistant storage for id -> (name, rev_id) maps
=head1 SYNOPSIS
use base qw( VCP::DB_File );
=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 ", ref $self, " 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 ", ref $self, " file to be loaded.
To write your own ", ref $self, " file, see VCP::DB_File::sdbm.
=for test_script t/01db_file.t
=cut
$VERSION = 1 ;
use strict ;
use Carp;
use VCP::Debug qw( :debug );
use VCP::Utils qw( start_dir );
use fields (
'StoreLoc', ## Where the data should be kept.
'TableName',
);
=head2 Methods
=over
=cut
=item new
VCP::DB_File::foo->new(
StoreLoc => $dir, ## path to a dir to keep the state store in
);
The C<Store> field indicates where the ", ref $self, " 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 %options = @_;
my $type = delete $options{Type} || "sdbm";
my $self = do {
my $try_type = "VCP::DB_File::$type";
eval "require $try_type"
? $type = $try_type
: (
eval "require $type;"
|| Carp::confess
"Could not load VCP::DB_File subclass $type for $options{TableName}"
);
no strict 'refs' ;
bless [ \%{"$type\::FIELDS"} ], $type;
};
while ( my ( $key, $value ) = each %options ) {
$self->{$key} = $value;
}
Carp::confess "undefined TableName" unless defined $self->{TableName};
$self->{StoreLoc} = "vcp_state"
unless defined $self->{StoreLoc};
$self->{StoreLoc} = File::Spec->rel2abs(
File::Spec->catdir( $self->{StoreLoc}, $self->{TableName} ),
start_dir
);
debug "vcp: storing ", ref $self, " 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::DB_File $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::DB_File $self = shift;
$self->close_db;
debug "vcp: deleting ", ref $self, " 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::DB_File $self = shift;
debug "vcp: opening ", ref $self, " 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::DB_File $self = shift;
debug "vcp: closing ", ref $self, " 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::DB_File $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::DB_File $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 | |
|---|---|---|---|---|---|
| #16 | 4021 | Barrie Slaymaker |
- Remove all phashes and all base & fields pragmas - Work around SWASHGET error |
||
| #15 | 4012 | Barrie Slaymaker | - Remove dependance on pseudohashes (deprecated Perl feature) | ||
| #14 | 3895 | Barrie Slaymaker | - Serialization now properly escapes multiple ";" and "\n" | ||
| #13 | 3849 | Barrie Slaymaker | - docs tweaked | ||
| #12 | 3771 | Barrie Slaymaker | - minor docs fix | ||
| #11 | 3532 | John Fetkovich |
changed File::Spec->rel2abs( blah, start_dir ) to start_dir_rel2abs blah everywhere. which does the same thing and is defined in VCP::Utils |
||
| #10 | 3433 | Barrie Slaymaker | - Merge in new VSS code. | ||
| #9 | 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. |
||
| #8 | 3008 | John Fetkovich |
make state database files go under vcp_state in the program start directory (start_dir) instead of start_dir itself. Also escape periods (.) from the database directory as well as the characters already escaped. |
||
| #7 | 2959 | John Fetkovich |
added dump method to lib/VCP/DB_File/sdbm.pm to dump keys => values from a sdbm file. removed similar code from bin/dump_head_revs, bin/dump_rev_map and bin/dump_main_branch_id and called this method instead. also made parse_files_and_revids_from_head_revs_db sub in TestUtils to use in test suites instead of parse_files_and_revids_from_p4_files et. al. |
||
| #6 | 2871 | Barrie Slaymaker | Try to fix empty stnig un/packing for real this time. | ||
| #5 | 2870 | Barrie Slaymaker | Fix sort, un/packing empty value problems | ||
| #4 | 2866 | Barrie Slaymaker | Improve error messages | ||
| #3 | 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. |
||
| #2 | 2723 | Barrie Slaymaker | Finish generalizing DB_File, implement HeadRevsDB | ||
| #1 | 2722 | Barrie Slaymaker | Generalize DB_File for reuse. |