MayaChemTools

   1 #!/usr/bin/perl -w
   2 #
   3 # $RCSfile: DBSQLToTextFiles.pl,v $
   4 # $Date: 2008/01/30 21:44:44 $
   5 # $Revision: 1.19 $
   6 #
   7 # Author: Manish Sud <msud@san.rr.com>
   8 #
   9 # Copyright (C) 2004-2008 Manish Sud. All rights reserved.
  10 #
  11 # This file is part of MayaChemTools.
  12 #
  13 # MayaChemTools is free software; you can redistribute it and/or modify it under
  14 # the terms of the GNU Lesser General Public License as published by the Free
  15 # Software Foundation; either version 3 of the License, or (at your option) any
  16 # later version.
  17 #
  18 # MayaChemTools is distributed in the hope that it will be useful, but without
  19 # any warranty; without even the implied warranty of merchantability of fitness
  20 # for a particular purpose.  See the GNU Lesser General Public License for more
  21 # details.
  22 #
  23 # You should have received a copy of the GNU Lesser General Public License
  24 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or
  25 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330,
  26 # Boston, MA, 02111-1307, USA.
  27 #
  28 
  29 use 5.006;
  30 use strict;
  31 use FindBin; use lib "$FindBin::Bin/../lib";
  32 use Getopt::Long;
  33 use File::Basename;
  34 use Text::ParseWords;
  35 use Benchmark;
  36 use FileUtil;
  37 use TextUtil;
  38 use DBUtil;
  39 
  40 my($ScriptName, %Options, $StartTime, $EndTime, $TotalTime);
  41 
  42 # Autoflush STDOUT
  43 $| = 1;
  44 
  45 # Starting message...
  46 $ScriptName = basename($0);
  47 print "\n$ScriptName: Starting...\n\n";
  48 $StartTime = new Benchmark;
  49 
  50 # Get the options and setup script...
  51 SetupScriptUsage();
  52 if ($Options{help} || @ARGV < 1) {
  53   die GetUsageFromPod("$FindBin::Bin/$ScriptName");
  54 }
  55 
  56 my($DBDriver, $DBHost, $DBName, $DBUser, $DBPassword, $DBMode, $ExportDataLabels, $ExportLOBs, $OutDelim, $OutQuote, $ReplaceNullStr);
  57 ProcessOptions();
  58 
  59 # Collect input parameters information...
  60 print "Checking input parameter(s)...\n";
  61 my(@DBSQLStatements, @DBTextFiles);
  62 RetrieveDBInfo();
  63 
  64 # Connect to database...
  65 my($DBHandle);
  66 print "Connecting to $DBDriver:database=$DBName as $DBUser...\n";
  67 $DBHandle = DBConnect($DBDriver, $DBName, $DBHost, $DBUser, $DBPassword);
  68 
  69 # Generate text files...
  70 if (@DBTextFiles > 1) {
  71   print "Generating text files...\n";
  72 }
  73 my($Index, $TextFile, $SQL);
  74 TEXTFILE: for $Index (0 .. $#DBTextFiles) {
  75   $TextFile = $DBTextFiles[$Index];
  76   $SQL = $DBSQLStatements[$Index];
  77 
  78   if (@DBTextFiles > 1) {
  79     print "\nGenerating text file $TextFile...\n";
  80   }
  81   else {
  82     print "Generating text file $TextFile...\n";
  83   }
  84   print "Processing SQL statement \"$SQL\"...\n";
  85 
  86   if (!open TEXTFILE, ">$TextFile") {
  87     warn "Warning: Abandoning $TextFile generation: Couldn't open it: $! \n";
  88     next TEXTFILE;
  89   }
  90 
  91   if (DBSQLToTextFile($DBHandle, $SQL, \*TEXTFILE, $OutDelim, $OutQuote, $ExportDataLabels, $ExportLOBs, $ReplaceNullStr)) {
  92     warn "Warning: Abandoning $TextFile generation...\n";
  93     next TEXTFILE;
  94   }
  95   close TEXTFILE;
  96 }
  97 print "\nDisconnecting from  $DBDriver:database=$DBName...\n";
  98 DBDisconnect($DBHandle);
  99 
 100 print "$ScriptName:Done...\n\n";
 101 
 102 $EndTime = new Benchmark;
 103 $TotalTime = timediff ($EndTime, $StartTime);
 104 print "Total time: ", timestr($TotalTime), "\n";
 105 
 106 ###############################################################################
 107 
 108 # Collect input parameters information...
 109 sub RetrieveDBInfo {
 110   my($FileExt, $UserFileName);
 111 
 112   # Setup out file ext...
 113   $FileExt = ($Options{outdelim} =~ /^tab$/i) ? "tsv" : "csv";
 114 
 115   # Get user specified information...
 116   if ($Options{root} && (@ARGV == 1)) {
 117     my($RootFileDir, $RootFileName, $RootFileExt) = ParseFileName($Options{root});
 118     if ($RootFileName && $RootFileExt) {
 119       $UserFileName = $RootFileName;
 120     }
 121     else {
 122       $UserFileName = $Options{root};
 123     }
 124   }
 125 
 126   my($Param, $SQL, $SQLNo, $FileName);
 127   # Go over all the input parameters...
 128   @DBSQLStatements = ();
 129   @DBTextFiles = ();
 130   $SQLNo = 0;
 131   PARAM: for $Param (@ARGV) {
 132     if ($DBMode =~ /^SQLStatement$/i) {
 133       $SQLNo++;
 134       $SQL = $Param;
 135       $FileName = ($Options{root} && (@ARGV == 1)) ? $UserFileName : ("SQLStatement" . "$SQLNo");
 136       $FileName .= ".$FileExt";
 137       if (!$Options{overwrite}) {
 138 	if (-e $FileName) {
 139 	  die "Error: The file $FileName already exists.\n";
 140 	}
 141       }
 142       push @DBSQLStatements, $SQL;
 143       push @DBTextFiles, $FileName;
 144     }
 145     elsif ($DBMode =~ /^SQLFile$/i) {
 146       # Read SQL file...
 147       my($SQLFile) = $Param;
 148       if (! -e $Param) {
 149 	warn "Warning: Ignoring file $SQLFile: It doesn't exist\n";
 150 	next PARAM;
 151       }
 152       if (!open SQLFILE, "$SQLFile" ) {
 153 	warn "Warning: Ignoring file $SQLFile: Couldn't open it: $! \n";
 154 	next PARAM;
 155       }
 156       my($Line, $SQLString);
 157       $SQLString = "";
 158       LINE: while ($Line = GetTextLine(\*SQLFILE)) {
 159            # Ignore comments line...
 160 	if ($Line =~ /^#/ || $Line =~ /^-/) {
 161 	  next LINE;
 162 	}
 163 	$SQLString .= $Line;
 164       }
 165       close SQLFILE;
 166       # Extract select SQL statements...
 167       my($SQLFileDir, $SQLFileName, $SQLFileExt) = ParseFileName($SQLFile);
 168       my(@SQLSplits) = split "\;", $SQLString;
 169       $SQLNo = 0;
 170       SQLSPLIT: for $SQL (@SQLSplits) {
 171 	$SQLNo++;
 172 	$FileName = ($Options{root} && (@ARGV == 1)) ? ("$UserFileName" . "$SQLNo") : ("$SQLFileName" . "SQLStatement" . "$SQLNo");
 173 	$FileName .= ".$FileExt";
 174 	if (!$Options{overwrite}) {
 175 	  if (-e $FileName) {
 176 	    die "Error: The file $FileName already exists.\n";
 177 	  }
 178 	}
 179 	push @DBSQLStatements, $SQL;
 180 	push @DBTextFiles, $FileName;
 181       }
 182     }
 183   }
 184 }
 185 
 186 # Process option values...
 187 sub ProcessOptions {
 188 
 189   $DBDriver = $Options{dbdriver} ? $Options{dbdriver} : (exists $ENV{DBI_DRIVER} ? $ENV{DBI_DRIVER} : "") ;
 190   if ($DBDriver) {
 191     if ($DBDriver =~ /^Oracle$/i) {
 192       $DBDriver = "Oracle";
 193     }
 194     elsif ($DBDriver =~ /^mysql$/i) {
 195       $DBDriver = "mysql";
 196     }
 197     else {
 198       if ($Options{dbdriver}) {
 199 	die "Error: The value specified, $DBDriver, for option \"-d --dbdriver\" is not valid. Allowed values: MySQL or Oracle\n";
 200       }
 201       else {
 202 	die "Error: The value specified, $DBDriver, using environment variable DBI_DRIVER not valid. Allowed values: MySQL or Oracle\n";
 203       }
 204     }
 205   }
 206   else {
 207     $DBDriver = "mysql";
 208   }
 209   $DBHost = $Options{dbhost} ? $Options{dbhost} : "127.0.0.1";
 210   $DBName = $Options{dbname} ? $Options{dbname} : "";
 211   if (!$DBName) {
 212     if ($DBDriver =~ /^mysql$/i) {
 213       $DBName = "mysql";
 214     }
 215     elsif ($DBDriver =~ /^Oracle$/i) {
 216       $DBName = exists $ENV{ORACLE_SID} ? $ENV{ORACLE_SID} : "";
 217     }
 218   }
 219   $DBUser = $Options{dbusername} ? $Options{dbusername} : (exists $ENV{DBI_USER} ? $ENV{DBI_USER} : "") ;
 220   if (!$DBUser) {
 221     die "Error: No database username specified. Use \"--dbusername\" option or environment variable DBI_USER to enter a valid value.\n";
 222   }
 223   $DBPassword = $Options{dbpassword} ? $Options{dbpassword} : (exists $ENV{DBI_PASS} ? $ENV{DBI_PASS} : "") ;
 224   if (!$DBPassword) {
 225     die "Error: No database password specified. Use \"--dbpassword\" option or environment variable DBI_PASS to enter a valid value.\n";
 226   }
 227   $DBMode = $Options{mode};
 228   $ExportLOBs = ($Options{exportlobs} =~ /^yes$/) ? 1 : 0;
 229   $ExportDataLabels = ($Options{exportdatalabels} =~ /^yes$/i) ? 1 : 0;
 230 
 231   $OutDelim = ($Options{outdelim} =~ /^tab$/i ) ? "\t" : (($Options{outdelim} =~ /^semicolon$/i) ? "\;" : "\,");
 232   $OutQuote = ($Options{quote} =~ /^yes$/i) ? 1 : 0;
 233 
 234   $ReplaceNullStr = (defined($Options{replacenullstr}) && length($Options{replacenullstr})) ? $Options{replacenullstr} : "";
 235 }
 236 
 237 # Setup script usage  and retrieve command line arguments specified using various options...
 238 sub SetupScriptUsage {
 239 
 240   # Retrieve all the options...
 241   %Options = ();
 242   $Options{mode} = "SQLStatement";
 243   $Options{exportlobs} = "no";
 244   $Options{exportdatalabels} = "yes";
 245   $Options{outdelim} = "comma";
 246   $Options{quote} = "yes";
 247 
 248   if (!GetOptions(\%Options, "dbdriver|d=s", "dbhost=s", "dbname=s", "dbpassword=s", "dbusername=s", "exportdatalabels=s", "exportlobs=s", "help|h",  "mode|m=s", "outdelim=s", "overwrite|o", "quote|q=s", "root|r=s", "replacenullstr=s", "workingdir|w=s")) {
 249     die "\nTo get a list of valid options and their values, use \"$ScriptName -h\" or\n\"perl -S $ScriptName -h\" command and try again...\n";
 250   }
 251   if ($Options{workingdir}) {
 252     if (! -d $Options{workingdir}) {
 253       die "Error: The value specified, $Options{workingdir}, for option \"-w --workingdir\" is not a directory name.\n";
 254     }
 255     chdir $Options{workingdir} or die "Error: Couldn't chdir $Options{workingdir}: $! \n";
 256   }
 257   if ($Options{exportdatalabels} !~ /^(yes|no)$/i) {
 258     die "Error: The value specified, $Options{exportlobs}, for option \"--exportdatalabels\" is not valid. Allowed values: yes or no\n";
 259   }
 260   if ($Options{exportlobs} !~ /^(yes|no)$/i) {
 261     die "Error: The value specified, $Options{exportlobs}, for option \"--exportlobs\" is not valid. Allowed values: yes or no\n";
 262   }
 263   if ($Options{mode} !~ /^(SQLStatement|SQLFile)$/i) {
 264     die "Error: The value specified, $Options{mode}, for option \"-m --mode\" is not valid. Allowed values: SQLStatement or SQLFile\n";
 265   }
 266   if ($Options{outdelim} !~ /^(comma|semicolon|tab)$/i) {
 267     die "Error: The value specified, $Options{outdelim}, for option \"--outdelim\" is not valid. Allowed values: comma, tab, or semicolon\n";
 268   }
 269   if ($Options{quote} !~ /^(yes|no)$/i) {
 270     die "Error: The value specified, $Options{quote}, for option \"-q --quote\" is not valid. Allowed values: yes or no\n";
 271   }
 272 }
 273