#! /usr/bin/perl
use Math::RandomOrg qw(randnum randbyte);
use DBD::mysql;
# The database schema for the dice table is:
# create table Dice (
# die_id int not null,
# value tinyint not null,
# primary key (die_id)
# )
my $DEBUG = 0;
my $LOW_MARK = 10000;
my $CHUNK_SIZE = 10;
if ($DEBUG) {
print "Check DB size and shift dice...\n";
}
my $dbh = DBI->connect("DBI:mysql:bg", "bg", "");
$dbh->do("LOCK TABLES Dice WRITE") || die "LOCK TABLES failed";
my $stmt = $dbh->prepare("SELECT MIN(die_id), MAX(die_id) FROM Dice");
$stmt->execute || die "Query failed: $stmt->errstr";
my ($min_die, $max_die) = $stmt->fetchrow_array;
my $entries = $max_die - $min_die;
# Shift the dice down, but only if there is room to prevent us from
# stomping on ourselves.
if ($min_die > $entries) {
$dbh->do("UPDATE Dice SET die_id=die_id-$min_die+1") || die "Shift Dice Failed";
}
$dbh->do("UNLOCK TABLES") || die "Unlock failed";
if ($entries > $LOW_MARK) {
if ($DEBUG) {
print "Table has $entries already... do nothing\n";
exit;
}
}
if ($DEBUG) {
print "Get dice from random.org...\n";
}
my $x = randbyte(16384) || die "randbyte failed\n";
my @dice = ();
foreach my $c (split //,$x) {
my $val = ord($c);
my $mix = int(rand 256);
my $byte = $val ^ $mix;
if ($byte > 252) {
next;
}
my $d1 = 1 + $byte % 6;
my $d2 = 1 + ($byte % 36 - $d1 + 1) / 6;
push @dice, "$d1$d2";
}
if ($DEBUG) {
my $numdice = $#dice + 1;
print "Got $numdice dice...\n";
}
while (@dice)
{
my @chunk = ();
my $i = 0;
while (@dice && $i < $CHUNK_SIZE) {
my $die = shift @dice;
push @chunk, $die;
$i++;
}
$dbh->do("LOCK TABLES Dice WRITE") || die "LOCK TABLES failed";
$stmt = $dbh->prepare("SELECT MAX(die_id) FROM Dice");
$stmt->execute || die "Query failed: $stmt->errstr";
(my $max_id) = $stmt->fetchrow_array;
my @VALUES = ();
foreach my $val (@chunk) {
$max_id++;
push @VALUES, "($max_id, $val)";
}
my $sql = "INSERT Dice (die_id, value) VALUES " . join(',', @VALUES);
$dbh->do($sql) || die "INSERT DICE failed";
$dbh->do("UNLOCK TABLES") || die "UNLOCK TABLES failed";
}