Index: gsdl/trunk/perllib/inexport.pm
===================================================================
--- gsdl/trunk/perllib/inexport.pm	(revision 18457)
+++ gsdl/trunk/perllib/inexport.pm	(revision 18457)
@@ -0,0 +1,157 @@
+###########################################################################
+#
+# inexport.pm -- useful utilities to support import.pl and export.pl
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package inexport;
+
+use strict;
+
+use util;
+use GDBMUtils;
+
+sub new_vs_old_import_diff
+{
+    my ($archive_info,$block_hash,$importdir) = @_;
+
+    # First convert all files to absolute form
+    # This is to support the situation where the import folder is not
+    # the default
+    
+    my $prev_all_files = $archive_info->{'prev_import_filelist'};
+    my $full_prev_all_files = {};
+
+    foreach my $prev_file (keys %$prev_all_files) {
+
+	if (!&util::filename_is_absolute($prev_file)) {
+	    my $full_prev_file = &util::filename_cat($ENV{'GSDLCOLLECTDIR'},$prev_file);
+	    $full_prev_all_files->{$full_prev_file} = $prev_file;
+	}
+	else {
+	    $full_prev_all_files->{$prev_file} = $prev_file;
+	}
+    }
+
+    # Figure out which are the new files, existing files and so
+    # by implication the files from the previous import that are not
+    # there any more => mark them for deletion
+    foreach my $curr_file (keys %{$block_hash->{'all_files'}}) {
+	
+	my $full_curr_file = $curr_file;
+
+	# entry in 'all_files' is moved to either 'existing_files', 
+	# 'deleted_files', or 'new_files'
+
+	if (!&util::filename_is_absolute($curr_file)) {
+	    # add in import dir to make absolute
+	    $full_curr_file = &util::filename_cat($importdir,$curr_file);
+	}
+
+	# figure of if new file or not
+	if (defined $full_prev_all_files->{$full_curr_file}) {
+	    # had it before
+	    $block_hash->{'existing_files'}->{$curr_file} = 1;
+	    # Now remove it, so by end of loop only the files
+	    # that need deleting are left
+
+	    delete $full_prev_all_files->{$full_curr_file};
+    	}
+	else {
+	    $block_hash->{'new_files'}->{$curr_file} = 1;
+	}
+	
+	delete $block_hash->{'all_files'}->{$curr_file};
+    }
+
+    # By this point full_prev_all_files contains only the files
+    # that are not in the current import folder => i.e. files
+    # to be deleted
+    #
+    # The value in each key is its "local" import file name, which is what 
+    # we want to use
+    my @deleted_files = values %$full_prev_all_files;
+    map { $block_hash->{'deleted_files'}->{$_} = 1 } @deleted_files;
+}
+
+sub mark_docs_for_deletion
+{
+    my ($archive_info,$deleted_files_ref,$archivedir,$verbosity) = @_;
+
+    my $db_ext = &util::is_little_endian() ? ".ldb" : ".bdb";
+    my $doc_db = "archiveinf-doc$db_ext";
+    my $src_db = "archiveinf-src$db_ext";
+    my $arcinfo_doc_filename = &util::filename_cat ($archivedir, $doc_db);
+    my $arcinfo_src_filename = &util::filename_cat ($archivedir, $src_db);
+
+
+    # record files marked for deletion in arcinfo
+    foreach my $file (@$deleted_files_ref) {
+	# use 'archiveinf-src' GDBM file to look up all the OIDs
+	# this file is used in (note in most cases, it's just one OID)
+	
+	# An improvement would be to have the record read
+	# into a hash array
+	my $src_rec = GDBMUtils::gdbmRecordToHash($arcinfo_src_filename,$file);
+	my $oids = $src_rec->{'oid'};
+	foreach my $oid (@$oids) {
+
+	    # find out if it's an assoc file or main doc
+
+	    my $doc_rec = GDBMUtils::gdbmRecordToHash($arcinfo_doc_filename,$oid);
+##	    print STDERR "file = $file\n";
+
+	    if ($doc_rec->{'src-file'}->[0] eq $file) {
+		# mark it for deletion
+		if ($verbosity>1) {
+		    print STDERR "$oid marked to be deleted\n";
+		}
+		$archive_info->set_status_info($oid,"D");
+
+		my $val = &GDBMUtils::gdbmDatabaseGet($arcinfo_doc_filename,$oid);
+		$val =~ s/^<index-status>(.*)$/<index-status>D/m;
+		&GDBMUtils::gdbmDatabaseSet($arcinfo_doc_filename,$oid,$val);
+	    }
+	    else {
+		# assoc file => mark it for re-indexing (safest thing to do)
+		my $curr_status = $archive_info->get_status_info($oid);
+
+
+		if (defined($curr_status) && (($curr_status ne "D") && ($curr_status ne "R"))) {
+		    if ($verbosity > 1) {
+			print STDERR "$oid marked for (potential) reindexing\n";
+			print STDERR "  (because associated file $file deleted)\n";
+		    }
+		    $archive_info->set_status_info($oid,"R");
+
+		    my $val = &GDBMUtils::gdbmDatabaseGet($arcinfo_doc_filename,$oid);
+		    $val =~ s/^<index-status>(.*)$/<index-status>R/m;
+		    &GDBMUtils::gdbmDatabaseSet($arcinfo_doc_filename,$oid,$val);
+		}
+	    }
+	}
+    }
+}
+
+
+
+1;
