added function to trim and null out all columns, useful when importing from reports
[migration-tools.git] / dump_oracle_query_output
1 #!/usr/bin/perl
2
3 # Copyright 2013, Equinox Software, Inc.
4
5 # Author: Galen Charlton <gmc@esilibrary.com>
6 #
7 # This program is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU General Public License
9 # as published by the Free Software Foundation; either version 2
10 # of the License, or (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
21 use strict;
22 use warnings;
23
24 use Carp;
25 use DBI;
26 use Getopt::Long;
27 use Encode;
28
29 my $host = 'localhost';
30 my $sid = $ENV{ORACLE_SID};
31 my $user;
32 my $pw;
33 my $out;
34 my $query,
35 my $show_help;
36 my $src_charset;
37
38 my $result = GetOptions(
39     'sid=s'             => \$sid,
40     'host=s'            => \$host,
41     'user=s'            => \$user,
42     'pw=s'              => \$pw,
43     'out=s'             => \$out,
44     'query=s'           => \$query,
45     'source-charset=s'  => \$src_charset,
46     'help'              => \$show_help,
47 );
48
49 if ($show_help || !$result || !$out || !$query || !$user || !$pw) {
50     print <<_USAGE_;
51 $0: dump results of query on Oracle database to file for loading into PostgreSQL
52
53 Usage: $0 \\
54     [--sid oracle_sid] [--host oracle_host] --user oracle_user --pw oracle_password \\
55     --query sql_query \\
56     --out output_tsv_file [--help]
57             
58 _USAGE_
59     exit 1;
60 }
61
62 my $dbh = DBI->connect("dbi:Oracle:host=$host;sid=$sid", $user, $pw) or croak "Cannot connect to the database";
63 $dbh->do("ALTER SESSION SET NLS_DATE_FORMAT='yyyy-mm-dd hh24:mi:ss'");
64
65 open my $outfh, '>', $out or croak "Cannot open output file $out: $!\n";
66 binmode $outfh, ':raw';
67
68 dump_query_output($query, $outfh);
69
70 close $outfh;
71
72 exit 0;
73
74 sub dump_query_output {
75     my $query = shift;
76     my $fh = shift;
77     my $sth = $dbh->prepare($query);
78     $sth->execute();
79     while (my $row = $sth->fetchrow_arrayref()) {
80         my @data = map { normalize_value_for_tsv($_) } @$row;
81         my $str = join("\t", @data);
82         $str =~ s/\0//g;
83         print $fh encode('utf8', "$str\n");
84     }
85     $sth->finish();
86 }
87
88 sub normalize_value_for_tsv {
89     my $val = shift;
90     if (defined $val) {
91         $val =~ s/\\/\\\\/g;
92         $val =~ s/\0//g;     # FIXME: not dealing with BLOBs for now
93         $val =~ s/[\b]/\\b/g;
94         $val =~ s/\f/\\f/g;
95         $val =~ s/\r/\\r/g;
96         $val =~ s/\n/\\n/g;
97         $val =~ s/\t/\\t/g;
98         $val =~ s/\v/\\v/g;
99         if ($src_charset) {
100             return decode($src_charset, $val);
101         } else {
102             return $val;
103         }
104     } else {
105         return '\N';
106     }
107 }