diff --git a/scripts/db-convert-0.1-to-0.2.plx b/scripts/db-convert-0.1-to-0.2.plx new file mode 100644 index 0000000..79d673c --- /dev/null +++ b/scripts/db-convert-0.1-to-0.2.plx @@ -0,0 +1,111 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use DBI; +use Encode qw(encode decode); + +my($OLD_SUPPORTERS_SQLITE_DB_FILE, $NEW_SUPPORTERS_SQLITE_DB_FILE) = @ARGV; + +my $dbhOld = DBI->connect("dbi:SQLite:dbname=$OLD_SUPPORTERS_SQLITE_DB_FILE", "", "", + { RaiseError => 1, sqlite_unicode => 1 }) + or die $DBI::errstr; + +my $dbhNew = DBI->connect("dbi:SQLite:dbname=$NEW_SUPPORTERS_SQLITE_DB_FILE", "", "", + { RaiseError => 1, sqlite_unicode => 1 }) + or die $DBI::errstr; + +# Insert t-shirt types and sizes + +my $sthNew = $dbhNew->prepare("INSERT INTO request_type(type) values(?)"); + +$sthNew->execute("t-shirt-0"); +my $tShirt0RequestTypeId = $dbhNew->last_insert_id("","","",""); +$sthNew->execute("t-shirt-1"); +my $tShirt1RequestTypeId = $dbhNew->last_insert_id("","","",""); +$sthNew->finish(); + +my %tShirt0SizeRequestConfigurationIds; + +$sthNew = $dbhNew->prepare("INSERT INTO request_configuration" . + "(request_type_id, description) values(?, ?)"); +foreach my $requestTypeId (qw/$tShirt1RequestTypeId $tShirt0RequestTypeId/) { + foreach my $size (qw/LadiesS LadiesM LadiesL LadiesXL MenS MenM MenXL Men2XL/) { + $sthNew->execute($requestTypeId, $size); + $tShirt0SizeRequestConfigurationIds{$size} = $dbhNew->last_insert_id("","","",""); + } +} +$sthNew->execute("join-announce-email-list"); +my $announceEmailListRequestTypeId = $dbhNew->last_insert_id("","","",""); +$sthNew->finish(); + +# Only one email Adress type so far +$sthNew = $dbhNew->prepare("INSERT INTO address_type(name) values('paypal_payer')"); +my $paypalPayerEmailAddresTypeId = $dbhNew->last_insert_id("","","",""); +$sthNew->finish(); + +# Legacy fulfillment confirmation +$sthNew = $dbhNew->prepare("INSERT INTO fulfillment(date, who, how)" . + "values(date('now'), 'bkuhn', 'legacy import of old database; exact details of this fulfillment are unknown')"); +my $fulfillmentId = $dbhNew->last_insert_id("","","",""); +$sthNew->finish(); + +my $sthNewInsertSupporter = $dbhNew->prepare('INSERT INTO supporter(' . + 'ledger_entity_id, display_name, public_ack) values (?, ?, ?)'); +my $sthInsertEmailAddress = $dbhNew->prepare('INSERT INTO email_address(supporter_id, email_address, email_type_id, date_encountered)' . + "values(?, ?, $paypalPayerEmailAddresTypeId, date('now'))"); + +my $sthLinkSupporterToEmail = $dbhNew->prepare('INSERT INTO supporter_email_address_mapping(supporter_id, email_address_id, preferred)' . + "values(?, ?, $paypalPayerEmailAddresTypeId, date('now'), 1)"); + +my $sthLinkSupporterToPostal = $dbhNew->prepare('INSERT INTO supporter_postal_address_mapping(supporter_id, postal_address_id, preferred)' . + "values(?, ?, $paypalPayerEmailAddresTypeId, date('now'), 1)"); + +my $sthInsertRequest = $dbhNew->prepare('INSERT INTO request' . + '(supporter_id, request_type_id, request_configuration_id, date_requested, fulfillment_id, notes) ' . + "values(?, ?, ?, date('now'), ?," . + '"import of old database; exact date of this request is unknown")'); + +my $sthPostalAddress = 'INSERT INTO postal_address(formatted_address, date_encountered)' . + "VALUES(? , date('now'))"; + +my $sthOld = $dbhOld->prepare('SELECT * from supporters order by id;'); +$sthOld->execute(); +while (my $row = $sthOld->fetchrow_hashref) { + $sthNewInsertSupporter->execute($row->{ledger_entity_id}, $row->{display_name}, + $row->{public_ack}); + my $supporterId = $dbhNew->last_insert_id("","","",""); + die("Database conversion failed on id matching: $row->{ledger_entity_id} had ID $row->{id} now has $supporterId") + unless ($row->{id} == $supporterId); + if ($row->{want_gift}) { + die "DB Convert Fail: Unknown shirt size of $row->{shirt_size} when someone wanted a shirt" + unless defined $tShirt0SizeRequestConfigurationIds{$row->{shirt_size}}; + $sthInsertRequest->execute($supporterId, $tShirt0RequestTypeId, + $tShirt0SizeRequestConfigurationIds{$row->{shirt_size}}, + ($row->{gift_sent} ? $fulfillmentId : undef)); + } + if ($row->{join_list}) { + $sthInsertRequest->execute($supporterId, $announceEmailListRequestTypeId, undef, + ($row->{on_announce_mailman_list} ? $fulfillmentId : undef)); + } + $sthInsertEmailAddress->execute($supporterId, $row->{paypal_payer}); + my $emailId = $dbhNew->last_insert_id("","","",""); + $sthLinkSupporterToEmail->execute($supporterId, $emailId); + $sthPostalAddress->execute($supporterId, $row->{formatted_address}); + my $postalId = $dbhNew->last_insert_id("","","",""); + $sthLinkSupporterToPostal->($supporterId, $postalId); +} +foreach my $sth (qw/$sthOld $sthOld $sthNewInsertSupporter $sthInsertEmailAddress + $sthLinkSupporterToEmail $sthInsertRequest $sthPostalAddress $sthLinkSupporterToPostal/) { + $sth->finish(); +} +foreach my $dbh (qw/$dbhNew $dbhOld/) { + $dbhNew->disconnect(); +} + +############################################################################### +# +# Local variables: +# compile-command: "perl -c db-convert-0.1-to-0.2.plx" +# End: diff --git a/sql/supporters-schema.sql b/sql/supporters-schema.sql index fcc8e20..3dedac0 100644 --- a/sql/supporters-schema.sql +++ b/sql/supporters-schema.sql @@ -1,16 +1,79 @@ -DROP TABLE IF EXISTS "supporters"; +-- Conservancy Supporter Database, Version 0.2 -CREATE TABLE "supporters" ( +DROP TABLE IF EXISTS "supporter"; + +CREATE TABLE "supporter" ( "id" integer NOT NULL PRIMARY KEY, - "paypal_payer" varchar(300) NOT NULL UNIQUE, "ledger_entity_id" varchar(300) NOT NULL UNIQUE, + "postal_address_id " integer, + "email_address_id " integer, "display_name" varchar(300), "public_ack" bool NOT NULL, - "want_gift" bool NOT NULL, - "join_list" bool, - "shirt_size" varchar(10), - "gift_sent" integer NOT NULL DEFAULT 0, - "on_announce_mailman_list" bool NOT NULL DEFAULT 0, - "formatted_address" varchar(5000) ); +CREATE TABLE "request" ( + "id" integer NOT NULL PRIMARY KEY, + "supporter_id" integer NOT NULL, + "request_type_id" integer NOT NULL, + "request_configuration_id" integer, + "date_requested" date NOT NULL, + "fulfillment_id" integer, + "notes" TEXT + ); + +CREATE TABLE "request_configuration" ( + "id" integer NOT NULL PRIMARY KEY, + "request_type_id" integer NOT NULL, + "description" varchar(100) NOT NULL, + ); + +CREATE TABLE "fulfillment" ( + "id" integer NOT NULL PRIMARY KEY, + "date" TEXT NOT NULL, + "who" varchar(300) NOT NULL, + "how" TEXT, +); + +CREATE TABLE "request_type" ( + "id" integer NOT NULL PRIMARY KEY, + "type" varchar(100) NOT NULL, + ); + +CREATE TABLE "email_address" ( + "id" integer NOT NULL PRIMARY KEY, + "email_address" varchar(300) NOT NULL UNIQUE, + "type_id" integer, + "date_encountered" date NOT NULL, + ); + +CREATE TABLE "supporter_email_address_mapping" ( + "supporter_id" integer NOT NULL, + "email_address_id integer NOT NULL, + "preferred" bool, + PRIMARY KEY(supporter_id, email_address_id) + ); + +CREATE UNIQUE INDEX supporter2email_single_prefferred_per_supporter + ON supporter2email(supporter_id, preferred); + +CREATE TABLE "address_type" ( + "id" integer NOT NULL PRIMARY KEY, + "name" varchar(50) NOT NULL UNIQUE, + ); + +CREATE TABLE "postal_address" ( + "id" integer NOT NULL PRIMARY KEY, + "formatted_address" varchar(5000), + "type_id" INTEGER NOT NULL, + "date_encountered" date NOT NULL, + ); + +CREATE TABLE "supporter_postal_address_mapping" ( + "postal_address_id integer NOT NULL, + "preferred" bool, + PRIMARY KEY(supporter_id, email_address_id) + ); + +CREATE UNIQUE INDEX supporter2postal_single_prefferred_per_supporter + ON supporter2email(supporter_id, preferred); +