package VCP::DB_File; =head1 NAME VCP::DB_File - Persistant storage for vcp_state data =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_rel2abs ); #use fields ( # 'StoreLoc', ## Where the data should be kept. # 'TableName', ## database table name #); =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; my $self = bless { @_ }, $class; my $type = delete $self->{Type} || "sdbm"; Carp::confess "undefined TableName" unless defined $self->{TableName}; $self->{StoreLoc} = "vcp_state" unless defined $self->{StoreLoc}; $self->{StoreLoc} = start_dir_rel2abs( File::Spec->catdir( $self->{StoreLoc}, $self->{TableName} ) ); debug "storing ", ref $self, " in ", $self->store_loc if debugging; return $self ; } =item store_loc Gets (does not set) the StoreLoc field as an absolute path. =cut sub store_loc { my $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 perform the deletion. (subclasses should call C<$self->SUPER::delete_db before doing anything else in their delete_db() overrides). =cut sub delete_db { my $self = shift; $self->close_db; debug "deleting ", ref $self, " in ", $self->store_loc if debugging; } =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 $self = shift; debug "opening ", ref $self, " in ", $self->store_loc if debugging; } =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 $self = shift; debug "closing ", ref $self, " in ", $self->store_loc if debugging; } =item set $db->set( $key, @values ); Sets the values for $key. =cut =item get my @values = $db->get( $key ); Gets the values for $key. =item keys my @keys = $db->keys; Returns a list of ARRAY references. Each ARRAY ref is a 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 $self = shift; return if -e $self->store_loc; debug "making dir ", $self->store_loc if debugging; 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 $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 ## The serialization is designed to be simple: we alter '%' to '%%' and ';' to ## '%,', then join with ";". This way, we can split on ';', then ## descape all '%%' and '%,'. We might be able to optimize this a bit ## by only using one s/// in packing and only one in unpacking. sub pack_values { shift; confess "no values to pack" unless @_; confess "can't pack undef" if grep !defined, @_; join ";", map { my $v = $_; $v =~ s/%/%%/g; $v =~ s/;/%,/g; $v } @_; } =item upack_values my @v = $self->unpack_values( $v ); =cut sub unpack_values { shift; confess unless @_ == 1; my @v = split /;/, "$_[0];", -1; pop @v; @v = map { s/%%/%/g; s/%,/;/g; $_ } @v; return @v; } =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 | |
---|---|---|---|---|---|
#1 | 6118 | Dimitry Andric | Integ from //public/revml to //guest/dimitry_andric/revml/main. | ||
//guest/perforce_software/revml/lib/VCP/DB_File.pm | |||||
#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. |