| 1 | ################################################################################ |
1 | ################################################################################ |
| 2 | # WeBWorK Online Homework Delivery System |
2 | # WeBWorK Online Homework Delivery System |
| 3 | # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/ |
3 | # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/ |
| 4 | # $CVSHeader: webwork-modperl/lib/WeBWorK/DB.pm,v 1.50 2004/06/16 17:13:28 sh002i Exp $ |
4 | # $CVSHeader: webwork-modperl/lib/WeBWorK/DB.pm,v 1.51 2004/06/16 18:26:59 toenail Exp $ |
| 5 | # |
5 | # |
| 6 | # This program is free software; you can redistribute it and/or modify it under |
6 | # This program is free software; you can redistribute it and/or modify it under |
| 7 | # the terms of either: (a) the GNU General Public License as published by the |
7 | # the terms of either: (a) the GNU General Public License as published by the |
| 8 | # Free Software Foundation; either version 2, or (at your option) any later |
8 | # Free Software Foundation; either version 2, or (at your option) any later |
| 9 | # version, or (b) the "Artistic License" which comes with this package. |
9 | # version, or (b) the "Artistic License" which comes with this package. |
| … | |
… | |
| 312 | } |
312 | } |
| 313 | } |
313 | } |
| 314 | |
314 | |
| 315 | ##### are all sets assigned to the user with ID globalUserID? ##### |
315 | ##### are all sets assigned to the user with ID globalUserID? ##### |
| 316 | |
316 | |
|
|
317 | # FIXME: this is way too slow! |
| 317 | my @userSetIDs = $self->{set_user}->list(undef, undef); |
318 | #my @userSetIDs = $self->{set_user}->list(undef, undef); |
| 318 | |
319 | |
| 319 | my %userSetStatus; |
320 | # Timing Data |
|
|
321 | # |
|
|
322 | # old method: |
|
|
323 | # TIMING 36119 1 1087502726.923311 (0.139117) mth143: WeBWorK::DB::hashDatabaseOK: about to get orphaned UserSets |
|
|
324 | # TIMING 36119 1 1087502768.074221 (41.290027) mth143: WeBWorK::DB::hashDatabaseOK: done getting orphaned UserSets |
|
|
325 | # |
|
|
326 | # new method: |
|
|
327 | # TIMING 36134 0 1087502854.579133 (0.141437) mth143: WeBWorK::DB::hashDatabaseOK: about to get orphaned UserSets |
|
|
328 | # TIMING 36134 0 1087502856.852504 (2.414808) mth143: WeBWorK::DB::hashDatabaseOK: done getting orphaned UserSets |
|
|
329 | # |
|
|
330 | # yay! |
|
|
331 | |
|
|
332 | $WeBWorK::timer->continue(__PACKAGE__ . "::hashDatabaseOK: about to get orphaned UserSets") if defined $WeBWorK::timer; |
|
|
333 | |
|
|
334 | # ... so instead, we're going to do things manually |
|
|
335 | |
|
|
336 | # key: setID, value: hash of userIDs of users to whom this set is assigned |
|
|
337 | my %orphanUserSets; |
|
|
338 | |
|
|
339 | if (ref $self->{set_user} eq "WeBWorK::DB::Schema::WW1Hash") { |
|
|
340 | # we can only do this with WW1Hash |
|
|
341 | #warn "the fast way!\n"; |
|
|
342 | |
|
|
343 | # connect |
|
|
344 | $self->{set_user}->{driver}->connect("ro") |
|
|
345 | or return 0, @results, "Failed to connect to set_user database."; |
|
|
346 | |
|
|
347 | # get PSVNs for global user (ČN) |
|
|
348 | my @globalUserPSVNs = $self->{set_user}->getPSVNsForUser($globalUserID); |
|
|
349 | #warn "found ", scalar @globalUserPSVNs, " PSVNs for the global user.\n"; |
|
|
350 | |
|
|
351 | # get setIDs for PSVNs (M) |
|
|
352 | my @globalUserSetIDs; |
|
|
353 | foreach my $PSVN (@globalUserPSVNs) { |
|
|
354 | #warn "getting setID for PSVN '$PSVN'...\n"; |
|
|
355 | my $string = $self->{set_user}->fetchString($PSVN); |
|
|
356 | my (undef, $setID) = $self->{set_user}->string2IDs($string); # discard userID, problemIDs |
|
|
357 | push @globalUserSetIDs, $setID; |
|
|
358 | #warn "got setID '$setID'\n"; |
|
|
359 | } |
|
|
360 | |
|
|
361 | # get PSVNs for each setID (ČN*M) |
|
|
362 | my @okPSVNs = map { $self->{set_user}->getPSVNsForSet($_) } @globalUserSetIDs; |
|
|
363 | #warn "found ", scalar @okPSVNs, " PSVNs for sets assigned to the global user.\n"; |
|
|
364 | |
|
|
365 | # get all PSVNs (N*M) |
|
|
366 | my @allPSVNs = $self->{set_user}->getAllPSVNs; |
|
|
367 | #warn "found ", scalar @allPSVNs, " PSVNs total.\n"; |
|
|
368 | |
|
|
369 | # eliminate PSVNs of sets that are assigned to the global user |
|
|
370 | my %allPSVNs; |
|
|
371 | @allPSVNs{@allPSVNs} = (); |
|
|
372 | |
|
|
373 | foreach my $PSVN (@okPSVNs) { |
|
|
374 | delete $allPSVNs{$PSVN}; |
|
|
375 | } |
|
|
376 | |
|
|
377 | # get setIDs for orphan PSVNs |
|
|
378 | foreach my $PSVN (keys %allPSVNs) { |
|
|
379 | #warn "getting userID and setID for PSVN '$PSVN'...\n"; |
|
|
380 | my $string = $self->{set_user}->fetchString($PSVN); |
|
|
381 | my ($userID, $setID) = $self->{set_user}->string2IDs($string); |
|
|
382 | $orphanUserSets{$setID}->{$userID} = 1; |
|
|
383 | #warn "got setID '$setID' for userID '$userID'\n"; |
|
|
384 | } |
|
|
385 | |
|
|
386 | # disconnect |
|
|
387 | $self->{set_user}->{driver}->disconnect; |
|
|
388 | } else { |
|
|
389 | # otherwise, do it the slow way (maybe it's not slow with some other schema?) |
|
|
390 | #warn "oddly enough, set_user isn't using WW1Hash, so we have to use the slow list() method"; |
|
|
391 | my @userSetIDs = $self->{set_user}->list(undef, undef); |
|
|
392 | |
| 320 | foreach my $userSetID (@userSetIDs) { |
393 | foreach my $userSetID (@userSetIDs) { |
| 321 | my ($userID, $setID) = @$userSetID; |
394 | my ($userID, $setID) = @$userSetID; |
| 322 | $userSetStatus{$setID}->{$userID} = 1; |
395 | $orphanUserSets{$setID}->{$userID} = 1; |
| 323 | } |
396 | } |
| 324 | |
397 | |
| 325 | foreach my $setID (keys %userSetStatus) { |
398 | foreach my $setID (keys %orphanUserSets) { |
| 326 | delete $userSetStatus{$setID} |
399 | delete $orphanUserSets{$setID} |
| 327 | if exists $userSetStatus{$setID}->{$globalUserID}; |
400 | if exists $orphanUserSets{$setID}->{$globalUserID}; |
| 328 | } |
401 | } |
|
|
402 | } |
| 329 | |
403 | |
|
|
404 | $WeBWorK::timer->continue(__PACKAGE__ . "::hashDatabaseOK: done getting orphaned UserSets") if defined $WeBWorK::timer; |
|
|
405 | |
| 330 | if (keys %userSetStatus) { |
406 | if (keys %orphanUserSets) { |
| 331 | if ($fix) { |
407 | if ($fix) { |
| 332 | foreach my $setID (keys %userSetStatus) { |
408 | foreach my $setID (keys %orphanUserSets) { |
| 333 | my $userID = ( keys %{$userSetStatus{$setID}} )[0]; |
409 | my $userID = ( keys %{$orphanUserSets{$setID}} )[0]; |
| 334 | |
410 | |
| 335 | # grab the first UserSet of this set (connect and disconnect required for get1*) |
411 | # grab the first UserSet of this set (connect and disconnect required for get1*) |
| 336 | $self->{set_user}->{driver}->connect("ro"); |
412 | $self->{set_user}->{driver}->connect("ro") |
|
|
413 | or return 0, @results, "Failed to connect to set_user database."; |
| 337 | my $RawUserSet = $self->{set_user}->get1NoFilter($userID, $setID); |
414 | my $RawUserSet = $self->{set_user}->get1NoFilter($userID, $setID); |
| 338 | $self->{set_user}->{driver}->disconnect(); |
415 | $self->{set_user}->{driver}->disconnect(); |
|
|
416 | unless ($RawUserSet) { |
|
|
417 | #warn "failed to fetch UserSet '$setID' for user '$userID'!\n"; |
|
|
418 | next; |
|
|
419 | } |
| 339 | |
420 | |
| 340 | # change user ID to globalUserID and add to database |
421 | # change user ID to globalUserID and add to database |
| 341 | $RawUserSet->user_id($globalUserID); |
422 | $RawUserSet->user_id($globalUserID); |
| 342 | $self->{set_user}->add($RawUserSet); |
423 | $self->{set_user}->add($RawUserSet); |
| 343 | |
424 | |
| 344 | push @results, "Set '$setID' not assigned to global user '$globalUserID' -- FIXED."; |
425 | push @results, "Set '$setID' not assigned to global user '$globalUserID' -- FIXED."; |
| 345 | |
426 | |
| 346 | #warn "hashDatabaseOK($fix): assigned set '$setID' to global user '$globalUserID' -- good.\n"; |
427 | #warn "hashDatabaseOK($fix): assigned set '$setID' to global user '$globalUserID' -- good.\n"; |
| 347 | } |
428 | } |
| 348 | } else { |
429 | } else { |
| 349 | foreach my $setID (keys %userSetStatus) { |
430 | foreach my $setID (keys %orphanUserSets) { |
| 350 | #warn "hashDatabaseOK($fix): set '$setID' not assigned to global user '$globalUserID' -- bad!\n"; |
431 | #warn "hashDatabaseOK($fix): set '$setID' not assigned to global user '$globalUserID' -- bad!\n"; |
| 351 | push @results, "Set '$setID' not assigned to global user '$globalUserID'."; |
432 | push @results, "Set '$setID' not assigned to global user '$globalUserID'."; |
| 352 | } |
433 | } |
| 353 | $errorsExist = 1; |
434 | $errorsExist = 1; |
| 354 | } |
435 | } |