Raw content of ImportUtils
use strict;
use warnings;
package ImportUtils;
use Exporter;
our @ISA = ('Exporter');
our @EXPORT_OK = qw(dumpSQL debug create_and_load load);
our $TMP_DIR = "/ecs4/scratch4/yuan/tmp";
our $TMP_FILE = 'tabledump.txt';
# successive dumping and loading of tables is typical for this process
# dump does effectively a select into outfile without server file system access
sub dumpSQL {
my $db = shift;
my $sql = shift;
local *FH;
my $counter = 0;
open( FH, ">$TMP_DIR/$TMP_FILE" )
or die( "Cannot open $TMP_DIR/$TMP_FILE: $!" );
my $sth = $db->prepare( $sql);
$sth->{mysql_use_result} = 1;
$sth->execute();
my $first;
while ( my $aref = $sth->fetchrow_arrayref() ) {
my @a = map {defined($_) ? $_ : '\N'} @$aref;
print FH join("\t", @a), "\n";
}
close FH;
$sth->finish();
}
# load imports a table, optionally not all columns
# if table doesnt exist, create a varchar(255) for each column
sub load {
my $db = shift;
my $tablename = shift;
my @colnames = @_;
my $cols = join( ",", @colnames );
my $table_file = "$TMP_DIR/$tablename\_$$\.txt";
rename("$TMP_DIR/$TMP_FILE", $table_file);
# my $host = $db->host();
# my $user = $db->user();
# my $pass = $db->pass();
# my $port = $db->port();
# my $dbname = $db->dbname();
# my $call = "mysqlimport -c $cols -h $host -u $user " .
# "-p$pass -P$port $dbname $table_file";
# system($call);
# unlink("$TMP_DIR/$tablename.txt");
##### Alternative way of doing same thing
my $sql;
#need to find out if possible use the LOCAL option
my $local_option = 'LOCAL'; #by default, use the LOCAL option
if( `hostname` =~ /^bc/ ){ # No LOCAL on bcs nodes
$local_option = '';
}
elsif( ! -e $table_file ){ # File is not on local filesystem
$local_option = '';
}
# my $host = `hostname`;
# chop $host;
# $host =~ /(ecs\d+)/; #get the machine, only use LOCAL in ecs machines (ecs2, ecs4)
# my $local_option = '';
# #the script is running in ecs machine, let's find out if the file is in the same machine, too
# if ($1){
# if ($table_file =~ /$1/){
# $local_option = 'LOCAL';
# }
# }
if ( @colnames ) {
$sql = qq{
LOAD DATA $local_option INFILE "$table_file"
INTO TABLE $tablename( $cols )
};
} else {
$sql = qq{
LOAD DATA $local_option INFILE "$table_file"
INTO TABLE $tablename
};
}
$db->do( $sql );
unlink( "$table_file" );
}
#
# creates a table with specified columns and loads data that was dumped
# to a tmp file into the table.
#
# by default all columns are VARCHAR(255), but an 'i' may be added after the
# column name to make it an INT. Additionally a '*' means add an index to
# the column.
#
# e.g. create_and_load('mytable', 'col0', 'col1 *', 'col2 i', 'col3 i*');
#
sub create_and_load {
my $db = shift;
my $tablename = shift;
my @cols = @_;
my $sql = "CREATE TABLE $tablename ( ";
my @col_defs;
my @idx_defs;
my @col_names;
foreach my $col (@cols) {
my ($name, $type) = split(/\s+/,$col);
push @col_names, $name;
if(defined($type) && $type =~ /i/) {
push @col_defs, "$name INT";
}
elsif (defined($type) && $type =~ /f/) {
push @col_defs, "$name FLOAT";
}
elsif (defined($type) && $type =~ /l/) {
push @col_defs, "$name TEXT";
}
else {
push @col_defs, "$name VARCHAR(255)";
}
if(defined($type) && $type =~ /\*/) {
push @idx_defs, "KEY ${name}_idx($name)";
}
}
my $create_cols = join( ",\n", @col_defs, @idx_defs);
$sql .= $create_cols.")";
$sql .= " MAX_ROWS = 100000000" if ($tablename =~ /^tmp.*gty$/); #need to make bigger this table for human
$db->do( $sql );
load( $db, $tablename, @col_names );
}
sub debug {
print STDERR @_, "\n";
}
1;