|
|
|
#!/usr/bin/env perl
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
|
|
|
|
use Getopt::Long;
|
|
|
|
use lib 'lib';
|
|
|
|
use Params::Util qw( _HASH );
|
|
|
|
use JSON::XS ();
|
|
|
|
use JSON::Syck;
|
|
|
|
#use WWW::OpenResty::Simple;
|
|
|
|
use Data::Dumper;
|
|
|
|
use Data::Structure::Util qw(_utf8_on _utf8_off);
|
|
|
|
use DBI;
|
|
|
|
|
|
|
|
sub usage {
|
|
|
|
my $progname;
|
|
|
|
if ($0 =~ m{[^/\\]+$}) {
|
|
|
|
$progname = $&;
|
|
|
|
}
|
|
|
|
return <<_EOC_;
|
|
|
|
Usage: $progname [options] <json_file>
|
|
|
|
Options:
|
|
|
|
--user <user> OpenResty user (i.e. agentzh.Admin)
|
|
|
|
--password <s> OpenResty password for the user specified
|
|
|
|
--model <model> OpenResty model name being imported
|
|
|
|
--server <host> OpenResty server hostname
|
|
|
|
--step <num> Size of the bulk insertion group
|
|
|
|
--retries <num> Number of automatic retries when failures occur
|
|
|
|
--no-id Skipped the id field in the records being imported
|
|
|
|
--skip N Skipped the first N rows in the input file (default 0)
|
|
|
|
--add-id N Add ID started from N (default 1)
|
|
|
|
--update-col <col> Update records according to the column given
|
|
|
|
--ignore-dup-error Ignore dupliciate errors
|
|
|
|
_EOC_
|
|
|
|
}
|
|
|
|
|
|
|
|
my $server = 'api.openresty.org';
|
|
|
|
my $step = 20;
|
|
|
|
my $skip = 0;
|
|
|
|
my $add_id = 1;
|
|
|
|
my $update_col;
|
|
|
|
GetOptions(
|
|
|
|
'help|h' => \(my $help),
|
|
|
|
'user|u=s' => \(my $user),
|
|
|
|
'model=s' => \(my $model),
|
|
|
|
'server=s' => \$server,
|
|
|
|
'password=s' => \(my $password),
|
|
|
|
'step=i' => \$step,
|
|
|
|
'reset' => \(my $reset),
|
|
|
|
'retries=i' => \(my $retries),
|
|
|
|
'no-id' => \(my $no_id),
|
|
|
|
'skip=i' => \$skip,
|
|
|
|
'add-id=i' => \$add_id,
|
|
|
|
'ignore-dup-error' => \(my $ignore_dup_error),
|
|
|
|
'update-col=s' => \$update_col,
|
|
|
|
'port=s' => \(my $port),
|
|
|
|
) or die usage();
|
|
|
|
|
|
|
|
if ($help) { print usage() }
|
|
|
|
|
|
|
|
$user or die "No --user given.\n";
|
|
|
|
$model or die "No --model given.\n";
|
|
|
|
|
|
|
|
my $json_xs = JSON::XS->new->utf8->allow_nonref;
|
|
|
|
|
|
|
|
my $database = 'test';
|
|
|
|
|
|
|
|
$port ||= 3306;
|
|
|
|
|
|
|
|
my $dsn = "DBI:mysql:database=$database;host=$server;port=$port;mysql_server_prepare=1";
|
|
|
|
my $dbh = DBI->connect($dsn, $user, $password, { RaiseError => 1, AutoCommit => 0 });
|
|
|
|
|
|
|
|
if ($reset) {
|
|
|
|
$dbh->do("truncate $model");
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($update_col) { $step = 1 }
|
|
|
|
|
|
|
|
my @rows;
|
|
|
|
my $inserted = 0;
|
|
|
|
local $| = 1;
|
|
|
|
|
|
|
|
my ($sth);
|
|
|
|
|
|
|
|
my @cols;
|
|
|
|
while (<>) {
|
|
|
|
#select(undef, undef, undef, 0.1);
|
|
|
|
#warn "count: ", scalar(@elems), "\n";
|
|
|
|
next if $. <= $skip;
|
|
|
|
my $row = $json_xs->decode($_);
|
|
|
|
#my $row = JSON::Syck::Load($_);
|
|
|
|
|
|
|
|
|
|
|
|
if (!defined $row->{id}) {
|
|
|
|
#warn "ADDing id...\n";
|
|
|
|
$row->{id} = $add_id++;
|
|
|
|
}
|
|
|
|
if ($no_id) {
|
|
|
|
delete $row->{id};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!defined $sth) {
|
|
|
|
@cols = reverse sort keys %$row;
|
|
|
|
my $cols = join ',', @cols;
|
|
|
|
my @holders = map { '?' } @cols;
|
|
|
|
my $holders = join ',', @holders;
|
|
|
|
$sth = $dbh->prepare("insert into $model ($cols) values ($holders)");
|
|
|
|
}
|
|
|
|
|
|
|
|
my @vals;
|
|
|
|
for my $col (@cols) {
|
|
|
|
push @vals, $row->{$col};
|
|
|
|
}
|
|
|
|
|
|
|
|
$sth->execute(@vals);
|
|
|
|
$inserted++;
|
|
|
|
|
|
|
|
if ($inserted % $step == 0) {
|
|
|
|
print STDERR "\r", ($update_col ? "Updated" : "Inserted"), " rows: $inserted (row $.)";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
print STDERR "\n$inserted row(s) inserted.\n";
|
|
|
|
|
|
|
|
$dbh->disconnect();
|
|
|
|
|
|
|
|
warn "\nFor tatal $inserted records inserted.\n";
|
|
|
|
#print encode('UTF-8', YAML::Syck::Dump(\@rows));
|
|
|
|
|