#!/usr/bin/env perl ################################################################################ # WeBWorK mod_perl (c) 1995-2002 WeBWorK Team, Univeristy of Rochester # $Id: hash2sql,v 1.2 2003-06-19 19:23:50 sh002i Exp $ ################################################################################ =head1 NAME hash2sql - copies data from a course using a hash-based database (without global tables) to a course using an sql-based database (with global tables). =cut use strict; use warnings; use FindBin; use lib "$FindBin::Bin/../lib"; use WeBWorK::CourseEnvironment; use WeBWorK::DB; use WeBWorK::DB::Utils qw(findDefaults); sub main(@) { my ($hashCourse, $sqlCourse) = @_; unless ($ENV{WEBWORK_ROOT}) { die "WEBWORK_ROOT not found in environment.\n"; } unless ($hashCourse and $sqlCourse) { die "usage: $0 hashCourse sqlCourse\n"; } my $hashCE = WeBWorK::CourseEnvironment->new($ENV{WEBWORK_ROOT}, "", "", $hashCourse); my $hashDB = WeBWorK::DB->new($hashCE); my $sqlCE = WeBWorK::CourseEnvironment->new($ENV{WEBWORK_ROOT}, "", "", $sqlCourse); my $sqlDB = WeBWorK::DB->new($sqlCE); # get names of global record classes my $globalSetClass = $sqlCE->{dbLayout}->{set}->{record}; my $globalProblemClass = $sqlCE->{dbLayout}->{problem}->{record}; # get non-key, global field names my @setFields = getNonKeyFields($sqlCE->{dbLayout}->{set}->{record}); my @problemFields = getNonKeyFields($sqlCE->{dbLayout}->{problem}->{record}); # hash to store all sets my %allSets; # populate user, password, permission, and key tables print "\n---------- adding users: ----------\n\n"; foreach my $userID ($hashDB->listUsers()) { print "adding user $userID:"; $sqlDB->addUser($hashDB->getUser($userID)); my $Password = $hashDB->getPassword($userID); if ($Password) { print " +password"; $sqlDB->addPassword($Password); } else { print " -password"; } my $PermissionLevel = $hashDB->getPermissionLevel($userID); if ($PermissionLevel) { print " +permissionLevel"; $sqlDB->addPermissionLevel($PermissionLevel); } else { print " -permissionLevel"; } my $Key = $hashDB->getKey($userID); if ($Key) { print " +key"; $sqlDB->addKey($Key) if $Key; } else { print " -key"; } print "\n"; # also get the names of all sets foreach my $setID ($hashDB->listUserSets($userID)) { $allSets{$setID}++; } } print "\n---------- found these sets: ----------\n\n"; print join(" ", keys %allSets), "\n"; print "\n---------- determining set defaults: ----------\n\n"; foreach my $setID (keys %allSets) { print "processing set $setID.\n"; # get a consensus view for each set my @setUserIDs = $hashDB->listSetUsers($setID); my @UserSets = map { $hashDB->getUserSet($_, $setID) } @setUserIDs; my $GlobalSet = findDefaults($globalSetClass, @UserSets); print "adding global set record.\n"; $sqlDB->addGlobalSet($GlobalSet); # remove default values from each user set # and store into sql db. foreach my $UserSet (@UserSets) { foreach my $field (@setFields) { if ($UserSet->$field() eq $GlobalSet->$field()) { $UserSet->$field(undef); } } print "adding user set for user ", $UserSet->user_id, ".\n"; $sqlDB->addUserSet($UserSet); } # get all problems in this set my %allProblems; foreach my $userID ($hashDB->listSetUsers($setID)) { foreach my $problemID ($hashDB->listUserProblems($userID, $setID)) { $allProblems{$problemID}++; } } print "\n----- found these problems in set $setID: ----\n\n"; print join(" ", keys %allProblems), "\n"; print "\n----- determining defaults for problems in set $setID: -----\n\n"; # get a consensus for each problem in this set foreach my $problemID (keys %allProblems) { print "determining defaults for problem $problemID.\n"; my @problemUserIDs = $hashDB->listProblemUsers($setID, $problemID); my @UserProblems; print "getting user problem for user:"; foreach (@problemUserIDs) { print " $_"; my $UserProblem = $hashDB->getUserProblem($_, $setID, $problemID); unless (defined $UserProblem) { print "(UNDEFINED!)"; next; } push @UserProblems, $UserProblem; } print "\n"; my $GlobalProblem = findDefaults($globalProblemClass, @UserProblems); print "adding global problem record.\n"; $sqlDB->addGlobalProblem($GlobalProblem); # remove defaults from each user problem foreach my $UserProblem (@UserProblems) { foreach my $field (@problemFields) { if ($UserProblem->$field() eq $GlobalProblem->$field()) { $UserProblem->$field(undef); } } print "adding user problem for user ", $UserProblem->user_id, ".\n"; $sqlDB->addUserProblem($UserProblem); } } } } sub getNonKeyFields($) { my ($Record) = @_; my %fields = map { $_ => {} } $Record->FIELDS(); delete $fields{$_} foreach $Record->KEYFIELDS(); return keys %fields; } main(@ARGV);