Apache2-Translation

 view release on metacpan or  search on metacpan

lib/Apache2/Translation/File.pm  view on Meta::CPAN

  truncate $fh, 0 or
    do {close $fh; die "ERROR: Cannot truncate to $fname: $!\n"};

  my $fmt=">>> %@{[$w_id-1]}s %-${w_key}s %-${w_uri}s %${w_blk}s %${w_ord}s\n";
  printf $fh '#'.$fmt, qw/id key uri blk ord/ or
    do {close $fh; die "ERROR: Cannot write to $fname: $!\n"};
  print $fh "# action\n" or
    do {close $fh; die "ERROR: Cannot write to $fname: $!\n"};

  $fmt=("##################################################################\n".
	">>> %${w_id}s %-${w_key}s %-${w_uri}s %${w_blk}s %${w_ord}s\n%s\n");
  # this sort-thing is not really necessary. It's just to have the saved
  # config file in a particular order for human readability.
  foreach my $v (map {$I->_cache->{$_}} sort keys %{$I->_cache}) {
    foreach my $el (sort {$a->[0] <=> $b->[0] or $a->[1] <=> $b->[1]} @{$v}) {
      printf $fh $fmt, @{$el}[3..5,0..2] or
	do {close $fh; die "ERROR: Cannot write to $fname: $!\n"};
      if( defined $dname and length $el->[6] ) {
	my $notesf=undef;
	if( open $notesf, '>'.File::Spec->catfile($dname, $el->[3]) ) {
	  print $notesf $el->[6];
	  close $notesf;
	} else {
	  warn "WARNING: Cannot open ".File::Spec->catfile($dname, $el->[3]).": $!\n";
	}
      }
      $#{$el}=5;
    }
  }

  select( (select( $fh ), $|=1)[0] );  # flush buffer

  my $time=time;
  $time=$oldtime+1 if( $time<=$oldtime );

  utime( $time, $time, $fname );
  $I->timestamp=$time;

  if( defined $dname ) {
    opendir my($d), $dname;
    if( $d ) {
      my %h=map {($_->[3]=>1)} map {@$_} values %{$I->_cache};
      while( my $el=readdir $d ) {
	unlink File::Spec->catfile($dname, $el) if( $el=~/^\d+$/ and !exists $h{$el} );
      }
      closedir $d;
    }
  }

  close $fh or die "ERROR: Cannot write to $fname: $!\n";

  return "0 but true";
}

sub rollback {
  my $I=shift;			# reread table
  $I->timestamp=0;
  $I->start;
}

sub update {
  my $I=shift;
  my $old=shift;
  my $new=shift;

  my $list=$I->_cache->{join "\0", @{$old}[0,1]};
  return "0 but true" unless( $list );

  if( $old->[oKEY] eq $new->[oKEY] and
      $old->[oURI] eq $new->[oURI] ) {
    # KEY and URI have not changed
    for( my $i=0; $i<@{$list}; $i++ ) {
      if( $list->[$i]->[ID]    == $old->[oID]    and # id
	  $list->[$i]->[BLOCK] == $old->[oBLOCK] and # block
	  $list->[$i]->[ORDER] == $old->[oORDER] ) { # order
	@{$list->[$i]}[BLOCK,ORDER,ACTION,NOTE]
	  = @{$new}[nBLOCK,nORDER,nACTION,nNOTE];
	@{$list}=sort {$a->[BLOCK] <=> $b->[BLOCK] or
		       $a->[ORDER] <=> $b->[ORDER]} @{$list};
	return 1;
      }
    }
  } else {
    die "ERROR: KEY must not contain spaces.\n" if( $new->[0]=~/\s/ );
    die "ERROR: URI must not contain spaces.\n" if( $new->[1]=~/\s/ );

    for( my $i=0; $i<@{$list}; $i++ ) {
      if( $list->[$i]->[ID]    == $old->[oID]    and # id
	  $list->[$i]->[BLOCK] == $old->[oBLOCK] and # block
	  $list->[$i]->[ORDER] == $old->[oORDER] ) { # order
	my ($el)=splice @{$list}, $i, 1;
	delete $I->_cache->{join "\0", @{$old}[oKEY,oURI]} unless( @{$list} );
	@{$el}[KEY,URI,BLOCK,ORDER,ACTION,NOTE]
	  = @{$new}[nKEY,nURI,nBLOCK,nORDER,nACTION,nNOTE];
	my $k=join("\0",@{$new}[nKEY,nURI]);
	if( exists $I->_cache->{$k} ) {
	  push @{$I->_cache->{$k}}, $el;
	  $I->_cache->{$k}=[sort {$a->[BLOCK] <=> $b->[BLOCK] or
				  $a->[ORDER] <=> $b->[ORDER]}
			    @{$I->_cache->{$k}}];
	} else {
	  $I->_cache->{$k}=[$el]
	}
	return 1;
      }
    }
  }
  return "0 but true";
}

sub insert {
  my $I=shift;
  my $new=shift;

  die "ERROR: KEY must not contain spaces.\n" if( $new->[0]=~/\s/ );
  die "ERROR: URI must not contain spaces.\n" if( $new->[1]=~/\s/ );

  my $newid=0;
  foreach my $v (values %{$I->_cache}) {
    foreach my $el (@{$v}) {
      $newid=$el->[3] if( $el->[3]>$newid );



( run in 2.570 seconds using v1.01-cache-2.11-cpan-5837b0d9d2c )