commit 1b5f4955158a707b25ddd4b4bfb1d76f27c9d959
parent febc336de199f02a52a2a4f542957ebdba21c3aa
Author: Kyle Milz <kyle@getaddrinfo.net>
Date: Thu, 2 Apr 2015 20:48:30 -0600
convert.pl: use once script to convert db schema
Diffstat:
A | convert.pl | | | 192 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 192 insertions(+), 0 deletions(-)
diff --git a/convert.pl b/convert.pl
@@ -0,0 +1,192 @@
+
+use strict;
+use warnings;
+
+use Config::Grammar;
+use Getopt::Std;
+use DBI;
+
+
+my %args;
+getopts("d:", \%args);
+
+$| = 1;
+
+print "info: unlinking old converted db file\n";
+unlink "pricechart_converted.db";
+
+my $cfg = get_config();
+
+my $old_dbh = DBI->connect(
+ "dbi:SQLite:dbname=$args{d}",
+ "",
+ "",
+ {RaiseError => 1}
+) or die $DBI::errstr;
+
+
+my $new_dbh = DBI->connect(
+ "dbi:SQLite:dbname=pricechart_converted.db",
+ "",
+ "",
+ {RaiseError => 1}
+) or die $DBI::errstr;
+
+$new_dbh->do(qq{
+ create table if not exists products(
+ manufacturer text not null,
+ part_num text not null,
+ retailer text not null,
+ type text,
+ first_seen int,
+ last_seen int,
+ last_scraped int,
+ primary key(manufacturer, part_num))
+}) or die $DBI::errstr;
+
+$new_dbh->do(qq{
+ create table if not exists descriptions(
+ manufacturer text not null,
+ part_num text not null,
+ retailer text not null,
+ description text not null,
+ date int not null,
+ primary key(manufacturer, part_num, retailer, description),
+ foreign key(manufacturer, part_num) references
+ products(manufacturer, part_num))
+}) or die $DBI::errstr;
+
+$new_dbh->do(qq{
+ create table if not exists retailers(
+ name text not null primary key,
+ color text not null,
+ url text not null)
+}) or die $DBI::errstr;
+
+$new_dbh->do(qq{
+ create table if not exists prices(
+ date int not null,
+ manufacturer text not null,
+ part_num text not null,
+ retailer text not null,
+ price int not null,
+ duration int,
+ primary key(date, part_num, retailer, price),
+ foreign key(manufacturer, part_num) references products(manufacturer, part_num),
+ foreign key(retailer) references retailers(name))
+}) or die $DBI::errstr;
+
+my $sql = "insert into products(manufacturer, part_num, retailer, type, first_seen,
+ last_seen, last_scraped) values (?, ?, ?, ?, ?, ?, ?)";
+my $product_sth = $new_dbh->prepare($sql);
+
+$sql = "insert or replace into descriptions(manufacturer, part_num, retailer, ".
+ "description, date) values (?, ?, ?, ?, ?)";
+my $description_sth = $new_dbh->prepare($sql);
+
+$sql = "insert or replace into retailers(name, color, url) values (?, ?, ?)";
+my $retailer_sth = $new_dbh->prepare($sql);
+
+$sql = "insert into prices(date, manufacturer, part_num, retailer, price, " .
+ "duration) values (?, ?, ?, ?, ?, ?)";
+my $price_sth = $new_dbh->prepare($sql);
+
+my $type_map = {
+ "televisions" => "Television",
+ "laptops" => "Laptop",
+ "hard drives" => "Hard Drive"
+};
+
+print "info: processing products ";
+$sql = "select * from products";
+my $products = $old_dbh->selectall_hashref($sql, "part_num");
+while (my ($part_num, $part_hash) = each %$products) {
+ my $manuf = $part_hash->{manufacturer};
+ my $first_seen = $part_hash->{first_seen};
+ spin();
+ # print "$manuf $part_num\n";
+
+ $product_sth->execute($manuf, $part_num,
+ "Memory Express", $type_map->{$part_hash->{type}},
+ $first_seen, $part_hash->{last_seen}, $part_hash->{last_scraped});
+
+ $description_sth->execute($manuf, $part_num, "Memory Express",
+ $part_hash->{description}, $first_seen);
+}
+$description_sth->finish();
+$product_sth->finish();
+print "\b" . scalar(keys %$products) . " done\n";
+
+print "info: processing prices ";
+$sql = "select * from prices";
+my $prices = $old_dbh->selectall_arrayref($sql);
+for (@$prices) {
+ my ($date, $part_num, $retailer, $price, $color, $duration, $title) = @$_;
+ spin();
+
+ $sql = "select manufacturer from products where part_num = ?";
+ my ($manuf) = $old_dbh->selectrow_array($sql, undef, $part_num);
+
+ $retailer_sth->execute($retailer, $cfg->{retailers}{$retailer}{color},
+ $cfg->{retailers}{$retailer}{url});
+
+ $price_sth->execute($date, $manuf, $part_num, $retailer,
+ $price, $duration);
+
+ $description_sth->execute($manuf, $part_num, $retailer,
+ $title, $date);
+}
+print "\b" . scalar @$prices . " done\n";
+
+my $state = 0;
+sub spin
+{
+ my @spin_states = ("-", "\\", "|", "/");
+
+ print "\b";
+ print $spin_states[++$state % 4];
+}
+
+sub get_config
+{
+ my $parser = Config::Grammar->new({
+ _sections => ["general", "http", "retailers"],
+ general => {
+ _vars => [
+ "agent",
+ "email",
+ "smtp",
+ # XXX: add simple regex validation here
+ "addrs"
+ ],
+ },
+ http => {
+ _vars => [
+ "socket",
+ "uid",
+ "gid",
+ "chroot",
+ "db_dir",
+ "htdocs",
+ "logs",
+ ],
+ },
+ retailers => {
+ _sections => ["/[A-Za-z ]+/"],
+ "/[A-Za-z ]+/" => {
+ _vars => [
+ "url",
+ "reg_tag",
+ "sale_tag",
+ "color",
+ "title"
+ ]
+ }
+ }
+ });
+
+ my $cfg_file = "/etc/pricechart.cfg";
+ my $cfg = $parser->parse($cfg_file) or die "error: $parser->{err}\n";
+
+ return $cfg;
+}