# if everything looks good, score it and dump fingerprints
score_marc($marc, $record);
- dump_fingerprints($marc);
+ dump_fingerprints_score_id($marc);
$scount++; progress_ticker();
}
}
# date1, date2
my $my_008 = $record->field('008');
+ my @my_007 = $record->field('007');
+ my $my_006 = $record->field('006');
$marc{tag008} = $my_008->as_string() if ($my_008);
if (defined $marc{tag008}) {
unless (length $marc{tag008} == 40) {
}
}
}
+ $marc{tag006} = $my_006->as_string() if ($my_006);
+ $marc{tag007} = \@my_007 if (@my_007);
+ $marc{audioformat}='';
+ $marc{videoformat}='';
+ foreach(@my_007)
+ {
+ if(substr($_->data(),0,1) eq 's' && $marc{audioformat} eq '')
+ {
+ $marc{audioformat} = substr($_->data(),3,1) unless (length $_->data() < 4);
+ }
+ elsif(substr($_->data(),0,1) eq 'v' && $marc{videoformat} eq '')
+ {
+ $marc{videoformat} = substr($_->data(),4,1) unless (length $_->data() < 5);
+ }
+ }
+ #print "$marc{audioformat}\n";
+ #print "$marc{videoformat}\n";
# item_form
+ $marc{item_form}='';
if ( $marc{record_type} =~ /[gkroef]/ ) { # MAP, VIS
- $marc{item_form} = substr($marc{tag008},29,1) if ($marc{tag008});
+ $marc{item_form} = substr($marc{tag008},29,1) if ($marc{tag008} && (length $marc{tag008} > 29 ));
} else {
- $marc{item_form} = substr($marc{tag008},23,1) if ($marc{tag008});
+ $marc{item_form} = substr($marc{tag008},23,1) if ($marc{tag008} && (length $marc{tag008} > 23 ));
+ }
+ #fall through to 006 if 008 doesn't have info for item form
+ if ($marc{item_form} eq '|')
+ {
+ $marc{item_form} = substr($marc{tag006},6,1) if ($marc{tag006} && (length $marc{tag006} > 6 ));
}
# isbns
}
}
+sub dump_fingerprints_score_id {
+ my ($marc) = @_;
+
+ if ($conf->{fingerprints}{baseline}) {
+ print OF join("\t", sortvalfromid($marc->{id}),"json", $marc->{id}, 'baseline',
+ $marc->{item_form}, $marc->{date1}, $marc->{record_type},
+ $marc->{bib_lvl},$marc->{audioformat},$marc->{videoformat}, $marc->{title}), "\n";
+ }
+
+ if ($conf->{fingerprints}{oclc} and scalar @{$marc->{oclc} }) {
+ for (@{$marc->{oclc} }) {
+ print OF join("\t", sortvalfromid($marc->{id}),"json", $marc->{id}, "oclc",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},$marc->{audioformat},$marc->{videoformat},
+ $marc->{title}, $_, "\n");
+ }
+ }
+
+ if ($conf->{fingerprints}{koha_bib_id} and exists $marc->{koha_bib_id}) {
+ print OF join("\t", sortvalfromid($marc->{id}),"json", $marc->{id}, "z_koha_bib_id",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type},
+ $marc->{bib_lvl},$marc->{audioformat},$marc->{videoformat}, $marc->{title},
+ $marc->{koha_bib_id}), "\n";
+ }
+
+ if ($conf->{fingerprints}{isbn}) {
+ if ((scalar @{ $marc->{isbns} } > 0) and $marc->{pages}) {
+ foreach my $isbn ( @{ $marc->{isbns}} ) {
+ print OF join("\t", sortvalfromid($marc->{id}),"json", $marc->{id}, "isbn",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type},
+ $marc->{bib_lvl},$marc->{audioformat},$marc->{videoformat}, $marc->{title},
+ $isbn, $marc->{pages}), "\n";
+ }
+ }
+ }
+
+ if ($conf->{fingerprints}{edition} and $marc->{edition} and $marc->{author}) {
+ print OF join("\t", sortvalfromid($marc->{id}),"json", $marc->{id}, "edition",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},$marc->{audioformat},$marc->{videoformat},
+ $marc->{title}, $marc->{author}, $marc->{edition}), "\n";
+ }
+
+ if ($conf->{fingerprints}{issn} and $marc->{issn}) {
+ print OF join("\t", sortvalfromid($marc->{id}),"json", $marc->{id}, "issn",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},$marc->{audioformat},$marc->{videoformat},
+ $marc->{title}, $marc->{issn}), "\n";
+ }
+
+ if ($conf->{fingerprints}{lccn} and $marc->{lccn}) {
+ print OF join("\t", sortvalfromid($marc->{id}),"json", $marc->{id}, "lccn",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},$marc->{audioformat},$marc->{videoformat},
+ $marc->{title}, $marc->{lccn}) ,"\n";
+ }
+
+ if ($conf->{fingerprints}{accomp} and $marc->{accomp}) {
+ print OF join("\t", sortvalfromid($marc->{id}),"json", $marc->{id}, "accomp",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},$marc->{audioformat},$marc->{videoformat},
+ $marc->{title}, $marc->{accomp}) ,"\n";
+ }
+
+ if ($conf->{fingerprints}{authpub} and $marc->{author} and
+ $marc->{publisher} and $marc->{pubyear} and $marc->{pages}) {
+ print OF join("\t", sortvalfromid($marc->{id}),"json", $marc->{id}, "authpub",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},$marc->{audioformat},$marc->{videoformat},
+ $marc->{title}, $marc->{author},
+ $marc->{publisher}, $marc->{pubyear},
+ $marc->{pages}), "\n";
+ }
+}
+
+sub sortvalfromid
+{
+ my $sortval = shift;
+ while(length($sortval)<17)
+ {
+ $sortval = '0'.$sortval;
+ }
+ return $sortval;
+}
+
+sub dump_fingerprints_hash_score {
+ my ($marc) = @_;
+
+ if ($conf->{fingerprints}{baseline}) {
+ my $string = join("", 'baseline',
+ $marc->{item_form}, $marc->{date1}, $marc->{record_type},
+ $marc->{bib_lvl}, $marc->{title});
+ $string =~ s/[^A-Za-z0-9]//g;
+ $string = sha1_base64($string);
+ print OF join("\t", $string,"json", $marc->{id}, 'baseline',
+ $marc->{item_form}, $marc->{date1}, $marc->{record_type},
+ $marc->{bib_lvl}, $marc->{title}), "\n";
+ }
+
+ if ($conf->{fingerprints}{oclc} and scalar @{$marc->{oclc} }) {
+ for (@{$marc->{oclc} }) {
+ my $string = join("", "oclc",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},
+ $marc->{title}, $_);
+ $string =~ s/[^A-Za-z0-9]//g;
+ $string = sha1_base64($string);
+ print OF join("\t", $string,"json", $marc->{id}, "oclc",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},
+ $marc->{title}, $_, "\n");
+ }
+ }
+
+ if ($conf->{fingerprints}{koha_bib_id} and exists $marc->{koha_bib_id}) {
+ my $string = join("", "z_koha_bib_id",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type},
+ $marc->{bib_lvl}, $marc->{title},
+ $marc->{koha_bib_id});
+ $string =~ s/[^A-Za-z0-9]//g;
+ $string = sha1_base64($string);
+ print OF join("\t", $string,"json", $marc->{id}, "z_koha_bib_id",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type},
+ $marc->{bib_lvl}, $marc->{title},
+ $marc->{koha_bib_id}), "\n";
+ }
+
+ if ($conf->{fingerprints}{isbn}) {
+ if ((scalar @{ $marc->{isbns} } > 0) and $marc->{pages}) {
+ foreach my $isbn ( @{ $marc->{isbns}} ) {
+ my $string = join("", "isbn",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type},
+ $marc->{bib_lvl}, $marc->{title},
+ $isbn, $marc->{pages});
+ $string =~ s/[^A-Za-z0-9]//g;
+ $string = sha1_base64($string);
+ print OF join("\t", $string,"json", $marc->{id}, "isbn",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type},
+ $marc->{bib_lvl}, $marc->{title},
+ $isbn, $marc->{pages}), "\n";
+ }
+ }
+ }
+
+ if ($conf->{fingerprints}{edition} and $marc->{edition} and $marc->{author}) {
+ my $string = join("", "edition",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},
+ $marc->{title}, $marc->{author}, $marc->{edition});
+ $string =~ s/[^A-Za-z0-9]//g;
+ $string = sha1_base64($string);
+ print OF join("\t", $string,"json", $marc->{id}, "edition",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},
+ $marc->{title}, $marc->{author}, $marc->{edition}), "\n";
+ }
+
+ if ($conf->{fingerprints}{issn} and $marc->{issn}) {
+ my $string = join("", "issn",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},
+ $marc->{title}, $marc->{issn});
+ $string =~ s/[^A-Za-z0-9]//g;
+ $string = sha1_base64($string);
+ print OF join("\t", $string,"json", $marc->{id}, "issn",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},
+ $marc->{title}, $marc->{issn}), "\n";
+ }
+
+ if ($conf->{fingerprints}{lccn} and $marc->{lccn}) {
+ my $string = join("", "lccn",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},
+ $marc->{title}, $marc->{lccn});
+ $string =~ s/[^A-Za-z0-9]//g;
+ $string = sha1_base64($string);
+ print OF join("\t", $string,"json", $marc->{id}, "lccn",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},
+ $marc->{title}, $marc->{lccn}) ,"\n";
+ }
+
+ if ($conf->{fingerprints}{accomp} and $marc->{accomp}) {
+ my $string = join("", "accomp",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},
+ $marc->{title}, $marc->{accomp});
+ $string =~ s/[^A-Za-z0-9]//g;
+ $string = sha1_base64($string);
+ print OF join("\t", $string,"json", $marc->{id}, "accomp",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},
+ $marc->{title}, $marc->{accomp}) ,"\n";
+ }
+
+ if ($conf->{fingerprints}{authpub} and $marc->{author} and
+ $marc->{publisher} and $marc->{pubyear} and $marc->{pages}) {
+ my $string = join("", "authpub",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},
+ $marc->{title}, $marc->{author},
+ $marc->{publisher}, $marc->{pubyear},
+ $marc->{pages});
+ $string =~ s/[^A-Za-z0-9]//g;
+ $string = sha1_base64($string);
+ print OF join("\t", $string,"json", $marc->{id}, "authpub",
+ $marc->{item_form}, $marc->{date1},
+ $marc->{record_type}, $marc->{bib_lvl},
+ $marc->{title}, $marc->{author},
+ $marc->{publisher}, $marc->{pubyear},
+ $marc->{pages}), "\n";
+ }
+}
+
=head2 dump_exception
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+# copy and paste raw text from acrobat reader to .txt file
+
+my $filename = $ARGV[0];
+open(my $fh, '<:encoding(UTF-8)', $filename)
+ or die "Could not open file '$filename' $!";
+
+my $user;
+
+while (my $row = <$fh>) {
+ chomp $row;
+ if ($row =~ m/Fines Due by patron/) { next; }
+ if ($row =~ m/Patron Title Barcode Date Due Fine/) { next; }
+ if ($row =~ m/Page: /) { next; }
+ if ($row =~ m/Program Files \(x86\)/) { next; }
+ if ($row =~ m/End Of Report/) { next; }
+ if ($row =~ m/Fines Due by Patron/) { next; }
+
+ my @str = split / /, $row;
+ my $str_length = scalar(@str);
+ if ($str[1] eq 'AM' or $str[1] eq 'PM') {
+ if ($str[2] =~ m/2019/) { next; }
+ }
+
+ if ($str[$str_length -1] !~ m/^\d*\.?\d*$/) {
+ $user = $str[$str_length -1];
+ next;
+ }
+
+ #print "$row\n";
+ if ($str[$str_length -1] =~ m/^\d*\.?\d*$/) {
+ my $f = $str[$str_length -1]; #fine
+ my $i = $str[$str_length -3]; #item barcode
+ print "$user\t$i\t$f\n";
+ }
+}
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+# copy and paste raw text from acrobat reader to .txt file
+
+my $filename = $ARGV[0];
+open(my $fh, '<:encoding(UTF-8)', $filename)
+ or die "Could not open file '$filename' $!";
+
+my $user;
+
+while (my $row = <$fh>) {
+ chomp $row;
+ if ($row =~ m/Items On Hold by Patron/) { next; }
+ if ($row =~ m/Patron Title Barcode /) { next; }
+ if ($row =~ m/Page: /) { next; }
+ if ($row =~ m/Program Files \(x86\)/) { next; }
+ if ($row =~ m/End Of Report/) { next; }
+
+ my @str = split / /, $row;
+ my $str_length = scalar(@str);
+ if ($str[1] eq 'AM' or $str[1] eq 'PM') {
+ if ($str[2] =~ m/2019/) { next; }
+ }
+
+ if ($str[$str_length -1] !~ m/\d\d\/\d\d\/\d\d\d\d/) {
+ $user = $str[$str_length -1];
+ next;
+ }
+
+ #print "$row\n";
+ if ($str[$str_length -1] =~ m/\d\d\/\d\d\/\d\d\d\d/) {
+ my $posted = $str[$str_length -1];
+ my $expire = $str[$str_length -2];
+ my $item = $str[$str_length -3]; #item
+ print "$user\t$item\t$posted\t$expire\n";
+ }
+}
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+# copy and paste raw text from acrobat reader to .txt file
+
+my $filename = $ARGV[0];
+open(my $fh, '<:encoding(UTF-8)', $filename)
+ or die "Could not open file '$filename' $!";
+
+my $user;
+
+while (my $row = <$fh>) {
+ chomp $row;
+ if ($row =~ m/Items On Loan by Patron/) { next; }
+ if ($row =~ m/Patron Title Barcode /) { next; }
+ if ($row =~ m/Page: /) { next; }
+ if ($row =~ m/Program Files \(x86\)/) { next; }
+ if ($row =~ m/End Of Report/) { next; }
+
+ my @str = split / /, $row;
+ my $str_length = scalar(@str);
+ if ($str[1] eq 'AM' or $str[1] eq 'PM') {
+ if ($str[2] =~ m/2019/) { next; }
+ }
+
+ if ($str[$str_length -1] !~ m/\d\d\/\d\d\/\d\d\d\d/) {
+ $user = $str[$str_length -1];
+ next;
+ }
+
+ #print "$row\n";
+ if ($str[$str_length -1] =~ m/\d\d\/\d\d\/\d\d\d\d/) {
+ my $due = $str[$str_length -1];
+ my $borrowed = $str[$str_length -2];
+ my $item = $str[$str_length -3]; #item
+ print "$user\t$item\t$due\t$borrowed\n";
+ }
+}
$fp{sha1} = sha1_base64($stripped);
# make sure file is sorted properly
- if ($lastscore and ($fp{compact} > $lastscore)) {
+ if ($lastscore and ($fp{compact} < $lastscore)) {
print "Input file is sorted improperly or unsorted.\n";
die "Sort descending (sort -r) and rerun this script.\n";
}
my $id = $fp->{id};
# only process records which haven't already been seen
- unless (defined $seen{$id}) {
+ #unless (defined $seen{$id}) {
unless (defined $fps{$sha1}) {
# haven't seen this fp before. create a new listref to hold subs
# and stow the hash of the fingerprint that we're lead of
push @{ $fps{$sha1} }, $id;
}
$seen{$id} = 1;
- }
+ #}
}
for my $rec (@recs) {
for ( @{ $fps{ $rec->{sha1} } } ) {
# check for dupes and die if they exist
- die "Collision: dupe sub record $_\n" if $subs{$_};
- $subs{$_} = 1;
- die "Collision: lead in sub list ", $rec->{id}, "\n"
- if $subs{ $rec->{id} };
-
- # we don't want subs below threshold
- next if ($_ < $conf->{threshold});
-
- # still here? output.
- print OUT $rec->{id}, "\t$_\n"
+ #die "Collision: dupe sub record $_\n" if $subs{$_};
+ if( not exists ($subs{$_}) ) {
+ #die "Collision: lead in sub list ", $rec->{id}, "\n"
+ # if $subs{ $rec->{id} };
+ my $lead = $rec->{id};
+
+ # we don't need to match onto itself
+ next if ($lead eq $_);
+
+ if ($subs{ $rec->{id} })
+ {
+ print "moving ".$lead." to ".$subs{$rec->{id}}."\n";
+ $lead = $subs{$rec->{id}};
+ }
+
+ if($_ eq '1459051')
+ {
+ print "looking at ".$rec->{sha1};
+ }
+
+ # we don't want subs below threshold
+ next if ($_ < $conf->{threshold});
+
+ # we don't need to match onto itself
+ next if ($lead eq $_);
+
+ # record this sub having this leader
+ $subs{$_} = $lead;
+
+ # still here? output.
+ print OUT $lead, "\t$_\n"
+ }
}
}
}
Takes three optional arguments:
---source
+
+--source
+
+Takes a numeric value and set the x_source of the bib record to that. Defaults to
+2 which is local system.
+
+--x_source
Sets an x_source value on the staging table to the one supplied instead of the
default of none.
pod2usage(-verbose => 1) if ! $ARGV[1];
my $append = 0;
-my $base_table = 'biblio_record_entry';
-my $stage_table = 'biblio_record_entry_legacy';
+my $base_table = 'm_biblio_record_entry';
+my $stage_table = 'm_biblio_record_entry_legacy';
my $auth = '';
my $serial = '';
-my $source = 'default';
+my $source = 2;
+my $x_source = 'default';
my $dbh = Mig::db_connect();
my $infile;
my $i = 0;
'file:s' => \$infile,
'serial:s' => \$serial,
'auth:s' => \$auth,
- 'source:s' => \$source,
+ 'x_source:s' => \$x_source,
+ 'source:i' => \$source,
'base_table:s' => \$base_table,
'stage_table:s' => \$stage_table
);
#if auth and serial = 1 fail
if ($serial == 1) {
- $base_table = 'authority_record_entry';
- $stage_table = 'authority_record_entry_legacy';
+ $base_table = 'm_authority_record_entry';
+ $stage_table = 'm_authority_record_entry_legacy';
}
if ($auth == 1) {
- $base_table = 'serial_record_entry';
- $stage_table = 'serial_record_entry_legacy';
+ $base_table = 'm_serial_record_entry';
+ $stage_table = 'm_serial_record_entry_legacy';
}
if ($auth == 1 and $serial == 1) { abort('are you sure you want to load these as authorities and serials?'); }
my $xmig_test = check_for_column($dbh,$stage_table,'x_migrate');
if ($xmig_test == 0) { add_column($dbh,$stage_table,'x_migrate','BOOLEAN DEFAULT TRUE'); }
-my $xsource_test = check_for_column($dbh,$stage_table,'x_source');
-if ($xsource_test == 0) { add_column($dbh,$stage_table,'x_source','TEXT'); }
+my $xx_source_test = check_for_column($dbh,$stage_table,'x_source');
+if ($xx_source_test == 0) { add_column($dbh,$stage_table,'x_source','TEXT'); }
#flatten out MARC XML FILE
open my $xml, "<:encoding(utf8)", $infile or abort('could not open MARC XML file');
chomp $line;
$record = $record . $line;
if ($line =~ /<\/record>$/) {
- stage_record($dbh,$record,$source);
+ stage_record($dbh,$record,$x_source,$source);
$record = '';
$i++;
if (($i % 100) == 0) { report_progress('Records stage', $i); }
sub stage_record {
my $dbh = shift;
my $record = shift;
- my $source = shift;
+ my $x_source = shift;
+ my $source = shift;
my $last_xact = "'$MIGSCHEMA'";
$record = '$_$' . $record . '$_$';
my $sql;
- if ($source eq 'default') { $sql = "INSERT INTO $MIGSCHEMA.$stage_table (last_xact_id,marc) VALUES ($last_xact,$record);"; }
- else { $sql = "INSERT INTO $MIGSCHEMA.$stage_table (last_xact_id,marc,x_source) VALUES ($last_xact,$record,'$source');"; }
+ if ($x_source eq 'default') { $sql = "INSERT INTO $MIGSCHEMA.$stage_table (last_xact_id,marc,source) VALUES ($last_xact,$record,$source);"; }
+ else { $sql = "INSERT INTO $MIGSCHEMA.$stage_table (last_xact_id,marc,x_source,source) VALUES ($last_xact,$record,'$x_source',$source);"; }
my $sth = $dbh->prepare($sql);
$sth->execute();
return;
,l_note TEXT
,x_migrate BOOLEAN NOT NULL DEFAULT TRUE
,x_shelf INTEGER
-) INHERITS (asset_copy_location);
+) INHERITS (m_asset_copy_location);
INSERT INTO gsheet_tracked_table
(sheet_name,table_name,tab_name,created)
<tag>money</tag> arbitrary tags, each should go in separate tag
<report_title>Migrated Billings</report_title> title used in the asciidoc output
<heading column='1'>Number of Billings.Migrated.Total</heading> period delimited
- <query>SELECT COUNT(id),x_migrate::TEXT,SUM(amount) FROM money_billing_legacy GROUP BY 2;</query> query itself, will be replaced
+ <query>SELECT COUNT(id),x_migrate::TEXT,SUM(amount) FROM m_money_billing_legacy GROUP BY 2;</query> query itself, will be replaced
<note>Arbitrary note that can be included in the entries.</note>
</report>
-->
<iteration>0</iteration>
<report_title>Migrated Circulations</report_title>
<heading>Circulation Status.Count of Circs</heading>
- <query>SELECT 'Closed Circulations', COUNT(id) FROM action_circulation_legacy WHERE xact_finish IS NOT NULL AND x_migrate
- UNION ALL SELECT 'Open Circulations', COUNT(id) FROM action_circulation_legacy WHERE xact_finish IS NULL AND x_migrate</query>
+ <query>SELECT 'Closed Circulations', COUNT(id) FROM m_action_circulation_legacy WHERE xact_finish IS NOT NULL AND x_migrate
+ UNION ALL SELECT 'Open Circulations', COUNT(id) FROM m_action_circulation_legacy WHERE xact_finish IS NULL AND x_migrate</query>
</report>
<report>
<iteration>0</iteration>
<report_title>Open Un-migrated Circulations</report_title>
<heading>Circulation Status.Count of Circs</heading>
- <query>SELECT 'No Matching User', COUNT(id) FROM action_circulation_legacy WHERE xact_finish IS NULL AND x_migrate = FALSE AND usr IS NULL
- UNION ALL SELECT 'No Matching Item', COUNT(id) FROM action_circulation_legacy WHERE xact_finish IS NULL AND x_migrate = FALSE AND target_copy IS NULL </query>
+ <query>SELECT 'No Matching User', COUNT(id) FROM m_action_circulation_legacy WHERE xact_finish IS NULL AND x_migrate = FALSE AND usr IS NULL
+ UNION ALL SELECT 'No Matching Item', COUNT(id) FROM m_action_circulation_legacy WHERE xact_finish IS NULL AND x_migrate = FALSE AND target_copy IS NULL </query>
</report>
<report>
<iteration>1</iteration>
<report_title>Open Circulations</report_title>
<heading>Circulation Status.Count of Circs</heading>
- <query>SELECT 'Closed Circulations', COUNT(id) FROM action_circulation WHERE xact_finish IS NOT NULL UNION ALL SELECT 'Open Circulations', COUNT(id) FROM action_circulation WHERE xact_finish IS NULL</query>
+ <query>SELECT 'Closed Circulations', COUNT(id) FROM m_action_circulation WHERE xact_finish IS NOT NULL UNION ALL SELECT 'Open Circulations', COUNT(id) FROM m_action_circulation WHERE xact_finish IS NULL</query>
</report>
<!-- intent is to add a report by circulated and item status
<report>
<iteration>0</iteration>
<report_title>Open Circulations</report_title>
<heading>Circulation Status.Migrated.Count of Circs</heading>
- <query>SELECT 'Closed Circulations', x_migrate::TEXT, COUNT(id) FROM action_circulation_legacy WHERE xact_finish IS NOT NULL GROUP BY 2 UNION ALL SELECT 'Open Circulations', x_migrate::TEXT, COUNT(id) FROM action_circulation_legacy WHERE xact_finish IS NULL GROUP BY 2</query>
+ <query>SELECT 'Closed Circulations', x_migrate::TEXT, COUNT(id) FROM m_action_circulation_legacy WHERE xact_finish IS NOT NULL GROUP BY 2 UNION ALL SELECT 'Open Circulations', x_migrate::TEXT, COUNT(id) FROM m_action_circulation_legacy WHERE xact_finish IS NULL GROUP BY 2</query>
</report>
-->
<report>
<iteration>0</iteration>
<report_title>Circulations by Org Unit</report_title>
<heading>Circulations Count.Migrated.Org Unit</heading>
- <query>SELECT COUNT(acirc.id), acirc.x_migrate::TEXT, aou.name FROM action_circulation_legacy acirc JOIN actor.org_unit aou ON aou.id = acirc.circ_lib WHERE acirc.xact_finish IS NULL GROUP BY 2, 3</query>
+ <query>SELECT COUNT(acirc.id), acirc.x_migrate::TEXT, aou.name FROM m_action_circulation_legacy acirc JOIN actor.org_unit aou ON aou.id = acirc.circ_lib WHERE acirc.xact_finish IS NULL GROUP BY 2, 3</query>
</report>
<report>
<iteration>1</iteration>
<report_title>Circulations by Org Unit</report_title>
<heading>Circulations Count.Org Unit</heading>
- <query>SELECT COUNT(acirc.id), aou.name FROM action_circulation acirc JOIN actor.org_unit aou ON aou.id = acirc.circ_lib WHERE acirc.xact_finish IS NULL GROUP BY 2</query>
+ <query>SELECT COUNT(acirc.id), aou.name FROM m_action_circulation acirc JOIN actor.org_unit aou ON aou.id = acirc.circ_lib WHERE acirc.xact_finish IS NULL GROUP BY 2</query>
</report>
<report>
<iteration>0</iteration>
<report_title>Migrated Circulations by Duration, Fine and Max Fine</report_title>
<heading>Count of Circs.Duration.Fine.Max Fine.Migrated</heading>
- <query>SELECT COUNT(id), duration_rule, recurring_fine_rule, max_fine_rule, x_migrate::TEXT FROM action_circulation_legacy WHERE x_migrate = TRUE GROUP BY 2, 3, 4, 5</query>
+ <query>SELECT COUNT(id), duration_rule, recurring_fine_rule, max_fine_rule, x_migrate::TEXT FROM m_action_circulation_legacy WHERE x_migrate = TRUE GROUP BY 2, 3, 4, 5</query>
</report>
<report>
<iteration>1</iteration>
<report_title>Circulations by Duration, Fine and Max Fine</report_title>
<heading>Count of Circs.Duration.Fine.Max Fine</heading>
- <query>SELECT COUNT(id), duration_rule, recurring_fine_rule, max_fine_rule FROM action_circulation GROUP BY 2, 3, 4 ORDER BY 2, 3, 4</query>
+ <query>SELECT COUNT(id), duration_rule, recurring_fine_rule, max_fine_rule FROM m_action_circulation GROUP BY 2, 3, 4 ORDER BY 2, 3, 4</query>
</report>
<report>
<iteration>0</iteration>
<report_title>Circulations by Rules and Patron Group</report_title>
<heading>Count of Circs.Duration.Fine.Max Fine.User Group.Matchpoints</heading>
- <query>SELECT COUNT(acirc.id), acirc.duration_rule, acirc.recurring_fine_rule, acirc.max_fine_rule, pgt.name, x.buildrows FROM action_circulation_legacy acirc JOIN actor.usr au ON au.id = acirc.usr JOIN permission.grp_tree pgt ON pgt.id = au.profile JOIN (SELECT acirc.id, ARRAY_TO_STRING(find_cmm(acirc.id),',') AS buildrows FROM action_circulation_legacy acirc WHERE acirc.x_migrate = TRUE) x ON x.id = acirc.id WHERE acirc.x_migrate = TRUE GROUP BY 2, 3, 4, 5, 6 ORDER BY 2, 3, 4, 5, 6</query>
+ <query>SELECT COUNT(acirc.id), acirc.duration_rule, acirc.recurring_fine_rule, acirc.max_fine_rule, pgt.name, x.buildrows FROM m_action_circulation_legacy acirc JOIN actor.usr au ON au.id = acirc.usr JOIN permission.grp_tree pgt ON pgt.id = au.profile JOIN (SELECT acirc.id, ARRAY_TO_STRING(find_cmm(acirc.id),',') AS buildrows FROM m_action_circulation_legacy acirc WHERE acirc.x_migrate = TRUE) x ON x.id = acirc.id WHERE acirc.x_migrate = TRUE GROUP BY 2, 3, 4, 5, 6 ORDER BY 2, 3, 4, 5, 6</query>
</report>
<report>
<iteration>1</iteration>
<report_title>Circulations by Rules and Patron Group</report_title>
<heading>Count of Circs.Duration.Fine.Max Fine.User Group.Matchpoints</heading>
- <query>SELECT COUNT(acirc.id), acirc.duration_rule, acirc.recurring_fine_rule, acirc.max_fine_rule, pgt.name, x.buildrows FROM action_circulation acirc JOIN actor.usr au ON au.id = acirc.usr JOIN permission.grp_tree pgt ON pgt.id = au.profile JOIN (SELECT acirc.id, ARRAY_TO_STRING(find_cmm(acirc.id),',') AS buildrows FROM action_circulation acirc) x ON x.id = acirc.id GROUP BY 2, 3, 4, 5, 6 ORDER BY 2, 3, 4, 5, 6</query>
+ <query>SELECT COUNT(acirc.id), acirc.duration_rule, acirc.recurring_fine_rule, acirc.max_fine_rule, pgt.name, x.buildrows FROM m_action_circulation acirc JOIN actor.usr au ON au.id = acirc.usr JOIN permission.grp_tree pgt ON pgt.id = au.profile JOIN (SELECT acirc.id, ARRAY_TO_STRING(find_cmm(acirc.id),',') AS buildrows FROM m_action_circulation acirc) x ON x.id = acirc.id GROUP BY 2, 3, 4, 5, 6 ORDER BY 2, 3, 4, 5, 6</query>
</report>
<report>
<iteration>0</iteration>
<report_title>Circulations by Rules and Circulation Modifier</report_title>
<heading>Count of Circs.Duration.Fine.Max Fine.Circulation Modifier.Matchpoints</heading>
- <query>SELECT COUNT(acirc.id), acirc.duration_rule, acirc.recurring_fine_rule, acirc.max_fine_rule, ac.circ_modifier, x.buildrows FROM action_circulation_legacy acirc JOIN asset.copy ac ON ac.id = acirc.target_copy JOIN (SELECT acirc.id, ARRAY_TO_STRING(find_cmm(acirc.id),',') AS buildrows FROM action_circulation_legacy acirc WHERE acirc.x_migrate = TRUE) x ON x.id = acirc.id WHERE acirc.x_migrate = TRUE GROUP BY 2, 3, 4, 5, 6 ORDER BY 2, 3, 4, 5, 6</query>
+ <query>SELECT COUNT(acirc.id), acirc.duration_rule, acirc.recurring_fine_rule, acirc.max_fine_rule, ac.circ_modifier, x.buildrows FROM m_action_circulation_legacy acirc JOIN asset.copy ac ON ac.id = acirc.target_copy JOIN (SELECT acirc.id, ARRAY_TO_STRING(find_cmm(acirc.id),',') AS buildrows FROM m_action_circulation_legacy acirc WHERE acirc.x_migrate = TRUE) x ON x.id = acirc.id WHERE acirc.x_migrate = TRUE GROUP BY 2, 3, 4, 5, 6 ORDER BY 2, 3, 4, 5, 6</query>
</report>
<report>
<iteration>1</iteration>
<report_title>Circulations by Rules and Circulation Modifier</report_title>
<heading>Count of Circs.Duration.Fine.Max Fine.Circulation Modifier.Matchpoints</heading>
- <query>SELECT COUNT(acirc.id), acirc.duration_rule, acirc.recurring_fine_rule, acirc.max_fine_rule, ac.circ_modifier, x.buildrows FROM action_circulation acirc JOIN asset.copy ac ON ac.id = acirc.target_copy JOIN (SELECT acirc.id, ARRAY_TO_STRING(find_cmm(acirc.id),',') AS buildrows FROM action_circulation acirc) x ON x.id = acirc.id
+ <query>SELECT COUNT(acirc.id), acirc.duration_rule, acirc.recurring_fine_rule, acirc.max_fine_rule, ac.circ_modifier, x.buildrows FROM m_action_circulation acirc JOIN asset.copy ac ON ac.id = acirc.target_copy JOIN (SELECT acirc.id, ARRAY_TO_STRING(find_cmm(acirc.id),',') AS buildrows FROM m_action_circulation acirc) x ON x.id = acirc.id
GROUP BY 2, 3, 4, 5, 6 ORDER BY 2, 3, 4, 5, 6</query>
</report>
<iteration>0</iteration>
<report_title>Circulations by Rules and Org Unit</report_title>
<heading>Count of Circs.Duration.Fine.Max Fine.Library Branch</heading>
- <query>SELECT COUNT(acirc.id), acirc.duration_rule, acirc.recurring_fine_rule, acirc.max_fine_rule, aou.name FROM action_circulation_legacy acirc JOIN actor.org_unit aou ON aou.id = acirc.circ_lib WHERE acirc.x_migrate = TRUE GROUP BY 2, 3, 4, 5 ORDER BY 2, 3, 4, 5</query>
+ <query>SELECT COUNT(acirc.id), acirc.duration_rule, acirc.recurring_fine_rule, acirc.max_fine_rule, aou.name FROM m_action_circulation_legacy acirc JOIN actor.org_unit aou ON aou.id = acirc.circ_lib WHERE acirc.x_migrate = TRUE GROUP BY 2, 3, 4, 5 ORDER BY 2, 3, 4, 5</query>
</report>
<report>
<iteration>1</iteration>
<report_title>Circulations by Rules and Org Unit</report_title>
<heading>Count of Circs.Duration.Fine.Max Fine.Library Branch</heading>
- <query>SELECT COUNT(acirc.id), acirc.duration_rule, acirc.recurring_fine_rule, acirc.max_fine_rule, aou.name FROM action_circulation acirc JOIN actor.org_unit aou ON aou.id = acirc.circ_lib GROUP BY 2, 3, 4, 5 ORDER BY 2, 3, 4, 5</query>
+ <query>SELECT COUNT(acirc.id), acirc.duration_rule, acirc.recurring_fine_rule, acirc.max_fine_rule, aou.name FROM m_action_circulation acirc JOIN actor.org_unit aou ON aou.id = acirc.circ_lib GROUP BY 2, 3, 4, 5 ORDER BY 2, 3, 4, 5</query>
</report>
<report>
<iteration>0</iteration>
<report_title>Non-Cataloged Circulation</report_title>
<heading>Circulations Count.Migrated</heading>
- <query>SELECT COUNT(id), x_migrate::TEXT FROM action_non_cataloged_circulation_legacy GROUP BY 2</query>
+ <query>SELECT COUNT(id), x_migrate::TEXT FROM m_action_non_cataloged_circulation_legacy GROUP BY 2</query>
</report>
<report>
<iteration>1</iteration>
<report_title>Non-Cataloged Circulation</report_title>
<heading>Circulations Count</heading>
- <query>SELECT COUNT(id) FROM action_non_cataloged_circulation</query>
+ <query>SELECT COUNT(id) FROM m_action_non_cataloged_circulation</query>
</report>
<report>
<iteration>0</iteration>
<report_title>In House Use</report_title>
<heading>In House Use Records.Migrated</heading>
- <query>SELECT COUNT(id), x_migrate::TEXT FROM action_in_house_use_legacy GROUP BY 2</query>
+ <query>SELECT COUNT(id), x_migrate::TEXT FROM m_action_in_house_use_legacy GROUP BY 2</query>
</report>
<report>
<iteration>1</iteration>
<report_title>In House Use</report_title>
<heading>In House Use Records</heading>
- <query>SELECT COUNT(id) FROM action_in_house_use</query>
+ <query>SELECT COUNT(id) FROM m_action_in_house_use</query>
</report>
<report>
<iteration>1</iteration>
<report_title>Circs Missing Rules</report_title>
<heading>Count.Field Missing</heading>
- <query>SELECT COUNT(id), 'Duration Rule Value' FROM action_circulation WHERE duration IS NULL
- UNION ALL SELECT COUNT(id), 'Recurring Fine Rule Value' FROM action_circulation WHERE recurring_fine IS NULL
- UNION ALL SELECT COUNT(id), 'Max Fine Rule Value' FROM action_circulation WHERE max_fine IS NULL
- UNION ALL SELECT COUNT(id), 'Duration Rule' FROM action_circulation WHERE duration_rule IS NULL
- UNION ALL SELECT COUNT(id), 'Recurring Fine Rule' FROM action_circulation WHERE recurring_fine_rule IS NULL
- UNION ALL SELECT COUNT(id), 'Max Fine Rule' FROM action_circulation WHERE max_fine_rule IS NULL
+ <query>SELECT COUNT(id), 'Duration Rule Value' FROM m_action_circulation WHERE duration IS NULL
+ UNION ALL SELECT COUNT(id), 'Recurring Fine Rule Value' FROM m_action_circulation WHERE recurring_fine IS NULL
+ UNION ALL SELECT COUNT(id), 'Max Fine Rule Value' FROM m_action_circulation WHERE max_fine IS NULL
+ UNION ALL SELECT COUNT(id), 'Duration Rule' FROM m_action_circulation WHERE duration_rule IS NULL
+ UNION ALL SELECT COUNT(id), 'Recurring Fine Rule' FROM m_action_circulation WHERE recurring_fine_rule IS NULL
+ UNION ALL SELECT COUNT(id), 'Max Fine Rule' FROM m_action_circulation WHERE max_fine_rule IS NULL
</query>
</report>
<iteration>0</iteration>
<report_title>Open Circulation and Status of Linked Items</report_title>
<heading>Count.Status</heading>
- <query>SELECT COUNT(acirc.id), ccs.name FROM action.circulation acirc JOIN asset.copy ac ON ac.id = acirc.target_copy JOIN config.copy_status ccs ON ccs.id = ac.status WHERE acirc.xact_finish IS NULL AND acirc.checkin_time IS NULL AND acirc.id IN (SELECT id FROM action_circulation) GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(acirc.id), ccs.name FROM action.circulation acirc JOIN asset.copy ac ON ac.id = acirc.target_copy JOIN config.copy_status ccs ON ccs.id = ac.status WHERE acirc.xact_finish IS NULL AND acirc.checkin_time IS NULL AND acirc.id IN (SELECT id FROM m_action_circulation) GROUP BY 2 ORDER BY 2</query>
</report>
<!-- HOLDS REPORTS -->
<iteration>0</iteration>
<report_title>Migrated Holds</report_title>
<heading>Hold Type.Hold Count.Migrated</heading>
- <query>SELECT 'Closed Holds', COUNT(id), x_migrate::TEXT FROM action_hold_request_legacy WHERE (expire_time::TIMESTAMP < now()) OR cancel_time IS NOT NULL OR fulfillment_time IS NOT NULL GROUP BY 3 UNION ALL SELECT 'Open Holds', COUNT(id), x_migrate::TEXT FROM action_hold_request_legacy WHERE (expire_time IS NULL OR expire_time::TIMESTAMP > now()) AND cancel_time IS NULL AND fulfillment_time IS NULL GROUP BY 3</query>
+ <query>SELECT 'Closed Holds', COUNT(id), x_migrate::TEXT FROM m_action_hold_request_legacy WHERE (expire_time::TIMESTAMP < now()) OR cancel_time IS NOT NULL OR fulfillment_time IS NOT NULL GROUP BY 3 UNION ALL SELECT 'Open Holds', COUNT(id), x_migrate::TEXT FROM m_action_hold_request_legacy WHERE (expire_time IS NULL OR expire_time::TIMESTAMP > now()) AND cancel_time IS NULL AND fulfillment_time IS NULL GROUP BY 3</query>
</report>
<report>
<iteration>0</iteration>
<report_title>Migrated Holds By Type</report_title>
<heading>Hold Type.Hold Count.Migrated</heading>
- <query>SELECT hold_type as "Hold Type", COUNT(id), x_migrate::TEXT FROM action_hold_request_legacy GROUP BY 1, 3</query>
+ <query>SELECT hold_type as "Hold Type", COUNT(id), x_migrate::TEXT FROM m_action_hold_request_legacy GROUP BY 1, 3</query>
</report>
<report>
<iteration>0</iteration>
<report_title>Transit Copy Records and Status of Linked Items</report_title>
<heading>Count.Status</heading>
- <query>SELECT COUNT(atc.id), ccs.name FROM action.transit_copy atc JOIN asset.copy ac ON ac.id = atc.target_copy JOIN config.copy_status ccs ON ccs.id = ac.status WHERE atc.id IN (SELECT id FROM action_transit_copy) AND atc.dest_recv_time IS NULL GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(atc.id), ccs.name FROM action.transit_copy atc JOIN asset.copy ac ON ac.id = atc.target_copy JOIN config.copy_status ccs ON ccs.id = ac.status WHERE atc.id IN (SELECT id FROM m_action_transit_copy) AND atc.dest_recv_time IS NULL GROUP BY 2 ORDER BY 2</query>
</report>
<report>
<iteration>0</iteration>
<report_title>Status of Items with Count of Open In Transits</report_title>
<heading>Count.Status.Count of Open Transits</heading>
- <query>SELECT COUNT(ac.id), ccs.name, SUM(CASE WHEN atc.id IS NULL THEN 0 ELSE 1 END) FROM asset.copy ac JOIN config.copy_status ccs ON ccs.id = ac.status LEFT JOIN (SELECT * FROM action.transit_copy WHERE id IN (SELECT id FROM action_transit_copy) AND dest_recv_time IS NULL) atc ON atc.target_copy = ac.id WHERE ac.id IN (SELECT id from asset_copy) GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(ac.id), ccs.name, SUM(CASE WHEN atc.id IS NULL THEN 0 ELSE 1 END) FROM asset.copy ac JOIN config.copy_status ccs ON ccs.id = ac.status LEFT JOIN (SELECT * FROM action.transit_copy WHERE id IN (SELECT id FROM m_action_transit_copy) AND dest_recv_time IS NULL) atc ON atc.target_copy = ac.id WHERE ac.id IN (SELECT id from m_asset_copy) GROUP BY 2 ORDER BY 2</query>
</report>
<report>
<iteration>0</iteration>
<report_title>Captured Holds with Status of Items</report_title>
<heading>Count of Captured Hold.Status of Item</heading>
- <query>SELECT COUNT(ahr.id), ccs.name FROM action.hold_request ahr JOIN asset.copy ac ON ac.id = ahr.current_copy JOIN config.copy_status ccs ON ccs.id = ac.status WHERE ahr.capture_time IS NOT NULL AND ahr.fulfillment_time IS NULL and ahr.cancel_time IS NULL AND ahr.id IN (SELECT id FROM action_hold_request) GROUP BY 2 ORDER By 2</query>
+ <query>SELECT COUNT(ahr.id), ccs.name FROM action.hold_request ahr JOIN asset.copy ac ON ac.id = ahr.current_copy JOIN config.copy_status ccs ON ccs.id = ac.status WHERE ahr.capture_time IS NOT NULL AND ahr.fulfillment_time IS NULL and ahr.cancel_time IS NULL AND ahr.id IN (SELECT id FROM m_action_hold_request) GROUP BY 2 ORDER By 2</query>
</report>
<report>
<iteration>0</iteration>
<report_title>Depth of Unfilled Holds</report_title>
<heading>Count.Depth</heading>
- <query>SELECT COUNT(ahr.id), ahr.selection_depth FROM action.hold_request ahr WHERE ahr.id IN (SELECT id FROM action_hold_request) AND ahr.cancel_time IS NULL AND ahr.capture_time IS NULL AND ahr.fulfillment_time IS NULL GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(ahr.id), ahr.selection_depth FROM action.hold_request ahr WHERE ahr.id IN (SELECT id FROM m_action_hold_request) AND ahr.cancel_time IS NULL AND ahr.capture_time IS NULL AND ahr.fulfillment_time IS NULL GROUP BY 2 ORDER BY 2</query>
</report>
<!-- ASSET REPORTS -->
<report>
- <name>asset_copy_count</name>
+ <name>m_asset_copy_count</name>
<report_title>Count of Copies by Library</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Copy Count.Library.Migrated</heading>
- <query>SELECT COUNT(ac.id), aou.name, ac.x_migrate::TEXT FROM asset_copy_legacy ac JOIN actor.org_unit aou ON aou.id = ac.circ_lib GROUP BY 2, 3 ORDER BY 2, 3</query>
+ <query>SELECT COUNT(ac.id), aou.name, ac.x_migrate::TEXT FROM m_asset_copy_legacy ac JOIN actor.org_unit aou ON aou.id = ac.circ_lib GROUP BY 2, 3 ORDER BY 2, 3</query>
</report>
<report>
- <name>asset_deleted_copies</name>
+ <name>m_asset_deleted_copies</name>
<report_title>Deleted Copies</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Copy Count.Deleted.Migrated</heading>
- <query>SELECT COUNT(ac.id), ac.deleted::TEXT, ac.x_migrate::TEXT FROM asset_copy_legacy ac GROUP BY 2, 3</query>
+ <query>SELECT COUNT(ac.id), ac.deleted::TEXT, ac.x_migrate::TEXT FROM m_asset_copy_legacy ac GROUP BY 2, 3</query>
</report>
<report>
- <name>asset_copies_by_status</name>
+ <name>m_asset_copies_by_status</name>
<report_title>Copies by Status</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Copy Count.Status.Migrated</heading>
- <query>SELECT COUNT(ac.id), cs.name, ac.x_migrate::TEXT FROM asset_copy_legacy ac JOIN config.copy_status cs ON cs.id = ac.status GROUP BY 2, 3 ORDER BY 2, 3</query>
+ <query>SELECT COUNT(ac.id), cs.name, ac.x_migrate::TEXT FROM m_asset_copy_legacy ac JOIN config.copy_status cs ON cs.id = ac.status GROUP BY 2, 3 ORDER BY 2, 3</query>
</report>
<report>
- <name>asset_circ_mod_copies_count</name>
+ <name>m_asset_circ_mod_copies_count</name>
<report_title>Copies by Circulation Modifier</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Copy Count.Circulation Modifier.Migrated</heading>
- <query>SELECT COUNT(ac.id), ac.circ_modifier, ac.x_migrate::TEXT FROM asset_copy_legacy ac GROUP BY 2, 3 ORDER BY 2, 3</query>
+ <query>SELECT COUNT(ac.id), ac.circ_modifier, ac.x_migrate::TEXT FROM m_asset_copy_legacy ac GROUP BY 2, 3 ORDER BY 2, 3</query>
</report>
<report>
- <name>asset_copy_notes</name>
+ <name>m_asset_copy_notes</name>
<report_title>Copy Notes</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Note Count.Public.Migrated</heading>
- <query>SELECT COUNT(acnote.id), acnote.pub::TEXT, acnote.x_migrate::TEXT FROM asset_copy_note_legacy acnote GROUP BY 2, 3 ORDER BY 2, 3</query>
+ <query>SELECT COUNT(acnote.id), acnote.pub::TEXT, acnote.x_migrate::TEXT FROM m_asset_copy_note_legacy acnote GROUP BY 2, 3 ORDER BY 2, 3</query>
</report>
<report>
- <name>asset_copy_notes</name>
+ <name>m_asset_copy_notes</name>
<report_title>Copy Notes</report_title>
<tag>assets</tag>
<iteration>1</iteration>
<heading>Note Count.Public</heading>
- <query>SELECT COUNT(acnote.id), acnote.pub::TEXT FROM asset_copy_note acnote GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(acnote.id), acnote.pub::TEXT FROM m_asset_copy_note acnote GROUP BY 2 ORDER BY 2</query>
</report>
<report>
- <name>asset_vols_by_lib</name>
+ <name>m_asset_vols_by_lib</name>
<report_title>Volumes by Library</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Volume Count.Library.Migrated</heading>
- <query>SELECT COUNT(acn.id), aou.name, acn.x_migrate::TEXT FROM asset_call_number_legacy acn JOIN actor_org_unit_legacy aou ON aou.id = acn.owning_lib GROUP BY 2, 3 ORDER BY 2, 3</query>
+ <query>SELECT COUNT(acn.id), aou.name, acn.x_migrate::TEXT FROM m_asset_call_number_legacy acn JOIN m_actor_org_unit_legacy aou ON aou.id = acn.owning_lib GROUP BY 2, 3 ORDER BY 2, 3</query>
</report>
<report>
- <name>asset_vols_by_lib</name>
+ <name>m_asset_vols_by_lib</name>
<report_title>Volumes by Library</report_title>
<tag>assets</tag>
<iteration>1</iteration>
<heading>Volume Count.Library</heading>
- <query>SELECT COUNT(acn.id), aou.name FROM asset_call_number acn JOIN actor.org_unit aou ON aou.id = acn.owning_lib GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(acn.id), aou.name FROM m_asset_call_number acn JOIN actor.org_unit aou ON aou.id = acn.owning_lib GROUP BY 2 ORDER BY 2</query>
</report>
- <!--
- <report>
- <name>asset_cops_by_loc</name>
- <report_title>Copies by Location</report_title>
- <tag>assets</tag>
- <iteration>0</iteration>
- <heading>Copy Count.Library.Migrated</heading>
- <query>SELECT COUNT(ac.id), acl.name, ac.x_migrate::TEXT FROM asset_copy_legacy ac JOIN asset.copy_location acl ON acl.id = ac.location GROUP BY 2, 3 ORDER BY 2, 3</query>
- </report>
- -->
+
<report>
- <name>asset_cops_by_loc_and_org</name>
+ <name>m_asset_cops_by_loc_and_org</name>
<report_title>Copies by Location</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Copy Count.Library.Circ Library.Migrated</heading>
- <query>SELECT COUNT(ac.id), acl.name, aou.name, ac.x_migrate::TEXT FROM asset_copy_legacy ac JOIN asset.copy_location acl ON acl.id = ac.location JOIN actor.org_unit aou ON aou.id = ac.circ_lib GROUP BY 2, 3, 4 ORDER BY 2, 3, 4</query>
+ <query>SELECT COUNT(ac.id), acl.name, aou.name, ac.x_migrate::TEXT FROM m_asset_copy_legacy ac JOIN asset.copy_location acl ON acl.id = ac.location JOIN actor.org_unit aou ON aou.id = ac.circ_lib GROUP BY 2, 3, 4 ORDER BY 2, 3, 4</query>
</report>
<report>
- <name>asset_cops_w_loc_one</name>
+ <name>m_asset_cops_w_loc_one</name>
<report_title>Copies with a Location of Stacks</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Barcode</heading>
- <query>SELECT barcode FROM asset_copy_legacy WHERE location = 1 AND x_migrate</query>
+ <query>SELECT barcode FROM m_asset_copy_legacy WHERE location = 1 AND x_migrate</query>
</report>
- <!-- report>
- <name>asset_barcode_lengths</name>
- <report_title>Barcode Lengths by Library</report_title>
- <tag>assets</tag>
- <iteration>0</iteration>
- <heading>Count of Barcode.Barcode Length.Library</heading>
- <query>SELECT COUNT(ac.id), LENGTH(ac.barcode), aou.name FROM asset_copy_legacy ac JOIN actor.org_unit aou ON aou.id = ac.circ_lib WHERE ac.x_migrate = TRUE GROUP BY 2, 3 ORDER BY 3, 2</query>
- </report -->
-
<report>
- <name>asset_no_barcode</name>
+ <name>m_asset_no_barcode</name>
<report_title>Items Without Barcodes</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Assigned Barcode</heading>
- <query>SELECT barcode FROM asset_copy_legacy WHERE barcode ~* 'no_barocde' AND x_migrate</query>
+ <query>SELECT barcode FROM m_asset_copy_legacy WHERE barcode ~* 'no_barocde' AND x_migrate</query>
</report>
<report>
- <name>asset_barcode_patterns</name>
+ <name>m_asset_barcode_patterns</name>
<report_title>Common Barcode Starting Patterns</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Count of Barcodes (greater than 10).Left 60% of Characters</heading>
- <query>SELECT COUNT(ac.id), LEFT(ac.barcode,(ROUND(LENGTH(ac.barcode)*.6))::INT) FROM asset_copy_legacy ac WHERE ac.x_migrate = TRUE GROUP BY 2 HAVING COUNT(ac.id) > 10 ORDER BY 2</query>
+ <query>SELECT COUNT(ac.id), LEFT(ac.barcode,(ROUND(LENGTH(ac.barcode)*.6))::INT) FROM m_asset_copy_legacy ac WHERE ac.x_migrate = TRUE GROUP BY 2 HAVING COUNT(ac.id) > 10 ORDER BY 2</query>
</report>
<report>
- <name>asset_barcode_incumbent_collisions</name>
- <report_title>Copy Barcode Incumbent Collisions</report_title>
+ <name>m_asset_barcode_collisions</name>
+ <report_title>Copy Barcode Collisions</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Collision Count</heading>
- <query>SELECT COUNT(id) FROM asset_copy_legacy WHERE x_migrate = TRUE AND barcode ~* 'collision' and barcode ~* 'incumbent'</query>
+ <query>SELECT COUNT(id) FROM m_asset_copy_legacy WHERE x_migrate = TRUE AND barcode LIKE 'x_%'</query>
<note>Incumbent collisions are those where the migrated barcodes collide with existing barcodes in the database.</note>
</report>
<report>
- <name>asset_barcode_incumbent_collisions</name>
- <report_title>Copy Barcode Incumbent Collisions</report_title>
+ <name>m_asset_barcode_collisions</name>
+ <report_title>Copy Barcode Collisions</report_title>
<tag>assets</tag>
<iteration>1</iteration>
<heading>Collision Count</heading>
- <query>SELECT COUNT(id) FROM asset_copy WHERE barcode ~* 'collision' and barcode ~* 'incumbent'</query>
+ <query>SELECT COUNT(id) FROM m_asset_copy WHERE barcode LIKE 'x_%'</query>
<note>Incumbent collisions are those where the migrated barcodes collide with existing barcodes in the database.</note>
</report>
<report>
- <name>asset_barcode_internal_collisions</name>
- <report_title>Copy Barcode Internal Collisions</report_title>
- <tag>assets</tag>
- <iteration>0</iteration>
- <heading>Collision Count</heading>
- <query>SELECT COUNT(id) FROM asset_copy_legacy WHERE x_migrate = TRUE AND barcode ~* 'collision' and barcode ~* 'internal'</query>
- <note>Internal collisions are those where the migrated barcodes have conflicts within their list of barcodes.</note>
- </report>
-
- <report>
- <name>asset_barcode_internal_collisions</name>
- <report_title>Copy Barcode Internal Collisions</report_title>
- <tag>assets</tag>
- <iteration>1</iteration>
- <heading>Collision Count</heading>
- <query>SELECT COUNT(id) FROM asset_copy WHERE barcode ~* 'collision' and barcode ~* 'internal'</query>
- <note>Internal collisions are those where the migrated barcodes have conflicts within their list of barcodes.</note>
- </report>
-
- <report>
- <name>asset_barcode_collisions_shortlist</name>
+ <name>m_asset_barcode_collisions_shortlist</name>
<report_title>Copy Barcode Collisions (first 20)</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Collision List</heading>
- <query>SELECT ac.barcode FROM asset_copy_legacy ac WHERE ac.barcode ~* 'collision' ORDER BY 1 LIMIT 20</query>
+ <query>SELECT ac.barcode FROM m_asset_copy_legacy ac WHERE ac.barcode LIKE 'x_%' ORDER BY 1 LIMIT 20</query>
<note>This is a shortlist of copy barcode collisions that maxes out at 20. If there are more collisions we will need to run a custom report.</note>
</report>
<report>
- <name>asset_barcode_collisions_shortlist</name>
+ <name>m_asset_barcode_collisions_shortlist</name>
<report_title>Copy Barcode Collisions (first 20)</report_title>
<tag>assets</tag>
<iteration>1</iteration>
<heading>Collision List</heading>
- <query>SELECT ac.barcode FROM asset_copy ac WHERE ac.barcode ~* 'collision' ORDER BY 1 LIMIT 20</query>
+ <query>SELECT ac.barcode FROM m_asset_copy ac WHERE ac.barcode LIKE 'x_%' ORDER BY 1 LIMIT 20</query>
<note>This is a shortlist of patron barcode collisions that maxes out at 20. If there are more collisions we will need to run a custom report.</note>
</report>
<report>
- <name>asset_barcode_collision_patterns</name>
+ <name>m_asset_barcode_collision_patterns</name>
<report_title>Common Copy Barcode Collision Patterns</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Number of Barcodes Matching Pattern Greater than 10.Left 60% of Characters</heading>
- <query>SELECT COUNT(ac.id), LEFT(ac.barcode,(ROUND(LENGTH(ac.barcode)*.6))::INT) FROM asset_copy_legacy ac WHERE barcode ~* 'collision' GROUP BY 2 HAVING COUNT(ac.id) > 10 ORDER BY 2</query>
+ <query>SELECT COUNT(ac.id), LEFT(ac.barcode,(ROUND(LENGTH(ac.barcode)*.6))::INT) FROM m_asset_copy_legacy ac WHERE barcode LIKE 'x_%' GROUP BY 2 HAVING COUNT(ac.id) > 10 ORDER BY 2</query>
</report>
<report>
- <name>asset_barcode_collision_patterns</name>
+ <name>m_asset_barcode_collision_patterns</name>
<report_title>Common Copy Barcode Collision Patterns</report_title>
<tag>assets</tag>
<iteration>1</iteration>
<heading>Number of Barcodes Matching Pattern Greater than 10.Left 60% of Characters</heading>
- <query>SELECT COUNT(ac.id), LEFT(ac.barcode,(ROUND(LENGTH(ac.barcode)*.6))::INT) FROM asset_copy ac WHERE barcode ~* 'collision' GROUP BY 2 HAVING COUNT(ac.id) > 10 ORDER BY 2</query>
+ <query>SELECT COUNT(ac.id), LEFT(ac.barcode,(ROUND(LENGTH(ac.barcode)*.6))::INT) FROM m_asset_copy ac WHERE barcode LIKE 'x_%' GROUP BY 2 HAVING COUNT(ac.id) > 10 ORDER BY 2</query>
</report>
<report>
- <name>asset_stat_cats</name>
+ <name>m_asset_stat_cats</name>
<report_title>Copy Statistical Categories</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Stat Cat Count.Library.Statistical Category</heading>
- <query>SELECT COUNT(ac_sc.id), aou.name, ac_sc.name FROM asset_stat_cat_legacy ac_sc JOIN actor.org_unit aou ON aou.id = ac_sc.owner GROUP BY 2,3 ORDER BY 2,3</query>
+ <query>SELECT COUNT(ac_sc.id), aou.name, ac_sc.name FROM m_asset_stat_cat_legacy ac_sc JOIN actor.org_unit aou ON aou.id = ac_sc.owner GROUP BY 2,3 ORDER BY 2,3</query>
</report>
<report>
- <name>asset_stat_cats</name>
+ <name>m_asset_stat_cats</name>
<report_title>Copy Statistical Categories</report_title>
<tag>assets</tag>
<iteration>1</iteration>
<heading>Stat Cat Count.Library.Statistical Category</heading>
- <query>SELECT COUNT(ac_sc.id), aou.name, ac_sc.name FROM asset_stat_cat ac_sc JOIN actor.org_unit aou ON aou.id = ac_sc.owner GROUP BY 2,3 ORDER BY 2,3</query>
+ <query>SELECT COUNT(ac_sc.id), aou.name, ac_sc.name FROM m_asset_stat_cat ac_sc JOIN actor.org_unit aou ON aou.id = ac_sc.owner GROUP BY 2,3 ORDER BY 2,3</query>
</report>
<report>
- <name>asset_stat_cat_entries</name>
+ <name>m_asset_stat_cat_entries</name>
<report_title>Copy Stat Cat User Entries</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Copy Stat Count.Library.Statistical Category</heading>
- <query>SELECT COUNT(map.id), aou.name, ac_sc.name FROM asset_stat_cat_entry_copy_map_legacy map JOIN asset_stat_cat_legacy ac_sc ON ac_sc.id = map.stat_cat JOIN actor.org_unit aou ON aou.id = ac_sc.owner GROUP BY 2,3 ORDER BY 2,3</query>
+ <query>SELECT COUNT(map.id), aou.name, ac_sc.name FROM m_asset_stat_cat_entry_copy_map_legacy map JOIN m_asset_stat_cat_legacy ac_sc ON ac_sc.id = map.stat_cat JOIN actor.org_unit aou ON aou.id = ac_sc.owner GROUP BY 2,3 ORDER BY 2,3</query>
</report>
<report>
- <name>asset_stat_cat_entries</name>
+ <name>m_asset_stat_cat_entries</name>
<report_title>Copy Stat Cat User Entries</report_title>
<tag>assets</tag>
<iteration>1</iteration>
<heading>Copy Stat Count.Library.Statistical Category</heading>
- <query>SELECT COUNT(map.id), aou.name, ac_sc.name FROM asset_stat_cat_entry_copy_map map JOIN asset_stat_cat ac_sc ON ac_sc.id = map.stat_cat JOIN actor.org_unit aou ON aou.
+ <query>SELECT COUNT(map.id), aou.name, ac_sc.name FROM m_asset_stat_cat_entry_copy_map map JOIN m_asset_stat_cat ac_sc ON ac_sc.id = map.stat_cat JOIN actor.org_unit aou ON aou.
id = ac_sc.owner GROUP BY 2,3 ORDER BY 2,3</query>
</report>
<report>
- <name>asset_copy_tags</name>
+ <name>m_asset_copy_tags</name>
<report_title>Copy Tags</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Tag Count.Copy Tag Type.Copy Tag Label.Staff Note.Public</heading>
- <query>SELECT COUNT(map.id), tag.tag_type, tag.label, tag.staff_note, tag.pub FROM asset_copy_tag tag JOIN asset_copy_tag_copy_map map ON map.tag = tag.id GROUP BY 2,3,4,5 ORDER BY 2,3</query>
+ <query>SELECT COUNT(map.id), tag.tag_type, tag.label, tag.staff_note, tag.pub FROM m_asset_copy_tag tag JOIN m_asset_copy_tag_copy_map map ON map.tag = tag.id GROUP BY 2,3,4,5 ORDER BY 2,3</query>
</report>
<report>
- <name>asset_copy_alerts</name>
+ <name>m_asset_copy_alerts</name>
<report_title>Copy Alerts</report_title>
<tag>assets</tag>
<iteration>0</iteration>
<heading>Alert Count.Alert Type</heading>
- <query>SELECT COUNT(*), cat.name FROM asset_copy_alert aca JOIN config.copy_alert_type cat ON cat.id = aca.alert_type GROUP BY 2</query>
+ <query>SELECT COUNT(*), cat.name FROM m_asset_copy_alert aca JOIN config.copy_alert_type cat ON cat.id = aca.alert_type GROUP BY 2</query>
</report>
<!-- MONEY REPORTS -->
<report>
- <name>money_billing_voided</name>
+ <name>m_money_billing_voided</name>
<report_title>Bills Voided And Not</report_title>
<tag>money</tag>
<iteration>0</iteration>
<heading>Count.Voided.Sum.Migrated</heading>
- <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount), a.x_migrate::TEXT FROM money_billing_legacy a GROUP BY 2, 4 ORDER BY 2, 4</query>
+ <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount), a.x_migrate::TEXT FROM m_money_billing_legacy a GROUP BY 2, 4 ORDER BY 2, 4</query>
</report>
<report>
- <name>money_billing_voided</name>
+ <name>m_money_billing_voided</name>
<report_title>Bills Voided And Not</report_title>
<tag>money</tag>
<iteration>1</iteration>
<heading>Count.Voided.Sum</heading>
- <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount) FROM money_billing a GROUP BY 2 ORDER BY 2, 3</query>
+ <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount) FROM m_money_billing a GROUP BY 2 ORDER BY 2, 3</query>
</report>
<report>
- <name>money_billing_by_type</name>
+ <name>m_money_billing_by_type</name>
<report_title>Bills by Type</report_title>
<tag>money</tag>
<iteration>0</iteration>
<heading>Count.Billing Type.Migrated</heading>
- <query>SELECT COUNT(a.id), a.billing_type, a.x_migrate::TEXT FROM money_billing_legacy a GROUP BY 2, 3 ORDER BY 2, 3</query>
+ <query>SELECT COUNT(a.id), a.billing_type, a.x_migrate::TEXT FROM m_money_billing_legacy a GROUP BY 2, 3 ORDER BY 2, 3</query>
</report>
<report>
- <name>money_billing_by_type</name>
+ <name>m_money_billing_by_type</name>
<report_title>Bills by Type</report_title>
<tag>money</tag>
<iteration>1</iteration>
<heading>Count.Billing Type</heading>
- <query>SELECT COUNT(a.id), a.billing_type FROM money_billing a GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(a.id), a.billing_type FROM m_money_billing a GROUP BY 2 ORDER BY 2</query>
</report>
<report>
- <name>money_cash_payment</name>
+ <name>m_money_cash_payment</name>
<report_title>Cash Payments</report_title>
<tag>money</tag>
<iteration>0</iteration>
<heading>Count.Voided.Sum.Migrated</heading>
- <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount), a.x_migrate::TEXT FROM money_cash_payment_legacy a GROUP BY 2, 4 ORDER BY 2, 4</query>
+ <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount), a.x_migrate::TEXT FROM m_money_cash_payment_legacy a GROUP BY 2, 4 ORDER BY 2, 4</query>
</report>
<report>
- <name>money_cash_payment</name>
+ <name>m_money_cash_payment</name>
<report_title>Cash Payments</report_title>
<tag>money</tag>
<iteration>1</iteration>
<heading>Count.Voided.Sum</heading>
- <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount) FROM money_cash_payment a GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount) FROM m_money_cash_payment a GROUP BY 2 ORDER BY 2</query>
</report>
<report>
- <name>money_check_payment</name>
+ <name>m_money_check_payment</name>
<report_title>Check Payments</report_title>
<tag>money</tag>
<iteration>0</iteration>
<heading>Count.Voided.Sum.Migrated</heading>
- <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount), a.x_migrate::TEXT FROM money_check_payment_legacy a GROUP BY 2, 4 ORDER BY 2, 4</query>
+ <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount), a.x_migrate::TEXT FROM m_money_check_payment_legacy a GROUP BY 2, 4 ORDER BY 2, 4</query>
</report>
<report>
- <name>money_forgive_payment</name>
+ <name>m_money_forgive_payment</name>
<report_title>Forgive Payments</report_title>
<tag>money</tag>
<iteration>0</iteration>
<heading>Count.Voided.Sum.Migrated</heading>
- <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount), a.x_migrate::TEXT FROM money_forgive_payment_legacy a GROUP BY 2, 4 ORDER BY 2, 4</query>
+ <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount), a.x_migrate::TEXT FROM m_money_forgive_payment_legacy a GROUP BY 2, 4 ORDER BY 2, 4</query>
</report>
<report>
- <name>money_forgive_payment</name>
+ <name>m_money_forgive_payment</name>
<report_title>Forgive Payments</report_title>
<tag>money</tag>
<iteration>1</iteration>
<heading>Count.Voided.Sum</heading>
- <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount) FROM money_forgive_paymen a GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount) FROM m_money_forgive_paymen a GROUP BY 2 ORDER BY 2</query>
</report>
<report>
- <name>money_goods_payment</name>
+ <name>m_money_goods_payment</name>
<report_title>Goods Payments</report_title>
<tag>money</tag>
<iteration>0</iteration>
<heading>Count.Voided.Sum.Migrated</heading>
- <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount), a.x_migrate::TEXT FROM money_goods_payment_legacy a GROUP BY 2, 4 ORDER BY 2, 4</query>
+ <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount), a.x_migrate::TEXT FROM m_money_goods_payment_legacy a GROUP BY 2, 4 ORDER BY 2, 4</query>
</report>
<report>
- <name>money_work_payment</name>
+ <name>m_money_work_payment</name>
<report_title>Work Payments</report_title>
<tag>money</tag>
<iteration>0</iteration>
<heading>Count.Voided.Sum.Migrated</heading>
- <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount), a.x_migrate::TEXT FROM money_work_payment_legacy a GROUP BY 2, 4 ORDER BY 2, 4</query>
+ <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount), a.x_migrate::TEXT FROM m_money_work_payment_legacy a GROUP BY 2, 4 ORDER BY 2, 4</query>
</report>
<report>
- <name>money_credit_card_payment</name>
+ <name>m_money_credit_card_payment</name>
<report_title>Credit Card Payments</report_title>
<tag>money</tag>
<iteration>0</iteration>
<heading>Count.Voided.Sum.Migrated</heading>
- <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount), a.x_migrate::TEXT FROM money_credit_card_payment_legacy a GROUP BY 2, 4 ORDER BY 2, 4</query>
+ <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount), a.x_migrate::TEXT FROM m_money_credit_card_payment_legacy a GROUP BY 2, 4 ORDER BY 2, 4</query>
</report>
<report>
- <name>money_credit_payment</name>
+ <name>m_money_credit_payment</name>
<report_title>Credit Payments</report_title>
<tag>money</tag>
<iteration>0</iteration>
<heading>Count.Voided.Sum.Migrated</heading>
- <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount), a.x_migrate::TEXT FROM money_credit_payment_legacy a GROUP BY 2, 4 ORDER BY 2, 4</query>
+ <query>SELECT COUNT(a.id), a.voided::TEXT, SUM(a.amount), a.x_migrate::TEXT FROM m_money_credit_payment_legacy a GROUP BY 2, 4 ORDER BY 2, 4</query>
</report>
<tag>bibs</tag>
<iteration>0</iteration>
<heading>Count</heading>
- <query>SELECT COUNT(bre.id) FROM biblio_record_entry_legacy bre WHERE id IN (SELECT id FROM biblio.record_entry) ORDER BY 1</query>
+ <query>SELECT COUNT(bre.id) FROM m_biblio_record_entry_legacy bre WHERE id IN (SELECT id FROM biblio.record_entry) ORDER BY 1</query>
</report>
<report>
<tag>bibs</tag>
<iteration>1</iteration>
<heading>Count</heading>
- <query>SELECT COUNT(bre.id) FROM biblio_record_entry bre WHERE id IN (SELECT id FROM biblio.record_entry) ORDER BY 1</query>
+ <query>SELECT COUNT(bre.id) FROM m_biblio_record_entry bre WHERE id IN (SELECT id FROM biblio.record_entry) ORDER BY 1</query>
</report>
<report>
<tag>bibs</tag>
<iteration>0</iteration>
<heading>Count</heading>
- <query>SELECT COUNT(id) FROM biblio_record_entry where id NOT IN (SELECT DISTINCT record FROM asset_call_number)</query>
+ <query>SELECT COUNT(id) FROM m_biblio_record_entry where id NOT IN (SELECT DISTINCT record FROM m_asset_call_number)</query>
<note>These records would not have been loaded.</note>
</report>
<tag>bibs</tag>
<iteration>0</iteration>
<heading>Count</heading>
- <query>SELECT COUNT(id) FROM biblio_record_entry where id IN (SELECT record FROM asset.call_number WHERE label ~* '##URI##')</query>
+ <query>SELECT COUNT(id) FROM m_biblio_record_entry where id IN (SELECT record FROM asset.call_number WHERE label ~* '##URI##')</query>
</report>
<report>
<tag>bibs</tag>
<iteration>0</iteration>
<heading>Count.Original Search Format.New Search Format</heading>
- <query>SELECT COUNT(*), ARRAY_TO_STRING(x_search_format,','), ARRAY_TO_STRING(x_after_search_format,',') FROM biblio_record_entry_legacy WHERE x_migrate AND x_after_search_format IS NOT NULL GROUP BY 2, 3 ORDER BY 3,2</query>
+ <query>SELECT COUNT(*), ARRAY_TO_STRING(x_search_format,','), ARRAY_TO_STRING(x_after_search_format,',') FROM m_biblio_record_entry_legacy WHERE x_migrate AND x_after_search_format IS NOT NULL GROUP BY 2, 3 ORDER BY 3,2</query>
</report>
<report>
<tag>bibs</tag>
<iteration>0</iteration>
<heading>Count.Migrated</heading>
- <query>SELECT COUNT(b.id), b.x_migrate::TEXT FROM biblio_record_note_legacy b GROUP BY 2</query>
+ <query>SELECT COUNT(b.id), b.x_migrate::TEXT FROM m_biblio_record_note_legacy b GROUP BY 2</query>
</report>
<report>
<tag>bibs</tag>
<iteration>1</iteration>
<heading>Count</heading>
- <query>SELECT COUNT(b.id) FROM biblio_record_note b</query>
+ <query>SELECT COUNT(b.id) FROM m_biblio_record_note b</query>
</report>
<report>
<tag>bibs</tag>
<iteration>0</iteration>
<heading>Count.Migrated</heading>
- <query>SELECT COUNT(b.id), b.x_migrate::TEXT FROM biblio_peer_bib_copy_map_legacy b GROUP BY 2</query>
+ <query>SELECT COUNT(b.id), b.x_migrate::TEXT FROM m_biblio_peer_bib_copy_map_legacy b GROUP BY 2</query>
</report>
<report>
<tag>bibs</tag>
<iteration>1</iteration>
<heading>Count</heading>
- <query>SELECT COUNT(b.id) FROM biblio_peer_bib_copy_map b</query>
+ <query>SELECT COUNT(b.id) FROM m_biblio_peer_bib_copy_map b</query>
</report>
<report>
<tag>bibs</tag>
<iteration>0</iteration>
<heading>Count.Migrated</heading>
- <query>SELECT COUNT(b.id), b.x_migrate::TEXT FROM biblio_monograph_part_legacy b GROUP BY 2</query>
+ <query>SELECT COUNT(b.id), b.x_migrate::TEXT FROM m_biblio_monograph_part_legacy b GROUP BY 2</query>
</report>
<report>
<tag>bibs</tag>
<iteration>1</iteration>
<heading>Count</heading>
- <query>SELECT COUNT(b.id) FROM biblio_monograph_part b</query>
+ <query>SELECT COUNT(b.id) FROM m_biblio_monograph_part b</query>
</report>
<report>
<tag>actors</tag>
<iteration>0</iteration>
<heading>Count.Library.Deleted.Migrated</heading>
- <query>SELECT COUNT(au.id), aou.name, au.deleted::TEXT, au.x_migrate::TEXT FROM actor_usr_legacy au JOIN actor.org_unit aou ON aou.id = au.home_ou GROUP BY 2, 3, 4 ORDER BY 2, 3, 4</query>
+ <query>SELECT COUNT(au.id), aou.name, au.deleted::TEXT, au.x_migrate::TEXT FROM m_actor_usr_legacy au JOIN actor.org_unit aou ON aou.id = au.home_ou GROUP BY 2, 3, 4 ORDER BY 2, 3, 4</query>
</report>
<report>
<tag>actors</tag>
<iteration>0</iteration>
<heading>Count.Permission Group.Migrated</heading>
- <query>SELECT COUNT(au.id), pgt.name, au.x_migrate::TEXT FROM actor_usr_legacy au JOIN permission.grp_tree pgt ON pgt.id = au.profile GROUP BY 2, 3 ORDER BY 2, 3</query>
+ <query>SELECT COUNT(au.id), pgt.name, au.x_migrate::TEXT FROM m_actor_usr_legacy au JOIN permission.grp_tree pgt ON pgt.id = au.profile GROUP BY 2, 3 ORDER BY 2, 3</query>
</report>
<report>
<tag>actors</tag>
<iteration>0</iteration>
<heading>Count of Users.Active.Migrated</heading>
- <query>SELECT COUNT(id), active::TEXT, x_migrate::TEXT FROM actor_usr_legacy GROUP BY 2, 3</query>
+ <query>SELECT COUNT(id), active::TEXT, x_migrate::TEXT FROM m_actor_usr_legacy GROUP BY 2, 3</query>
</report>
<report>
<tag>actors</tag>
<iteration>1</iteration>
<heading>Count of Users.Active</heading>
- <query>SELECT COUNT(id), active::TEXT FROM actor_usr GROUP BY 2</query>
+ <query>SELECT COUNT(id), active::TEXT FROM m_actor_usr GROUP BY 2</query>
</report>
<report>
<tag>actors</tag>
<iteration>0</iteration>
<heading>Count of Barcodes.Active.Migrated</heading>
- <query>SELECT COUNT(id), active::TEXT, x_migrate::TEXT FROM actor_card_legacy GROUP BY 2, 3</query>
+ <query>SELECT COUNT(id), active::TEXT, x_migrate::TEXT FROM m_actor_card_legacy GROUP BY 2, 3</query>
</report>
<report>
<tag>actors</tag>
<iteration>1</iteration>
<heading>Count of Barcodes.Active</heading>
- <query>SELECT COUNT(id), active::TEXT FROM actor_card GROUP BY 2</query>
+ <query>SELECT COUNT(id), active::TEXT FROM m_actor_card GROUP BY 2</query>
</report>
- <!-- report>
- <name>usr_barcode_lengths</name>
- <report_title>Barcode Lengths by Library</report_title>
- <tag>actors</tag>
- <iteration>0</iteration>
- <heading>Count of Barcode.Barcode Length.Library</heading>
- <query>SELECT COUNT(acard.id), LENGTH(acard.barcode), aou.name FROM actor_card_legacy acard JOIN actor_usr_legacy au ON au.id = acard.usr JOIN actor.org_unit aou ON aou.id = au.home_ou WHERE acard.x_migrate = TRUE GROUP BY 2, 3 ORDER BY 3, 2</query>
- </report -->
-
- <!-- report>
- <name>usr_barcode_lengths</name>
- <report_title>Barcode Lengths by Library</report_title>
- <tag>actors</tag>
- <iteration>1</iteration>
- <heading>Count of Barcode.Barcode Length.Library</heading>
- <query>SELECT COUNT(acard.id), LENGTH(acard.barcode), aou.name FROM actor_card acard JOIN actor_usr au ON au.id = acard.usr JOIN actor.org_unit aou ON aou.id = au.home_ou GROUP BY 2, 3 ORDER BY 3, 2</query>
- </report -->
-
<report>
<name>usr_barcode_patterns</name>
<report_title>Common Barcode Starting Patterns</report_title>
<tag>actors</tag>
<iteration>0</iteration>
<heading>Count of Barcodes (greater than 10).Left 60% of Characters</heading>
- <query>SELECT COUNT(acard.id), LEFT(acard.barcode,(ROUND(LENGTH(acard.barcode)*.6))::INT) FROM actor_card_legacy acard WHERE acard.x_migrate = TRUE GROUP BY 2 HAVING COUNT(acard.id) > 10 ORDER BY 2</query>
+ <query>SELECT COUNT(acard.id), LEFT(acard.barcode,(ROUND(LENGTH(acard.barcode)*.6))::INT) FROM m_actor_card_legacy acard WHERE acard.x_migrate = TRUE GROUP BY 2 HAVING COUNT(acard.id) > 10 ORDER BY 2</query>
</report>
<report>
<tag>actors</tag>
<iteration>1</iteration>
<heading>Count of Barcodes (greater than 10).Left 60% of Characters</heading>
- <query>SELECT COUNT(acard.id), LEFT(acard.barcode,(ROUND(LENGTH(acard.barcode)*.6))::INT) FROM actor_card acard GROUP BY 2 HAVING COUNT(acard.id) > 10 ORDER BY 2</query>
+ <query>SELECT COUNT(acard.id), LEFT(acard.barcode,(ROUND(LENGTH(acard.barcode)*.6))::INT) FROM m_actor_card acard GROUP BY 2 HAVING COUNT(acard.id) > 10 ORDER BY 2</query>
</report>
<report>
- <name>usr_barcode_incoming_collisions</name>
- <report_title>Incoming Patron Barcode Collisions</report_title>
+ <name>usr_barcode_collisions</name>
+ <report_title>Patron Barcode Collisions</report_title>
<tag>actors</tag>
<iteration>0</iteration>
<heading>Collision Count</heading>
- <query>SELECT COUNT(acard.id) FROM actor_card_legacy acard WHERE barcode ~* 'collision' AND x_migrate = TRUE</query>
+ <query>SELECT COUNT(acard.id) FROM m_actor_card_legacy acard WHERE barcode LIKE 'x_%' AND x_migrate = TRUE</query>
</report>
<report>
- <name>usr_barcode_incoming_collisions</name>
- <report_title>Incoming Patron Barcode Collisions</report_title>
+ <name>usr_barcode_collisions</name>
+ <report_title>Patron Barcode Collisions</report_title>
<tag>actors</tag>
<iteration>1</iteration>
<heading>Collision Count</heading>
- <query>SELECT COUNT(acard.id) FROM actor_card acard WHERE barcode ~* 'collision'</query>
+ <query>SELECT COUNT(acard.id) FROM m_actor_card acard WHERE barcode LIKE 'x_%'</query>
</report>
- <report>
- <name>usr_barcode_incumbent_collisions</name>
- <report_title>Incumbent Patron Barcode Collisions</report_title>
- <tag>actors</tag>
- <iteration>0</iteration>
- <heading>Collision Count</heading>
- <query>SELECT COUNT(acard.id) FROM actor_card_legacy acard WHERE barcode ~* '^x_' AND x_migrate = TRUE</query>
- </report>
-
- <report>
- <name>usr_barcode_incumbent_collisions</name>
- <report_title>Incumbent Patron Barcode Collisions</report_title>
- <tag>actors</tag>
- <iteration>1</iteration>
- <heading>Collision Count</heading>
- <query>SELECT COUNT(acard.id) FROM actor_card acard WHERE barcode ~* '^x_'</query>
- </report>
-
<report>
<name>usr_barcode_collision_shortlist</name>
<report_title>Patron Barcode Collisions (first 20)</report_title>
<tag>actors</tag>
<iteration>0</iteration>
<heading>Collision List</heading>
- <query>SELECT acard.barcode FROM actor_card_legacy acard WHERE (acard.barcode ~* 'collision' OR acard.barcode ~* '^x_') AND acard.x_migrate = TRUE ORDER BY 1 LIMIT 20</query>
+ <query>SELECT acard.barcode FROM m_actor_card_legacy acard WHERE acard.barcode LIKE 'x_' AND acard.x_migrate = TRUE ORDER BY 1 LIMIT 20</query>
<note>This is a shortlist of patron barcode collisions that maxes out at 20. If there are more collisions we will need to run a custom report. In some cases we may flag individual accounts to not migrate.</note>
</report>
<tag>actors</tag>
<iteration>1</iteration>
<heading>Collision List</heading>
- <query>SELECT acard.barcode FROM actor_card acard WHERE (acard.barcode ~* 'collision' OR acard.barcode ~* '^x_') ORDER BY 1 LIMIT 20</query>
+ <query>SELECT acard.barcode FROM m_actor_card acard WHERE acard.barcode LIKE 'x_%' ORDER BY 1 LIMIT 20</query>
<note>This is a shortlist of patron barcode collisions that maxes out at 20. If there are more collisions we will need to run a custom report. In some cases we may flag individual accounts to not migrate.</note>
</report>
<tag>actors</tag>
<iteration>0</iteration>
<heading>Number of Barcodes Matching Pattern Greater than 10.Left 60% of Characters</heading>
- <query>SELECT COUNT(acard.id), LEFT(acard.barcode,(ROUND(LENGTH(acard.barcode)*.6))::INT) FROM actor_card_legacy acard WHERE (acard.barcode ~* 'collision' OR acard.barcode ~* '^x_') AND acard.x_migrate = TRUE GROUP BY 2 HAVING COUNT(acard.id) > 10 ORDER BY 2</query>
+ <query>SELECT COUNT(acard.id), LEFT(acard.barcode,(ROUND(LENGTH(acard.barcode)*.6))::INT) FROM m_actor_card_legacy acard WHERE (acard.barcode ~* 'collision' OR acard.barcode ~* '^x_') AND acard.x_migrate = TRUE GROUP BY 2 HAVING COUNT(acard.id) > 10 ORDER BY 2</query>
</report>
<report>
<tag>actors</tag>
<iteration>1</iteration>
<heading>Number of Barcodes Matching Pattern Greater than 10.Left 60% of Characters</heading>
- <query>SELECT COUNT(acard.id), LEFT(acard.barcode,(ROUND(LENGTH(acard.barcode)*.6))::INT) FROM actor_card acard WHERE (acard.barcode ~* 'collision' OR acard.barcode ~* '^x_') GROUP BY 2 HAVING COUNT(acard.id) > 10 ORDER BY 2</query>
+ <query>SELECT COUNT(acard.id), LEFT(acard.barcode,(ROUND(LENGTH(acard.barcode)*.6))::INT) FROM m_actor_card acard WHERE (acard.barcode ~* 'collision' OR acard.barcode ~* '^x_') GROUP BY 2 HAVING COUNT(acard.id) > 10 ORDER BY 2</query>
</report>
<report>
<tag>actors</tag>
<iteration>0</iteration>
<heading>Count.Valid.Migrated</heading>
- <query>SELECT COUNT(aua.id), valid::TEXT, x_migrate::TEXT FROM actor_usr_address_legacy aua GROUP BY 2, 3</query>
+ <query>SELECT COUNT(aua.id), valid::TEXT, x_migrate::TEXT FROM m_actor_usr_address_legacy aua GROUP BY 2, 3</query>
</report>
<report>
<tag>actors</tag>
<iteration>1</iteration>
<heading>Count.Valid</heading>
- <query>SELECT COUNT(aua.id), valid::TEXT FROM actor_usr_address aua GROUP BY 2</query>
+ <query>SELECT COUNT(aua.id), valid::TEXT FROM m_actor_usr_address aua GROUP BY 2</query>
</report>
<report>
<tag>actors</tag>
<iteration>0</iteration>
<heading>Count of Addresses.Pending.Migrated</heading>
- <query>SELECT COUNT(aua.id), pending::TEXT, x_migrate::TEXT FROM actor_usr_address_legacy aua GROUP BY 2, 3</query>
+ <query>SELECT COUNT(aua.id), pending::TEXT, x_migrate::TEXT FROM m_actor_usr_address_legacy aua GROUP BY 2, 3</query>
</report>
<report>
<tag>actors</tag>
<iteration>1</iteration>
<heading>Count of Addresses.Pending</heading>
- <query>SELECT COUNT(aua.id), pending::TEXT FROM actor_usr_address aua GROUP BY 2</query>
+ <query>SELECT COUNT(aua.id), pending::TEXT FROM m_actor_usr_address aua GROUP BY 2</query>
</report>
<report>
<tag>actors</tag>
<iteration>0</iteration>
<heading>Count.Deleted.Migrated</heading>
- <query>SELECT COUNT(aum.id), deleted::TEXT, x_migrate::TEXT FROM actor_usr_message_legacy aum GROUP BY 2, 3</query>
+ <query>SELECT COUNT(aum.id), deleted::TEXT, x_migrate::TEXT FROM m_actor_usr_message_legacy aum GROUP BY 2, 3</query>
</report>
<report>
<tag>actors</tag>
<iteration>1</iteration>
<heading>Count.Deleted</heading>
- <query>SELECT COUNT(aum.id), deleted::TEXT FROM actor_usr_message_legacy aum GROUP BY 2</query>
+ <query>SELECT COUNT(aum.id), deleted::TEXT FROM m_actor_usr_message_legacy aum GROUP BY 2</query>
</report>
<report>
<tag>actors</tag>
<iteration>0</iteration>
<heading>Count.Public.Migrated</heading>
- <query>SELECT COUNT(aun.id), pub::TEXT, x_migrate::TEXT FROM actor_usr_note_legacy aun GROUP BY 2, 3</query>
+ <query>SELECT COUNT(aun.id), pub::TEXT, x_migrate::TEXT FROM m_actor_usr_note_legacy aun GROUP BY 2, 3</query>
</report>
<report>
<tag>actors</tag>
<iteration>1</iteration>
<heading>Count.Public</heading>
- <query>SELECT COUNT(aun.id), pub::TEXT FROM actor_usr_note aun GROUP BY 2</query>
+ <query>SELECT COUNT(aun.id), pub::TEXT FROM m_actor_usr_note aun GROUP BY 2</query>
</report>
<report>
<tag>actors</tag>
<iteration>0</iteration>
<heading>Stat Cat Count.Library.Statistical Category.Migrated</heading>
- <query>SELECT COUNT(au_sc.id), aou.name, au_sc.name, au_sc.x_migrate::TEXT FROM actor_stat_cat_legacy au_sc JOIN actor.org_unit aou ON aou.id = au_sc.owner GROUP BY 2, 3, 4 ORDER BY 2, 3, 4</query>
+ <query>SELECT COUNT(au_sc.id), aou.name, au_sc.name, au_sc.x_migrate::TEXT FROM m_actor_stat_cat_legacy au_sc JOIN actor.org_unit aou ON aou.id = au_sc.owner GROUP BY 2, 3, 4 ORDER BY 2, 3, 4</query>
</report>
<report>
<tag>actors</tag>
<iteration>1</iteration>
<heading>Stat Cat Count.Library.Statistical Category</heading>
- <query>SELECT COUNT(au_sc.id), aou.name, au_sc.name FROM actor_stat_cat au_sc JOIN actor.org_unit aou ON aou.id = au_sc.owner GROUP BY 2, 3 ORDER BY 2, 3</query>
+ <query>SELECT COUNT(au_sc.id), aou.name, au_sc.name FROM m_actor_stat_cat au_sc JOIN actor.org_unit aou ON aou.id = au_sc.owner GROUP BY 2, 3 ORDER BY 2, 3</query>
</report>
<report>
<tag>actors</tag>
<iteration>0</iteration>
<heading>Patron Stat Count.Library.Statistical Category.Migrated</heading>
- <query>SELECT COUNT(map.id), aou.name, au_sc.name, map.x_migrate::TEXT FROM actor_stat_cat_entry_usr_map_legacy map JOIN actor_stat_cat_legacy au_sc ON au_sc.id = map.stat_cat JOIN actor.org_unit aou ON aou.id = au_sc.owner GROUP BY 2, 3, 4 ORDER BY 2,3, 4</query>
+ <query>SELECT COUNT(map.id), aou.name, au_sc.name, map.x_migrate::TEXT FROM m_actor_stat_cat_entry_usr_map_legacy map JOIN m_actor_stat_cat_legacy au_sc ON au_sc.id = map.stat_cat JOIN actor.org_unit aou ON aou.id = au_sc.owner GROUP BY 2, 3, 4 ORDER BY 2,3, 4</query>
</report>
<report>
<tag>actors</tag>
<iteration>1</iteration>
<heading>Patron Stat Count.Library.Statistical Category</heading>
- <query>SELECT COUNT(map.id), aou.name, au_sc.name FROM actor_stat_cat_entry_usr_map map JOIN actor_stat_cat au_sc ON au_sc.id = map.stat_cat JOIN actor.org_unit aou ON aou.id = au_sc.owner GROUP BY 2, 3 ORDER BY 2,3</query>
+ <query>SELECT COUNT(map.id), aou.name, au_sc.name FROM m_actor_stat_cat_entry_usr_map map JOIN m_actor_stat_cat au_sc ON au_sc.id = map.stat_cat JOIN actor.org_unit aou ON aou.id = au_sc.owner GROUP BY 2, 3 ORDER BY 2,3</query>
</report>
<report>
<tag>actors</tag>
<iteration>0</iteration>
<heading>Count.Setting.Value</heading>
- <query>SELECT COUNT(*), name, 'User''s Phone' FROM actor_usr_setting WHERE name IN ('opac.default_phone') GROUP BY 2, 3
- UNION ALL SELECT COUNT(*), name, value FROM actor_usr_setting WHERE name IN ('opac.hold_notify') GROUP BY 2, 3
- UNION ALL SELECT COUNT(*), a.name, aou.shortname FROM actor_usr_setting a JOIN actor.org_unit aou ON aou.id = REPLACE(a.value,'"','')::INTEGER
+ <query>SELECT COUNT(*), name, 'User''s Phone' FROM m_actor_usr_setting WHERE name IN ('opac.default_phone') GROUP BY 2, 3
+ UNION ALL SELECT COUNT(*), name, value FROM m_actor_usr_setting WHERE name IN ('opac.hold_notify') GROUP BY 2, 3
+ UNION ALL SELECT COUNT(*), a.name, aou.shortname FROM m_actor_usr_setting a JOIN actor.org_unit aou ON aou.id = REPLACE(a.value,'"','')::INTEGER
WHERE a.name IN ('opac.default_pickup_location','opac.default_search_location') GROUP BY 2, 3 ORDER BY 2, 3;</query>
</report>
<tag>acq</tag>
<report_title>Migrated Funds</report_title>
<heading>Number of Funds.Migrated</heading>
- <query>SELECT COUNT(id), x_migrate::TEXT FROM acq_fund_legacy GROUP BY 2;</query>
+ <query>SELECT COUNT(id), x_migrate::TEXT FROM m_acq_fund_legacy GROUP BY 2;</query>
</report>
<report>
<tag>acq</tag>
<report_title>Migrated Funds</report_title>
<heading>Number of Funds</heading>
- <query>SELECT COUNT(id) FROM acq_fund;</query>
+ <query>SELECT COUNT(id) FROM m_acq_fund;</query>
</report>
<report>
<tag>acq</tag>
<report_title>Migrated Invoices</report_title>
<heading>Number of Invoices.Migrated</heading>
- <query>SELECT COUNT(id), x_migrate::TEXT FROM acq_invoice_legacy GROUP BY 2;</query>
+ <query>SELECT COUNT(id), x_migrate::TEXT FROM m_acq_invoice_legacy GROUP BY 2;</query>
</report>
<report>
<tag>acq</tag>
<report_title>Migrated Invoices</report_title>
<heading>Number of Funds</heading>
- <query>SELECT COUNT(id) FROM acq_invoice;</query>
+ <query>SELECT COUNT(id) FROM m_acq_invoice;</query>
</report>
<!-- SERIALS REPORTS -->
<iteration>0</iteration>
<report_title>Migrated Serial MFHDs</report_title>
<heading>Number of MFHDs</heading>
- <query>SELECT COUNT(id) FROM serial_record_entry</query>
+ <query>SELECT COUNT(id) FROM m_serial_record_entry</query>
</report>
<!-- DEDUPE REPORTS -->
<report_title>Action Triggers Setup for Notices</report_title>
<heading>ID.Active.Owner.Name</heading>
<query>SELECT ed.id, ed.active, aou.shortname, ed.name
- FROM action_trigger.event_definition ed
+ FROM m_action_trigger.event_definition ed
JOIN actor.org_unit aou ON aou.id = ed.owner
- WHERE ed.owner IN (SELECT DISTINCT home_ou FROM actor_usr)
- OR ed.owner IN (SELECT DISTINCT parent_ou FROM actor.org_unit WHERE id in (SELECT DISTINCT home_ou FROM actor_usr));
+ WHERE ed.owner IN (SELECT DISTINCT home_ou FROM m_actor_usr)
+ OR ed.owner IN (SELECT DISTINCT parent_ou FROM actor.org_unit WHERE id in (SELECT DISTINCT home_ou FROM m_actor_usr));
</query>
</report>
<report_title>Count of Notices Run with State</report_title>
<heading>Count of Notices.State.ID.Owner.Name</heading>
<query>SELECT COUNT(ate.id), ate.state, ed.id, aou.shortname, ed.name
- FROM action_trigger.event_definition ed
+ FROM m_action_trigger.event_definition ed
JOIN actor.org_unit aou ON aou.id = ed.owner
- JOIN action_trigger.event ate ON ate.event_def = ed.id
- WHERE ed.owner IN (SELECT DISTINCT home_ou FROM actor_usr)
- OR ed.owner IN (SELECT DISTINCT parent_ou FROM actor.org_unit WHERE id in (SELECT DISTINCT home_ou FROM actor_usr))
+ JOIN m_action_trigger.event ate ON ate.event_def = ed.id
+ WHERE ed.owner IN (SELECT DISTINCT home_ou FROM m_actor_usr)
+ OR ed.owner IN (SELECT DISTINCT parent_ou FROM actor.org_unit WHERE id in (SELECT DISTINCT home_ou FROM m_actor_usr))
GROUP BY 2,3,4;
</query>
</report>
<tag>money</tag> arbitrary tags, each should go in separate tag
<report_title>Migrated Billings</report_title> title used in the asciidoc output
<heading column='1'>Number of Billings.Migrated.Total</heading> period delimited
- <query>SELECT COUNT(id),x_migrate,SUM(amount) FROM money_billing_legacy GROUP BY 2;</query> query itself, will be replaced
+ <query>SELECT COUNT(id),x_migrate,SUM(amount) FROM m_money_billing_legacy GROUP BY 2;</query> query itself, will be replaced
<note>Arbitrary note that can be included in the entries.</note>
</report>
-->
<!-- evergreen -->
<report>
- <name>evg_asset_copy_statuses</name>
+ <name>evg_m_asset_copy_statuses</name>
<report_title>Statuses</report_title>
<tag>evergreen</tag>
<iteration>0</iteration>
<heading>Copy Count.Migrating Status.New Evergreen Status.Notes</heading>
- <query>SELECT COUNT(ac.l_id), cs.l_name FROM asset_copy_legacy ac JOIN config_copy_status_legacy cs ON cs.l_id = ac.l_status GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(ac.l_id), cs.l_name FROM m_asset_copy_legacy ac JOIN config_copy_status_legacy cs ON cs.l_id = ac.l_status GROUP BY 2 ORDER BY 2</query>
<note>You only need to fill this sheet out if you use custom statuses that need to be migrated.</note>
</report>
<report>
- <name>evg_asset_circ_mods</name>
+ <name>evg_m_asset_circ_mods</name>
<report_title>Circulation Modifiers</report_title>
<tag>evergreen</tag>
<iteration>0</iteration>
<heading>Copy Count.Migrating Circ Mod.New Circ Mod.Notes</heading>
- <query>SELECT COUNT(ac.l_id), ac.l_circ_modifier FROM asset_copy_legacy ac GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(ac.l_id), ac.l_circ_modifier FROM m_asset_copy_legacy ac GROUP BY 2 ORDER BY 2</query>
</report>
<report>
- <name>evg_asset_copy_locs</name>
+ <name>evg_m_asset_copy_locs</name>
<report_title>Copy Locations</report_title>
<tag>evergreen</tag>
<iteration>0</iteration>
<heading>Count.Library.Migrating Copy Location.New Copy Location.Notes</heading>
- <query>SELECT COUNT(ac.l_id), aou.l_name, acl.l_name FROM asset_copy_location_legacy acl JOIN actor_org_unit_legacy aou ON aou.l_id = acl.l_owning_lib JOIN asset_copy_legacy ac ON ac.l_location = acl.l_id GROUP BY 2, 3 ORDER BY 2, 3</query>
+ <query>SELECT COUNT(ac.l_id), aou.l_name, acl.l_name FROM m_asset_copy_location_legacy acl JOIN m_actor_org_unit_legacy aou ON aou.l_id = acl.l_owning_lib JOIN m_asset_copy_legacy ac ON ac.l_location = acl.l_id GROUP BY 2, 3 ORDER BY 2, 3</query>
<note>Any locations not mapped can be moved over as their existing locations.</note>
</report>
<tag>evergreen</tag>
<iteration>0</iteration>
<heading>Count.Migrating Permission Group.New Permission Group.Notes</heading>
- <query>SELECT COUNT(au.l_id), pgt.l_name FROM actor_usr_legacy au JOIN permission_grp_tree_legacy pgt ON pgt.l_id = au.l_profile GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(au.l_id), pgt.l_name FROM m_actor_usr_legacy au JOIN permission_grp_tree_legacy pgt ON pgt.l_id = au.l_profile GROUP BY 2 ORDER BY 2</query>
</report>
<!-- tlc -->
</report>
<report>
- <name>tlc_load_asset_notes</name>
+ <name>tlc_load_m_asset_notes</name>
<report_title>Item Notes</report_title>
<tag>tlc</tag>
<iteration>0</iteration>
</report>
<report>
- <name>tlc_load_asset_holdings_codes</name>
+ <name>tlc_load_m_asset_holdings_codes</name>
<report_title>Holdings Codes</report_title>
<tag>tlc</tag>
<iteration>0</iteration>
</report>
<!--
<report>
- <name>tlc_load_asset_callnumbertype</name>
+ <name>tlc_load_m_asset_callnumbertype</name>
<report_title>Call Number Types</report_title>
<tag>tlc</tag>
<iteration>0</iteration>
-->
<!--
<report>
- <name>tlc_load_asset_callnumberparts</name>
+ <name>tlc_load_m_asset_callnumberparts</name>
<report_title>Call Number Parts</report_title>
<tag>tlc</tag>
<iteration>0</iteration>
</report>
-->
<report>
- <name>tlc_load_money_migrating_bills</name>
+ <name>tlc_load_m_money_migrating_bills</name>
<report_title>Migrating Bills By Bill Type</report_title>
<tag>tlc</tag>
<iteration>0</iteration>
</report>
<report>
- <name>destiny_load_asset_categories</name>
+ <name>destiny_load_m_asset_categories</name>
<report_title>Count of Categories</report_title>
<tag>destiny</tag>
<iteration>0</iteration>
</report>
<report>
- <name>destiny_load_asset_notes</name>
+ <name>destiny_load_m_asset_notes</name>
<report_title>Copies by Note Types</report_title>
<tag>destiny</tag>
<iteration>0</iteration>
</report>
<report>
- <name>destiny_load_asset_sublocation</name>
+ <name>destiny_load_m_asset_sublocation</name>
<report_title>Copies by Sub Location</report_title>
<tag>destiny</tag>
<iteration>0</iteration>
</report>
<report>
- <name>destiny_load_asset_vendor</name>
+ <name>destiny_load_m_asset_vendor</name>
<report_title>Copies by Vendor</report_title>
<tag>destiny</tag>
<iteration>0</iteration>
</report>
<report>
- <name>destiny_load_asset_descriptions</name>
+ <name>destiny_load_m_asset_descriptions</name>
<report_title>Copies with Description Fields</report_title>
<tag>destiny</tag>
<iteration>0</iteration>
<tag>apollo</tag>
<iteration>0</iteration>
<heading>Count.Status.Type</heading>
- <query>SELECT COUNT(id), l_status, l_type FROM action_circulation_legacy GROUP BY 2, 3</query>
+ <query>SELECT COUNT(id), l_status, l_type FROM m_action_circulation_legacy GROUP BY 2, 3</query>
<note>Circulations will only not be migrated if they can't be attached to a migrated patron and holding.</note>
</report>
<tag>apollo</tag>
<iteration>0</iteration>
<heading>Count.Status</heading>
- <query> SELECT COUNT(id), l_status FROM action_hold_request_legacy GROUP BY 2</query>
+ <query> SELECT COUNT(id), l_status FROM m_action_hold_request_legacy GROUP BY 2</query>
<note>Only unfilled holds are being migrated.</note>
</report>
<report>
- <name>asset_pending_bibs</name>
+ <name>m_asset_pending_bibs</name>
<report_title>Pending Records</report_title>
<tag>apollo</tag>
<iteration>0</iteration>
<heading>Count.Year of Last Edit.Count of Copies Attached</heading>
- <query>SELECT COUNT(bre.id), CASE WHEN LENGTH(bre.l_edited) > 1 THEN EXTRACT(YEAR FROM bre.l_edited::TIMESTAMP) ELSE '1900' END, COUNT(ac.id) FROM biblio_record_entry_legacy bre LEFT JOIN asset_copy_legacy ac ON ac.l_biblio = bre.l_id WHERE bre.l_status = 'pending' GROUP BY 2 ORDER BY 2
+ <query>SELECT COUNT(bre.id), CASE WHEN LENGTH(bre.l_edited) > 1 THEN EXTRACT(YEAR FROM bre.l_edited::TIMESTAMP) ELSE '1900' END, COUNT(ac.id) FROM m_biblio_record_entry_legacy bre LEFT JOIN m_asset_copy_legacy ac ON ac.l_biblio = bre.l_id WHERE bre.l_status = 'pending' GROUP BY 2 ORDER BY 2
</query>
</report>
<report>
- <name>asset_copies_by_status</name>
+ <name>m_asset_copies_by_status</name>
<report_title>Copies by Status</report_title>
<tag>apollo</tag>
<iteration>0</iteration>
<heading>Count.Status</heading>
- <query>SELECT COUNT(id), l_status FROM asset_copy_legacy GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(id), l_status FROM m_asset_copy_legacy GROUP BY 2 ORDER BY 2</query>
<note>Deleted copies with a delete date were not exported additionally those with the deleted status won't get loaded.</note>
</report>
<report>
- <name>asset_pending_copies</name>
+ <name>m_asset_pending_copies</name>
<report_title>Pending Copies by Last Edit</report_title>
<tag>apollo</tag>
<iteration>0</iteration>
<heading>Count.Last Edited</heading>
- <query>SELECT COUNT(id), CASE WHEN LENGTH(l_edited) > 1 THEN EXTRACT(YEAR FROM l_edited::TIMESTAMP) ELSE '1900' END FROM asset_copy_legacy WHERE l_status = 'pending' GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(id), CASE WHEN LENGTH(l_edited) > 1 THEN EXTRACT(YEAR FROM l_edited::TIMESTAMP) ELSE '1900' END FROM m_asset_copy_legacy WHERE l_status = 'pending' GROUP BY 2 ORDER BY 2</query>
</report>
<report>
<tag>apollo</tag>
<iteration>0</iteration>
<heading>Count.Membership Number.Membership Name</heading>
- <query>SELECT COUNT(ac.id), acl.l_membership_number, acl.l_membership_name FROM asset_copy_legacy ac JOIN asset_copy_location_legacy acl ON acl.l_membership_name = ac.l_memberships GROUP BY 2,3 ORDER BY 2
+ <query>SELECT COUNT(ac.id), acl.l_membership_number, acl.l_membership_name FROM m_asset_copy_legacy ac JOIN m_asset_copy_location_legacy acl ON acl.l_membership_name = ac.l_memberships GROUP BY 2,3 ORDER BY 2
</query>
</report>
<report>
- <name>money_bills</name>
+ <name>m_money_bills</name>
<report_title>Bills</report_title>
<tag>apollo</tag>
<iteration>0</iteration>
<heading>Count.Status</heading>
- <query>SELECT COUNT(id), l_status FROM money_billing_legacy GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(id), l_status FROM m_money_billing_legacy GROUP BY 2 ORDER BY 2</query>
<note>Unless there is a good reason to do so forgiven and paid bills will not be migrated.</note>
</report>
<report>
- <name>actor_groups</name>
+ <name>m_actor_groups</name>
<report_title>Patron Membership Groups</report_title>
<tag>apollo</tag>
<iteration>0</iteration>
<heading>Membership List Name.Membership List ID.Membership Number.Membership Name.Membership Length in Monthst</heading>
- <query>SELECT l_membership_list_name, l_membership_list_id, l_membership_number, l_membership_name, l_membership_length_months FROM actor_usr_legacy_groups_tsv ORDER BY 1, 3</query>
+ <query>SELECT l_membership_list_name, l_membership_list_id, l_membership_number, l_membership_name, l_membership_length_months FROM m_actor_usr_legacy_groups_tsv ORDER BY 1, 3</query>
<note>Age looks like a good target for a stat cat and / or juvenile setting while the patron type can map to profiles.</note>
</report>
<report>
- <name>actor_by_groups</name>
+ <name>m_actor_by_groups</name>
<report_title>Patrons by Membership Groups</report_title>
<tag>apollo</tag>
<iteration>0</iteration>
<heading>Count.Membership List Name.Membership Number</heading>
- <query>SELECT COUNT(*), l_membership_list_name, l_membership_number FROM (SELECT id, UNNEST(STRING_TO_ARRAY(l_memberships,'|')) AS m FROM actor_usr_legacy ) x JOIN actor_usr_legacy_groups_tsv t ON t.l_membership_name = x.m GROUP BY 2, 3 ORDER BY 2, 3</query>
+ <query>SELECT COUNT(*), l_membership_list_name, l_membership_number FROM (SELECT id, UNNEST(STRING_TO_ARRAY(l_memberships,'|')) AS m FROM m_actor_usr_legacy ) x JOIN m_actor_usr_legacy_groups_tsv t ON t.l_membership_name = x.m GROUP BY 2, 3 ORDER BY 2, 3</query>
</report>
<report>
- <name>actor_addresses_nulls</name>
+ <name>m_actor_addresses_nulls</name>
<report_title>Patron Addresses</report_title>
<tag>apollo</tag>
<iteration>0</iteration>
<heading>Address Field.Nulls</heading>
- <query>SELECT 'Street Address', COUNT(id) FROM actor_usr_address_legacy WHERE l_lines IS NULL UNION ALL SELECT 'City', COUNT(id) FROM actor_usr_address_legacy UNION ALL SELECT 'State', COUNT(id) FROM actor_usr_address_legacy WHERE l_country_division IS NULL UNION ALL SELECT 'Postal Code', COUNT(id) FROM actor_usr_address_legacy WHERE l_postal_code IS NULL </query>
+ <query>SELECT 'Street Address', COUNT(id) FROM m_actor_usr_address_legacy WHERE l_lines IS NULL UNION ALL SELECT 'City', COUNT(id) FROM m_actor_usr_address_legacy UNION ALL SELECT 'State', COUNT(id) FROM m_actor_usr_address_legacy WHERE l_country_division IS NULL UNION ALL SELECT 'Postal Code', COUNT(id) FROM m_actor_usr_address_legacy WHERE l_postal_code IS NULL </query>
<note>If any of these fields are null then we need defaults to fill in, note the extract had no city data.</note>
</report>
<report>
- <name>actor_phones</name>
+ <name>m_actor_phones</name>
<report_title>Patron Phones</report_title>
<tag>apollo</tag>
<iteration>0</iteration>
<heading>Count.Type</heading>
- <query>SELECT COUNT(*), l_type FROM actor_usr_phones_tsv GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(*), l_type FROM m_actor_usr_phones_tsv GROUP BY 2 ORDER BY 2</query>
<note>These need to be mapped to Evergreen phone types.</note>
</report>
<tag>horizon</tag>
<iteration>0</iteration>
<heading>Count.Borrower Type</heading>
- <query>SELECT COUNT(id), l_borrower_btype FROM actor_usr_legacy GROUP BY 2 ORDER BY 2;</query>
+ <query>SELECT COUNT(id), l_borrower_btype FROM m_actor_usr_legacy GROUP BY 2 ORDER BY 2;</query>
</report>
<report>
<tag>horizon</tag>
<iteration>0</iteration>
<heading>Count of Migratable Passwords / PINs</heading>
- <query>SELECT COUNT(l_borrower_pin) FROM actor_usr_legacy WHERE LENGTH(l_borrower_pin) > 1;</query>
+ <query>SELECT COUNT(l_borrower_pin) FROM m_actor_usr_legacy WHERE LENGTH(l_borrower_pin) > 1;</query>
</report>
<report>
<tag>horizon</tag>
<iteration>0</iteration>
<heading>Sample of Migratable Notes</heading>
- <query>SELECT l_borrower_borrower_note FROM actor_usr_legacy WHERE LENGTH(l_borrower_borrower_note) > 1 LIMIT 20;</query>
+ <query>SELECT l_borrower_borrower_note FROM m_actor_usr_legacy WHERE LENGTH(l_borrower_borrower_note) > 1 LIMIT 20;</query>
</report>
<report>
<tag>horizon</tag>
<iteration>0</iteration>
<heading>Count</heading>
- <query>SELECT COUNT(l_borrower_borrower_note) FROM actor_usr_legacy WHERE LENGTH(l_borrower_borrower_note) > 1;</query>
+ <query>SELECT COUNT(l_borrower_borrower_note) FROM m_actor_usr_legacy WHERE LENGTH(l_borrower_borrower_note) > 1;</query>
</report>
<report>
<tag>horizon</tag>
<iteration>0</iteration>
<heading>Count</heading>
- <query>SELECT l_borrower_note2 FROM actor_usr_legacy WHERE LENGTH(l_borrower_note2) > 1 LIMIT 20;</query>
+ <query>SELECT l_borrower_note2 FROM m_actor_usr_legacy WHERE LENGTH(l_borrower_note2) > 1 LIMIT 20;</query>
</report>
<report>
<tag>horizon</tag>
<iteration>0</iteration>
<heading>Count</heading>
- <query>SELECT l_borrower_note3 FROM actor_usr_legacy WHERE LENGTH(l_borrower_note3) > 1 LIMIT 20;</query>
+ <query>SELECT l_borrower_note3 FROM m_actor_usr_legacy WHERE LENGTH(l_borrower_note3) > 1 LIMIT 20;</query>
</report>
<report>
<heading>Count.Borrower Phone Type</heading>
<query>
SELECT COUNT(*), b
- FROM (SELECT l_borrower_phone_1_phone_type AS b FROM actor_usr_legacy
- UNION ALL SELECT l_borrower_phone_2_phone_type AS b FROM actor_usr_legacy
- UNION ALL SELECT l_borrower_phone_3_phone_type AS b FROM actor_usr_legacy
- UNION ALL SELECT l_borrower_phone_4_phone_type AS b FROM actor_usr_legacy) x
+ FROM (SELECT l_borrower_phone_1_phone_type AS b FROM m_actor_usr_legacy
+ UNION ALL SELECT l_borrower_phone_2_phone_type AS b FROM m_actor_usr_legacy
+ UNION ALL SELECT l_borrower_phone_3_phone_type AS b FROM m_actor_usr_legacy
+ UNION ALL SELECT l_borrower_phone_4_phone_type AS b FROM m_actor_usr_legacy) x
GROUP BY 2 ORDER BY 2
</query>
</report>
<iteration>0</iteration>
<heading>Count.BStat</heading>
<query>SELECT COUNT(*), b
- FROM (SELECT l_borrower_bstat_1_bstat AS b FROM actor_usr_legacy
+ FROM (SELECT l_borrower_bstat_1_bstat AS b FROM m_actor_usr_legacy
UNION ALL
- SELECT l_borrower_bstat_2_bstat AS b FROM actor_usr_legacy
+ SELECT l_borrower_bstat_2_bstat AS b FROM m_actor_usr_legacy
UNION ALL
- SELECT l_borrower_bstat_3_bstat AS b FROM actor_usr_legacy) x
+ SELECT l_borrower_bstat_3_bstat AS b FROM m_actor_usr_legacy) x
GROUP BY 2 ORDER BY 1;
</query>
</report>
<tag>horizon</tag>
<iteration>0</iteration>
<heading>Count.Collection</heading>
- <query>SELECT COUNT(id), l_collection FROM asset_copy_legacy GROUP BY 2 ORDER BY 2;</query>
+ <query>SELECT COUNT(id), l_collection FROM m_asset_copy_legacy GROUP BY 2 ORDER BY 2;</query>
</report>
<report>
<tag>horizon</tag>
<iteration>0</iteration>
<heading>Count.Item Type (itype)</heading>
- <query>SELECT COUNT(id), l_itype FROM asset_copy_legacy GROUP BY 2 ORDER BY 2;</query>
+ <query>SELECT COUNT(id), l_itype FROM m_asset_copy_legacy GROUP BY 2 ORDER BY 2;</query>
</report>
<report>
<tag>horizon</tag>
<iteration>0</iteration>
<heading>Count</heading>
- <query>SELECT COUNT(l_internal_note) FROM asset_copy_legacy WHERE LENGTH(l_internal_note) > 1;</query>
+ <query>SELECT COUNT(l_internal_note) FROM m_asset_copy_legacy WHERE LENGTH(l_internal_note) > 1;</query>
</report>
<report>
<tag>horizon</tag>
<iteration>0</iteration>
<heading>Count</heading>
- <query>SELECT l_internal_note FROM asset_copy_legacy WHERE LENGTH(l_internal_note) > 1 LIMIT 20;</query>
+ <query>SELECT l_internal_note FROM m_asset_copy_legacy WHERE LENGTH(l_internal_note) > 1 LIMIT 20;</query>
</report>
<report>
<iteration>0</iteration>
<report_title>Circs by Status</report_title>
<heading>Count of Circs.Status</heading>
- <query>SELECT COUNT(id), l_is_checked_out FROM asset_copy_legacy GROUP BY 2</query>
+ <query>SELECT COUNT(id), l_is_checked_out FROM m_asset_copy_legacy GROUP BY 2</query>
</report>
<report>
- <name>rm_load_asset_by_resource_type</name>
+ <name>rm_load_m_asset_by_resource_type</name>
<report_title>Resource Type</report_title>
<tag>rm</tag>
<iteration>0</iteration>
<heading>Count.Resource Type</heading>
- <query>SELECT COUNT(*), l_resource_type FROM asset_copy_legacy GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(*), l_resource_type FROM m_asset_copy_legacy GROUP BY 2 ORDER BY 2</query>
</report>
<report>
- <name>rm_load_asset_by_location</name>
+ <name>rm_load_m_asset_by_location</name>
<report_title>Copies by Location</report_title>
<tag>rm</tag>
<iteration>0</iteration>
<heading>Count.Location</heading>
- <query>SELECT COUNT(*), l_location FROM asset_copy_legacy GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(*), l_location FROM m_asset_copy_legacy GROUP BY 2 ORDER BY 2</query>
</report>
<report>
- <name>rm_load_asset_by_category</name>
+ <name>rm_load_m_asset_by_category</name>
<report_title>Copies by Category</report_title>
<tag>rm</tag>
<iteration>0</iteration>
<heading>Count.Category</heading>
- <query>SELECT COUNT(*), l_category FROM asset_copy_legacy GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(*), l_category FROM m_asset_copy_legacy GROUP BY 2 ORDER BY 2</query>
</report>
<report>
- <name>rm_load_asset_by_status</name>
+ <name>rm_load_m_asset_by_status</name>
<report_title>Copies by Status</report_title>
<tag>rm</tag>
<iteration>0</iteration>
<heading>Count.Status</heading>
- <query>SELECT COUNT(*), l_status FROM asset_copy_legacy GROUP BY 2 ORDER BY 2</query>
+ <query>SELECT COUNT(*), l_status FROM m_asset_copy_legacy GROUP BY 2 ORDER BY 2</query>
</report>
<report>
- <name>rm_actor_groups</name>
+ <name>rm_m_actor_groups</name>
<report_title>Patrons by User Groups</report_title>
<tag>rm</tag>
<iteration>0</iteration>
<heading>Count.Group</heading>
- <query>SELECT COUNT(id), l_user_group FROM actor_usr_legacy GROUP BY 2 ORDER BY 2;
+ <query>SELECT COUNT(id), l_user_group FROM m_actor_usr_legacy GROUP BY 2 ORDER BY 2;
</query>
</report>
<report>
- <name>rm_actor_access</name>
+ <name>rm_m_actor_access</name>
<report_title>Patrons by Access Field</report_title>
<tag>rm</tag>
<iteration>0</iteration>
<heading>Count.Access</heading>
- <query>SELECT COUNT(id), l_access_if_applicable FROM actor_usr_legacy GROUP BY 2 ORDER BY 2;
+ <query>SELECT COUNT(id), l_access_if_applicable FROM m_actor_usr_legacy GROUP BY 2 ORDER BY 2;
</query>
</report>
<report>
- <name>rm_actor_comments</name>
+ <name>rm_m_actor_comments</name>
<report_title>Patron Comments</report_title>
<tag>rm</tag>
<iteration>0</iteration>
<heading>Count.Sample</heading>
- <query>SELECT COUNT(id), 'All Comments' FROM actor_usr_legacy WHERE LENGTH(l_comments) > 1
- UNION ALL SELECT NULL, l_comments FROM actor_usr_legacy WHERE LENGTH(l_comments) > 1 LIMIT 10
+ <query>SELECT COUNT(id), 'All Comments' FROM m_actor_usr_legacy WHERE LENGTH(l_comments) > 1
+ UNION ALL SELECT NULL, l_comments FROM m_actor_usr_legacy WHERE LENGTH(l_comments) > 1 LIMIT 10
</query>
</report>
<report>
- <name>rm_actor_circulation_note</name>
+ <name>rm_m_actor_circulation_note</name>
<report_title>Patron Circ Notes</report_title>
<tag>rm</tag>
<iteration>0</iteration>
<heading>Count.Sample</heading>
- <query>SELECT COUNT(id), 'All Notes' FROM actor_usr_legacy WHERE LENGTH(l_circulation_note) > 1
- UNION ALL SELECT NULL, l_circulation_note FROM actor_usr_legacy WHERE LENGTH(l_circulation_note) > 1 LIMIT 10
+ <query>SELECT COUNT(id), 'All Notes' FROM m_actor_usr_legacy WHERE LENGTH(l_circulation_note) > 1
+ UNION ALL SELECT NULL, l_circulation_note FROM m_actor_usr_legacy WHERE LENGTH(l_circulation_note) > 1 LIMIT 10
</query>
</report>
<!-- tlc reports
<report>
- <name>tlc_reports_load_asset_holdings_codes</name>
+ <name>tlc_reports_load_m_asset_holdings_codes</name>
<report_title>Holdings Codes</report_title>
<tag>tlc_reports</tag>
<iteration>0</iteration>
<heading>Count.Library.Holdings Codes.Evergreen Circulation Modifier.Evergreen Shelving Locatione</heading>
- <query>SELECT COUNT(id), x_source, l_holdingscode FROM asset_copy_legacy GROUP BY 2, 3 ORDER BY 2, 3</query>
+ <query>SELECT COUNT(id), x_source, l_holdingscode FROM m_asset_copy_legacy GROUP BY 2, 3 ORDER BY 2, 3</query>
</report>
<report>
<tag>tlc_reports</tag>
<iteration>0</iteration>
<heading>Count.Library.Permission Group.Evergreen Permission Group</heading>
- <query>SELECT COUNT(id), l_location, l_borrower_type FROM actor_usr_legacy GROUP BY 2, 3 ORDER BY 2, 3</query>
+ <query>SELECT COUNT(id), l_location, l_borrower_type FROM m_actor_usr_legacy GROUP BY 2, 3 ORDER BY 2, 3</query>
</report>
<report>
<tag>tlc_reports</tag>
<iteration>0</iteration>
<heading>Count.SUM.Migrate?</heading>
- <query>SELECT COUNT(id), SUM(l_current_fine_balance::NUMERIC(6,2)) FROM actor_usr_address_legacy WHERE l_current_fine_balance != '0' AND l_current_fine_balance IS NOT NULL</query>
+ <query>SELECT COUNT(id), SUM(l_current_fine_balance::NUMERIC(6,2)) FROM m_actor_usr_address_legacy WHERE l_current_fine_balance != '0' AND l_current_fine_balance IS NOT NULL</query>
</report>
<report>
<tag>tlc_reports</tag>
<iteration>0</iteration>
<heading>Count.Blocked.Migrate?</heading>
- <query>SELECT COUNT(id), l_blocked FROM actor_usr_address_legacy GROUP BY 2</query>
+ <query>SELECT COUNT(id), l_blocked FROM m_actor_usr_address_legacy GROUP BY 2</query>
</report>
<report>
<tag>tlc_reports</tag>
<iteration>0</iteration>
<heading>Count.Phone Type.Phone Type</heading>
- <query>SELECT COUNT(id), 'Phone 1' FROM actor_usr_address_legacy WHERE l_phone_1 IS NOT NULL GROUP BY 2 UNION ALL SELECT COUNT(id), 'Phone 2' FROM actor_usr_address_legacy WHERE l_phone_2 IS NOT NULL GROUP BY 2</query>
+ <query>SELECT COUNT(id), 'Phone 1' FROM m_actor_usr_address_legacy WHERE l_phone_1 IS NOT NULL GROUP BY 2 UNION ALL SELECT COUNT(id), 'Phone 2' FROM m_actor_usr_address_legacy WHERE l_phone_2 IS NOT NULL GROUP BY 2</query>
</report>
-->
</reports_file>
BEGIN
SELECT migration_tools.production_tables(migration_schema) INTO STRICT production_tables;
PERFORM migration_tools.build_base_staging_tables(migration_schema,production_tables);
- EXECUTE 'CREATE UNIQUE INDEX ' || migration_schema || '_patron_barcode_key ON ' || migration_schema || '.actor_card ( barcode );';
- EXECUTE 'CREATE UNIQUE INDEX ' || migration_schema || '_patron_usrname_key ON ' || migration_schema || '.actor_usr ( usrname );';
- EXECUTE 'CREATE UNIQUE INDEX ' || migration_schema || '_copy_barcode_key ON ' || migration_schema || '.asset_copy ( barcode );';
- EXECUTE 'CREATE UNIQUE INDEX ' || migration_schema || '_copy_id_key ON ' || migration_schema || '.asset_copy ( id );';
- EXECUTE 'CREATE INDEX ' || migration_schema || '_callnum_record_idx ON ' || migration_schema || '.asset_call_number ( record );';
- EXECUTE 'CREATE INDEX ' || migration_schema || '_callnum_upper_label_id_lib_idx ON ' || migration_schema || '.asset_call_number ( UPPER(label),id,owning_lib );';
- EXECUTE 'CREATE UNIQUE INDEX ' || migration_schema || '_callnum_label_once_per_lib ON ' || migration_schema || '.asset_call_number ( record,owning_lib,label,prefix,suffix );';
+ EXECUTE 'CREATE UNIQUE INDEX ' || migration_schema || '_patron_barcode_key ON ' || migration_schema || '.m_actor_card ( barcode );';
+ EXECUTE 'CREATE UNIQUE INDEX ' || migration_schema || '_patron_usrname_key ON ' || migration_schema || '.m_actor_usr ( usrname );';
+ EXECUTE 'CREATE UNIQUE INDEX ' || migration_schema || '_copy_barcode_key ON ' || migration_schema || '.m_asset_copy ( barcode );';
+ EXECUTE 'CREATE UNIQUE INDEX ' || migration_schema || '_copy_id_key ON ' || migration_schema || '.m_asset_copy ( id );';
+ EXECUTE 'CREATE INDEX ' || migration_schema || '_callnum_record_idx ON ' || migration_schema || '.m_asset_call_number ( record );';
+ EXECUTE 'CREATE INDEX ' || migration_schema || '_callnum_upper_label_id_lib_idx ON ' || migration_schema || '.m_asset_call_number ( UPPER(label),id,owning_lib );';
+ EXECUTE 'CREATE UNIQUE INDEX ' || migration_schema || '_callnum_label_once_per_lib ON ' || migration_schema || '.m_asset_call_number ( record,owning_lib,label,prefix,suffix );';
END;
$$ LANGUAGE PLPGSQL STRICT VOLATILE;
base_staging_table TEXT;
columns RECORD;
BEGIN
- base_staging_table = REPLACE( production_table, '.', '_' );
+ base_staging_table = REPLACE( 'm_' || production_table, '.', '_' );
EXECUTE 'CREATE TABLE ' || migration_schema || '.' || base_staging_table || ' ( LIKE ' || production_table || ' INCLUDING DEFAULTS EXCLUDING CONSTRAINTS );';
FOR columns IN
SELECT table_schema, table_name, column_name, data_type
BEGIN
create_sql := 'CREATE TABLE ' || migration_schema || '.' || parent_table || '_legacy ( ';
FOR columns IN
- SELECT table_schema, table_name, column_name, data_type
+ SELECT table_schema, table_name, column_name, data_type, numeric_precision, numeric_scale
FROM information_schema.columns
WHERE table_schema = migration_schema AND table_name = source_table
LOOP
create_sql := create_sql || columns.column_name || ' ';
if columns.data_type = 'ARRAY' then
create_sql := create_sql || 'TEXT[]';
+ elsif columns.data_type = 'numeric' then
+ create_sql := create_sql || 'NUMERIC('||columns.numeric_precision||','||columns.numeric_scale||')';
else
create_sql := create_sql || columns.data_type;
end if;
END;
$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+-- creates other child table so you can have more than one child table in a schema from a base table
+CREATE OR REPLACE FUNCTION migration_tools.build_variant_staging_table(text, text, text)
+ RETURNS void
+ LANGUAGE plpgsql
+ STRICT
+AS $function$
+ DECLARE
+ migration_schema ALIAS FOR $1;
+ production_table ALIAS FOR $2;
+ base_staging_table ALIAS FOR $3;
+ columns RECORD;
+ BEGIN
+ --RAISE INFO 'In migration_tools.build_specific_base_staging_table(%,%) -> %', migration_schema, production_table, base_staging_table;
+ EXECUTE 'CREATE TABLE ' || migration_schema || '.' || base_staging_table || ' ( LIKE ' || production_table || ' INCLUDING DEFAULTS EXCLUDING CONSTRAINTS );';
+ EXECUTE '
+ INSERT INTO ' || migration_schema || '.fields_requiring_mapping
+ SELECT table_schema, table_name, column_name, data_type
+ FROM information_schema.columns
+ WHERE table_schema = ''' || migration_schema || ''' AND table_name = ''' || base_staging_table || ''' AND is_nullable = ''NO'' AND column_default IS NULL;
+ ';
+ FOR columns IN
+ SELECT table_schema, table_name, column_name, data_type
+ FROM information_schema.columns
+ WHERE table_schema = migration_schema AND table_name = base_staging_table AND is_nullable = 'NO' AND column_default IS NULL
+ LOOP
+ EXECUTE 'ALTER TABLE ' || columns.table_schema || '.' || columns.table_name || ' ALTER COLUMN ' || columns.column_name || ' DROP NOT NULL;';
+ END LOOP;
+ END;
+$function$;
+
+CREATE OR REPLACE FUNCTION migration_tools.assert (BOOLEAN) RETURNS VOID AS $$
+ DECLARE
+ test ALIAS FOR $1;
+ BEGIN
+ IF NOT test THEN
+ RAISE EXCEPTION 'assertion';
+ END IF;
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+CREATE OR REPLACE FUNCTION migration_tools.assert (BOOLEAN,TEXT) RETURNS VOID AS $$
+ DECLARE
+ test ALIAS FOR $1;
+ msg ALIAS FOR $2;
+ BEGIN
+ IF NOT test THEN
+ RAISE EXCEPTION '%', msg;
+ END IF;
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+CREATE OR REPLACE FUNCTION migration_tools.assert (BOOLEAN,TEXT,TEXT) RETURNS TEXT AS $$
+ DECLARE
+ test ALIAS FOR $1;
+ fail_msg ALIAS FOR $2;
+ success_msg ALIAS FOR $3;
+ BEGIN
+ IF NOT test THEN
+ RAISE EXCEPTION '%', fail_msg;
+ END IF;
+ RETURN success_msg;
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
-- circ_lib, target_copy, usr, and *_renewal). User profiles and
-- circ modifiers must also be in place.
--
--- SELECT migration_tools.apply_circ_matrix('m_pioneer.action_circulation');
+-- SELECT migration_tools.apply_circ_matrix('m_pioneer.m_action_circulation');
--
DECLARE
-- circ_lib, target_copy, usr, and *_renewal). User profiles and
-- circ modifiers must also be in place.
--
--- SELECT migration_tools.apply_circ_matrix_to_specific_circ('m_nwrl.action_circulation', 18391960);
+-- SELECT migration_tools.apply_circ_matrix_to_specific_circ('m_nwrl.m_action_circulation', 18391960);
--
DECLARE
CREATE OR REPLACE FUNCTION migration_tools.create_cards( schemaname TEXT ) RETURNS VOID AS $$
--- USAGE: Make sure the patrons are staged in schemaname.actor_usr_legacy and have 'usrname' assigned.
+-- USAGE: Make sure the patrons are staged in schemaname.m_actor_usr_legacy and have 'usrname' assigned.
-- Then SELECT migration_tools.create_cards('m_foo');
DECLARE
- u TEXT := schemaname || '.actor_usr_legacy';
- c TEXT := schemaname || '.actor_card';
+ u TEXT := schemaname || '.m_actor_usr_legacy';
+ c TEXT := schemaname || '.m_actor_card';
BEGIN
BEGIN
EXECUTE $$COPY (SELECT * FROM actor.hours_of_operation WHERE id IN ($$ ||
ARRAY_TO_STRING(orgs, ',') || $$)$$ ||
- $$) TO '$$ || dir || $$/actor_hours_of_operation'$$;
+ $$) TO '$$ || dir || $$/m_actor_hours_of_operation'$$;
EXECUTE $$COPY (SELECT org_unit, close_start, close_end, reason FROM actor.org_unit_closed WHERE org_unit IN ($$ ||
ARRAY_TO_STRING(orgs, ',') || $$)$$ ||
- $$) TO '$$ || dir || $$/actor_org_unit_closed'$$;
+ $$) TO '$$ || dir || $$/m_actor_org_unit_closed'$$;
EXECUTE $$COPY (SELECT org_unit, name, value FROM actor.org_unit_setting WHERE org_unit IN ($$ ||
ARRAY_TO_STRING(orgs, ',') || $$)$$ ||
- $$) TO '$$ || dir || $$/actor_org_unit_setting'$$;
+ $$) TO '$$ || dir || $$/m_actor_org_unit_setting'$$;
EXECUTE $$COPY (SELECT name, owning_lib, holdable, hold_verify, opac_visible, circulate FROM asset.copy_location WHERE owning_lib IN ($$ ||
ARRAY_TO_STRING(orgs, ',') || $$)$$ ||
- $$) TO '$$ || dir || $$/asset_copy_location'$$;
+ $$) TO '$$ || dir || $$/m_asset_copy_location'$$;
EXECUTE $$COPY (SELECT grp, org_unit, penalty, threshold FROM permission.grp_penalty_threshold WHERE org_unit IN ($$ ||
ARRAY_TO_STRING(orgs, ',') || $$)$$ ||
- $$) TO '$$ || dir || $$/permission_grp_penalty_threshold'$$;
+ $$) TO '$$ || dir || $$/m_permission_grp_penalty_threshold'$$;
EXECUTE $$COPY (SELECT owning_lib, label, label_sortkey FROM asset.call_number_prefix WHERE owning_lib IN ($$ ||
ARRAY_TO_STRING(orgs, ',') || $$)$$ ||
- $$) TO '$$ || dir || $$/asset_call_number_prefix'$$;
+ $$) TO '$$ || dir || $$/m_asset_call_number_prefix'$$;
EXECUTE $$COPY (SELECT owning_lib, label, label_sortkey FROM asset.call_number_suffix WHERE owning_lib IN ($$ ||
ARRAY_TO_STRING(orgs, ',') || $$)$$ ||
- $$) TO '$$ || dir || $$/asset_call_number_suffix'$$;
- EXECUTE $$COPY config.rule_circ_duration TO '$$ || dir || $$/config_rule_circ_duration'$$;
- EXECUTE $$COPY config.rule_age_hold_protect TO '$$ || dir || $$/config_rule_age_hold_protect'$$;
- EXECUTE $$COPY config.rule_max_fine TO '$$ || dir || $$/config_rule_max_fine'$$;
- EXECUTE $$COPY config.rule_recurring_fine TO '$$ || dir || $$/config_rule_recurring_fine'$$;
- EXECUTE $$COPY permission.grp_tree TO '$$ || dir || $$/permission_grp_tree'$$;
+ $$) TO '$$ || dir || $$/m_asset_call_number_suffix'$$;
+ EXECUTE $$COPY config.rule_circ_duration TO '$$ || dir || $$/m_config_rule_circ_duration'$$;
+ EXECUTE $$COPY config.rule_age_hold_protect TO '$$ || dir || $$/m_config_rule_age_hold_protect'$$;
+ EXECUTE $$COPY config.rule_max_fine TO '$$ || dir || $$/m_config_rule_max_fine'$$;
+ EXECUTE $$COPY config.rule_recurring_fine TO '$$ || dir || $$/m_config_rule_recurring_fine'$$;
+ EXECUTE $$COPY permission.grp_tree TO '$$ || dir || $$/m_permission_grp_tree'$$;
END;
$FUNC$ LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION migration_tools.simple_import_library_config(dir TEXT) RETURNS VOID AS $FUNC$
BEGIN
- EXECUTE $$COPY actor.hours_of_operation FROM '$$ || dir || $$/actor_hours_of_operation'$$;
- EXECUTE $$COPY actor.org_unit_closed (org_unit, close_start, close_end, reason) FROM '$$ || dir || $$/actor_org_unit_closed'$$;
- EXECUTE $$COPY actor.org_unit_setting (org_unit, name, value) FROM '$$ || dir || $$/actor_org_unit_setting'$$;
- EXECUTE $$COPY asset.copy_location (name, owning_lib, holdable, hold_verify, opac_visible, circulate) FROM '$$ || dir || $$/asset_copy_location'$$;
- EXECUTE $$COPY permission.grp_penalty_threshold (grp, org_unit, penalty, threshold) FROM '$$ || dir || $$/permission_grp_penalty_threshold'$$;
- EXECUTE $$COPY asset.call_number_prefix (owning_lib, label, label_sortkey) FROM '$$ || dir || $$/asset_call_number_prefix'$$;
- EXECUTE $$COPY asset.call_number_suffix (owning_lib, label, label_sortkey) FROM '$$ || dir || $$/asset_call_number_suffix'$$;
+ EXECUTE $$COPY actor.hours_of_operation FROM '$$ || dir || $$/m_actor_hours_of_operation'$$;
+ EXECUTE $$COPY actor.org_unit_closed (org_unit, close_start, close_end, reason) FROM '$$ || dir || $$/m_actor_org_unit_closed'$$;
+ EXECUTE $$COPY actor.org_unit_setting (org_unit, name, value) FROM '$$ || dir || $$/m_actor_org_unit_setting'$$;
+ EXECUTE $$COPY asset.copy_location (name, owning_lib, holdable, hold_verify, opac_visible, circulate) FROM '$$ || dir || $$/m_asset_copy_location'$$;
+ EXECUTE $$COPY permission.grp_penalty_threshold (grp, org_unit, penalty, threshold) FROM '$$ || dir || $$/m_permission_grp_penalty_threshold'$$;
+ EXECUTE $$COPY asset.call_number_prefix (owning_lib, label, label_sortkey) FROM '$$ || dir || $$/m_asset_call_number_prefix'$$;
+ EXECUTE $$COPY asset.call_number_suffix (owning_lib, label, label_sortkey) FROM '$$ || dir || $$/m_asset_call_number_suffix'$$;
-- import any new circ rules
PERFORM migration_tools.simple_import_new_rows_by_value(dir, 'config', 'rule_circ_duration', 'id', 'name');
)
);
$$ LANGUAGE SQL;
+
+-- set a new salted password
+
+CREATE OR REPLACE FUNCTION migration_tools.set_salted_passwd(INTEGER,TEXT) RETURNS BOOLEAN AS $$
+ DECLARE
+ usr_id ALIAS FOR $1;
+ plain_passwd ALIAS FOR $2;
+ plain_salt TEXT;
+ md5_passwd TEXT;
+ BEGIN
+
+ SELECT actor.create_salt('main') INTO plain_salt;
+
+ SELECT MD5(plain_passwd) INTO md5_passwd;
+
+ PERFORM actor.set_passwd(usr_id, 'main', MD5(plain_salt || md5_passwd), plain_salt);
+
+ RETURN TRUE;
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+-- internal function for handle_shelf
+
+CREATE OR REPLACE FUNCTION migration_tools._handle_shelf (TEXT,TEXT,TEXT,INTEGER,BOOLEAN) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_name ALIAS FOR $2;
+ org_shortname ALIAS FOR $3;
+ org_range ALIAS FOR $4;
+ make_assertion ALIAS FOR $5;
+ proceed BOOLEAN;
+ org INTEGER;
+ -- if x_org is on the mapping table, it'll take precedence over the passed org_shortname param
+ -- though we'll still use the passed org for the full path traversal when needed
+ x_org_found BOOLEAN;
+ x_org INTEGER;
+ org_list INTEGER[];
+ o INTEGER;
+ row_count NUMERIC;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = ''desired_shelf''
+ )' INTO proceed USING table_schema, table_name;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'Missing column desired_shelf';
+ END IF;
+
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = ''x_org''
+ )' INTO x_org_found USING table_schema, table_name;
+
+ SELECT id INTO org FROM actor.org_unit WHERE shortname = org_shortname;
+ IF org IS NULL THEN
+ RAISE EXCEPTION 'Cannot find org by shortname';
+ END IF;
+
+ SELECT INTO org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( org );
+
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' DROP COLUMN IF EXISTS x_shelf';
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' ADD COLUMN x_shelf INTEGER';
+
+ IF x_org_found THEN
+ RAISE INFO 'Found x_org column';
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_shelf = b.id FROM m_asset_copy_location b'
+ || ' WHERE BTRIM(UPPER(a.desired_shelf)) = BTRIM(UPPER(b.name))'
+ || ' AND b.owning_lib = x_org'
+ || ' AND NOT b.deleted';
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_shelf = b.id FROM asset.copy_location b'
+ || ' WHERE BTRIM(UPPER(a.desired_shelf)) = BTRIM(UPPER(b.name))'
+ || ' AND b.owning_lib = x_org'
+ || ' AND x_shelf IS NULL'
+ || ' AND NOT b.deleted';
+ ELSE
+ RAISE INFO 'Did not find x_org column';
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_shelf = b.id FROM m_asset_copy_location b'
+ || ' WHERE BTRIM(UPPER(a.desired_shelf)) = BTRIM(UPPER(b.name))'
+ || ' AND b.owning_lib = $1'
+ || ' AND NOT b.deleted'
+ USING org;
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_shelf = b.id FROM m_asset_copy_location b'
+ || ' WHERE BTRIM(UPPER(a.desired_shelf)) = BTRIM(UPPER(b.name))'
+ || ' AND b.owning_lib = $1'
+ || ' AND x_shelf IS NULL'
+ || ' AND NOT b.deleted'
+ USING org;
+ END IF;
+
+ FOREACH o IN ARRAY org_list LOOP
+ RAISE INFO 'Considering org %', o;
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_shelf = b.id FROM asset.copy_location b'
+ || ' WHERE BTRIM(UPPER(a.desired_shelf)) = BTRIM(UPPER(b.name))'
+ || ' AND b.owning_lib = $1 AND x_shelf IS NULL'
+ || ' AND NOT b.deleted'
+ USING o;
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ RAISE INFO 'Updated % rows', row_count;
+ END LOOP;
+
+ IF make_assertion THEN
+ EXECUTE 'SELECT migration_tools.assert(
+ NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_shelf <> '''' AND x_shelf IS NULL),
+ ''Cannot find a desired location'',
+ ''Found all desired locations''
+ );';
+ END IF;
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+-- convenience functions for handling copy_location maps
+CREATE OR REPLACE FUNCTION migration_tools.handle_shelf (TEXT,TEXT,TEXT,INTEGER) RETURNS VOID AS $$
+ SELECT migration_tools._handle_shelf($1,$2,$3,$4,TRUE);
+$$ LANGUAGE SQL;
+
+-- convenience functions for handling circmod maps
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_circmod (TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_name ALIAS FOR $2;
+ proceed BOOLEAN;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = ''desired_circmod''
+ )' INTO proceed USING table_schema, table_name;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'Missing column desired_circmod';
+ END IF;
+
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' DROP COLUMN IF EXISTS x_circmod';
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' ADD COLUMN x_circmod TEXT';
+
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_circmod = code FROM config.circ_modifier b'
+ || ' WHERE BTRIM(UPPER(a.desired_circmod)) = BTRIM(UPPER(b.code))';
+
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_circmod = code FROM config.circ_modifier b'
+ || ' WHERE BTRIM(UPPER(a.desired_circmod)) = BTRIM(UPPER(b.name))'
+ || ' AND x_circmod IS NULL';
+
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_circmod = code FROM config.circ_modifier b'
+ || ' WHERE BTRIM(UPPER(a.desired_circmod)) = BTRIM(UPPER(b.description))'
+ || ' AND x_circmod IS NULL';
+
+ EXECUTE 'SELECT migration_tools.assert(
+ NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_circmod <> '''' AND x_circmod IS NULL),
+ ''Cannot find a desired circulation modifier'',
+ ''Found all desired circulation modifiers''
+ );';
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+-- convenience functions for handling item status maps
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_status (TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_name ALIAS FOR $2;
+ proceed BOOLEAN;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = ''desired_status''
+ )' INTO proceed USING table_schema, table_name;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'Missing column desired_status';
+ END IF;
+
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' DROP COLUMN IF EXISTS x_status';
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' ADD COLUMN x_status INTEGER';
+
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_status = id FROM config.copy_status b'
+ || ' WHERE BTRIM(UPPER(a.desired_status)) = BTRIM(UPPER(b.name))';
+
+ EXECUTE 'SELECT migration_tools.assert(
+ NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_status <> '''' AND x_status IS NULL),
+ ''Cannot find a desired copy status'',
+ ''Found all desired copy statuses''
+ );';
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+-- convenience functions for handling org maps
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_org (TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_name ALIAS FOR $2;
+ proceed BOOLEAN;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = ''desired_org''
+ )' INTO proceed USING table_schema, table_name;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'Missing column desired_org';
+ END IF;
+
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' DROP COLUMN IF EXISTS x_org';
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' ADD COLUMN x_org INTEGER';
+
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_org = b.id FROM actor.org_unit b'
+ || ' WHERE BTRIM(a.desired_org) = BTRIM(b.shortname)';
+
+ EXECUTE 'SELECT migration_tools.assert(
+ NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_org <> '''' AND x_org IS NULL),
+ ''Cannot find a desired org unit'',
+ ''Found all desired org units''
+ );';
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+-- convenience function for handling desired_not_migrate
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_not_migrate (TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_name ALIAS FOR $2;
+ proceed BOOLEAN;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = ''desired_not_migrate''
+ )' INTO proceed USING table_schema, table_name;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'Missing column desired_not_migrate';
+ END IF;
+
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' DROP COLUMN IF EXISTS x_migrate';
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' ADD COLUMN x_migrate BOOLEAN';
+
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_migrate = CASE'
+ || ' WHEN BTRIM(desired_not_migrate) = ''TRUE'' THEN FALSE'
+ || ' WHEN BTRIM(desired_not_migrate) = ''DNM'' THEN FALSE'
+ || ' WHEN BTRIM(desired_not_migrate) = ''Do Not Migrate'' THEN FALSE'
+ || ' WHEN BTRIM(desired_not_migrate) = ''FALSE'' THEN TRUE'
+ || ' WHEN BTRIM(desired_not_migrate) = ''Migrate'' THEN TRUE'
+ || ' WHEN BTRIM(desired_not_migrate) = '''' THEN TRUE'
+ || ' END';
+
+ EXECUTE 'SELECT migration_tools.assert(
+ NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE x_migrate IS NULL),
+ ''Not all desired_not_migrate values understood'',
+ ''All desired_not_migrate values understood''
+ );';
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+-- convenience function for handling desired_not_migrate
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_barred_or_blocked (TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_name ALIAS FOR $2;
+ proceed BOOLEAN;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = ''desired_barred_or_blocked''
+ )' INTO proceed USING table_schema, table_name;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'Missing column desired_barred_or_blocked';
+ END IF;
+
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' DROP COLUMN IF EXISTS x_barred';
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' ADD COLUMN x_barred BOOLEAN';
+
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' DROP COLUMN IF EXISTS x_blocked';
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' ADD COLUMN x_blocked BOOLEAN';
+
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_barred = CASE'
+ || ' WHEN BTRIM(desired_barred_or_blocked) = ''Barred'' THEN TRUE'
+ || ' WHEN BTRIM(desired_barred_or_blocked) = ''Blocked'' THEN FALSE'
+ || ' WHEN BTRIM(desired_barred_or_blocked) = ''Neither'' THEN FALSE'
+ || ' WHEN BTRIM(desired_barred_or_blocked) = '''' THEN FALSE'
+ || ' END';
+
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_blocked = CASE'
+ || ' WHEN BTRIM(desired_barred_or_blocked) = ''Blocked'' THEN TRUE'
+ || ' WHEN BTRIM(desired_barred_or_blocked) = ''Barred'' THEN FALSE'
+ || ' WHEN BTRIM(desired_barred_or_blocked) = ''Neither'' THEN FALSE'
+ || ' WHEN BTRIM(desired_barred_or_blocked) = '''' THEN FALSE'
+ || ' END';
+
+ EXECUTE 'SELECT migration_tools.assert(
+ NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE x_barred IS NULL or x_blocked IS NULL),
+ ''Not all desired_barred_or_blocked values understood'',
+ ''All desired_barred_or_blocked values understood''
+ );';
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+-- convenience function for handling desired_profile
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_profile (TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_name ALIAS FOR $2;
+ proceed BOOLEAN;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = ''desired_profile''
+ )' INTO proceed USING table_schema, table_name;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'Missing column desired_profile';
+ END IF;
+
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' DROP COLUMN IF EXISTS x_profile';
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' ADD COLUMN x_profile INTEGER';
+
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_profile = b.id FROM permission.grp_tree b'
+ || ' WHERE BTRIM(UPPER(a.desired_profile)) = BTRIM(UPPER(b.name))';
+
+ EXECUTE 'SELECT migration_tools.assert(
+ NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_profile <> '''' AND x_profile IS NULL),
+ ''Cannot find a desired profile'',
+ ''Found all desired profiles''
+ );';
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+-- convenience function for handling desired actor stat cats
+
+CREATE OR REPLACE FUNCTION migration_tools.vivicate_actor_sc_and_sce (TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_name ALIAS FOR $2;
+ field_suffix ALIAS FOR $3; -- for distinguishing between desired_sce1, desired_sce2, etc.
+ org_shortname ALIAS FOR $4;
+ proceed BOOLEAN;
+ org INTEGER;
+ org_list INTEGER[];
+ sc TEXT;
+ sce TEXT;
+ BEGIN
+
+ SELECT 'desired_sc' || field_suffix INTO sc;
+ SELECT 'desired_sce' || field_suffix INTO sce;
+
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_name, sc;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'Missing column %', sc;
+ END IF;
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_name, sce;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'Missing column %', sce;
+ END IF;
+
+ SELECT id INTO org FROM actor.org_unit WHERE shortname = org_shortname;
+ IF org IS NULL THEN
+ RAISE EXCEPTION 'Cannot find org by shortname';
+ END IF;
+ SELECT INTO org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( org );
+
+ -- caller responsible for their own truncates though we try to prevent duplicates
+ EXECUTE 'INSERT INTO m_actor_stat_cat (owner, name)
+ SELECT DISTINCT
+ $1
+ ,BTRIM('||sc||')
+ FROM
+ ' || quote_ident(table_name) || '
+ WHERE
+ NULLIF(BTRIM('||sc||'),'''') IS NOT NULL
+ AND NOT EXISTS (
+ SELECT id
+ FROM actor.stat_cat
+ WHERE owner = ANY ($2)
+ AND name = BTRIM('||sc||')
+ )
+ AND NOT EXISTS (
+ SELECT id
+ FROM m_actor_stat_cat
+ WHERE owner = ANY ($2)
+ AND name = BTRIM('||sc||')
+ )
+ ORDER BY 2;'
+ USING org, org_list;
+
+ EXECUTE 'INSERT INTO m_actor_stat_cat_entry (stat_cat, owner, value)
+ SELECT DISTINCT
+ COALESCE(
+ (SELECT id
+ FROM actor.stat_cat
+ WHERE owner = ANY ($2)
+ AND BTRIM('||sc||') = BTRIM(name))
+ ,(SELECT id
+ FROM m_actor_stat_cat
+ WHERE owner = ANY ($2)
+ AND BTRIM('||sc||') = BTRIM(name))
+ )
+ ,$1
+ ,BTRIM('||sce||')
+ FROM
+ ' || quote_ident(table_name) || '
+ WHERE
+ NULLIF(BTRIM('||sc||'),'''') IS NOT NULL
+ AND NULLIF(BTRIM('||sce||'),'''') IS NOT NULL
+ AND NOT EXISTS (
+ SELECT id
+ FROM actor.stat_cat_entry
+ WHERE stat_cat = (
+ SELECT id
+ FROM actor.stat_cat
+ WHERE owner = ANY ($2)
+ AND BTRIM('||sc||') = BTRIM(name)
+ ) AND value = BTRIM('||sce||')
+ AND owner = ANY ($2)
+ )
+ AND NOT EXISTS (
+ SELECT id
+ FROM m_actor_stat_cat_entry
+ WHERE stat_cat = (
+ SELECT id
+ FROM m_actor_stat_cat
+ WHERE owner = ANY ($2)
+ AND BTRIM('||sc||') = BTRIM(name)
+ ) AND value = BTRIM('||sce||')
+ AND owner = ANY ($2)
+ )
+ ORDER BY 1,3;'
+ USING org, org_list;
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_actor_sc_and_sce (TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_name ALIAS FOR $2;
+ field_suffix ALIAS FOR $3; -- for distinguishing between desired_sce1, desired_sce2, etc.
+ org_shortname ALIAS FOR $4;
+ proceed BOOLEAN;
+ org INTEGER;
+ org_list INTEGER[];
+ o INTEGER;
+ sc TEXT;
+ sce TEXT;
+ BEGIN
+ SELECT 'desired_sc' || field_suffix INTO sc;
+ SELECT 'desired_sce' || field_suffix INTO sce;
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_name, sc;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'Missing column %', sc;
+ END IF;
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_name, sce;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'Missing column %', sce;
+ END IF;
+
+ SELECT id INTO org FROM actor.org_unit WHERE shortname = org_shortname;
+ IF org IS NULL THEN
+ RAISE EXCEPTION 'Cannot find org by shortname';
+ END IF;
+
+ SELECT INTO org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( org );
+
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' DROP COLUMN IF EXISTS x_sc' || field_suffix;
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' ADD COLUMN x_sc' || field_suffix || ' INTEGER';
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' DROP COLUMN IF EXISTS x_sce' || field_suffix;
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' ADD COLUMN x_sce' || field_suffix || ' INTEGER';
+
+
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || '
+ SET
+ x_sc' || field_suffix || ' = id
+ FROM
+ (SELECT id, name, owner FROM m_actor_stat_cat
+ UNION SELECT id, name, owner FROM actor.stat_cat) u
+ WHERE
+ BTRIM(UPPER(u.name)) = BTRIM(UPPER(' || sc || '))
+ AND u.owner = ANY ($1);'
+ USING org_list;
+
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || '
+ SET
+ x_sce' || field_suffix || ' = id
+ FROM
+ (SELECT id, stat_cat, owner, value FROM m_actor_stat_cat_entry
+ UNION SELECT id, stat_cat, owner, value FROM actor.stat_cat_entry) u
+ WHERE
+ u.stat_cat = x_sc' || field_suffix || '
+ AND BTRIM(UPPER(u.value)) = BTRIM(UPPER(' || sce || '))
+ AND u.owner = ANY ($1);'
+ USING org_list;
+
+ EXECUTE 'SELECT migration_tools.assert(
+ NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_sc' || field_suffix || ' <> '''' AND x_sc' || field_suffix || ' IS NULL),
+ ''Cannot find a desired stat cat'',
+ ''Found all desired stat cats''
+ );';
+
+ EXECUTE 'SELECT migration_tools.assert(
+ NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_sce' || field_suffix || ' <> '''' AND x_sce' || field_suffix || ' IS NULL),
+ ''Cannot find a desired stat cat entry'',
+ ''Found all desired stat cat entries''
+ );';
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+-- convenience functions for adding shelving locations
+DROP FUNCTION IF EXISTS migration_tools.find_shelf(INT,TEXT);
+CREATE OR REPLACE FUNCTION migration_tools.find_shelf(org_id INT, shelf_name TEXT) RETURNS INTEGER AS $$
+DECLARE
+ return_id INT;
+ d INT;
+ cur_id INT;
+BEGIN
+ SELECT INTO d MAX(distance) FROM actor.org_unit_ancestors_distance(org_id);
+ WHILE d >= 0
+ LOOP
+ SELECT INTO cur_id id FROM actor.org_unit_ancestor_at_depth(org_id,d);
+ SELECT INTO return_id id FROM asset.copy_location WHERE owning_lib = cur_id AND name ILIKE shelf_name;
+ IF return_id IS NOT NULL THEN
+ RETURN return_id;
+ END IF;
+ d := d - 1;
+ END LOOP;
+
+ RETURN NULL;
+END
+$$ LANGUAGE plpgsql;
+
+-- may remove later but testing using this with new migration scripts and not loading acls until go live
+
+DROP FUNCTION IF EXISTS migration_tools.find_mig_shelf(INT,TEXT);
+CREATE OR REPLACE FUNCTION migration_tools.find_mig_shelf(org_id INT, shelf_name TEXT) RETURNS INTEGER AS $$
+DECLARE
+ return_id INT;
+ d INT;
+ cur_id INT;
+BEGIN
+ SELECT INTO d MAX(distance) FROM actor.org_unit_ancestors_distance(org_id);
+ WHILE d >= 0
+ LOOP
+ SELECT INTO cur_id id FROM actor.org_unit_ancestor_at_depth(org_id,d);
+
+ SELECT INTO return_id id FROM
+ (SELECT * FROM asset.copy_location UNION ALL SELECT * FROM m_asset_copy_location) x
+ WHERE owning_lib = cur_id AND name ILIKE shelf_name;
+ IF return_id IS NOT NULL THEN
+ RETURN return_id;
+ END IF;
+ d := d - 1;
+ END LOOP;
+
+ RETURN NULL;
+END
+$$ LANGUAGE plpgsql;
+
+-- convenience function for linking to the item staging table
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_item_barcode (TEXT,TEXT,TEXT,TEXT,BOOLEAN) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_name ALIAS FOR $2;
+ foreign_column_name ALIAS FOR $3;
+ main_column_name ALIAS FOR $4;
+ btrim_desired ALIAS FOR $5;
+ proceed BOOLEAN;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_name, foreign_column_name;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_name, foreign_column_name;
+ END IF;
+
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = ''m_asset_copy_legacy''
+ and column_name = $2
+ )' INTO proceed USING table_schema, main_column_name;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'No %.m_asset_copy_legacy with column %', table_schema, main_column_name;
+ END IF;
+
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' DROP COLUMN IF EXISTS x_item';
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' ADD COLUMN x_item BIGINT';
+
+ IF btrim_desired THEN
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_item = b.id FROM m_asset_copy_legacy b'
+ || ' WHERE BTRIM(a.' || quote_ident(foreign_column_name)
+ || ') = BTRIM(b.' || quote_ident(main_column_name) || ')';
+ ELSE
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_item = b.id FROM m_asset_copy_legacy b'
+ || ' WHERE a.' || quote_ident(foreign_column_name)
+ || ' = b.' || quote_ident(main_column_name);
+ END IF;
+
+ --EXECUTE 'SELECT migration_tools.assert(
+ -- NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE ' || quote_ident(foreign_column_name) || ' <> '''' AND x_item IS NULL),
+ -- ''Cannot link every barcode'',
+ -- ''Every barcode linked''
+ --);';
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+-- convenience function for linking to the user staging table
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_user_barcode (TEXT,TEXT,TEXT,TEXT,BOOLEAN) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_name ALIAS FOR $2;
+ foreign_column_name ALIAS FOR $3;
+ main_column_name ALIAS FOR $4;
+ btrim_desired ALIAS FOR $5;
+ proceed BOOLEAN;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_name, foreign_column_name;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_name, foreign_column_name;
+ END IF;
+
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = ''m_actor_usr_legacy''
+ and column_name = $2
+ )' INTO proceed USING table_schema, main_column_name;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'No %.m_actor_usr_legacy with column %', table_schema, main_column_name;
+ END IF;
+
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' DROP COLUMN IF EXISTS x_user';
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' ADD COLUMN x_user INTEGER';
+
+ IF btrim_desired THEN
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_user = b.id FROM m_actor_usr_legacy b'
+ || ' WHERE BTRIM(a.' || quote_ident(foreign_column_name)
+ || ') = BTRIM(b.' || quote_ident(main_column_name) || ')';
+ ELSE
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
+ || ' SET x_user = b.id FROM m_actor_usr_legacy b'
+ || ' WHERE a.' || quote_ident(foreign_column_name)
+ || ' = b.' || quote_ident(main_column_name);
+ END IF;
+
+ --EXECUTE 'SELECT migration_tools.assert(
+ -- NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE ' || quote_ident(foreign_column_name) || ' <> '''' AND x_user IS NULL),
+ -- ''Cannot link every barcode'',
+ -- ''Every barcode linked''
+ --);';
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+-- convenience function for handling desired asset stat cats
+
+CREATE OR REPLACE FUNCTION migration_tools.vivicate_asset_sc_and_sce (TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_name ALIAS FOR $2;
+ field_suffix ALIAS FOR $3; -- for distinguishing between desired_sce1, desired_sce2, etc.
+ org_shortname ALIAS FOR $4;
+ proceed BOOLEAN;
+ org INTEGER;
+ org_list INTEGER[];
+ sc TEXT;
+ sce TEXT;
+ BEGIN
+
+ SELECT 'desired_sc' || field_suffix INTO sc;
+ SELECT 'desired_sce' || field_suffix INTO sce;
+
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_name, sc;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'Missing column %', sc;
+ END IF;
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_name, sce;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'Missing column %', sce;
+ END IF;
+
+ SELECT id INTO org FROM actor.org_unit WHERE shortname = org_shortname;
+ IF org IS NULL THEN
+ RAISE EXCEPTION 'Cannot find org by shortname';
+ END IF;
+ SELECT INTO org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( org );
+
+ -- caller responsible for their own truncates though we try to prevent duplicates
+ EXECUTE 'INSERT INTO m_asset_stat_cat (owner, name)
+ SELECT DISTINCT
+ $1
+ ,BTRIM('||sc||')
+ FROM
+ ' || quote_ident(table_name) || '
+ WHERE
+ NULLIF(BTRIM('||sc||'),'''') IS NOT NULL
+ AND NOT EXISTS (
+ SELECT id
+ FROM asset.stat_cat
+ WHERE owner = ANY ($2)
+ AND name = BTRIM('||sc||')
+ )
+ AND NOT EXISTS (
+ SELECT id
+ FROM m_asset_stat_cat
+ WHERE owner = ANY ($2)
+ AND name = BTRIM('||sc||')
+ )
+ ORDER BY 2;'
+ USING org, org_list;
+
+ EXECUTE 'INSERT INTO m_asset_stat_cat_entry (stat_cat, owner, value)
+ SELECT DISTINCT
+ COALESCE(
+ (SELECT id
+ FROM asset.stat_cat
+ WHERE owner = ANY ($2)
+ AND BTRIM('||sc||') = BTRIM(name))
+ ,(SELECT id
+ FROM m_asset_stat_cat
+ WHERE owner = ANY ($2)
+ AND BTRIM('||sc||') = BTRIM(name))
+ )
+ ,$1
+ ,BTRIM('||sce||')
+ FROM
+ ' || quote_ident(table_name) || '
+ WHERE
+ NULLIF(BTRIM('||sc||'),'''') IS NOT NULL
+ AND NULLIF(BTRIM('||sce||'),'''') IS NOT NULL
+ AND NOT EXISTS (
+ SELECT id
+ FROM asset.stat_cat_entry
+ WHERE stat_cat = (
+ SELECT id
+ FROM asset.stat_cat
+ WHERE owner = ANY ($2)
+ AND BTRIM('||sc||') = BTRIM(name)
+ ) AND value = BTRIM('||sce||')
+ AND owner = ANY ($2)
+ )
+ AND NOT EXISTS (
+ SELECT id
+ FROM m_asset_stat_cat_entry
+ WHERE stat_cat = (
+ SELECT id
+ FROM m_asset_stat_cat
+ WHERE owner = ANY ($2)
+ AND BTRIM('||sc||') = BTRIM(name)
+ ) AND value = BTRIM('||sce||')
+ AND owner = ANY ($2)
+ )
+ ORDER BY 1,3;'
+ USING org, org_list;
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_asset_sc_and_sce (TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_name ALIAS FOR $2;
+ field_suffix ALIAS FOR $3; -- for distinguishing between desired_sce1, desired_sce2, etc.
+ org_shortname ALIAS FOR $4;
+ proceed BOOLEAN;
+ org INTEGER;
+ org_list INTEGER[];
+ o INTEGER;
+ sc TEXT;
+ sce TEXT;
+ BEGIN
+ SELECT 'desired_sc' || field_suffix INTO sc;
+ SELECT 'desired_sce' || field_suffix INTO sce;
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_name, sc;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'Missing column %', sc;
+ END IF;
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_name, sce;
+ IF NOT proceed THEN
+ RAISE EXCEPTION 'Missing column %', sce;
+ END IF;
+
+ SELECT id INTO org FROM actor.org_unit WHERE shortname = org_shortname;
+ IF org IS NULL THEN
+ RAISE EXCEPTION 'Cannot find org by shortname';
+ END IF;
+
+ SELECT INTO org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( org );
+
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' DROP COLUMN IF EXISTS x_sc' || field_suffix;
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' ADD COLUMN x_sc' || field_suffix || ' INTEGER';
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' DROP COLUMN IF EXISTS x_sce' || field_suffix;
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_name)
+ || ' ADD COLUMN x_sce' || field_suffix || ' INTEGER';
+
+
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || '
+ SET
+ x_sc' || field_suffix || ' = id
+ FROM
+ (SELECT id, name, owner FROM m_asset_stat_cat
+ UNION SELECT id, name, owner FROM asset.stat_cat) u
+ WHERE
+ BTRIM(UPPER(u.name)) = BTRIM(UPPER(' || sc || '))
+ AND u.owner = ANY ($1);'
+ USING org_list;
+
+ EXECUTE 'UPDATE ' || quote_ident(table_name) || '
+ SET
+ x_sce' || field_suffix || ' = id
+ FROM
+ (SELECT id, stat_cat, owner, value FROM m_asset_stat_cat_entry
+ UNION SELECT id, stat_cat, owner, value FROM asset.stat_cat_entry) u
+ WHERE
+ u.stat_cat = x_sc' || field_suffix || '
+ AND BTRIM(UPPER(u.value)) = BTRIM(UPPER(' || sce || '))
+ AND u.owner = ANY ($1);'
+ USING org_list;
+
+ EXECUTE 'SELECT migration_tools.assert(
+ NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_sc' || field_suffix || ' <> '''' AND x_sc' || field_suffix || ' IS NULL),
+ ''Cannot find a desired stat cat'',
+ ''Found all desired stat cats''
+ );';
+
+ EXECUTE 'SELECT migration_tools.assert(
+ NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_sce' || field_suffix || ' <> '''' AND x_sce' || field_suffix || ' IS NULL),
+ ''Cannot find a desired stat cat entry'',
+ ''Found all desired stat cat entries''
+ );';
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+-- convenience function for handling item barcode collisions in m_asset_copy_legacy
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_asset_barcode_collisions(migration_schema TEXT) RETURNS VOID AS $function$
+DECLARE
+ x_barcode TEXT;
+ x_id BIGINT;
+ row_count NUMERIC;
+ internal_collision_count NUMERIC := 0;
+ incumbent_collision_count NUMERIC := 0;
+BEGIN
+ FOR x_barcode IN SELECT barcode FROM m_asset_copy_legacy WHERE x_migrate GROUP BY 1 HAVING COUNT(*) > 1
+ LOOP
+ FOR x_id IN SELECT id FROM m_asset_copy WHERE barcode = x_barcode
+ LOOP
+ UPDATE m_asset_copy SET barcode = migration_schema || '_internal_collision_' || id || '_' || barcode WHERE id = x_id;
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ internal_collision_count := internal_collision_count + row_count;
+ END LOOP;
+ END LOOP;
+ RAISE INFO '% internal collisions', internal_collision_count;
+ FOR x_barcode IN SELECT a.barcode FROM asset.copy a, m_asset_copy_legacy b WHERE x_migrate AND a.deleted IS FALSE AND a.barcode = b.barcode
+ LOOP
+ FOR x_id IN SELECT id FROM m_asset_copy_legacy WHERE barcode = x_barcode
+ LOOP
+ UPDATE m_asset_copy_legacy SET barcode = migration_schema || '_incumbent_collision_' || id || '_' || barcode WHERE id = x_id;
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ incumbent_collision_count := incumbent_collision_count + row_count;
+ END LOOP;
+ END LOOP;
+ RAISE INFO '% incumbent collisions', incumbent_collision_count;
+END
+$function$ LANGUAGE plpgsql;
+
+-- convenience function for handling patron barcode/usrname collisions in m_actor_usr_legacy
+-- this should be ran prior to populating m_actor_card
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_actor_barcode_collisions(migration_schema TEXT) RETURNS VOID AS $function$
+DECLARE
+ x_barcode TEXT;
+ x_id BIGINT;
+ row_count NUMERIC;
+ internal_collision_count NUMERIC := 0;
+ incumbent_barcode_collision_count NUMERIC := 0;
+ incumbent_usrname_collision_count NUMERIC := 0;
+BEGIN
+ FOR x_barcode IN SELECT usrname FROM m_actor_usr_legacy WHERE x_migrate GROUP BY 1 HAVING COUNT(*) > 1
+ LOOP
+ FOR x_id IN SELECT id FROM m_actor_usr_legacy WHERE x_migrate AND usrname = x_barcode
+ LOOP
+ UPDATE m_actor_usr_legacy SET usrname = migration_schema || '_internal_collision_' || id || '_' || usrname WHERE id = x_id;
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ internal_collision_count := internal_collision_count + row_count;
+ END LOOP;
+ END LOOP;
+ RAISE INFO '% internal usrname/barcode collisions', internal_collision_count;
+
+ FOR x_barcode IN
+ SELECT a.barcode FROM actor.card a, m_actor_usr_legacy b WHERE x_migrate AND a.barcode = b.usrname
+ LOOP
+ FOR x_id IN SELECT DISTINCT id FROM m_actor_usr_legacy WHERE x_migrate AND usrname = x_barcode
+ LOOP
+ UPDATE m_actor_usr_legacy SET usrname = migration_schema || '_incumbent_barcode_collision_' || id || '_' || usrname WHERE id = x_id;
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ incumbent_barcode_collision_count := incumbent_barcode_collision_count + row_count;
+ END LOOP;
+ END LOOP;
+ RAISE INFO '% incumbent barcode collisions', incumbent_barcode_collision_count;
+
+ FOR x_barcode IN
+ SELECT a.usrname FROM actor.usr a, m_actor_usr_legacy b WHERE x_migrate AND a.usrname = b.usrname
+ LOOP
+ FOR x_id IN SELECT DISTINCT id FROM m_actor_usr_legacy WHERE x_migrate AND usrname = x_barcode
+ LOOP
+ UPDATE m_actor_usr_legacy SET usrname = migration_schema || '_incumbent_usrname_collision_' || id || '_' || usrname WHERE id = x_id;
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ incumbent_usrname_collision_count := incumbent_usrname_collision_count + row_count;
+ END LOOP;
+ END LOOP;
+ RAISE INFO '% incumbent usrname collisions (post barcode collision munging)', incumbent_usrname_collision_count;
+END
+$function$ LANGUAGE plpgsql;
+
+-- alternate version: convenience function for handling item barcode collisions in m_asset_copy_legacy
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_asset_barcode_collisions2(migration_schema TEXT) RETURNS VOID AS $function$
+DECLARE
+ x_barcode TEXT;
+ x_id BIGINT;
+ row_count NUMERIC;
+ internal_collision_count NUMERIC := 0;
+ incumbent_collision_count NUMERIC := 0;
+BEGIN
+ FOR x_barcode IN SELECT barcode FROM m_asset_copy_legacy WHERE x_migrate GROUP BY 1 HAVING COUNT(*) > 1
+ LOOP
+ FOR x_id IN SELECT id FROM m_asset_copy WHERE barcode = x_barcode
+ LOOP
+ UPDATE m_asset_copy SET barcode = migration_schema || '_internal_collision_' || id || '_' || barcode WHERE id = x_id;
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ internal_collision_count := internal_collision_count + row_count;
+ END LOOP;
+ END LOOP;
+ RAISE INFO '% internal collisions', internal_collision_count;
+ FOR x_barcode IN SELECT a.barcode FROM asset.copy a, m_asset_copy_legacy b WHERE x_migrate AND a.deleted IS FALSE AND a.barcode = b.barcode
+ LOOP
+ FOR x_id IN SELECT id FROM m_asset_copy_legacy WHERE barcode = x_barcode
+ LOOP
+ UPDATE m_asset_copy_legacy SET barcode = migration_schema || '_' || barcode WHERE id = x_id;
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ incumbent_collision_count := incumbent_collision_count + row_count;
+ END LOOP;
+ END LOOP;
+ RAISE INFO '% incumbent collisions', incumbent_collision_count;
+END
+$function$ LANGUAGE plpgsql;
+
+-- alternate version: convenience function for handling patron barcode/usrname collisions in m_actor_usr_legacy
+-- this should be ran prior to populating m_actor_card
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_actor_barcode_collisions2(migration_schema TEXT) RETURNS VOID AS $function$
+DECLARE
+ x_barcode TEXT;
+ x_id BIGINT;
+ row_count NUMERIC;
+ internal_collision_count NUMERIC := 0;
+ incumbent_barcode_collision_count NUMERIC := 0;
+ incumbent_usrname_collision_count NUMERIC := 0;
+BEGIN
+ FOR x_barcode IN SELECT usrname FROM m_actor_usr_legacy WHERE x_migrate GROUP BY 1 HAVING COUNT(*) > 1
+ LOOP
+ FOR x_id IN SELECT id FROM m_actor_usr_legacy WHERE x_migrate AND usrname = x_barcode
+ LOOP
+ UPDATE m_actor_usr_legacy SET usrname = migration_schema || '_internal_collision_' || id || '_' || usrname WHERE id = x_id;
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ internal_collision_count := internal_collision_count + row_count;
+ END LOOP;
+ END LOOP;
+ RAISE INFO '% internal usrname/barcode collisions', internal_collision_count;
+
+ FOR x_barcode IN
+ SELECT a.barcode FROM actor.card a, m_actor_usr_legacy b WHERE x_migrate AND a.barcode = b.usrname
+ LOOP
+ FOR x_id IN SELECT DISTINCT id FROM m_actor_usr_legacy WHERE x_migrate AND usrname = x_barcode
+ LOOP
+ UPDATE m_actor_usr_legacy SET usrname = migration_schema || '_' || usrname WHERE id = x_id;
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ incumbent_barcode_collision_count := incumbent_barcode_collision_count + row_count;
+ END LOOP;
+ END LOOP;
+ RAISE INFO '% incumbent barcode collisions', incumbent_barcode_collision_count;
+
+ FOR x_barcode IN
+ SELECT a.usrname FROM actor.usr a, m_actor_usr_legacy b WHERE x_migrate AND a.usrname = b.usrname
+ LOOP
+ FOR x_id IN SELECT DISTINCT id FROM m_actor_usr_legacy WHERE x_migrate AND usrname = x_barcode
+ LOOP
+ UPDATE m_actor_usr_legacy SET usrname = migration_schema || '_' || usrname WHERE id = x_id;
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ incumbent_usrname_collision_count := incumbent_usrname_collision_count + row_count;
+ END LOOP;
+ END LOOP;
+ RAISE INFO '% incumbent usrname collisions (post barcode collision munging)', incumbent_usrname_collision_count;
+END
+$function$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION migration_tools.is_circ_rule_safe_to_delete( test_matchpoint INTEGER ) RETURNS BOOLEAN AS $func$
+-- WARNING: Use at your own risk
+-- FIXME: not considering marc_type, marc_form, marc_bib_level, marc_vr_format, usr_age_lower_bound, usr_age_upper_bound, item_age
+DECLARE
+ item_object asset.copy%ROWTYPE;
+ user_object actor.usr%ROWTYPE;
+ test_rule_object config.circ_matrix_matchpoint%ROWTYPE;
+ result_rule_object config.circ_matrix_matchpoint%ROWTYPE;
+ safe_to_delete BOOLEAN := FALSE;
+ m action.found_circ_matrix_matchpoint;
+ n action.found_circ_matrix_matchpoint;
+ -- ( success BOOL, matchpoint config.circ_matrix_matchpoint, buildrows INT[] )
+ result_matchpoint INTEGER;
+BEGIN
+ SELECT INTO test_rule_object * FROM config.circ_matrix_matchpoint WHERE id = test_matchpoint;
+ RAISE INFO 'testing rule: %', test_rule_object;
+
+ INSERT INTO actor.usr (
+ profile,
+ usrname,
+ passwd,
+ ident_type,
+ first_given_name,
+ family_name,
+ home_ou,
+ juvenile
+ ) SELECT
+ COALESCE(test_rule_object.grp, 2),
+ 'is_circ_rule_safe_to_delete_' || test_matchpoint || '_' || NOW()::text,
+ MD5(NOW()::TEXT),
+ 1,
+ 'Ima',
+ 'Test',
+ COALESCE(test_rule_object.user_home_ou, test_rule_object.org_unit),
+ COALESCE(test_rule_object.juvenile_flag, FALSE)
+ ;
+
+ SELECT INTO user_object * FROM actor.usr WHERE id = currval('actor.usr_id_seq');
+
+ INSERT INTO asset.call_number (
+ creator,
+ editor,
+ record,
+ owning_lib,
+ label,
+ label_class
+ ) SELECT
+ 1,
+ 1,
+ -1,
+ COALESCE(test_rule_object.copy_owning_lib,test_rule_object.org_unit),
+ 'is_circ_rule_safe_to_delete_' || test_matchpoint || '_' || NOW()::text,
+ 1
+ ;
+
+ INSERT INTO asset.copy (
+ barcode,
+ circ_lib,
+ creator,
+ call_number,
+ editor,
+ location,
+ loan_duration,
+ fine_level,
+ ref,
+ circ_modifier
+ ) SELECT
+ 'is_circ_rule_safe_to_delete_' || test_matchpoint || '_' || NOW()::text,
+ COALESCE(test_rule_object.copy_circ_lib,test_rule_object.org_unit),
+ 1,
+ currval('asset.call_number_id_seq'),
+ 1,
+ COALESCE(test_rule_object.copy_location,1),
+ 2,
+ 2,
+ COALESCE(test_rule_object.ref_flag,FALSE),
+ test_rule_object.circ_modifier
+ ;
+
+ SELECT INTO item_object * FROM asset.copy WHERE id = currval('asset.copy_id_seq');
+
+ SELECT INTO m * FROM action.find_circ_matrix_matchpoint(
+ test_rule_object.org_unit,
+ item_object,
+ user_object,
+ COALESCE(test_rule_object.is_renewal,FALSE)
+ );
+ RAISE INFO ' action.find_circ_matrix_matchpoint(%,%,%,%) = (%,%,%)',
+ test_rule_object.org_unit,
+ item_object.id,
+ user_object.id,
+ COALESCE(test_rule_object.is_renewal,FALSE),
+ m.success,
+ m.matchpoint,
+ m.buildrows
+ ;
+
+ -- disable the rule being tested to see if the outcome changes
+ UPDATE config.circ_matrix_matchpoint SET active = FALSE WHERE id = (m.matchpoint).id;
+
+ SELECT INTO n * FROM action.find_circ_matrix_matchpoint(
+ test_rule_object.org_unit,
+ item_object,
+ user_object,
+ COALESCE(test_rule_object.is_renewal,FALSE)
+ );
+ RAISE INFO 'VS action.find_circ_matrix_matchpoint(%,%,%,%) = (%,%,%)',
+ test_rule_object.org_unit,
+ item_object.id,
+ user_object.id,
+ COALESCE(test_rule_object.is_renewal,FALSE),
+ n.success,
+ n.matchpoint,
+ n.buildrows
+ ;
+
+ -- FIXME: We could dig deeper and see if the referenced config.rule_*
+ -- entries are effectively equivalent, but for now, let's assume no
+ -- duplicate rules at that level
+ IF (
+ (m.matchpoint).circulate = (n.matchpoint).circulate
+ AND (m.matchpoint).duration_rule = (n.matchpoint).duration_rule
+ AND (m.matchpoint).recurring_fine_rule = (n.matchpoint).recurring_fine_rule
+ AND (m.matchpoint).max_fine_rule = (n.matchpoint).max_fine_rule
+ AND (
+ (m.matchpoint).hard_due_date = (n.matchpoint).hard_due_date
+ OR (
+ (m.matchpoint).hard_due_date IS NULL
+ AND (n.matchpoint).hard_due_date IS NULL
+ )
+ )
+ AND (
+ (m.matchpoint).renewals = (n.matchpoint).renewals
+ OR (
+ (m.matchpoint).renewals IS NULL
+ AND (n.matchpoint).renewals IS NULL
+ )
+ )
+ AND (
+ (m.matchpoint).grace_period = (n.matchpoint).grace_period
+ OR (
+ (m.matchpoint).grace_period IS NULL
+ AND (n.matchpoint).grace_period IS NULL
+ )
+ )
+ AND (
+ (m.matchpoint).total_copy_hold_ratio = (n.matchpoint).total_copy_hold_ratio
+ OR (
+ (m.matchpoint).total_copy_hold_ratio IS NULL
+ AND (n.matchpoint).total_copy_hold_ratio IS NULL
+ )
+ )
+ AND (
+ (m.matchpoint).available_copy_hold_ratio = (n.matchpoint).available_copy_hold_ratio
+ OR (
+ (m.matchpoint).available_copy_hold_ratio IS NULL
+ AND (n.matchpoint).available_copy_hold_ratio IS NULL
+ )
+ )
+ AND NOT EXISTS (
+ SELECT limit_set, fallthrough
+ FROM config.circ_matrix_limit_set_map
+ WHERE active and matchpoint = (m.matchpoint).id
+ EXCEPT
+ SELECT limit_set, fallthrough
+ FROM config.circ_matrix_limit_set_map
+ WHERE active and matchpoint = (n.matchpoint).id
+ )
+
+ ) THEN
+ RAISE INFO 'rule has same outcome';
+ safe_to_delete := TRUE;
+ ELSE
+ RAISE INFO 'rule has different outcome';
+ safe_to_delete := FALSE;
+ END IF;
+
+ RAISE EXCEPTION 'rollback the temporary changes';
+
+EXCEPTION WHEN OTHERS THEN
+
+ RAISE INFO 'inside exception block: %, %', SQLSTATE, SQLERRM;
+ RETURN safe_to_delete;
+
+END;
+$func$ LANGUAGE plpgsql;
+
END;
$$ LANGUAGE PLPGSQL STRICT STABLE;
+DROP FUNCTION IF EXISTS migration_tools.btrim_lcolumns(TEXT,TEXT);
+CREATE OR REPLACE FUNCTION migration_tools.btrim_lcolumns(s_name TEXT, t_name TEXT) RETURNS BOOLEAN
+ LANGUAGE plpgsql
+AS $function$
+DECLARE
+ c_name TEXT;
+BEGIN
+
+ FOR c_name IN SELECT column_name FROM information_schema.columns WHERE
+ table_name = t_name
+ AND table_schema = s_name
+ AND (data_type='text' OR data_type='character varying')
+ AND column_name like 'l_%'
+ LOOP
+ EXECUTE FORMAT('UPDATE ' || s_name || '.' || t_name || ' SET ' || c_name || ' = BTRIM(' || c_name || ')');
+ END LOOP;
+
+ RETURN TRUE;
+END
+$function$;
+
+DROP FUNCTION IF EXISTS migration_tools.btrim_columns(TEXT,TEXT);
+CREATE OR REPLACE FUNCTION migration_tools.btrim_columns(s_name TEXT, t_name TEXT) RETURNS BOOLEAN
+ LANGUAGE plpgsql
+AS $function$
+DECLARE
+ c_name TEXT;
+BEGIN
+
+ FOR c_name IN SELECT column_name FROM information_schema.columns WHERE
+ table_name = t_name
+ AND table_schema = s_name
+ AND (data_type='text' OR data_type='character varying')
+ LOOP
+ EXECUTE FORMAT('UPDATE ' || s_name || '.' || t_name || ' SET ' || c_name || ' = BTRIM(' || c_name || ')');
+ END LOOP;
+
+ RETURN TRUE;
+END
+$function$;
+
+DROP FUNCTION IF EXISTS migration_tools.null_empty_lcolumns(TEXT,TEXT);
+CREATE OR REPLACE FUNCTION migration_tools.null_empty_lcolumns(s_name TEXT, t_name TEXT) RETURNS BOOLEAN
+ LANGUAGE plpgsql
+AS $function$
+DECLARE
+ c_name TEXT;
+BEGIN
+
+ FOR c_name IN SELECT column_name FROM information_schema.columns WHERE
+ table_name = t_name
+ AND table_schema = s_name
+ AND (data_type='text' OR data_type='character varying')
+ AND column_name like 'l_%'
+ LOOP
+ EXECUTE FORMAT('UPDATE ' || s_name || '.' || t_name || ' SET ' || c_name || ' = NULL WHERE ' || c_name || ' = '''' ');
+ END LOOP;
+
+ RETURN TRUE;
+END
+$function$;
+
+DROP FUNCTION IF EXISTS migration_tools.null_empty_columns(TEXT,TEXT);
+CREATE OR REPLACE FUNCTION migration_tools.null_empty_columns(s_name TEXT, t_name TEXT) RETURNS BOOLEAN
+ LANGUAGE plpgsql
+AS $function$
+DECLARE
+ c_name TEXT;
+BEGIN
+
+ FOR c_name IN SELECT column_name FROM information_schema.columns WHERE
+ table_name = t_name
+ AND table_schema = s_name
+ AND (data_type='text' OR data_type='character varying')
+ LOOP
+ EXECUTE FORMAT('UPDATE ' || s_name || '.' || t_name || ' SET ' || c_name || ' = NULL WHERE ' || c_name || ' = '''' ');
+ END LOOP;
+
+ RETURN TRUE;
+END
+$function$;
END;
$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION migration_tools.log (TEXT,TEXT,INTEGER) RETURNS VOID AS $$
+ DECLARE
+ migration_schema ALIAS FOR $1;
+ sql ALIAS FOR $2;
+ nrows ALIAS FOR $3;
+ BEGIN
+ EXECUTE 'INSERT INTO ' || migration_schema || '.sql_log ( sql, row_count ) VALUES ( ' || quote_literal(sql) || ', ' || nrows || ' );';
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+CREATE OR REPLACE FUNCTION migration_tools.exec (TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ migration_schema ALIAS FOR $1;
+ sql ALIAS FOR $2;
+ nrows INTEGER;
+ BEGIN
+ EXECUTE 'UPDATE ' || migration_schema || '.sql_current SET sql = ' || quote_literal(sql) || ';';
+ --RAISE INFO '%', sql;
+ EXECUTE sql;
+ GET DIAGNOSTICS nrows = ROW_COUNT;
+ PERFORM migration_tools.log(migration_schema,sql,nrows);
+ EXCEPTION
+ WHEN OTHERS THEN
+ RAISE EXCEPTION '!!!!!!!!!!! state = %, msg = %, sql = %', SQLSTATE, SQLERRM, sql;
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+CREATE OR REPLACE FUNCTION migration_tools.debug_exec (TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ migration_schema ALIAS FOR $1;
+ sql ALIAS FOR $2;
+ nrows INTEGER;
+ BEGIN
+ EXECUTE 'UPDATE ' || migration_schema || '.sql_current SET sql = ' || quote_literal(sql) || ';';
+ RAISE INFO 'debug_exec sql = %', sql;
+ EXECUTE sql;
+ GET DIAGNOSTICS nrows = ROW_COUNT;
+ PERFORM migration_tools.log(migration_schema,sql,nrows);
+ EXCEPTION
+ WHEN OTHERS THEN
+ RAISE EXCEPTION '!!!!!!!!!!! state = %, msg = %, sql = %', SQLSTATE, SQLERRM, sql;
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+CREATE OR REPLACE FUNCTION migration_tools.insert_base_into_production (TEXT) RETURNS VOID AS $$
+ DECLARE
+ migration_schema ALIAS FOR $1;
+ production_tables TEXT[];
+ BEGIN
+ --RAISE INFO 'In migration_tools.insert_into_production(%)', migration_schema;
+ SELECT migration_tools.production_tables(migration_schema) INTO STRICT production_tables;
+ FOR i IN array_lower(production_tables,1) .. array_upper(production_tables,1) LOOP
+ PERFORM migration_tools.insert_into_production(migration_schema,production_tables[i]);
+ END LOOP;
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+CREATE OR REPLACE FUNCTION migration_tools.insert_into_production (TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ migration_schema ALIAS FOR $1;
+ production_table ALIAS FOR $2;
+ base_staging_table TEXT;
+ columns RECORD;
+ BEGIN
+ base_staging_table = REPLACE( production_table, '.', '_' );
+ --RAISE INFO 'In migration_tools.insert_into_production(%,%) -> %', migration_schema, production_table, base_staging_table;
+ EXECUTE 'INSERT INTO ' || production_table || ' SELECT * FROM ' || migration_schema || '.' || base_staging_table || ';';
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+-- push bib sequence and return starting value for reserved range
+CREATE OR REPLACE FUNCTION migration_tools.push_bib_sequence(INTEGER) RETURNS BIGINT AS $$
+ DECLARE
+ bib_count ALIAS FOR $1;
+ output BIGINT;
+ BEGIN
+ PERFORM setval('biblio.record_entry_id_seq',(SELECT MAX(id) FROM biblio.record_entry) + bib_count + 2000);
+ FOR output IN
+ SELECT CEIL(MAX(id)/1000)*1000+1000 FROM biblio.record_entry WHERE id < (SELECT last_value FROM biblio.record_entry_id_seq)
+ LOOP
+ RETURN output;
+ END LOOP;
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+-- convenience function for linking two tables
+-- e.g. select migration_tools.handle_link(:'migschema','asset_copy','barcode','test_foo','l_barcode','x_acp_id',false);
+CREATE OR REPLACE FUNCTION migration_tools.handle_link (TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,BOOLEAN) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_a ALIAS FOR $2;
+ column_a ALIAS FOR $3;
+ table_b ALIAS FOR $4;
+ column_b ALIAS FOR $5;
+ column_x ALIAS FOR $6;
+ btrim_desired ALIAS FOR $7;
+ proceed BOOLEAN;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_a, column_a;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_a, column_a;
+ END IF;
+
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_b, column_b;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_b, column_b;
+ END IF;
+
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_b)
+ || ' DROP COLUMN IF EXISTS ' || quote_ident(column_x);
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_b)
+ || ' ADD COLUMN ' || quote_ident(column_x) || ' BIGINT';
+
+ IF btrim_desired THEN
+ EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
+ || ' SET ' || quote_ident(column_x) || ' = a.id FROM ' || quote_ident(table_a) || ' a'
+ || ' WHERE BTRIM(a.' || quote_ident(column_a)
+ || ') = BTRIM(b.' || quote_ident(column_b) || ')';
+ ELSE
+ EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
+ || ' SET ' || quote_ident(column_x) || ' = a.id FROM ' || quote_ident(table_a) || ' a'
+ || ' WHERE a.' || quote_ident(column_a)
+ || ' = b.' || quote_ident(column_b);
+ END IF;
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+-- convenience function for linking two tables, but copying column w into column x instead of "id"
+-- e.g. select migration_tools.handle_link2(:'migschema','asset_copy','barcode','test_foo','l_barcode','id','x_acp_id',false);
+CREATE OR REPLACE FUNCTION migration_tools.handle_link2 (TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,BOOLEAN) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_a ALIAS FOR $2;
+ column_a ALIAS FOR $3;
+ table_b ALIAS FOR $4;
+ column_b ALIAS FOR $5;
+ column_w ALIAS FOR $6;
+ column_x ALIAS FOR $7;
+ btrim_desired ALIAS FOR $8;
+ proceed BOOLEAN;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_a, column_a;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_a, column_a;
+ END IF;
+
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_b, column_b;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_b, column_b;
+ END IF;
+
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_b)
+ || ' DROP COLUMN IF EXISTS ' || quote_ident(column_x);
+ EXECUTE 'ALTER TABLE '
+ || quote_ident(table_b)
+ || ' ADD COLUMN ' || quote_ident(column_x) || ' TEXT';
+
+ IF btrim_desired THEN
+ EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
+ || ' SET ' || quote_ident(column_x) || ' = a.' || quote_ident(column_w) || ' FROM ' || quote_ident(table_a) || ' a'
+ || ' WHERE BTRIM(a.' || quote_ident(column_a)
+ || ') = BTRIM(b.' || quote_ident(column_b) || ')';
+ ELSE
+ EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
+ || ' SET ' || quote_ident(column_x) || ' = a.' || quote_ident(column_w) || ' FROM ' || quote_ident(table_a) || ' a'
+ || ' WHERE a.' || quote_ident(column_a)
+ || ' = b.' || quote_ident(column_b);
+ END IF;
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+-- convenience function for linking two tables, but copying column w into column x instead of "id". Unlike handle_link2, this one won't drop the target column, and it also doesn't have a final boolean argument for btrim
+-- e.g. select migration_tools.handle_link3(:'migschema','asset_copy','barcode','test_foo','l_barcode','id','x_acp_id');
+CREATE OR REPLACE FUNCTION migration_tools.handle_link3 (TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_a ALIAS FOR $2;
+ column_a ALIAS FOR $3;
+ table_b ALIAS FOR $4;
+ column_b ALIAS FOR $5;
+ column_w ALIAS FOR $6;
+ column_x ALIAS FOR $7;
+ proceed BOOLEAN;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_a, column_a;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_a, column_a;
+ END IF;
+
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_b, column_b;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_b, column_b;
+ END IF;
+
+ EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
+ || ' SET ' || quote_ident(column_x) || ' = a.' || quote_ident(column_w) || ' FROM ' || quote_ident(table_a) || ' a'
+ || ' WHERE a.' || quote_ident(column_a)
+ || ' = b.' || quote_ident(column_b);
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_link3_skip_null_or_empty_string (TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_a ALIAS FOR $2;
+ column_a ALIAS FOR $3;
+ table_b ALIAS FOR $4;
+ column_b ALIAS FOR $5;
+ column_w ALIAS FOR $6;
+ column_x ALIAS FOR $7;
+ proceed BOOLEAN;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_a, column_a;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_a, column_a;
+ END IF;
+
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_b, column_b;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_b, column_b;
+ END IF;
+
+ EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
+ || ' SET ' || quote_ident(column_x) || ' = a.' || quote_ident(column_w) || ' FROM ' || quote_ident(table_a) || ' a'
+ || ' WHERE a.' || quote_ident(column_a)
+ || ' = b.' || quote_ident(column_b)
+ || ' AND NULLIF(a.' || quote_ident(column_w) || ','''') IS NOT NULL';
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_link3_skip_null (TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_a ALIAS FOR $2;
+ column_a ALIAS FOR $3;
+ table_b ALIAS FOR $4;
+ column_b ALIAS FOR $5;
+ column_w ALIAS FOR $6;
+ column_x ALIAS FOR $7;
+ proceed BOOLEAN;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_a, column_a;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_a, column_a;
+ END IF;
+
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_b, column_b;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_b, column_b;
+ END IF;
+
+ EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
+ || ' SET ' || quote_ident(column_x) || ' = a.' || quote_ident(column_w) || ' FROM ' || quote_ident(table_a) || ' a'
+ || ' WHERE a.' || quote_ident(column_a)
+ || ' = b.' || quote_ident(column_b)
+ || ' AND a.' || quote_ident(column_w) || ' IS NOT NULL';
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_link3_skip_true (TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_a ALIAS FOR $2;
+ column_a ALIAS FOR $3;
+ table_b ALIAS FOR $4;
+ column_b ALIAS FOR $5;
+ column_w ALIAS FOR $6;
+ column_x ALIAS FOR $7;
+ proceed BOOLEAN;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_a, column_a;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_a, column_a;
+ END IF;
+
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_b, column_b;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_b, column_b;
+ END IF;
+
+ EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
+ || ' SET ' || quote_ident(column_x) || ' = a.' || quote_ident(column_w) || ' FROM ' || quote_ident(table_a) || ' a'
+ || ' WHERE a.' || quote_ident(column_a)
+ || ' = b.' || quote_ident(column_b)
+ || ' AND a.' || quote_ident(column_w) || ' IS NOT TRUE';
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_link3_skip_false (TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_a ALIAS FOR $2;
+ column_a ALIAS FOR $3;
+ table_b ALIAS FOR $4;
+ column_b ALIAS FOR $5;
+ column_w ALIAS FOR $6;
+ column_x ALIAS FOR $7;
+ proceed BOOLEAN;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_a, column_a;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_a, column_a;
+ END IF;
+
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_b, column_b;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_b, column_b;
+ END IF;
+
+ EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
+ || ' SET ' || quote_ident(column_x) || ' = a.' || quote_ident(column_w) || ' FROM ' || quote_ident(table_a) || ' a'
+ || ' WHERE a.' || quote_ident(column_a)
+ || ' = b.' || quote_ident(column_b)
+ || ' AND a.' || quote_ident(column_w) || ' IS NOT FALSE';
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
+
+CREATE OR REPLACE FUNCTION migration_tools.handle_link3_concat_skip_null (TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
+ DECLARE
+ table_schema ALIAS FOR $1;
+ table_a ALIAS FOR $2;
+ column_a ALIAS FOR $3;
+ table_b ALIAS FOR $4;
+ column_b ALIAS FOR $5;
+ column_w ALIAS FOR $6;
+ column_x ALIAS FOR $7;
+ proceed BOOLEAN;
+ BEGIN
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_a, column_a;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_a, column_a;
+ END IF;
+
+ EXECUTE 'SELECT EXISTS (
+ SELECT 1
+ FROM information_schema.columns
+ WHERE table_schema = $1
+ AND table_name = $2
+ and column_name = $3
+ )' INTO proceed USING table_schema, table_b, column_b;
+ IF NOT proceed THEN
+ RAISE EXCEPTION '%.% missing column %', table_schema, table_b, column_b;
+ END IF;
+
+ EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
+ || ' SET ' || quote_ident(column_x) || ' = CONCAT_WS('' ; '',b.' || quote_ident(column_x) || ',a.' || quote_ident(column_w) || ') FROM ' || quote_ident(table_a) || ' a'
+ || ' WHERE a.' || quote_ident(column_a)
+ || ' = b.' || quote_ident(column_b)
+ || ' AND NULLIF(a.' || quote_ident(column_w) || ','''') IS NOT NULL';
+
+ END;
+$$ LANGUAGE PLPGSQL STRICT VOLATILE;
#!/bin/bash
-grep -i 'CREATE OR REPLACE FUNCTION' *.sql | perl -ne 'if (/^(.+?):.*(migration_tools.+?)[ \(].*$/) { print "# $1:$2\n"; }' | sort
+grep -i 'CREATE OR REPLACE FUNCTION' *.sql | perl -ne 'if (/^(.+?):.*(migration_tools.+?)[ \(].*$/) { print "# $1:$2\n"; }' | sort | uniq
+# 00-infrastructure.sql:migration_tools.assert
# 00-infrastructure.sql:migration_tools.build
# 00-infrastructure.sql:migration_tools.build_base_staging_tables
# 00-infrastructure.sql:migration_tools.build_specific_base_staging_table
# 01-marc.sql:migration_tools.get_marc_tags
# 01-marc.sql:migration_tools.get_marc_tags_filtered
# 01-marc.sql:migration_tools.insert_tags
-# 01-marc.sql:migration_tools.insert_tags
-# 01-marc.sql:migration_tools.make_stub_bib
# 01-marc.sql:migration_tools.make_stub_bib
# 01-marc.sql:migration_tools.marc_parses
# 01-marc.sql:migration_tools.merge_marc_fields
# 01-marc.sql:migration_tools.owner_change_sf9_substring_match
# 01-marc.sql:migration_tools.owner_change_sf9_substring_match2
# 01-marc.sql:migration_tools.set_008
-# 01-marc.sql:migration_tools.set_008
# 01-marc.sql:migration_tools.set_indicator
# 01-marc.sql:migration_tools.set_leader
-# 01-marc.sql:migration_tools.set_leader
-# 01-marc.sql:migration_tools.strip_tag
# 01-marc.sql:migration_tools.strip_tag
# 02-barcodes.sql:migration_tools.add_codabar_checkdigit
# 02-barcodes.sql:migration_tools.add_code39mod43_checkdigit
# 02-barcodes.sql:migration_tools.rebarcode
# 03-items.sql:migration_tools.change_call_number
# 03-items.sql:migration_tools.change_owning_lib
-# 03-items.sql:migration_tools.change_owning_lib
# 04-names.sql:migration_tools.name_parse_out_first_middle_last_comma_suffix
# 04-names.sql:migration_tools.name_parse_out_fuller_last_first_middle_and_random_affix
# 04-names.sql:migration_tools.name_parse_out_fuller_last_first_middle_and_random_affix2
# 07-eg-specific.sql:migration_tools.find_circ_matrix_matchpoint
# 07-eg-specific.sql:migration_tools.find_hold_matrix_matchpoint
# 07-eg-specific.sql:migration_tools.find_hold_matrix_matchpoint2
+# 07-eg-specific.sql:migration_tools.find_mig_shelf
+# 07-eg-specific.sql:migration_tools.find_shelf
# 07-eg-specific.sql:migration_tools.get_copy_price
+# 07-eg-specific.sql:migration_tools.handle_actor_barcode_collisions
+# 07-eg-specific.sql:migration_tools.handle_actor_barcode_collisions2
+# 07-eg-specific.sql:migration_tools.handle_actor_sc_and_sce
+# 07-eg-specific.sql:migration_tools.handle_asset_barcode_collisions
+# 07-eg-specific.sql:migration_tools.handle_asset_barcode_collisions2
+# 07-eg-specific.sql:migration_tools.handle_asset_sc_and_sce
+# 07-eg-specific.sql:migration_tools.handle_barred_or_blocked
+# 07-eg-specific.sql:migration_tools.handle_circmod
+# 07-eg-specific.sql:migration_tools.handle_item_barcode
+# 07-eg-specific.sql:migration_tools.handle_not_migrate
+# 07-eg-specific.sql:migration_tools.handle_org
+# 07-eg-specific.sql:migration_tools.handle_profile
+# 07-eg-specific.sql:migration_tools._handle_shelf
+# 07-eg-specific.sql:migration_tools.handle_shelf
+# 07-eg-specific.sql:migration_tools.handle_status
+# 07-eg-specific.sql:migration_tools.handle_user_barcode
# 07-eg-specific.sql:migration_tools.insert_metarecords_for_incumbent_database
# 07-eg-specific.sql:migration_tools.insert_metarecords_for_pristine_database
+# 07-eg-specific.sql:migration_tools.is_circ_rule_safe_to_delete
# 07-eg-specific.sql:migration_tools.is_staff_profile
# 07-eg-specific.sql:migration_tools.reset_event
+# 07-eg-specific.sql:migration_tools.set_salted_passwd
# 07-eg-specific.sql:migration_tools.simple_export_library_config
# 07-eg-specific.sql:migration_tools.simple_import_library_config
+# 07-eg-specific.sql:migration_tools.vivicate_actor_sc_and_sce
+# 07-eg-specific.sql:migration_tools.vivicate_asset_sc_and_sce
# 08-casting-and-validation.sql:migration_tools.attempt_cast
# 08-casting-and-validation.sql:migration_tools.attempt_date
# 08-casting-and-validation.sql:migration_tools.attempt_money
# 08-casting-and-validation.sql:migration_tools.attempt_money_from_pennies
# 08-casting-and-validation.sql:migration_tools.attempt_money_from_pennies6
# 08-casting-and-validation.sql:migration_tools.attempt_timestamptz
+# 09-misc.sql:migration_tools.btrim_columns
+# 09-misc.sql:migration_tools.btrim_lcolumns
# 09-misc.sql:migration_tools.is_blank
+# 09-misc.sql:migration_tools.null_empty_columns
+# 09-misc.sql:migration_tools.null_empty_lcolumns
# 10-staging.sql:migration_tools.simple_import_new_rows_by_value
# 10-staging.sql:migration_tools.split_rows_on_column_with_delimiter
# 10-staging.sql:migration_tools.stage_not_applicable_asset_stat_cats
# 21-fixed-fields.sql:migration_tools.stage_vlist
# 21-fixed-fields.sql:migration_tools.view_staged_vlist
# 22-anyarray.sql:migration_tools.anyarray_concat
-# 22-anyarray.sql:migration_tools.anyarray_concat
-# 22-anyarray.sql:migration_tools.anyarray_concat_uniq
# 22-anyarray.sql:migration_tools.anyarray_concat_uniq
# 22-anyarray.sql:migration_tools.anyarray_diff
# 22-anyarray.sql:migration_tools.anyarray_diff_uniq
# 22-anyarray.sql:migration_tools.anyarray_numeric_only
# 22-anyarray.sql:migration_tools.anyarray_ranges
# 22-anyarray.sql:migration_tools.anyarray_remove
-# 22-anyarray.sql:migration_tools.anyarray_remove
# 22-anyarray.sql:migration_tools.anyarray_remove_null
# 22-anyarray.sql:migration_tools.anyarray_sort
# 22-anyarray.sql:migration_tools.anyarray_uniq
# 99-deprecated.sql:migration_tools.base_circ_field_map
# 99-deprecated.sql:migration_tools.base_copy_location_map
# 99-deprecated.sql:migration_tools.base_item_dynamic_field_map
+# 99-deprecated.sql:migration_tools.debug_exec
+# 99-deprecated.sql:migration_tools.exec
+# 99-deprecated.sql:migration_tools.handle_link
+# 99-deprecated.sql:migration_tools.handle_link2
+# 99-deprecated.sql:migration_tools.handle_link3
+# 99-deprecated.sql:migration_tools.handle_link3_concat_skip_null
+# 99-deprecated.sql:migration_tools.handle_link3_skip_false
+# 99-deprecated.sql:migration_tools.handle_link3_skip_null
+# 99-deprecated.sql:migration_tools.handle_link3_skip_null_or_empty_string
+# 99-deprecated.sql:migration_tools.handle_link3_skip_true
# 99-deprecated.sql:migration_tools.insert_856_9
# 99-deprecated.sql:migration_tools.insert_856_9_conditional
+# 99-deprecated.sql:migration_tools.insert_base_into_production
+# 99-deprecated.sql:migration_tools.insert_into_production
# 99-deprecated.sql:migration_tools.is_staff_profile
+# 99-deprecated.sql:migration_tools.log
# 99-deprecated.sql:migration_tools.map_base_circ_table_dynamic
# 99-deprecated.sql:migration_tools.map_base_item_table_dynamic
# 99-deprecated.sql:migration_tools.map_base_item_table_locations
# 99-deprecated.sql:migration_tools.map_base_patron_profile
+# 99-deprecated.sql:migration_tools.push_bib_sequence
# 99-deprecated.sql:migration_tools.refresh_opac_visible_copies
-# base.sql:migration_tools.assert
-# base.sql:migration_tools.assert
-# base.sql:migration_tools.assert
-# base.sql:migration_tools.btrim_columns
-# base.sql:migration_tools.btrim_lcolumns
-# base.sql:migration_tools.build
-# base.sql:migration_tools.build_base_staging_tables
-# base.sql:migration_tools.build_specific_base_staging_table
-# base.sql:migration_tools.country_code
-# base.sql:migration_tools.create_linked_legacy_table_from
-# base.sql:migration_tools.debug_exec
-# base.sql:migration_tools.exec
-# base.sql:migration_tools.find_mig_shelf
-# base.sql:migration_tools.find_shelf
-# base.sql:migration_tools.handle_actor_barcode_collisions
-# base.sql:migration_tools.handle_actor_barcode_collisions2
-# base.sql:migration_tools.handle_actor_sc_and_sce
-# base.sql:migration_tools.handle_asset_barcode_collisions
-# base.sql:migration_tools.handle_asset_barcode_collisions2
-# base.sql:migration_tools.handle_asset_sc_and_sce
-# base.sql:migration_tools.handle_barred_or_blocked
-# base.sql:migration_tools.handle_circmod
-# base.sql:migration_tools.handle_item_barcode
-# base.sql:migration_tools.handle_link
-# base.sql:migration_tools.handle_link2
-# base.sql:migration_tools.handle_link3
-# base.sql:migration_tools.handle_link3_concat_skip_null
-# base.sql:migration_tools.handle_link3_skip_false
-# base.sql:migration_tools.handle_link3_skip_null
-# base.sql:migration_tools.handle_link3_skip_null_or_empty_string
-# base.sql:migration_tools.handle_link3_skip_true
-# base.sql:migration_tools.handle_not_migrate
-# base.sql:migration_tools.handle_org
-# base.sql:migration_tools.handle_profile
-# base.sql:migration_tools._handle_shelf
-# base.sql:migration_tools.handle_shelf
-# base.sql:migration_tools.handle_status
-# base.sql:migration_tools.handle_user_barcode
-# base.sql:migration_tools.init
-# base.sql:migration_tools.insert_base_into_production
-# base.sql:migration_tools.insert_into_production
-# base.sql:migration_tools.is_circ_rule_safe_to_delete
-# base.sql:migration_tools.log
-# base.sql:migration_tools.null_empty_columns
-# base.sql:migration_tools.null_empty_lcolumns
-# base.sql:migration_tools.production_tables
-# base.sql:migration_tools.push_bib_sequence
-# base.sql:migration_tools.set_salted_passwd
-# base.sql:migration_tools.vivicate_actor_sc_and_sce
-# base.sql:migration_tools.vivicate_asset_sc_and_sce
--- Copyright 2009-2012, Equinox Software, Inc.
---
--- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
---------------------------------------------------------------------------
--- An example of how to use:
---
--- DROP SCHEMA foo CASCADE; CREATE SCHEMA foo;
--- \i base.sql
--- SELECT migration_tools.init('foo');
--- SELECT migration_tools.build('foo');
--- SELECT * FROM foo.fields_requiring_mapping;
--- \d foo.actor_usr
--- create some incoming ILS specific staging tables, like CREATE foo.legacy_items ( l_barcode TEXT, .. ) INHERITS (foo.asset_copy);
--- Do some mapping, like UPDATE foo.legacy_items SET barcode = TRIM(BOTH ' ' FROM l_barcode);
--- Then, to move into production, do: select migration_tools.insert_base_into_production('foo')
-
-CREATE SCHEMA migration_tools;
-
-CREATE OR REPLACE FUNCTION migration_tools.production_tables (TEXT) RETURNS TEXT[] AS $$
- DECLARE
- migration_schema ALIAS FOR $1;
- output RECORD;
- BEGIN
- FOR output IN
- EXECUTE 'SELECT string_to_array(value,'','') AS tables FROM ' || migration_schema || '.config WHERE key = ''production_tables'';'
- LOOP
- RETURN output.tables;
- END LOOP;
- END;
-$$ LANGUAGE PLPGSQL STRICT STABLE;
-
-CREATE OR REPLACE FUNCTION migration_tools.country_code (TEXT) RETURNS TEXT AS $$
- DECLARE
- migration_schema ALIAS FOR $1;
- output TEXT;
- BEGIN
- FOR output IN
- EXECUTE 'SELECT value FROM ' || migration_schema || '.config WHERE key = ''country_code'';'
- LOOP
- RETURN output;
- END LOOP;
- END;
-$$ LANGUAGE PLPGSQL STRICT STABLE;
-
-
-CREATE OR REPLACE FUNCTION migration_tools.log (TEXT,TEXT,INTEGER) RETURNS VOID AS $$
- DECLARE
- migration_schema ALIAS FOR $1;
- sql ALIAS FOR $2;
- nrows ALIAS FOR $3;
- BEGIN
- EXECUTE 'INSERT INTO ' || migration_schema || '.sql_log ( sql, row_count ) VALUES ( ' || quote_literal(sql) || ', ' || nrows || ' );';
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.exec (TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- migration_schema ALIAS FOR $1;
- sql ALIAS FOR $2;
- nrows INTEGER;
- BEGIN
- EXECUTE 'UPDATE ' || migration_schema || '.sql_current SET sql = ' || quote_literal(sql) || ';';
- --RAISE INFO '%', sql;
- EXECUTE sql;
- GET DIAGNOSTICS nrows = ROW_COUNT;
- PERFORM migration_tools.log(migration_schema,sql,nrows);
- EXCEPTION
- WHEN OTHERS THEN
- RAISE EXCEPTION '!!!!!!!!!!! state = %, msg = %, sql = %', SQLSTATE, SQLERRM, sql;
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.debug_exec (TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- migration_schema ALIAS FOR $1;
- sql ALIAS FOR $2;
- nrows INTEGER;
- BEGIN
- EXECUTE 'UPDATE ' || migration_schema || '.sql_current SET sql = ' || quote_literal(sql) || ';';
- RAISE INFO 'debug_exec sql = %', sql;
- EXECUTE sql;
- GET DIAGNOSTICS nrows = ROW_COUNT;
- PERFORM migration_tools.log(migration_schema,sql,nrows);
- EXCEPTION
- WHEN OTHERS THEN
- RAISE EXCEPTION '!!!!!!!!!!! state = %, msg = %, sql = %', SQLSTATE, SQLERRM, sql;
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.init (TEXT) RETURNS VOID AS $$
- DECLARE
- migration_schema ALIAS FOR $1;
- sql TEXT;
- BEGIN
- EXECUTE 'DROP TABLE IF EXISTS ' || migration_schema || '.sql_current;';
- EXECUTE 'CREATE TABLE ' || migration_schema || '.sql_current ( sql TEXT);';
- EXECUTE 'INSERT INTO ' || migration_schema || '.sql_current ( sql ) VALUES ( '''' );';
- BEGIN
- SELECT 'CREATE TABLE ' || migration_schema || '.sql_log ( time TIMESTAMP NOT NULL DEFAULT NOW(), row_count INTEGER, sql TEXT );' INTO STRICT sql;
- EXECUTE sql;
- EXCEPTION
- WHEN OTHERS THEN
- RAISE INFO '!!!!!!!!!!! state = %, msg = %, sql = %', SQLSTATE, SQLERRM, sql;
- END;
- PERFORM migration_tools.exec( $1, 'DROP TABLE IF EXISTS ' || migration_schema || '.config;' );
- PERFORM migration_tools.exec( $1, 'CREATE TABLE ' || migration_schema || '.config ( key TEXT UNIQUE, value TEXT);' );
- PERFORM migration_tools.exec( $1, 'INSERT INTO ' || migration_schema || '.config (key,value) VALUES ( ''production_tables'', ''asset.call_number,asset.call_number_prefix,asset.call_number_suffix,asset.copy_location,asset.copy,asset.copy_alert,asset.stat_cat,asset.stat_cat_entry,asset.stat_cat_entry_copy_map,asset.copy_note,actor.usr,actor.card,actor.usr_address,actor.stat_cat,actor.stat_cat_entry,actor.stat_cat_entry_usr_map,actor.usr_note,actor.usr_standing_penalty,actor.usr_setting,action.circulation,action.hold_request,action.hold_notification,action.hold_request_note,action.hold_transit_copy,action.transit_copy,money.grocery,money.billing,money.cash_payment,money.forgive_payment,acq.provider,acq.provider_address,acq.provider_note,acq.provider_contact,acq.provider_contact_address,acq.fund,acq.fund_allocation,acq.fund_tag,acq.fund_tag_map,acq.funding_source,acq.funding_source_credit,acq.lineitem,acq.purchase_order,acq.po_item,acq.invoice,acq.invoice_item,acq.invoice_entry,acq.lineitem_detail,acq.fund_debit,acq.fund_transfer,acq.po_note,config.circ_matrix_matchpoint,config.circ_matrix_limit_set_map,config.hold_matrix_matchpoint,asset.copy_tag,asset.copy_tag_copy_map,config.copy_tag_type,serial.item,serial.item_note,serial.record_entry,biblio.record_entry'' );' );
- PERFORM migration_tools.exec( $1, 'INSERT INTO ' || migration_schema || '.config (key,value) VALUES ( ''country_code'', ''USA'' );' );
- PERFORM migration_tools.exec( $1, 'DROP TABLE IF EXISTS ' || migration_schema || '.fields_requiring_mapping;' );
- PERFORM migration_tools.exec( $1, 'CREATE TABLE ' || migration_schema || '.fields_requiring_mapping( table_schema TEXT, table_name TEXT, column_name TEXT, data_type TEXT);' );
- PERFORM migration_tools.exec( $1, 'DROP TABLE IF EXISTS ' || migration_schema || '.base_profile_map;' );
- PERFORM migration_tools.exec( $1, 'CREATE TABLE ' || migration_schema || E'.base_profile_map (
- id SERIAL,
- perm_grp_id INTEGER,
- transcribed_perm_group TEXT,
- legacy_field1 TEXT,
- legacy_value1 TEXT,
- legacy_field2 TEXT,
- legacy_value2 TEXT,
- legacy_field3 TEXT,
- legacy_value3 TEXT
- );' );
- PERFORM migration_tools.exec( $1, 'INSERT INTO ' || migration_schema || '.config (key,value) VALUES ( ''base_profile_map'', ''base_profile_map'' );' );
- PERFORM migration_tools.exec( $1, 'DROP TABLE IF EXISTS ' || migration_schema || '.base_item_dynamic_field_map;' );
- PERFORM migration_tools.exec( $1, 'CREATE TABLE ' || migration_schema || E'.base_item_dynamic_field_map (
- id SERIAL,
- evergreen_field TEXT,
- evergreen_value TEXT,
- evergreen_datatype TEXT,
- legacy_field1 TEXT,
- legacy_value1 TEXT,
- legacy_field2 TEXT,
- legacy_value2 TEXT,
- legacy_field3 TEXT,
- legacy_value3 TEXT
- );' );
- PERFORM migration_tools.exec( $1, 'CREATE INDEX ' || migration_schema || '_item_dynamic_lf1_idx ON ' || migration_schema || '.base_item_dynamic_field_map (legacy_field1,legacy_value1);' );
- PERFORM migration_tools.exec( $1, 'CREATE INDEX ' || migration_schema || '_item_dynamic_lf2_idx ON ' || migration_schema || '.base_item_dynamic_field_map (legacy_field2,legacy_value2);' );
- PERFORM migration_tools.exec( $1, 'CREATE INDEX ' || migration_schema || '_item_dynamic_lf3_idx ON ' || migration_schema || '.base_item_dynamic_field_map (legacy_field3,legacy_value3);' );
- PERFORM migration_tools.exec( $1, 'INSERT INTO ' || migration_schema || '.config (key,value) VALUES ( ''base_item_dynamic_field_map'', ''base_item_dynamic_field_map'' );' );
- PERFORM migration_tools.exec( $1, 'DROP TABLE IF EXISTS ' || migration_schema || '.base_copy_location_map;' );
- PERFORM migration_tools.exec( $1, 'CREATE TABLE ' || migration_schema || E'.base_copy_location_map (
- id SERIAL,
- location INTEGER,
- holdable BOOLEAN NOT NULL DEFAULT TRUE,
- hold_verify BOOLEAN NOT NULL DEFAULT FALSE,
- opac_visible BOOLEAN NOT NULL DEFAULT TRUE,
- circulate BOOLEAN NOT NULL DEFAULT TRUE,
- transcribed_location TEXT,
- legacy_field1 TEXT,
- legacy_value1 TEXT,
- legacy_field2 TEXT,
- legacy_value2 TEXT,
- legacy_field3 TEXT,
- legacy_value3 TEXT
- );' );
- PERFORM migration_tools.exec( $1, 'CREATE INDEX ' || migration_schema || '_base_copy_location_lf1_idx ON ' || migration_schema || '.base_copy_location_map (legacy_field1,legacy_value1);' );
- PERFORM migration_tools.exec( $1, 'CREATE INDEX ' || migration_schema || '_base_copy_location_lf2_idx ON ' || migration_schema || '.base_copy_location_map (legacy_field2,legacy_value2);' );
- PERFORM migration_tools.exec( $1, 'CREATE INDEX ' || migration_schema || '_base_copy_location_lf3_idx ON ' || migration_schema || '.base_copy_location_map (legacy_field3,legacy_value3);' );
- PERFORM migration_tools.exec( $1, 'CREATE INDEX ' || migration_schema || '_base_copy_location_loc_idx ON ' || migration_schema || '.base_copy_location_map (transcribed_location);' );
- PERFORM migration_tools.exec( $1, 'INSERT INTO ' || migration_schema || '.config (key,value) VALUES ( ''base_copy_location_map'', ''base_copy_location_map'' );' );
- PERFORM migration_tools.exec( $1, 'DROP TABLE IF EXISTS ' || migration_schema || '.base_circ_field_map;' );
- PERFORM migration_tools.exec( $1, 'CREATE TABLE ' || migration_schema || E'.base_circ_field_map (
- id SERIAL,
- circulate BOOLEAN,
- loan_period TEXT,
- max_renewals TEXT,
- max_out TEXT,
- fine_amount TEXT,
- fine_interval TEXT,
- max_fine TEXT,
- item_field1 TEXT,
- item_value1 TEXT,
- item_field2 TEXT,
- item_value2 TEXT,
- patron_field1 TEXT,
- patron_value1 TEXT,
- patron_field2 TEXT,
- patron_value2 TEXT
- );' );
- PERFORM migration_tools.exec( $1, 'CREATE INDEX ' || migration_schema || '_circ_dynamic_lf1_idx ON ' || migration_schema || '.base_circ_field_map (item_field1,item_value1);' );
- PERFORM migration_tools.exec( $1, 'CREATE INDEX ' || migration_schema || '_circ_dynamic_lf2_idx ON ' || migration_schema || '.base_circ_field_map (item_field2,item_value2);' );
- PERFORM migration_tools.exec( $1, 'CREATE INDEX ' || migration_schema || '_circ_dynamic_lf3_idx ON ' || migration_schema || '.base_circ_field_map (patron_field1,patron_value1);' );
- PERFORM migration_tools.exec( $1, 'CREATE INDEX ' || migration_schema || '_circ_dynamic_lf4_idx ON ' || migration_schema || '.base_circ_field_map (patron_field2,patron_value2);' );
- PERFORM migration_tools.exec( $1, 'INSERT INTO ' || migration_schema || '.config (key,value) VALUES ( ''base_circ_field_map'', ''base_circ_field_map'' );' );
-
- BEGIN
- PERFORM migration_tools.exec( $1, 'INSERT INTO ' || migration_schema || '.config (key,value) VALUES ( ''last_init'', now() );' );
- EXCEPTION
- WHEN OTHERS THEN PERFORM migration_tools.exec( $1, 'UPDATE ' || migration_schema || '.config SET value = now() WHERE key = ''last_init'';' );
- END;
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.build (TEXT) RETURNS VOID AS $$
- DECLARE
- migration_schema ALIAS FOR $1;
- production_tables TEXT[];
- BEGIN
- --RAISE INFO 'In migration_tools.build(%)', migration_schema;
- SELECT migration_tools.production_tables(migration_schema) INTO STRICT production_tables;
- PERFORM migration_tools.build_base_staging_tables(migration_schema,production_tables);
- PERFORM migration_tools.exec( $1, 'CREATE UNIQUE INDEX ' || migration_schema || '_patron_barcode_key ON ' || migration_schema || '.actor_card ( barcode );' );
- PERFORM migration_tools.exec( $1, 'CREATE UNIQUE INDEX ' || migration_schema || '_patron_usrname_key ON ' || migration_schema || '.actor_usr ( usrname );' );
- PERFORM migration_tools.exec( $1, 'CREATE UNIQUE INDEX ' || migration_schema || '_copy_barcode_key ON ' || migration_schema || '.asset_copy ( barcode );' );
- PERFORM migration_tools.exec( $1, 'CREATE UNIQUE INDEX ' || migration_schema || '_copy_id_key ON ' || migration_schema || '.asset_copy ( id );' );
- PERFORM migration_tools.exec( $1, 'CREATE INDEX ' || migration_schema || '_callnum_record_idx ON ' || migration_schema || '.asset_call_number ( record );' );
- PERFORM migration_tools.exec( $1, 'CREATE INDEX ' || migration_schema || '_callnum_upper_label_id_lib_idx ON ' || migration_schema || '.asset_call_number ( UPPER(label),id,owning_lib );' );
- PERFORM migration_tools.exec( $1, 'CREATE UNIQUE INDEX ' || migration_schema || '_callnum_label_once_per_lib ON ' || migration_schema || '.asset_call_number ( record,owning_lib,label,prefix,suffix );' );
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.build_base_staging_tables (TEXT,TEXT[]) RETURNS VOID AS $$
- DECLARE
- migration_schema ALIAS FOR $1;
- production_tables ALIAS FOR $2;
- BEGIN
- --RAISE INFO 'In migration_tools.build_base_staging_tables(%,%)', migration_schema, production_tables;
- FOR i IN array_lower(production_tables,1) .. array_upper(production_tables,1) LOOP
- PERFORM migration_tools.build_specific_base_staging_table(migration_schema,production_tables[i]);
- END LOOP;
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.build_specific_base_staging_table (TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- migration_schema ALIAS FOR $1;
- production_table ALIAS FOR $2;
- base_staging_table TEXT;
- columns RECORD;
- BEGIN
- base_staging_table = REPLACE( production_table, '.', '_' );
- --RAISE INFO 'In migration_tools.build_specific_base_staging_table(%,%) -> %', migration_schema, production_table, base_staging_table;
- PERFORM migration_tools.exec( $1, 'CREATE TABLE ' || migration_schema || '.' || base_staging_table || ' ( LIKE ' || production_table || ' INCLUDING DEFAULTS EXCLUDING CONSTRAINTS );' );
- PERFORM migration_tools.exec( $1, '
- INSERT INTO ' || migration_schema || '.fields_requiring_mapping
- SELECT table_schema, table_name, column_name, data_type
- FROM information_schema.columns
- WHERE table_schema = ''' || migration_schema || ''' AND table_name = ''' || base_staging_table || ''' AND is_nullable = ''NO'' AND column_default IS NULL;
- ' );
- FOR columns IN
- SELECT table_schema, table_name, column_name, data_type
- FROM information_schema.columns
- WHERE table_schema = migration_schema AND table_name = base_staging_table AND is_nullable = 'NO' AND column_default IS NULL
- LOOP
- PERFORM migration_tools.exec( $1, 'ALTER TABLE ' || columns.table_schema || '.' || columns.table_name || ' ALTER COLUMN ' || columns.column_name || ' DROP NOT NULL;' );
- END LOOP;
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
--- creates other child table so you can have more than one child table in a schema from a base table
-CREATE OR REPLACE FUNCTION build_variant_staging_table(text, text, text)
- RETURNS void
- LANGUAGE plpgsql
- STRICT
-AS $function$
- DECLARE
- migration_schema ALIAS FOR $1;
- production_table ALIAS FOR $2;
- base_staging_table ALIAS FOR $3;
- columns RECORD;
- BEGIN
- --RAISE INFO 'In migration_tools.build_specific_base_staging_table(%,%) -> %', migration_schema, production_table, base_staging_table;
- PERFORM migration_tools.exec( $1, 'CREATE TABLE ' || migration_schema || '.' || base_staging_table || ' ( LIKE ' || production_table || ' INCLUDING DEFAULTS EXCLUDING CONSTRAINTS );' );
- PERFORM migration_tools.exec( $1, '
- INSERT INTO ' || migration_schema || '.fields_requiring_mapping
- SELECT table_schema, table_name, column_name, data_type
- FROM information_schema.columns
- WHERE table_schema = ''' || migration_schema || ''' AND table_name = ''' || base_staging_table || ''' AND is_nullable = ''NO'' AND column_default IS NULL;
- ' );
- FOR columns IN
- SELECT table_schema, table_name, column_name, data_type
- FROM information_schema.columns
- WHERE table_schema = migration_schema AND table_name = base_staging_table AND is_nullable = 'NO' AND column_default IS NULL
- LOOP
- PERFORM migration_tools.exec( $1, 'ALTER TABLE ' || columns.table_schema || '.' || columns.table_name || ' ALTER COLUMN ' || columns.column_name || ' DROP NOT NULL;' );
- END LOOP;
- END;
-$function$
-
-CREATE OR REPLACE FUNCTION migration_tools.create_linked_legacy_table_from (TEXT,TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- migration_schema ALIAS FOR $1;
- parent_table ALIAS FOR $2;
- source_table ALIAS FOR $3;
- columns RECORD;
- create_sql TEXT;
- insert_sql TEXT;
- column_list TEXT := '';
- column_count INTEGER := 0;
- BEGIN
- create_sql := 'CREATE TABLE ' || migration_schema || '.' || parent_table || '_legacy ( ';
- FOR columns IN
- SELECT table_schema, table_name, column_name, data_type
- FROM information_schema.columns
- WHERE table_schema = migration_schema AND table_name = source_table
- LOOP
- column_count := column_count + 1;
- if column_count > 1 then
- create_sql := create_sql || ', ';
- column_list := column_list || ', ';
- end if;
- create_sql := create_sql || columns.column_name || ' ';
- if columns.data_type = 'ARRAY' then
- create_sql := create_sql || 'TEXT[]';
- else
- create_sql := create_sql || columns.data_type;
- end if;
- column_list := column_list || columns.column_name;
- END LOOP;
- create_sql := create_sql || ' ) INHERITS ( ' || migration_schema || '.' || parent_table || ' );';
- --RAISE INFO 'create_sql = %', create_sql;
- EXECUTE create_sql;
- insert_sql := 'INSERT INTO ' || migration_schema || '.' || parent_table || '_legacy (' || column_list || ') SELECT ' || column_list || ' FROM ' || migration_schema || '.' || source_table || ';';
- --RAISE INFO 'insert_sql = %', insert_sql;
- EXECUTE insert_sql;
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.insert_base_into_production (TEXT) RETURNS VOID AS $$
- DECLARE
- migration_schema ALIAS FOR $1;
- production_tables TEXT[];
- BEGIN
- --RAISE INFO 'In migration_tools.insert_into_production(%)', migration_schema;
- SELECT migration_tools.production_tables(migration_schema) INTO STRICT production_tables;
- FOR i IN array_lower(production_tables,1) .. array_upper(production_tables,1) LOOP
- PERFORM migration_tools.insert_into_production(migration_schema,production_tables[i]);
- END LOOP;
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.insert_into_production (TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- migration_schema ALIAS FOR $1;
- production_table ALIAS FOR $2;
- base_staging_table TEXT;
- columns RECORD;
- BEGIN
- base_staging_table = REPLACE( production_table, '.', '_' );
- --RAISE INFO 'In migration_tools.insert_into_production(%,%) -> %', migration_schema, production_table, base_staging_table;
- PERFORM migration_tools.exec( $1, 'INSERT INTO ' || production_table || ' SELECT * FROM ' || migration_schema || '.' || base_staging_table || ';' );
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-
-CREATE OR REPLACE FUNCTION migration_tools.assert (BOOLEAN) RETURNS VOID AS $$
- DECLARE
- test ALIAS FOR $1;
- BEGIN
- IF NOT test THEN
- RAISE EXCEPTION 'assertion';
- END IF;
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.assert (BOOLEAN,TEXT) RETURNS VOID AS $$
- DECLARE
- test ALIAS FOR $1;
- msg ALIAS FOR $2;
- BEGIN
- IF NOT test THEN
- RAISE EXCEPTION '%', msg;
- END IF;
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.assert (BOOLEAN,TEXT,TEXT) RETURNS TEXT AS $$
- DECLARE
- test ALIAS FOR $1;
- fail_msg ALIAS FOR $2;
- success_msg ALIAS FOR $3;
- BEGIN
- IF NOT test THEN
- RAISE EXCEPTION '%', fail_msg;
- END IF;
- RETURN success_msg;
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
--- push bib sequence and return starting value for reserved range
-CREATE OR REPLACE FUNCTION migration_tools.push_bib_sequence(INTEGER) RETURNS BIGINT AS $$
- DECLARE
- bib_count ALIAS FOR $1;
- output BIGINT;
- BEGIN
- PERFORM setval('biblio.record_entry_id_seq',(SELECT MAX(id) FROM biblio.record_entry) + bib_count + 2000);
- FOR output IN
- SELECT CEIL(MAX(id)/1000)*1000+1000 FROM biblio.record_entry WHERE id < (SELECT last_value FROM biblio.record_entry_id_seq)
- LOOP
- RETURN output;
- END LOOP;
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
--- set a new salted password
-
-CREATE OR REPLACE FUNCTION migration_tools.set_salted_passwd(INTEGER,TEXT) RETURNS BOOLEAN AS $$
- DECLARE
- usr_id ALIAS FOR $1;
- plain_passwd ALIAS FOR $2;
- plain_salt TEXT;
- md5_passwd TEXT;
- BEGIN
-
- SELECT actor.create_salt('main') INTO plain_salt;
-
- SELECT MD5(plain_passwd) INTO md5_passwd;
-
- PERFORM actor.set_passwd(usr_id, 'main', MD5(plain_salt || md5_passwd), plain_salt);
-
- RETURN TRUE;
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-
--- convenience functions for handling copy_location maps
-CREATE OR REPLACE FUNCTION migration_tools.handle_shelf (TEXT,TEXT,TEXT,INTEGER) RETURNS VOID AS $$
- SELECT migration_tools._handle_shelf($1,$2,$3,$4,TRUE);
-$$ LANGUAGE SQL;
-
-CREATE OR REPLACE FUNCTION migration_tools._handle_shelf (TEXT,TEXT,TEXT,INTEGER,BOOLEAN) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_name ALIAS FOR $2;
- org_shortname ALIAS FOR $3;
- org_range ALIAS FOR $4;
- make_assertion ALIAS FOR $5;
- proceed BOOLEAN;
- org INTEGER;
- -- if x_org is on the mapping table, it'll take precedence over the passed org_shortname param
- -- though we'll still use the passed org for the full path traversal when needed
- x_org_found BOOLEAN;
- x_org INTEGER;
- org_list INTEGER[];
- o INTEGER;
- row_count NUMERIC;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = ''desired_shelf''
- )' INTO proceed USING table_schema, table_name;
- IF NOT proceed THEN
- RAISE EXCEPTION 'Missing column desired_shelf';
- END IF;
-
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = ''x_org''
- )' INTO x_org_found USING table_schema, table_name;
-
- SELECT id INTO org FROM actor.org_unit WHERE shortname = org_shortname;
- IF org IS NULL THEN
- RAISE EXCEPTION 'Cannot find org by shortname';
- END IF;
-
- SELECT INTO org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( org );
-
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' DROP COLUMN IF EXISTS x_shelf';
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' ADD COLUMN x_shelf INTEGER';
-
- IF x_org_found THEN
- RAISE INFO 'Found x_org column';
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_shelf = b.id FROM asset_copy_location b'
- || ' WHERE BTRIM(UPPER(a.desired_shelf)) = BTRIM(UPPER(b.name))'
- || ' AND b.owning_lib = x_org'
- || ' AND NOT b.deleted';
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_shelf = b.id FROM asset.copy_location b'
- || ' WHERE BTRIM(UPPER(a.desired_shelf)) = BTRIM(UPPER(b.name))'
- || ' AND b.owning_lib = x_org'
- || ' AND x_shelf IS NULL'
- || ' AND NOT b.deleted';
- ELSE
- RAISE INFO 'Did not find x_org column';
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_shelf = b.id FROM asset_copy_location b'
- || ' WHERE BTRIM(UPPER(a.desired_shelf)) = BTRIM(UPPER(b.name))'
- || ' AND b.owning_lib = $1'
- || ' AND NOT b.deleted'
- USING org;
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_shelf = b.id FROM asset_copy_location b'
- || ' WHERE BTRIM(UPPER(a.desired_shelf)) = BTRIM(UPPER(b.name))'
- || ' AND b.owning_lib = $1'
- || ' AND x_shelf IS NULL'
- || ' AND NOT b.deleted'
- USING org;
- END IF;
-
- FOREACH o IN ARRAY org_list LOOP
- RAISE INFO 'Considering org %', o;
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_shelf = b.id FROM asset.copy_location b'
- || ' WHERE BTRIM(UPPER(a.desired_shelf)) = BTRIM(UPPER(b.name))'
- || ' AND b.owning_lib = $1 AND x_shelf IS NULL'
- || ' AND NOT b.deleted'
- USING o;
- GET DIAGNOSTICS row_count = ROW_COUNT;
- RAISE INFO 'Updated % rows', row_count;
- END LOOP;
-
- IF make_assertion THEN
- EXECUTE 'SELECT migration_tools.assert(
- NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_shelf <> '''' AND x_shelf IS NULL),
- ''Cannot find a desired location'',
- ''Found all desired locations''
- );';
- END IF;
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
--- convenience functions for handling circmod maps
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_circmod (TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_name ALIAS FOR $2;
- proceed BOOLEAN;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = ''desired_circmod''
- )' INTO proceed USING table_schema, table_name;
- IF NOT proceed THEN
- RAISE EXCEPTION 'Missing column desired_circmod';
- END IF;
-
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' DROP COLUMN IF EXISTS x_circmod';
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' ADD COLUMN x_circmod TEXT';
-
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_circmod = code FROM config.circ_modifier b'
- || ' WHERE BTRIM(UPPER(a.desired_circmod)) = BTRIM(UPPER(b.code))';
-
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_circmod = code FROM config.circ_modifier b'
- || ' WHERE BTRIM(UPPER(a.desired_circmod)) = BTRIM(UPPER(b.name))'
- || ' AND x_circmod IS NULL';
-
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_circmod = code FROM config.circ_modifier b'
- || ' WHERE BTRIM(UPPER(a.desired_circmod)) = BTRIM(UPPER(b.description))'
- || ' AND x_circmod IS NULL';
-
- EXECUTE 'SELECT migration_tools.assert(
- NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_circmod <> '''' AND x_circmod IS NULL),
- ''Cannot find a desired circulation modifier'',
- ''Found all desired circulation modifiers''
- );';
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
--- convenience functions for handling item status maps
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_status (TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_name ALIAS FOR $2;
- proceed BOOLEAN;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = ''desired_status''
- )' INTO proceed USING table_schema, table_name;
- IF NOT proceed THEN
- RAISE EXCEPTION 'Missing column desired_status';
- END IF;
-
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' DROP COLUMN IF EXISTS x_status';
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' ADD COLUMN x_status INTEGER';
-
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_status = id FROM config.copy_status b'
- || ' WHERE BTRIM(UPPER(a.desired_status)) = BTRIM(UPPER(b.name))';
-
- EXECUTE 'SELECT migration_tools.assert(
- NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_status <> '''' AND x_status IS NULL),
- ''Cannot find a desired copy status'',
- ''Found all desired copy statuses''
- );';
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
--- convenience functions for handling org maps
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_org (TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_name ALIAS FOR $2;
- proceed BOOLEAN;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = ''desired_org''
- )' INTO proceed USING table_schema, table_name;
- IF NOT proceed THEN
- RAISE EXCEPTION 'Missing column desired_org';
- END IF;
-
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' DROP COLUMN IF EXISTS x_org';
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' ADD COLUMN x_org INTEGER';
-
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_org = b.id FROM actor.org_unit b'
- || ' WHERE BTRIM(a.desired_org) = BTRIM(b.shortname)';
-
- EXECUTE 'SELECT migration_tools.assert(
- NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_org <> '''' AND x_org IS NULL),
- ''Cannot find a desired org unit'',
- ''Found all desired org units''
- );';
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
--- convenience function for handling desired_not_migrate
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_not_migrate (TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_name ALIAS FOR $2;
- proceed BOOLEAN;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = ''desired_not_migrate''
- )' INTO proceed USING table_schema, table_name;
- IF NOT proceed THEN
- RAISE EXCEPTION 'Missing column desired_not_migrate';
- END IF;
-
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' DROP COLUMN IF EXISTS x_migrate';
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' ADD COLUMN x_migrate BOOLEAN';
-
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_migrate = CASE'
- || ' WHEN BTRIM(desired_not_migrate) = ''TRUE'' THEN FALSE'
- || ' WHEN BTRIM(desired_not_migrate) = ''DNM'' THEN FALSE'
- || ' WHEN BTRIM(desired_not_migrate) = ''Do Not Migrate'' THEN FALSE'
- || ' WHEN BTRIM(desired_not_migrate) = ''FALSE'' THEN TRUE'
- || ' WHEN BTRIM(desired_not_migrate) = ''Migrate'' THEN TRUE'
- || ' WHEN BTRIM(desired_not_migrate) = '''' THEN TRUE'
- || ' END';
-
- EXECUTE 'SELECT migration_tools.assert(
- NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE x_migrate IS NULL),
- ''Not all desired_not_migrate values understood'',
- ''All desired_not_migrate values understood''
- );';
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
--- convenience function for handling desired_not_migrate
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_barred_or_blocked (TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_name ALIAS FOR $2;
- proceed BOOLEAN;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = ''desired_barred_or_blocked''
- )' INTO proceed USING table_schema, table_name;
- IF NOT proceed THEN
- RAISE EXCEPTION 'Missing column desired_barred_or_blocked';
- END IF;
-
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' DROP COLUMN IF EXISTS x_barred';
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' ADD COLUMN x_barred BOOLEAN';
-
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' DROP COLUMN IF EXISTS x_blocked';
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' ADD COLUMN x_blocked BOOLEAN';
-
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_barred = CASE'
- || ' WHEN BTRIM(desired_barred_or_blocked) = ''Barred'' THEN TRUE'
- || ' WHEN BTRIM(desired_barred_or_blocked) = ''Blocked'' THEN FALSE'
- || ' WHEN BTRIM(desired_barred_or_blocked) = ''Neither'' THEN FALSE'
- || ' WHEN BTRIM(desired_barred_or_blocked) = '''' THEN FALSE'
- || ' END';
-
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_blocked = CASE'
- || ' WHEN BTRIM(desired_barred_or_blocked) = ''Blocked'' THEN TRUE'
- || ' WHEN BTRIM(desired_barred_or_blocked) = ''Barred'' THEN FALSE'
- || ' WHEN BTRIM(desired_barred_or_blocked) = ''Neither'' THEN FALSE'
- || ' WHEN BTRIM(desired_barred_or_blocked) = '''' THEN FALSE'
- || ' END';
-
- EXECUTE 'SELECT migration_tools.assert(
- NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE x_barred IS NULL or x_blocked IS NULL),
- ''Not all desired_barred_or_blocked values understood'',
- ''All desired_barred_or_blocked values understood''
- );';
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
--- convenience function for handling desired_profile
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_profile (TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_name ALIAS FOR $2;
- proceed BOOLEAN;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = ''desired_profile''
- )' INTO proceed USING table_schema, table_name;
- IF NOT proceed THEN
- RAISE EXCEPTION 'Missing column desired_profile';
- END IF;
-
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' DROP COLUMN IF EXISTS x_profile';
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' ADD COLUMN x_profile INTEGER';
-
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_profile = b.id FROM permission.grp_tree b'
- || ' WHERE BTRIM(UPPER(a.desired_profile)) = BTRIM(UPPER(b.name))';
-
- EXECUTE 'SELECT migration_tools.assert(
- NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_profile <> '''' AND x_profile IS NULL),
- ''Cannot find a desired profile'',
- ''Found all desired profiles''
- );';
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
--- convenience function for handling desired actor stat cats
-
-CREATE OR REPLACE FUNCTION migration_tools.vivicate_actor_sc_and_sce (TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_name ALIAS FOR $2;
- field_suffix ALIAS FOR $3; -- for distinguishing between desired_sce1, desired_sce2, etc.
- org_shortname ALIAS FOR $4;
- proceed BOOLEAN;
- org INTEGER;
- org_list INTEGER[];
- sc TEXT;
- sce TEXT;
- BEGIN
-
- SELECT 'desired_sc' || field_suffix INTO sc;
- SELECT 'desired_sce' || field_suffix INTO sce;
-
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_name, sc;
- IF NOT proceed THEN
- RAISE EXCEPTION 'Missing column %', sc;
- END IF;
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_name, sce;
- IF NOT proceed THEN
- RAISE EXCEPTION 'Missing column %', sce;
- END IF;
-
- SELECT id INTO org FROM actor.org_unit WHERE shortname = org_shortname;
- IF org IS NULL THEN
- RAISE EXCEPTION 'Cannot find org by shortname';
- END IF;
- SELECT INTO org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( org );
-
- -- caller responsible for their own truncates though we try to prevent duplicates
- EXECUTE 'INSERT INTO actor_stat_cat (owner, name)
- SELECT DISTINCT
- $1
- ,BTRIM('||sc||')
- FROM
- ' || quote_ident(table_name) || '
- WHERE
- NULLIF(BTRIM('||sc||'),'''') IS NOT NULL
- AND NOT EXISTS (
- SELECT id
- FROM actor.stat_cat
- WHERE owner = ANY ($2)
- AND name = BTRIM('||sc||')
- )
- AND NOT EXISTS (
- SELECT id
- FROM actor_stat_cat
- WHERE owner = ANY ($2)
- AND name = BTRIM('||sc||')
- )
- ORDER BY 2;'
- USING org, org_list;
-
- EXECUTE 'INSERT INTO actor_stat_cat_entry (stat_cat, owner, value)
- SELECT DISTINCT
- COALESCE(
- (SELECT id
- FROM actor.stat_cat
- WHERE owner = ANY ($2)
- AND BTRIM('||sc||') = BTRIM(name))
- ,(SELECT id
- FROM actor_stat_cat
- WHERE owner = ANY ($2)
- AND BTRIM('||sc||') = BTRIM(name))
- )
- ,$1
- ,BTRIM('||sce||')
- FROM
- ' || quote_ident(table_name) || '
- WHERE
- NULLIF(BTRIM('||sc||'),'''') IS NOT NULL
- AND NULLIF(BTRIM('||sce||'),'''') IS NOT NULL
- AND NOT EXISTS (
- SELECT id
- FROM actor.stat_cat_entry
- WHERE stat_cat = (
- SELECT id
- FROM actor.stat_cat
- WHERE owner = ANY ($2)
- AND BTRIM('||sc||') = BTRIM(name)
- ) AND value = BTRIM('||sce||')
- AND owner = ANY ($2)
- )
- AND NOT EXISTS (
- SELECT id
- FROM actor_stat_cat_entry
- WHERE stat_cat = (
- SELECT id
- FROM actor_stat_cat
- WHERE owner = ANY ($2)
- AND BTRIM('||sc||') = BTRIM(name)
- ) AND value = BTRIM('||sce||')
- AND owner = ANY ($2)
- )
- ORDER BY 1,3;'
- USING org, org_list;
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_actor_sc_and_sce (TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_name ALIAS FOR $2;
- field_suffix ALIAS FOR $3; -- for distinguishing between desired_sce1, desired_sce2, etc.
- org_shortname ALIAS FOR $4;
- proceed BOOLEAN;
- org INTEGER;
- org_list INTEGER[];
- o INTEGER;
- sc TEXT;
- sce TEXT;
- BEGIN
- SELECT 'desired_sc' || field_suffix INTO sc;
- SELECT 'desired_sce' || field_suffix INTO sce;
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_name, sc;
- IF NOT proceed THEN
- RAISE EXCEPTION 'Missing column %', sc;
- END IF;
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_name, sce;
- IF NOT proceed THEN
- RAISE EXCEPTION 'Missing column %', sce;
- END IF;
-
- SELECT id INTO org FROM actor.org_unit WHERE shortname = org_shortname;
- IF org IS NULL THEN
- RAISE EXCEPTION 'Cannot find org by shortname';
- END IF;
-
- SELECT INTO org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( org );
-
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' DROP COLUMN IF EXISTS x_sc' || field_suffix;
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' ADD COLUMN x_sc' || field_suffix || ' INTEGER';
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' DROP COLUMN IF EXISTS x_sce' || field_suffix;
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' ADD COLUMN x_sce' || field_suffix || ' INTEGER';
-
-
- EXECUTE 'UPDATE ' || quote_ident(table_name) || '
- SET
- x_sc' || field_suffix || ' = id
- FROM
- (SELECT id, name, owner FROM actor_stat_cat
- UNION SELECT id, name, owner FROM actor.stat_cat) u
- WHERE
- BTRIM(UPPER(u.name)) = BTRIM(UPPER(' || sc || '))
- AND u.owner = ANY ($1);'
- USING org_list;
-
- EXECUTE 'UPDATE ' || quote_ident(table_name) || '
- SET
- x_sce' || field_suffix || ' = id
- FROM
- (SELECT id, stat_cat, owner, value FROM actor_stat_cat_entry
- UNION SELECT id, stat_cat, owner, value FROM actor.stat_cat_entry) u
- WHERE
- u.stat_cat = x_sc' || field_suffix || '
- AND BTRIM(UPPER(u.value)) = BTRIM(UPPER(' || sce || '))
- AND u.owner = ANY ($1);'
- USING org_list;
-
- EXECUTE 'SELECT migration_tools.assert(
- NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_sc' || field_suffix || ' <> '''' AND x_sc' || field_suffix || ' IS NULL),
- ''Cannot find a desired stat cat'',
- ''Found all desired stat cats''
- );';
-
- EXECUTE 'SELECT migration_tools.assert(
- NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_sce' || field_suffix || ' <> '''' AND x_sce' || field_suffix || ' IS NULL),
- ''Cannot find a desired stat cat entry'',
- ''Found all desired stat cat entries''
- );';
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
--- convenience functions for adding shelving locations
-DROP FUNCTION IF EXISTS migration_tools.find_shelf(INT,TEXT);
-CREATE OR REPLACE FUNCTION migration_tools.find_shelf(org_id INT, shelf_name TEXT) RETURNS INTEGER AS $$
-DECLARE
- return_id INT;
- d INT;
- cur_id INT;
-BEGIN
- SELECT INTO d MAX(distance) FROM actor.org_unit_ancestors_distance(org_id);
- WHILE d >= 0
- LOOP
- SELECT INTO cur_id id FROM actor.org_unit_ancestor_at_depth(org_id,d);
- SELECT INTO return_id id FROM asset.copy_location WHERE owning_lib = cur_id AND name ILIKE shelf_name;
- IF return_id IS NOT NULL THEN
- RETURN return_id;
- END IF;
- d := d - 1;
- END LOOP;
-
- RETURN NULL;
-END
-$$ LANGUAGE plpgsql;
-
--- may remove later but testing using this with new migration scripts and not loading acls until go live
-
-DROP FUNCTION IF EXISTS migration_tools.find_mig_shelf(INT,TEXT);
-CREATE OR REPLACE FUNCTION migration_tools.find_mig_shelf(org_id INT, shelf_name TEXT) RETURNS INTEGER AS $$
-DECLARE
- return_id INT;
- d INT;
- cur_id INT;
-BEGIN
- SELECT INTO d MAX(distance) FROM actor.org_unit_ancestors_distance(org_id);
- WHILE d >= 0
- LOOP
- SELECT INTO cur_id id FROM actor.org_unit_ancestor_at_depth(org_id,d);
-
- SELECT INTO return_id id FROM
- (SELECT * FROM asset.copy_location UNION ALL SELECT * FROM asset_copy_location) x
- WHERE owning_lib = cur_id AND name ILIKE shelf_name;
- IF return_id IS NOT NULL THEN
- RETURN return_id;
- END IF;
- d := d - 1;
- END LOOP;
-
- RETURN NULL;
-END
-$$ LANGUAGE plpgsql;
-
--- convenience function for linking to the item staging table
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_item_barcode (TEXT,TEXT,TEXT,TEXT,BOOLEAN) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_name ALIAS FOR $2;
- foreign_column_name ALIAS FOR $3;
- main_column_name ALIAS FOR $4;
- btrim_desired ALIAS FOR $5;
- proceed BOOLEAN;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_name, foreign_column_name;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_name, foreign_column_name;
- END IF;
-
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = ''asset_copy_legacy''
- and column_name = $2
- )' INTO proceed USING table_schema, main_column_name;
- IF NOT proceed THEN
- RAISE EXCEPTION 'No %.asset_copy_legacy with column %', table_schema, main_column_name;
- END IF;
-
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' DROP COLUMN IF EXISTS x_item';
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' ADD COLUMN x_item BIGINT';
-
- IF btrim_desired THEN
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_item = b.id FROM asset_copy_legacy b'
- || ' WHERE BTRIM(a.' || quote_ident(foreign_column_name)
- || ') = BTRIM(b.' || quote_ident(main_column_name) || ')';
- ELSE
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_item = b.id FROM asset_copy_legacy b'
- || ' WHERE a.' || quote_ident(foreign_column_name)
- || ' = b.' || quote_ident(main_column_name);
- END IF;
-
- --EXECUTE 'SELECT migration_tools.assert(
- -- NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE ' || quote_ident(foreign_column_name) || ' <> '''' AND x_item IS NULL),
- -- ''Cannot link every barcode'',
- -- ''Every barcode linked''
- --);';
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
--- convenience function for linking to the user staging table
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_user_barcode (TEXT,TEXT,TEXT,TEXT,BOOLEAN) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_name ALIAS FOR $2;
- foreign_column_name ALIAS FOR $3;
- main_column_name ALIAS FOR $4;
- btrim_desired ALIAS FOR $5;
- proceed BOOLEAN;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_name, foreign_column_name;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_name, foreign_column_name;
- END IF;
-
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = ''actor_usr_legacy''
- and column_name = $2
- )' INTO proceed USING table_schema, main_column_name;
- IF NOT proceed THEN
- RAISE EXCEPTION 'No %.actor_usr_legacy with column %', table_schema, main_column_name;
- END IF;
-
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' DROP COLUMN IF EXISTS x_user';
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' ADD COLUMN x_user INTEGER';
-
- IF btrim_desired THEN
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_user = b.id FROM actor_usr_legacy b'
- || ' WHERE BTRIM(a.' || quote_ident(foreign_column_name)
- || ') = BTRIM(b.' || quote_ident(main_column_name) || ')';
- ELSE
- EXECUTE 'UPDATE ' || quote_ident(table_name) || ' a'
- || ' SET x_user = b.id FROM actor_usr_legacy b'
- || ' WHERE a.' || quote_ident(foreign_column_name)
- || ' = b.' || quote_ident(main_column_name);
- END IF;
-
- --EXECUTE 'SELECT migration_tools.assert(
- -- NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE ' || quote_ident(foreign_column_name) || ' <> '''' AND x_user IS NULL),
- -- ''Cannot link every barcode'',
- -- ''Every barcode linked''
- --);';
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
--- convenience function for linking two tables
--- e.g. select migration_tools.handle_link(:'migschema','asset_copy','barcode','test_foo','l_barcode','x_acp_id',false);
-CREATE OR REPLACE FUNCTION migration_tools.handle_link (TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,BOOLEAN) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_a ALIAS FOR $2;
- column_a ALIAS FOR $3;
- table_b ALIAS FOR $4;
- column_b ALIAS FOR $5;
- column_x ALIAS FOR $6;
- btrim_desired ALIAS FOR $7;
- proceed BOOLEAN;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_a, column_a;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_a, column_a;
- END IF;
-
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_b, column_b;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_b, column_b;
- END IF;
-
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_b)
- || ' DROP COLUMN IF EXISTS ' || quote_ident(column_x);
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_b)
- || ' ADD COLUMN ' || quote_ident(column_x) || ' BIGINT';
-
- IF btrim_desired THEN
- EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
- || ' SET ' || quote_ident(column_x) || ' = a.id FROM ' || quote_ident(table_a) || ' a'
- || ' WHERE BTRIM(a.' || quote_ident(column_a)
- || ') = BTRIM(b.' || quote_ident(column_b) || ')';
- ELSE
- EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
- || ' SET ' || quote_ident(column_x) || ' = a.id FROM ' || quote_ident(table_a) || ' a'
- || ' WHERE a.' || quote_ident(column_a)
- || ' = b.' || quote_ident(column_b);
- END IF;
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
--- convenience function for linking two tables, but copying column w into column x instead of "id"
--- e.g. select migration_tools.handle_link2(:'migschema','asset_copy','barcode','test_foo','l_barcode','id','x_acp_id',false);
-CREATE OR REPLACE FUNCTION migration_tools.handle_link2 (TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,BOOLEAN) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_a ALIAS FOR $2;
- column_a ALIAS FOR $3;
- table_b ALIAS FOR $4;
- column_b ALIAS FOR $5;
- column_w ALIAS FOR $6;
- column_x ALIAS FOR $7;
- btrim_desired ALIAS FOR $8;
- proceed BOOLEAN;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_a, column_a;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_a, column_a;
- END IF;
-
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_b, column_b;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_b, column_b;
- END IF;
-
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_b)
- || ' DROP COLUMN IF EXISTS ' || quote_ident(column_x);
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_b)
- || ' ADD COLUMN ' || quote_ident(column_x) || ' TEXT';
-
- IF btrim_desired THEN
- EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
- || ' SET ' || quote_ident(column_x) || ' = a.' || quote_ident(column_w) || ' FROM ' || quote_ident(table_a) || ' a'
- || ' WHERE BTRIM(a.' || quote_ident(column_a)
- || ') = BTRIM(b.' || quote_ident(column_b) || ')';
- ELSE
- EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
- || ' SET ' || quote_ident(column_x) || ' = a.' || quote_ident(column_w) || ' FROM ' || quote_ident(table_a) || ' a'
- || ' WHERE a.' || quote_ident(column_a)
- || ' = b.' || quote_ident(column_b);
- END IF;
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
--- convenience function for linking two tables, but copying column w into column x instead of "id". Unlike handle_link2, this one won't drop the target column, and it also doesn't have a final boolean argument for btrim
--- e.g. select migration_tools.handle_link3(:'migschema','asset_copy','barcode','test_foo','l_barcode','id','x_acp_id');
-CREATE OR REPLACE FUNCTION migration_tools.handle_link3 (TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_a ALIAS FOR $2;
- column_a ALIAS FOR $3;
- table_b ALIAS FOR $4;
- column_b ALIAS FOR $5;
- column_w ALIAS FOR $6;
- column_x ALIAS FOR $7;
- proceed BOOLEAN;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_a, column_a;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_a, column_a;
- END IF;
-
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_b, column_b;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_b, column_b;
- END IF;
-
- EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
- || ' SET ' || quote_ident(column_x) || ' = a.' || quote_ident(column_w) || ' FROM ' || quote_ident(table_a) || ' a'
- || ' WHERE a.' || quote_ident(column_a)
- || ' = b.' || quote_ident(column_b);
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_link3_skip_null_or_empty_string (TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_a ALIAS FOR $2;
- column_a ALIAS FOR $3;
- table_b ALIAS FOR $4;
- column_b ALIAS FOR $5;
- column_w ALIAS FOR $6;
- column_x ALIAS FOR $7;
- proceed BOOLEAN;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_a, column_a;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_a, column_a;
- END IF;
-
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_b, column_b;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_b, column_b;
- END IF;
-
- EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
- || ' SET ' || quote_ident(column_x) || ' = a.' || quote_ident(column_w) || ' FROM ' || quote_ident(table_a) || ' a'
- || ' WHERE a.' || quote_ident(column_a)
- || ' = b.' || quote_ident(column_b)
- || ' AND NULLIF(a.' || quote_ident(column_w) || ','''') IS NOT NULL';
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_link3_skip_null (TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_a ALIAS FOR $2;
- column_a ALIAS FOR $3;
- table_b ALIAS FOR $4;
- column_b ALIAS FOR $5;
- column_w ALIAS FOR $6;
- column_x ALIAS FOR $7;
- proceed BOOLEAN;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_a, column_a;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_a, column_a;
- END IF;
-
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_b, column_b;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_b, column_b;
- END IF;
-
- EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
- || ' SET ' || quote_ident(column_x) || ' = a.' || quote_ident(column_w) || ' FROM ' || quote_ident(table_a) || ' a'
- || ' WHERE a.' || quote_ident(column_a)
- || ' = b.' || quote_ident(column_b)
- || ' AND a.' || quote_ident(column_w) || ' IS NOT NULL';
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_link3_skip_true (TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_a ALIAS FOR $2;
- column_a ALIAS FOR $3;
- table_b ALIAS FOR $4;
- column_b ALIAS FOR $5;
- column_w ALIAS FOR $6;
- column_x ALIAS FOR $7;
- proceed BOOLEAN;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_a, column_a;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_a, column_a;
- END IF;
-
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_b, column_b;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_b, column_b;
- END IF;
-
- EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
- || ' SET ' || quote_ident(column_x) || ' = a.' || quote_ident(column_w) || ' FROM ' || quote_ident(table_a) || ' a'
- || ' WHERE a.' || quote_ident(column_a)
- || ' = b.' || quote_ident(column_b)
- || ' AND a.' || quote_ident(column_w) || ' IS NOT TRUE';
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_link3_skip_false (TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_a ALIAS FOR $2;
- column_a ALIAS FOR $3;
- table_b ALIAS FOR $4;
- column_b ALIAS FOR $5;
- column_w ALIAS FOR $6;
- column_x ALIAS FOR $7;
- proceed BOOLEAN;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_a, column_a;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_a, column_a;
- END IF;
-
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_b, column_b;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_b, column_b;
- END IF;
-
- EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
- || ' SET ' || quote_ident(column_x) || ' = a.' || quote_ident(column_w) || ' FROM ' || quote_ident(table_a) || ' a'
- || ' WHERE a.' || quote_ident(column_a)
- || ' = b.' || quote_ident(column_b)
- || ' AND a.' || quote_ident(column_w) || ' IS NOT FALSE';
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_link3_concat_skip_null (TEXT,TEXT,TEXT,TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_a ALIAS FOR $2;
- column_a ALIAS FOR $3;
- table_b ALIAS FOR $4;
- column_b ALIAS FOR $5;
- column_w ALIAS FOR $6;
- column_x ALIAS FOR $7;
- proceed BOOLEAN;
- BEGIN
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_a, column_a;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_a, column_a;
- END IF;
-
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_b, column_b;
- IF NOT proceed THEN
- RAISE EXCEPTION '%.% missing column %', table_schema, table_b, column_b;
- END IF;
-
- EXECUTE 'UPDATE ' || quote_ident(table_b) || ' b'
- || ' SET ' || quote_ident(column_x) || ' = CONCAT_WS('' ; '',b.' || quote_ident(column_x) || ',a.' || quote_ident(column_w) || ') FROM ' || quote_ident(table_a) || ' a'
- || ' WHERE a.' || quote_ident(column_a)
- || ' = b.' || quote_ident(column_b)
- || ' AND NULLIF(a.' || quote_ident(column_w) || ','''') IS NOT NULL';
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
--- convenience function for handling desired asset stat cats
-
-CREATE OR REPLACE FUNCTION migration_tools.vivicate_asset_sc_and_sce (TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_name ALIAS FOR $2;
- field_suffix ALIAS FOR $3; -- for distinguishing between desired_sce1, desired_sce2, etc.
- org_shortname ALIAS FOR $4;
- proceed BOOLEAN;
- org INTEGER;
- org_list INTEGER[];
- sc TEXT;
- sce TEXT;
- BEGIN
-
- SELECT 'desired_sc' || field_suffix INTO sc;
- SELECT 'desired_sce' || field_suffix INTO sce;
-
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_name, sc;
- IF NOT proceed THEN
- RAISE EXCEPTION 'Missing column %', sc;
- END IF;
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_name, sce;
- IF NOT proceed THEN
- RAISE EXCEPTION 'Missing column %', sce;
- END IF;
-
- SELECT id INTO org FROM actor.org_unit WHERE shortname = org_shortname;
- IF org IS NULL THEN
- RAISE EXCEPTION 'Cannot find org by shortname';
- END IF;
- SELECT INTO org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( org );
-
- -- caller responsible for their own truncates though we try to prevent duplicates
- EXECUTE 'INSERT INTO asset_stat_cat (owner, name)
- SELECT DISTINCT
- $1
- ,BTRIM('||sc||')
- FROM
- ' || quote_ident(table_name) || '
- WHERE
- NULLIF(BTRIM('||sc||'),'''') IS NOT NULL
- AND NOT EXISTS (
- SELECT id
- FROM asset.stat_cat
- WHERE owner = ANY ($2)
- AND name = BTRIM('||sc||')
- )
- AND NOT EXISTS (
- SELECT id
- FROM asset_stat_cat
- WHERE owner = ANY ($2)
- AND name = BTRIM('||sc||')
- )
- ORDER BY 2;'
- USING org, org_list;
-
- EXECUTE 'INSERT INTO asset_stat_cat_entry (stat_cat, owner, value)
- SELECT DISTINCT
- COALESCE(
- (SELECT id
- FROM asset.stat_cat
- WHERE owner = ANY ($2)
- AND BTRIM('||sc||') = BTRIM(name))
- ,(SELECT id
- FROM asset_stat_cat
- WHERE owner = ANY ($2)
- AND BTRIM('||sc||') = BTRIM(name))
- )
- ,$1
- ,BTRIM('||sce||')
- FROM
- ' || quote_ident(table_name) || '
- WHERE
- NULLIF(BTRIM('||sc||'),'''') IS NOT NULL
- AND NULLIF(BTRIM('||sce||'),'''') IS NOT NULL
- AND NOT EXISTS (
- SELECT id
- FROM asset.stat_cat_entry
- WHERE stat_cat = (
- SELECT id
- FROM asset.stat_cat
- WHERE owner = ANY ($2)
- AND BTRIM('||sc||') = BTRIM(name)
- ) AND value = BTRIM('||sce||')
- AND owner = ANY ($2)
- )
- AND NOT EXISTS (
- SELECT id
- FROM asset_stat_cat_entry
- WHERE stat_cat = (
- SELECT id
- FROM asset_stat_cat
- WHERE owner = ANY ($2)
- AND BTRIM('||sc||') = BTRIM(name)
- ) AND value = BTRIM('||sce||')
- AND owner = ANY ($2)
- )
- ORDER BY 1,3;'
- USING org, org_list;
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_asset_sc_and_sce (TEXT,TEXT,TEXT,TEXT) RETURNS VOID AS $$
- DECLARE
- table_schema ALIAS FOR $1;
- table_name ALIAS FOR $2;
- field_suffix ALIAS FOR $3; -- for distinguishing between desired_sce1, desired_sce2, etc.
- org_shortname ALIAS FOR $4;
- proceed BOOLEAN;
- org INTEGER;
- org_list INTEGER[];
- o INTEGER;
- sc TEXT;
- sce TEXT;
- BEGIN
- SELECT 'desired_sc' || field_suffix INTO sc;
- SELECT 'desired_sce' || field_suffix INTO sce;
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_name, sc;
- IF NOT proceed THEN
- RAISE EXCEPTION 'Missing column %', sc;
- END IF;
- EXECUTE 'SELECT EXISTS (
- SELECT 1
- FROM information_schema.columns
- WHERE table_schema = $1
- AND table_name = $2
- and column_name = $3
- )' INTO proceed USING table_schema, table_name, sce;
- IF NOT proceed THEN
- RAISE EXCEPTION 'Missing column %', sce;
- END IF;
-
- SELECT id INTO org FROM actor.org_unit WHERE shortname = org_shortname;
- IF org IS NULL THEN
- RAISE EXCEPTION 'Cannot find org by shortname';
- END IF;
-
- SELECT INTO org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( org );
-
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' DROP COLUMN IF EXISTS x_sc' || field_suffix;
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' ADD COLUMN x_sc' || field_suffix || ' INTEGER';
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' DROP COLUMN IF EXISTS x_sce' || field_suffix;
- EXECUTE 'ALTER TABLE '
- || quote_ident(table_name)
- || ' ADD COLUMN x_sce' || field_suffix || ' INTEGER';
-
-
- EXECUTE 'UPDATE ' || quote_ident(table_name) || '
- SET
- x_sc' || field_suffix || ' = id
- FROM
- (SELECT id, name, owner FROM asset_stat_cat
- UNION SELECT id, name, owner FROM asset.stat_cat) u
- WHERE
- BTRIM(UPPER(u.name)) = BTRIM(UPPER(' || sc || '))
- AND u.owner = ANY ($1);'
- USING org_list;
-
- EXECUTE 'UPDATE ' || quote_ident(table_name) || '
- SET
- x_sce' || field_suffix || ' = id
- FROM
- (SELECT id, stat_cat, owner, value FROM asset_stat_cat_entry
- UNION SELECT id, stat_cat, owner, value FROM asset.stat_cat_entry) u
- WHERE
- u.stat_cat = x_sc' || field_suffix || '
- AND BTRIM(UPPER(u.value)) = BTRIM(UPPER(' || sce || '))
- AND u.owner = ANY ($1);'
- USING org_list;
-
- EXECUTE 'SELECT migration_tools.assert(
- NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_sc' || field_suffix || ' <> '''' AND x_sc' || field_suffix || ' IS NULL),
- ''Cannot find a desired stat cat'',
- ''Found all desired stat cats''
- );';
-
- EXECUTE 'SELECT migration_tools.assert(
- NOT EXISTS (SELECT 1 FROM ' || quote_ident(table_name) || ' WHERE desired_sce' || field_suffix || ' <> '''' AND x_sce' || field_suffix || ' IS NULL),
- ''Cannot find a desired stat cat entry'',
- ''Found all desired stat cat entries''
- );';
-
- END;
-$$ LANGUAGE PLPGSQL STRICT VOLATILE;
-
-DROP FUNCTION IF EXISTS migration_tools.btrim_lcolumns(TEXT,TEXT);
-CREATE OR REPLACE FUNCTION migration_tools.btrim_lcolumns(s_name TEXT, t_name TEXT) RETURNS BOOLEAN
- LANGUAGE plpgsql
-AS $function$
-DECLARE
- c_name TEXT;
-BEGIN
-
- FOR c_name IN SELECT column_name FROM information_schema.columns WHERE
- table_name = t_name
- AND table_schema = s_name
- AND (data_type='text' OR data_type='character varying')
- AND column_name like 'l_%'
- LOOP
- EXECUTE FORMAT('UPDATE ' || s_name || '.' || t_name || ' SET ' || c_name || ' = BTRIM(' || c_name || ')');
- END LOOP;
-
- RETURN TRUE;
-END
-$function$;
-
-DROP FUNCTION IF EXISTS migration_tools.btrim_columns(TEXT,TEXT);
-CREATE OR REPLACE FUNCTION migration_tools.btrim_columns(s_name TEXT, t_name TEXT) RETURNS BOOLEAN
- LANGUAGE plpgsql
-AS $function$
-DECLARE
- c_name TEXT;
-BEGIN
-
- FOR c_name IN SELECT column_name FROM information_schema.columns WHERE
- table_name = t_name
- AND table_schema = s_name
- AND (data_type='text' OR data_type='character varying')
- LOOP
- EXECUTE FORMAT('UPDATE ' || s_name || '.' || t_name || ' SET ' || c_name || ' = BTRIM(' || c_name || ')');
- END LOOP;
-
- RETURN TRUE;
-END
-$function$;
-
-DROP FUNCTION IF EXISTS migration_tools.null_empty_lcolumns(TEXT,TEXT);
-CREATE OR REPLACE FUNCTION migration_tools.null_empty_lcolumns(s_name TEXT, t_name TEXT) RETURNS BOOLEAN
- LANGUAGE plpgsql
-AS $function$
-DECLARE
- c_name TEXT;
-BEGIN
-
- FOR c_name IN SELECT column_name FROM information_schema.columns WHERE
- table_name = t_name
- AND table_schema = s_name
- AND (data_type='text' OR data_type='character varying')
- AND column_name like 'l_%'
- LOOP
- EXECUTE FORMAT('UPDATE ' || s_name || '.' || t_name || ' SET ' || c_name || ' = NULL WHERE ' || c_name || ' = '''' ');
- END LOOP;
-
- RETURN TRUE;
-END
-$function$;
-
-DROP FUNCTION IF EXISTS migration_tools.null_empty_columns(TEXT,TEXT);
-CREATE OR REPLACE FUNCTION migration_tools.null_empty_columns(s_name TEXT, t_name TEXT) RETURNS BOOLEAN
- LANGUAGE plpgsql
-AS $function$
-DECLARE
- c_name TEXT;
-BEGIN
-
- FOR c_name IN SELECT column_name FROM information_schema.columns WHERE
- table_name = t_name
- AND table_schema = s_name
- AND (data_type='text' OR data_type='character varying')
- LOOP
- EXECUTE FORMAT('UPDATE ' || s_name || '.' || t_name || ' SET ' || c_name || ' = NULL WHERE ' || c_name || ' = '''' ');
- END LOOP;
-
- RETURN TRUE;
-END
-$function$;
-
-
--- convenience function for handling item barcode collisions in asset_copy_legacy
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_asset_barcode_collisions(migration_schema TEXT) RETURNS VOID AS $function$
-DECLARE
- x_barcode TEXT;
- x_id BIGINT;
- row_count NUMERIC;
- internal_collision_count NUMERIC := 0;
- incumbent_collision_count NUMERIC := 0;
-BEGIN
- FOR x_barcode IN SELECT barcode FROM asset_copy_legacy WHERE x_migrate GROUP BY 1 HAVING COUNT(*) > 1
- LOOP
- FOR x_id IN SELECT id FROM asset_copy WHERE barcode = x_barcode
- LOOP
- UPDATE asset_copy SET barcode = migration_schema || '_internal_collision_' || id || '_' || barcode WHERE id = x_id;
- GET DIAGNOSTICS row_count = ROW_COUNT;
- internal_collision_count := internal_collision_count + row_count;
- END LOOP;
- END LOOP;
- RAISE INFO '% internal collisions', internal_collision_count;
- FOR x_barcode IN SELECT a.barcode FROM asset.copy a, asset_copy_legacy b WHERE x_migrate AND a.deleted IS FALSE AND a.barcode = b.barcode
- LOOP
- FOR x_id IN SELECT id FROM asset_copy_legacy WHERE barcode = x_barcode
- LOOP
- UPDATE asset_copy_legacy SET barcode = migration_schema || '_incumbent_collision_' || id || '_' || barcode WHERE id = x_id;
- GET DIAGNOSTICS row_count = ROW_COUNT;
- incumbent_collision_count := incumbent_collision_count + row_count;
- END LOOP;
- END LOOP;
- RAISE INFO '% incumbent collisions', incumbent_collision_count;
-END
-$function$ LANGUAGE plpgsql;
-
--- convenience function for handling patron barcode/usrname collisions in actor_usr_legacy
--- this should be ran prior to populating actor_card
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_actor_barcode_collisions(migration_schema TEXT) RETURNS VOID AS $function$
-DECLARE
- x_barcode TEXT;
- x_id BIGINT;
- row_count NUMERIC;
- internal_collision_count NUMERIC := 0;
- incumbent_barcode_collision_count NUMERIC := 0;
- incumbent_usrname_collision_count NUMERIC := 0;
-BEGIN
- FOR x_barcode IN SELECT usrname FROM actor_usr_legacy WHERE x_migrate GROUP BY 1 HAVING COUNT(*) > 1
- LOOP
- FOR x_id IN SELECT id FROM actor_usr_legacy WHERE x_migrate AND usrname = x_barcode
- LOOP
- UPDATE actor_usr_legacy SET usrname = migration_schema || '_internal_collision_' || id || '_' || usrname WHERE id = x_id;
- GET DIAGNOSTICS row_count = ROW_COUNT;
- internal_collision_count := internal_collision_count + row_count;
- END LOOP;
- END LOOP;
- RAISE INFO '% internal usrname/barcode collisions', internal_collision_count;
-
- FOR x_barcode IN
- SELECT a.barcode FROM actor.card a, actor_usr_legacy b WHERE x_migrate AND a.barcode = b.usrname
- LOOP
- FOR x_id IN SELECT DISTINCT id FROM actor_usr_legacy WHERE x_migrate AND usrname = x_barcode
- LOOP
- UPDATE actor_usr_legacy SET usrname = migration_schema || '_incumbent_barcode_collision_' || id || '_' || usrname WHERE id = x_id;
- GET DIAGNOSTICS row_count = ROW_COUNT;
- incumbent_barcode_collision_count := incumbent_barcode_collision_count + row_count;
- END LOOP;
- END LOOP;
- RAISE INFO '% incumbent barcode collisions', incumbent_barcode_collision_count;
-
- FOR x_barcode IN
- SELECT a.usrname FROM actor.usr a, actor_usr_legacy b WHERE x_migrate AND a.usrname = b.usrname
- LOOP
- FOR x_id IN SELECT DISTINCT id FROM actor_usr_legacy WHERE x_migrate AND usrname = x_barcode
- LOOP
- UPDATE actor_usr_legacy SET usrname = migration_schema || '_incumbent_usrname_collision_' || id || '_' || usrname WHERE id = x_id;
- GET DIAGNOSTICS row_count = ROW_COUNT;
- incumbent_usrname_collision_count := incumbent_usrname_collision_count + row_count;
- END LOOP;
- END LOOP;
- RAISE INFO '% incumbent usrname collisions (post barcode collision munging)', incumbent_usrname_collision_count;
-END
-$function$ LANGUAGE plpgsql;
-
--- alternate version: convenience function for handling item barcode collisions in asset_copy_legacy
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_asset_barcode_collisions2(migration_schema TEXT) RETURNS VOID AS $function$
-DECLARE
- x_barcode TEXT;
- x_id BIGINT;
- row_count NUMERIC;
- internal_collision_count NUMERIC := 0;
- incumbent_collision_count NUMERIC := 0;
-BEGIN
- FOR x_barcode IN SELECT barcode FROM asset_copy_legacy WHERE x_migrate GROUP BY 1 HAVING COUNT(*) > 1
- LOOP
- FOR x_id IN SELECT id FROM asset_copy WHERE barcode = x_barcode
- LOOP
- UPDATE asset_copy SET barcode = migration_schema || '_internal_collision_' || id || '_' || barcode WHERE id = x_id;
- GET DIAGNOSTICS row_count = ROW_COUNT;
- internal_collision_count := internal_collision_count + row_count;
- END LOOP;
- END LOOP;
- RAISE INFO '% internal collisions', internal_collision_count;
- FOR x_barcode IN SELECT a.barcode FROM asset.copy a, asset_copy_legacy b WHERE x_migrate AND a.deleted IS FALSE AND a.barcode = b.barcode
- LOOP
- FOR x_id IN SELECT id FROM asset_copy_legacy WHERE barcode = x_barcode
- LOOP
- UPDATE asset_copy_legacy SET barcode = migration_schema || '_' || barcode WHERE id = x_id;
- GET DIAGNOSTICS row_count = ROW_COUNT;
- incumbent_collision_count := incumbent_collision_count + row_count;
- END LOOP;
- END LOOP;
- RAISE INFO '% incumbent collisions', incumbent_collision_count;
-END
-$function$ LANGUAGE plpgsql;
-
--- alternate version: convenience function for handling patron barcode/usrname collisions in actor_usr_legacy
--- this should be ran prior to populating actor_card
-
-CREATE OR REPLACE FUNCTION migration_tools.handle_actor_barcode_collisions2(migration_schema TEXT) RETURNS VOID AS $function$
-DECLARE
- x_barcode TEXT;
- x_id BIGINT;
- row_count NUMERIC;
- internal_collision_count NUMERIC := 0;
- incumbent_barcode_collision_count NUMERIC := 0;
- incumbent_usrname_collision_count NUMERIC := 0;
-BEGIN
- FOR x_barcode IN SELECT usrname FROM actor_usr_legacy WHERE x_migrate GROUP BY 1 HAVING COUNT(*) > 1
- LOOP
- FOR x_id IN SELECT id FROM actor_usr_legacy WHERE x_migrate AND usrname = x_barcode
- LOOP
- UPDATE actor_usr_legacy SET usrname = migration_schema || '_internal_collision_' || id || '_' || usrname WHERE id = x_id;
- GET DIAGNOSTICS row_count = ROW_COUNT;
- internal_collision_count := internal_collision_count + row_count;
- END LOOP;
- END LOOP;
- RAISE INFO '% internal usrname/barcode collisions', internal_collision_count;
-
- FOR x_barcode IN
- SELECT a.barcode FROM actor.card a, actor_usr_legacy b WHERE x_migrate AND a.barcode = b.usrname
- LOOP
- FOR x_id IN SELECT DISTINCT id FROM actor_usr_legacy WHERE x_migrate AND usrname = x_barcode
- LOOP
- UPDATE actor_usr_legacy SET usrname = migration_schema || '_' || usrname WHERE id = x_id;
- GET DIAGNOSTICS row_count = ROW_COUNT;
- incumbent_barcode_collision_count := incumbent_barcode_collision_count + row_count;
- END LOOP;
- END LOOP;
- RAISE INFO '% incumbent barcode collisions', incumbent_barcode_collision_count;
-
- FOR x_barcode IN
- SELECT a.usrname FROM actor.usr a, actor_usr_legacy b WHERE x_migrate AND a.usrname = b.usrname
- LOOP
- FOR x_id IN SELECT DISTINCT id FROM actor_usr_legacy WHERE x_migrate AND usrname = x_barcode
- LOOP
- UPDATE actor_usr_legacy SET usrname = migration_schema || '_' || usrname WHERE id = x_id;
- GET DIAGNOSTICS row_count = ROW_COUNT;
- incumbent_usrname_collision_count := incumbent_usrname_collision_count + row_count;
- END LOOP;
- END LOOP;
- RAISE INFO '% incumbent usrname collisions (post barcode collision munging)', incumbent_usrname_collision_count;
-END
-$function$ LANGUAGE plpgsql;
-
-CREATE OR REPLACE FUNCTION migration_tools.is_circ_rule_safe_to_delete( test_matchpoint INTEGER ) RETURNS BOOLEAN AS $func$
--- WARNING: Use at your own risk
--- FIXME: not considering marc_type, marc_form, marc_bib_level, marc_vr_format, usr_age_lower_bound, usr_age_upper_bound, item_age
-DECLARE
- item_object asset.copy%ROWTYPE;
- user_object actor.usr%ROWTYPE;
- test_rule_object config.circ_matrix_matchpoint%ROWTYPE;
- result_rule_object config.circ_matrix_matchpoint%ROWTYPE;
- safe_to_delete BOOLEAN := FALSE;
- m action.found_circ_matrix_matchpoint;
- n action.found_circ_matrix_matchpoint;
- -- ( success BOOL, matchpoint config.circ_matrix_matchpoint, buildrows INT[] )
- result_matchpoint INTEGER;
-BEGIN
- SELECT INTO test_rule_object * FROM config.circ_matrix_matchpoint WHERE id = test_matchpoint;
- RAISE INFO 'testing rule: %', test_rule_object;
-
- INSERT INTO actor.usr (
- profile,
- usrname,
- passwd,
- ident_type,
- first_given_name,
- family_name,
- home_ou,
- juvenile
- ) SELECT
- COALESCE(test_rule_object.grp, 2),
- 'is_circ_rule_safe_to_delete_' || test_matchpoint || '_' || NOW()::text,
- MD5(NOW()::TEXT),
- 1,
- 'Ima',
- 'Test',
- COALESCE(test_rule_object.user_home_ou, test_rule_object.org_unit),
- COALESCE(test_rule_object.juvenile_flag, FALSE)
- ;
-
- SELECT INTO user_object * FROM actor.usr WHERE id = currval('actor.usr_id_seq');
-
- INSERT INTO asset.call_number (
- creator,
- editor,
- record,
- owning_lib,
- label,
- label_class
- ) SELECT
- 1,
- 1,
- -1,
- COALESCE(test_rule_object.copy_owning_lib,test_rule_object.org_unit),
- 'is_circ_rule_safe_to_delete_' || test_matchpoint || '_' || NOW()::text,
- 1
- ;
-
- INSERT INTO asset.copy (
- barcode,
- circ_lib,
- creator,
- call_number,
- editor,
- location,
- loan_duration,
- fine_level,
- ref,
- circ_modifier
- ) SELECT
- 'is_circ_rule_safe_to_delete_' || test_matchpoint || '_' || NOW()::text,
- COALESCE(test_rule_object.copy_circ_lib,test_rule_object.org_unit),
- 1,
- currval('asset.call_number_id_seq'),
- 1,
- COALESCE(test_rule_object.copy_location,1),
- 2,
- 2,
- COALESCE(test_rule_object.ref_flag,FALSE),
- test_rule_object.circ_modifier
- ;
-
- SELECT INTO item_object * FROM asset.copy WHERE id = currval('asset.copy_id_seq');
-
- SELECT INTO m * FROM action.find_circ_matrix_matchpoint(
- test_rule_object.org_unit,
- item_object,
- user_object,
- COALESCE(test_rule_object.is_renewal,FALSE)
- );
- RAISE INFO ' action.find_circ_matrix_matchpoint(%,%,%,%) = (%,%,%)',
- test_rule_object.org_unit,
- item_object.id,
- user_object.id,
- COALESCE(test_rule_object.is_renewal,FALSE),
- m.success,
- m.matchpoint,
- m.buildrows
- ;
-
- -- disable the rule being tested to see if the outcome changes
- UPDATE config.circ_matrix_matchpoint SET active = FALSE WHERE id = (m.matchpoint).id;
-
- SELECT INTO n * FROM action.find_circ_matrix_matchpoint(
- test_rule_object.org_unit,
- item_object,
- user_object,
- COALESCE(test_rule_object.is_renewal,FALSE)
- );
- RAISE INFO 'VS action.find_circ_matrix_matchpoint(%,%,%,%) = (%,%,%)',
- test_rule_object.org_unit,
- item_object.id,
- user_object.id,
- COALESCE(test_rule_object.is_renewal,FALSE),
- n.success,
- n.matchpoint,
- n.buildrows
- ;
-
- -- FIXME: We could dig deeper and see if the referenced config.rule_*
- -- entries are effectively equivalent, but for now, let's assume no
- -- duplicate rules at that level
- IF (
- (m.matchpoint).circulate = (n.matchpoint).circulate
- AND (m.matchpoint).duration_rule = (n.matchpoint).duration_rule
- AND (m.matchpoint).recurring_fine_rule = (n.matchpoint).recurring_fine_rule
- AND (m.matchpoint).max_fine_rule = (n.matchpoint).max_fine_rule
- AND (
- (m.matchpoint).hard_due_date = (n.matchpoint).hard_due_date
- OR (
- (m.matchpoint).hard_due_date IS NULL
- AND (n.matchpoint).hard_due_date IS NULL
- )
- )
- AND (
- (m.matchpoint).renewals = (n.matchpoint).renewals
- OR (
- (m.matchpoint).renewals IS NULL
- AND (n.matchpoint).renewals IS NULL
- )
- )
- AND (
- (m.matchpoint).grace_period = (n.matchpoint).grace_period
- OR (
- (m.matchpoint).grace_period IS NULL
- AND (n.matchpoint).grace_period IS NULL
- )
- )
- AND (
- (m.matchpoint).total_copy_hold_ratio = (n.matchpoint).total_copy_hold_ratio
- OR (
- (m.matchpoint).total_copy_hold_ratio IS NULL
- AND (n.matchpoint).total_copy_hold_ratio IS NULL
- )
- )
- AND (
- (m.matchpoint).available_copy_hold_ratio = (n.matchpoint).available_copy_hold_ratio
- OR (
- (m.matchpoint).available_copy_hold_ratio IS NULL
- AND (n.matchpoint).available_copy_hold_ratio IS NULL
- )
- )
- AND NOT EXISTS (
- SELECT limit_set, fallthrough
- FROM config.circ_matrix_limit_set_map
- WHERE active and matchpoint = (m.matchpoint).id
- EXCEPT
- SELECT limit_set, fallthrough
- FROM config.circ_matrix_limit_set_map
- WHERE active and matchpoint = (n.matchpoint).id
- )
-
- ) THEN
- RAISE INFO 'rule has same outcome';
- safe_to_delete := TRUE;
- ELSE
- RAISE INFO 'rule has different outcome';
- safe_to_delete := FALSE;
- END IF;
-
- RAISE EXCEPTION 'rollback the temporary changes';
-
-EXCEPTION WHEN OTHERS THEN
-
- RAISE INFO 'inside exception block: %, %', SQLSTATE, SQLERRM;
- RETURN safe_to_delete;
-
-END;
-$func$ LANGUAGE plpgsql;
-
+\i 00-infrastructure.sql
+\i 01-marc.sql
+\i 02-barcodes.sql
+\i 03-items.sql
+\i 04-names.sql
+\i 05-addresses.sql
+\i 06-ils-specific.sql
+\i 07-eg-specific.sql
+\i 08-casting-and-validation.sql
+\i 09-misc.sql
+\i 10-staging.sql
+\i 21-fixed-fields.sql
+\i 22-anyarray.sql
+--\i 99-deprecated.sql
+++ /dev/null
-\i 00-infrastructure.sql
-\i 01-marc.sql
-\i 02-barcodes.sql
-\i 03-items.sql
-\i 04-names.sql
-\i 05-addresses.sql
-\i 06-ils-specific.sql
-\i 07-eg-specific.sql
-\i 08-casting-and-validation.sql
-\i 09-misc.sql
-\i 10-staging.sql
-\i 21-fixed-fields.sql
-\i 22-anyarray.sql
-\i 99-deprecated.sql
################################################################## CSV Setup
$CSV_options{sep_char} = get_separator( path => $ARGV[0], lucky => 1 );
if ($config && -e $config) {
- do $config;
+ eval `cat $config`;
}
$csv = Text::CSV_XS->new(\%CSV_options);
$csv->callbacks(
$dbh = connect_db($PGDATABASE,$PGUSER,undef,$PGHOST) or die $DBI::errstr;
} else {
our %config;
- do '/openils/conf/offline-config.pl';
+ eval `cat /openils/conf/offline-config.pl`;
$dbh = DBI->connect( $config{dsn}, $config{usr}, $config{pw} ) or die $DBI::errstr;
}
die "$csv_config does not exist\n";
}
if ($csv_config && -e $csv_config) {
- do $csv_config;
+ eval `cat $csv_config`;
}
if (! -e $ARGV[0]) {
die "$ARGV[0] does not exist\n";