App-SnerpVortex

 view release on metacpan or  search on metacpan

lib/SVN/Analysis.pm  view on Meta::CPAN

		CREATE INDEX rev_map_other ON rev_map (other_rev, svn_rev)
	") or die $self->dbh()->errstr();
}

### Public entry points.

sub consider_add {
	my ($self, $path, $revision, $kind) = @_;

	warn "add: $path $revision" if $self->verbose();

	# Touch the parent directory of the thing being added.
	$self->_touch_parent_directory($path, $revision);

	# If this is a file, we're done.
	return if $kind ne "dir";

	# Adding a directory.  It shall not previously exist.
	confess "adding previously existing path $path at r$revision" if (
		$self->_path_exists($path, $revision)
	);

	# Add unconditionally.
	my $sth = $self->dbh()->prepare_cached("
		INSERT INTO dir (
			path, rev_first, rev_last, op_first, op_last,
			is_active, is_add, is_copy, is_modified
		)
		VALUES (
			?, ?, ?, ?, ?,
			?, ?, ?, ?
		)
	") or die $self->dbh()->errstr();

	warn "INSERT $path r$revision" if $self->verbose();
	$sth->execute($path, $revision, $revision, "add", "add", 1, 1, 0, 0) or die (
		$sth->errstr()
	);

	return;
}

sub consider_change {
	my ($self, $path, $revision, $kind) = @_;
	return $self->_touch_parent_directory($path, $revision) if $kind ne "dir";
	return $self->_touch_directory($path, $revision);
}

sub consider_copy {
	my ($self, $dst_path, $dst_rev, $kind, $src_path, $src_rev) = @_;

	my $sth_copy = $self->dbh()->prepare_cached("
		INSERT INTO copy (src_path, src_rev, kind, dst_path, dst_rev)
		VALUES (?, ?, ?, ?, ?)
	") or die $self->dbh()->errstr();

	$sth_copy->execute($src_path, $src_rev, $kind, $dst_path, $dst_rev) or die(
		$sth_copy->errstr()
	);

	# It would suck if the relocated path existed.
	confess "target path $dst_path exists at r$dst_rev" if (
		$self->_path_exists($dst_path, $dst_rev)
	);

	# Touch the directory where the copy is landing.
	$self->_touch_parent_directory($dst_path, $dst_rev);

	# If this is a file, we're done.
	return if $kind ne "dir";

	warn "copy: $src_path $src_rev > $dst_path $dst_rev" if (
		$self->verbose()
	);

	# Copy the source path and all the entire tree below.
	foreach my $path_to_copy ($self->_get_tree_paths($src_path, $src_rev)) {
		my $relocated_path = $path_to_copy;
		$relocated_path =~ s/^\Q$src_path\E(\/|$)/$dst_path$1/ or confess(
			"can't relocate $path_to_copy from $src_path to $dst_path"
		);

		warn "copy includes: $path_to_copy > $relocated_path" if $self->verbose();

		my $sth = $self->dbh()->prepare_cached("
			INSERT INTO dir (
				path, rev_first, rev_last, op_first, op_last,
				is_active, is_add, is_copy, is_modified,
				src_path, src_rev
			)
			VALUES (
				?, ?, ?, ?, ?,
				?, ?, ?, ?,
				?, ?
			)
		") or die $self->dbh()->errstr();

		my $is_add = ($path_to_copy eq $src_path) ? 1 : 0;

		$sth->execute(
			$relocated_path, $dst_rev, $dst_rev, "copy", "copy",
			1, $is_add, 1, 0,
			$path_to_copy, $src_rev,
		) or die $sth->errstr();
	}

	return;
}

sub consider_delete {
	my ($self, $path, $revision) = @_;

	# Touch the parent directory and all its ancestors back to the root.
	$self->_touch_parent_directory($path, $revision);

	# If the path doesn't exist, then we just deleted a file.
	# TODO - Or we deleted a defunct directory?
	return unless $self->_path_exists($path, $revision);

	# Otherwise flag the tree at the deletion point.
	foreach my $path_to_delete ($self->_get_tree_paths($path, $revision)) {

		# Double deletion is bad.
		confess "deleting nonexistent $path_to_delete at r$revision" unless (
			$self->_path_exists($path_to_delete, $revision)
		);

		warn "UPDATE $path $revision (is_active=0)" if $self->verbose();

		my $sth = $self->dbh()->prepare_cached("
			UPDATE dir SET rev_last = ?, op_last = ?, is_active = ?
			WHERE path = ? and rev_first <= ? and is_active = 1
		") or die $self->dbh()->errstr();

		$sth->execute(
			$revision, "delete", 0,
			$path_to_delete, $revision,
		);
	}

	return;
}

sub analyze {
	my $self = shift;

	# Sanity check.  Each path may have at most one active row.

	my $sth = $self->dbh()->prepare_cached("
		SELECT path, count(is_active) as ct
		FROM dir
		WHERE is_active = 1
		GROUP BY path
		HAVING ct > 1
	") or die $self->dbh()->errstr();

	$sth->execute() or die $sth->errstr();
	$sth->bind_columns(\my ($path, $count)) or die $sth->errstr();

	my $failures = 0;
	while ($sth->fetch()) {



( run in 1.500 second using v1.01-cache-2.11-cpan-71847e10f99 )