use 5.14.2; use warnings; use Text::CSV_XS qw( csv ); use DBI; use Socket; use Net::CIDR; my $tbl = "geoip"; my $dbh = DBI->connect ("dbi:Pg:dbname=cidr", undef, undef, { AutoCommit => 0, RaiseError => 1, PrintError => 1, ShowErrorStatement => 1, }); if (grep m/\b $tbl $/ix => $dbh->tables (undef, undef, undef, undef)) { say "Clear table $tbl"; $dbh->do ("truncate table $tbl"); } else { say "Create table $tbl"; $dbh->do (qq; create table $tbl ( netblock cidr not null primary key, type smallint not null, ip_from text not null, ip_to text not null, ip_from_n bigint, ip_to_n bigint, country_code text not null, country_name text not null); ); } my $sth = $dbh->prepare ("insert into $tbl values (?, ?, ?, ?, ?, ?, ?, ?)"); foreach my $file (qw( GeoIPCountryWhois.csv GeoIPv6.csv )) { print "Inserting from $file...\n"; csv (in => $file, out => undef, allow_whitespace => 1, headers => [qw( firstip lastip x1 x2 iso name )], on_in => sub { foreach my $cidr (Net::CIDR::range2cidr ("$_{firstip}-$_{lastip}")) { my @rng = Net::CIDR::cidr2range ($cidr); my ($f, $t) = split m/\s*-\s*/ => $rng[0]; my ($type, $F, $T) = $f =~ m/:/ ? (6, undef, undef) : (4, map { unpack "L>", inet_aton $_ } $f, $t); $sth->execute ($cidr, $type, $f, $t, $F, $T, $_{iso}, $_{name}); } }, ); } $dbh->commit;