#!/usr/bin/perl -w # # usage: ./db-idempotent-populate # creates or updates OCEAN-Oceanname.db # from master-master.txt # This is part of ypp-sc-tools, a set of third-party tools for assisting # players of Yohoho Puzzle Pirates. # # Copyright (C) 2009 Ian Jackson # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Yohoho and Puzzle Pirates are probably trademarks of Three Rings and # are used without permission. This program is not endorsed or # sponsored by Three Rings. use strict (qw(vars)); use DBI; use Commods; @ARGV==1 or die; my ($oceanname) = @ARGV; my $dbfn= "OCEAN-$oceanname.db"; our $dbh; sub dbdoall ($) { foreach my $cmd (split /\;/, $_[0]) { $dbh->do("$cmd;") if $cmd =~ m/\S/; } } #---------- setup ---------- parse_masters_ocean($oceanname); our $ocean= $oceans{$oceanname}; $dbh= DBI->connect("dbi:SQLite:$dbfn",'','', { AutoCommit=>0, RaiseError=>1, ShowErrorStatement=>1, unicode=>1 }) or die "$dbfn $DBI::errstr ?"; #---------- schema ---------- foreach my $bs (qw(buy sell)) { dbdoall(<commit; #---------- commodity list ---------- { my $sth= $dbh->prepare(<<'END') INSERT OR IGNORE INTO commods (commodname) VALUES (?); END ; foreach my $commod (sort keys %commods) { $sth->execute($commod); } $dbh->commit; } #---------- island list ---------- { my $sth= $dbh->prepare(<<'END') INSERT OR IGNORE INTO islands (islandname, archipelago) VALUES (?, ?); END ; foreach my $archname (sort keys %$ocean) { my $arch= $ocean->{$archname}; foreach my $islandname (sort keys %$arch) { $sth->execute($islandname, $archname); } } $dbh->commit; } #---------- routes ---------- { foreach my $islandname (sort keys %{ $route_mysteries{$oceanname} }) { warn "$route_mysteries{$oceanname}{$islandname} routes". " for unknown island $islandname\n"; } dbdoall(<prepare(<<'END') INSERT INTO newdists VALUES ((SELECT islandid FROM islands WHERE islandname == ?), (SELECT islandid FROM islands WHERE islandname == ?), ?); END ; my $allroutes= $routes{$oceanname}; foreach my $an (keys %$allroutes) { my $routes= $allroutes->{$an}; foreach my $bn (keys %$routes) { $sth->execute($an, $bn, $routes->{$bn}); } } my $stmt_updatemain= $dbh->prepare(<<'END') UPDATE dists SET dist = ( SELECT min(dist) FROM newdists WHERE dists.aiid == newdists.aiid AND dists.biid == newdists.biid AND NOT dists.dist <= newdists.dist ); END my $stmt_removeredund= $dbh->prepare(<<'END') DELETE FROM newdists WHERE dist > ( SELECT dists.dist WHERE dists.aiid == newdists.aiid AND dists.aiid == newdists.aiid ); END ; my $stmt_gennew= $dbh->prepare(<<'END') INSERT INTO newdists ( SELECT src.aiid, dst.biid, min(src.dist + dst.dist) FROM dists AS src, dists AS dst ON src.biid == dst.aiid GROUP BY src.aiid, dst.biid ); END ; for (;;) { $ar= $dbh->selectall_arrayref("select ia.islandname, ib.islandname,newdists.dist from newdists, islands as ia on newdists.aiid = ia.islandid, islands as ib on newdists.biid = ib.islandid;"); print Dumper($ar); my $affected= $stmt_updatemain->execute(); last unless $affected; $stmt_ } #use Data::Dumper; #print Dumper(\%routes); __DATA__