--- loncom/interface/loncoursedata.pm 2005/03/03 18:57:36 1.144 +++ loncom/interface/loncoursedata.pm 2006/02/05 18:49:47 1.153 @@ -1,6 +1,6 @@ # The LearningOnline Network with CAPA # -# $Id: loncoursedata.pm,v 1.144 2005/03/03 18:57:36 matthew Exp $ +# $Id: loncoursedata.pm,v 1.153 2006/02/05 18:49:47 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -50,7 +50,7 @@ package Apache::loncoursedata; use strict; use Apache::Constants qw(:common :http); -use Apache::lonnet(); +use Apache::lonnet; use Apache::lonhtmlcommon; use Time::HiRes; use Apache::lonmysql; @@ -71,8 +71,8 @@ sub LoadDiscussion { my %Discuss=(); my %contrib=&Apache::lonnet::dump( $courseID, - $ENV{'course.'.$courseID.'.domain'}, - $ENV{'course.'.$courseID.'.num'}); + $env{'course.'.$courseID.'.domain'}, + $env{'course.'.$courseID.'.num'}); #my %contrib=&DownloadCourseInformation($name, $courseID, 0); @@ -645,7 +645,7 @@ Returns: nothing ################################################ sub delete_caches { my $courseid = shift; - $courseid = $ENV{'request.course.id'} if (! defined($courseid)); + $courseid = $env{'request.course.id'} if (! defined($courseid)); # &setup_table_names($courseid); # @@ -861,7 +861,7 @@ sub get_student { sub populate_student_table { my ($courseid) = @_; if (! defined($courseid)) { - $courseid = $ENV{'request.course.id'}; + $courseid = $env{'request.course.id'}; } # &setup_table_names($courseid); @@ -869,7 +869,9 @@ sub populate_student_table { my $dbh = &Apache::lonmysql::get_dbh(); my $request = 'INSERT IGNORE INTO '.$student_table. "(student,section,status) VALUES "; - my $classlist = &get_classlist($courseid); + my $cdom = $env{'course.'.$courseid.'.domain'}; + my $cnum = $env{'course.'.$courseid.'.num'}; + my $classlist = &get_classlist($cdom,$cnum); my $student_count=0; while (my ($student,$data) = each %$classlist) { my ($section,$status) = ($data->[&CL_SECTION()], @@ -1214,7 +1216,7 @@ sub update_student_data { # # Set the students update time if ($Results[0] eq 'okay') { - &store_updatetime($student_id,$time_of_retrieval,$time_of_retrieval); + &store_updatetime($student_id,$time_of_retrieval); } # return @Results; @@ -1270,23 +1272,29 @@ sub store_student_data { # make sure the symb is set up properly my $symb_id = &get_symb_id($current_symb); # - # Load data into the tables + # Parameters while (my ($parameter,$value) = each(%$param_hash)) { - my $newstring; if ($parameter !~ /(timestamp|resource\.(.*)\.(solved|tries|awarded|award|awarddetail|previous))/) { - $newstring = "('".join("','", - $symb_id,$student_id, - $parameter)."',". - $dbh->quote($value)."),\n"; + my $sql_parameter = "('".join("','", + $symb_id,$student_id, + $parameter)."',". + $dbh->quote($value)."),\n"; $num_parameters ++; - if ($newstring !~ /''/) { - $store_parameters_command .= $newstring; - $rows_stored++; + if ($sql_parameter !~ /''/) { + $store_parameters_command .= $sql_parameter; + #$rows_stored++; } } - next if ($parameter !~ /^resource\.(.*)\.solved$/); - # + } + # Performance + my %stored; + while (my ($parameter,$value) = each(%$param_hash)) { + next if ($parameter !~ /^resource\.(.*)\.(solved|awarded)$/); my $part = $1; + next if ($part =~ /\./); + next if (exists($stored{$part})); + $stored{$part}++; + # my $part_id = &get_part_id($part); next if (!defined($part_id)); my $solved = $value; @@ -1301,29 +1309,31 @@ sub store_student_data { $awarded = '' if (! defined($awarded)); $award = '' if (! defined($award)); $awarddetail = '' if (! defined($awarddetail)); - $newstring = "('".join("','",$symb_id,$student_id,$part_id,$part, - $solved,$tries,$awarded,$award, - $awarddetail,$timestamp)."'),\n"; - $store_performance_command .= $newstring; + my $sql_performance = + "('".join("','",$symb_id,$student_id,$part_id,$part, + $solved,$tries,$awarded,$award, + $awarddetail,$timestamp)."'),\n"; + $store_performance_command .= $sql_performance; $rows_stored++; } } - chop $store_parameters_command; - chop $store_parameters_command; - chop $store_performance_command; - chop $store_performance_command; + if (! $rows_stored) { return ($returnstatus, undef); } + $store_parameters_command =~ s|,\n$||; + $store_performance_command =~ s|,\n$||; my $start = Time::HiRes::time; $dbh->do($store_performance_command); if ($dbh->err()) { - &Apache::lonnet::logthis(' bigass insert error:'.$dbh->errstr()); - &Apache::lonnet::logthis('command = '.$store_performance_command); + &Apache::lonnet::logthis('performance bigass insert error:'. + $dbh->errstr()); + &Apache::lonnet::logthis('command = '.$/.$store_performance_command); $returnstatus = 'error: unable to insert performance into database'; return ($returnstatus,$student_data); } $dbh->do($store_parameters_command) if ($num_parameters>0); if ($dbh->err()) { - &Apache::lonnet::logthis(' bigass insert error:'.$dbh->errstr()); - &Apache::lonnet::logthis('command = '.$store_parameters_command); + &Apache::lonnet::logthis('parameters bigass insert error:'. + $dbh->errstr()); + &Apache::lonnet::logthis('command = '.$/.$store_parameters_command); &Apache::lonnet::logthis('rows_stored = '.$rows_stored); &Apache::lonnet::logthis('student_id = '.$student_id); $returnstatus = 'error: unable to insert parameters into database'; @@ -1351,7 +1361,7 @@ Returns nothing on success and 'error' o ###################################### sub ensure_tables_are_set_up { my ($courseid) = @_; - $courseid = $ENV{'request.course.id'} if (! defined($courseid)); + $courseid = $env{'request.course.id'} if (! defined($courseid)); # # Clean out package variables &setup_table_names($courseid); @@ -1408,7 +1418,7 @@ sub ensure_current_data { my ($sname,$sdom,$courseid) = @_; my $status = 'okay'; # return value # - $courseid = $ENV{'request.course.id'} if (! defined($courseid)); + $courseid = $env{'request.course.id'} if (! defined($courseid)); &ensure_tables_are_set_up($courseid); # # Get the update time for the user @@ -1457,7 +1467,7 @@ sub ensure_current_full_data { my ($sname,$sdom,$courseid) = @_; my $status = 'okay'; # return value # - $courseid = $ENV{'request.course.id'} if (! defined($courseid)); + $courseid = $env{'request.course.id'} if (! defined($courseid)); &ensure_tables_are_set_up($courseid); # # Get the update time for the user @@ -1633,7 +1643,7 @@ an empty list is returned. sub get_current_state { my ($sname,$sdom,$symb,$courseid,$forcedownload)=@_; # - $courseid = $ENV{'request.course.id'} if (! defined($courseid)); + $courseid = $env{'request.course.id'} if (! defined($courseid)); # return () if (! defined($sname) || ! defined($sdom)); # @@ -1736,7 +1746,7 @@ able to answer it correctly. sub get_problem_statistics { my ($Sections,$status,$symb,$part,$courseid,$starttime,$endtime) = @_; return if (! defined($symb) || ! defined($part)); - $courseid = $ENV{'request.course.id'} if (! defined($courseid)); + $courseid = $env{'request.course.id'} if (! defined($courseid)); # &setup_table_names($courseid); my $symb_id = &get_symb_id($symb); @@ -1863,6 +1873,9 @@ sub execute_SQL_request { my ($dbh,$request)=@_; # &Apache::lonnet::logthis($request); my $sth = $dbh->prepare($request); + if (!$sth) { + die($dbh->errstr . " SQL: $request"); + } $sth->execute(); my $row = $sth->fetchrow_arrayref(); if (ref($row) eq 'ARRAY' && scalar(@$row)>0) { @@ -1885,7 +1898,7 @@ sub execute_SQL_request { sub populate_weight_table { my ($courseid) = @_; if (! defined($courseid)) { - $courseid = $ENV{'request.course.id'}; + $courseid = $env{'request.course.id'}; } # &setup_table_names($courseid); @@ -2035,7 +2048,7 @@ sub rank_students_by_scores_on_resources my ($resources,$Sections,$enrollment,$courseid,$starttime,$endtime) = @_; return if (! defined($resources) || ! ref($resources) eq 'ARRAY'); if (! defined($courseid)) { - $courseid = $ENV{'request.course.id'}; + $courseid = $env{'request.course.id'}; } # &setup_table_names($courseid); @@ -2095,7 +2108,7 @@ Returns: the sum of the score on the pro sub get_sum_of_scores { my ($symb,$part,$students,$courseid,$starttime,$endtime) = @_; if (! defined($courseid)) { - $courseid = $ENV{'request.course.id'}; + $courseid = $env{'request.course.id'}; } if (defined($students) && ((@$students == 0) || @@ -2159,7 +2172,7 @@ Returns: minimum, maximum, mean, s.d., n sub score_stats { my ($Sections,$enrollment,$symbs,$starttime,$endtime,$courseid)=@_; if (! defined($courseid)) { - $courseid = $ENV{'request.course.id'}; + $courseid = $env{'request.course.id'}; } # &setup_table_names($courseid); @@ -2202,7 +2215,7 @@ sub score_stats { # &Apache::lonnet::logthis('request = '.$/.$request); $request = 'SELECT SUM(weight) FROM '.$weight_table. - ' WHERE ('.$symb_restriction.')'; + ' AS a WHERE ('.$symb_restriction.')'; my ($max_possible) = &execute_SQL_request($dbh,$request); # &Apache::lonnet::logthis('request = '.$/.$request); return($min,$max,$ave,$std,$count,$max_possible); @@ -2233,7 +2246,7 @@ Returns: minimum, maximum, mean, s.d., a sub count_stats { my ($Sections,$enrollment,$symbs,$starttime,$endtime,$courseid)=@_; if (! defined($courseid)) { - $courseid = $ENV{'request.course.id'}; + $courseid = $env{'request.course.id'}; } # &setup_table_names($courseid); @@ -2251,11 +2264,10 @@ sub count_stats { $request = 'CREATE TEMPORARY TABLE '.$stats_table.' '. 'SELECT a.student_id,'. - 'COUNT(a.award) AS count FROM '. + 'SUM(a.awarded) AS count FROM '. $performance_table.' AS a '. 'LEFT JOIN '.$student_table.' AS b ON a.student_id=b.student_id '. - 'WHERE ('.$symb_restriction.')'. - " AND a.award!='INCORRECT_ATTEMPTED'"; + 'WHERE ('.$symb_restriction.')'; if ($time_limits) { $request .= ' AND '.$time_limits; } @@ -2290,7 +2302,7 @@ sub count_stats { ###################################################### sub get_student_data { my ($students,$courseid) = @_; - $courseid = $ENV{'request.course.id'} if (! defined($courseid)); + $courseid = $env{'request.course.id'} if (! defined($courseid)); &setup_table_names($courseid); my $dbh = &Apache::lonmysql::get_dbh(); return undef if (! defined($dbh)); @@ -2331,7 +2343,7 @@ sub get_response_data { my ($Sections,$enrollment,$symb,$response,$courseid) = @_; return undef if (! defined($symb) || ! defined($response)); - $courseid = $ENV{'request.course.id'} if (! defined($courseid)); + $courseid = $env{'request.course.id'} if (! defined($courseid)); # &setup_table_names($courseid); my $symb_id = &get_symb_id($symb); @@ -2404,7 +2416,7 @@ sub get_response_data_by_student { my ($student,$symb,$response,$courseid) = @_; return undef if (! defined($symb) || ! defined($response)); - $courseid = $ENV{'request.course.id'} if (! defined($courseid)); + $courseid = $env{'request.course.id'} if (! defined($courseid)); # &setup_table_names($courseid); my $symb_id = &get_symb_id($symb); @@ -2460,7 +2472,7 @@ sub get_response_time_data { my ($sections,$enrollment,$symb,$part,$courseid) = @_; return undef if (! defined($symb) || ! defined($part)); - $courseid = $ENV{'request.course.id'} if (! defined($courseid)); + $courseid = $env{'request.course.id'} if (! defined($courseid)); # &setup_table_names($courseid); my $symb_id = &get_symb_id($symb); @@ -2526,12 +2538,15 @@ sub get_response_time_data { ################################################ ################################################ sub get_student_scores { - my ($Sections,$Symbs,$enrollment,$courseid,$starttime,$endtime) = @_; - $courseid = $ENV{'request.course.id'} if (! defined($courseid)); + my ($sections,$Symbs,$enrollment,$courseid,$starttime,$endtime) = @_; + $courseid = $env{'request.course.id'} if (! defined($courseid)); &setup_table_names($courseid); my $dbh = &Apache::lonmysql::get_dbh(); return (undef) if (! defined($dbh)); my $tmptable = $courseid.'_temp_'.time; + my $request = 'DROP TABLE IF EXISTS '.$tmptable; +# &Apache::lonnet::logthis('request = '.$/.$request); + $dbh->do($request); # my $symb_requirements; if (defined($Symbs) && @$Symbs) { @@ -2542,34 +2557,17 @@ sub get_student_scores { } @$Symbs).')'; } # - my $student_requirements; - if ( (defined($Sections) && $Sections->[0] ne 'all')) { - $student_requirements = '('. - join(' OR ', map { "b.section='".$_."'" } @$Sections - ).')'; - } - # - my $enrollment_requirements=undef; - if (defined($enrollment) && $enrollment ne 'Any') { - $enrollment_requirements = "b.status='".$enrollment."'"; - } + my ($student_requirements,$enrollment_requirements) = + &limit_by_section_and_status($sections,$enrollment,'b'); # - my $time_requirements = undef; - if (defined($starttime)) { - $time_requirements .= "a.timestamp>='".$starttime."'"; - if (defined($endtime)) { - $time_requirements .= " AND a.timestamp<='".$endtime."'"; - } - } elsif (defined($endtime)) { - $time_requirements .= "a.timestamp<='".$endtime."'"; - } - ## + my $time_requirements = &limit_by_start_end_time($starttime,$endtime,'a'); ## - my $request = 'CREATE TEMPORARY TABLE IF NOT EXISTS '.$tmptable. - ' SELECT a.student_id,SUM(a.awarded) AS score FROM '. + $request = 'CREATE TEMPORARY TABLE IF NOT EXISTS '.$tmptable. + ' SELECT a.student_id,SUM(a.awarded*c.weight) AS score FROM '. $performance_table.' AS a '; + $request .= "LEFT JOIN ".$weight_table.' AS c ON a.symb_id=c.symb_id AND a.part_id=c.part_id '; if (defined($student_requirements) || defined($enrollment_requirements)) { - $request .= ' NATURAL LEFT JOIN '.$student_table.' AS b '; + $request .= ' LEFT JOIN '.$student_table.' AS b ON a.student_id=b.student_id'; } if (defined($symb_requirements) || defined($student_requirements) || @@ -2631,7 +2629,7 @@ Cleans up the package variables for loca sub setup_table_names { my ($courseid) = @_; if (! defined($courseid)) { - $courseid = $ENV{'request.course.id'}; + $courseid = $env{'request.course.id'}; } # if (! defined($current_course) || $current_course ne $courseid) { @@ -2704,10 +2702,10 @@ Retrieve the classist of a given class o information is returned from the classlist.db file and, if needed, from the students environment. -Optional arguments are $cid, $cdom, and $cnum (course id, course domain, -and course number, respectively). Any omitted arguments will be taken -from the current environment ($ENV{'request.course.id'}, -$ENV{'course.'.$cid.'.domain'}, and $ENV{'course.'.$cid.'.num'}). +Optional arguments are $cdom, and $cnum (course domain, +and course number, respectively). If either is ommitted the course +will be taken from the current environment ($env{'request.course.id'}, +$env{'course.'.$cid.'.domain'}, and $env{'course.'.$cid.'.num'}). Returns a reference to a hash which contains: keys '$sname:$sdom' @@ -2734,10 +2732,13 @@ sub CL_TYPE { return 8; } sub CL_LOCKEDTYPE { return 9; } sub get_classlist { - my ($cid,$cdom,$cnum) = @_; - $cid = $cid || $ENV{'request.course.id'}; - $cdom = $cdom || $ENV{'course.'.$cid.'.domain'}; - $cnum = $cnum || $ENV{'course.'.$cid.'.num'}; + my ($cdom,$cnum) = @_; + my $cid = $cdom.'_'.$cnum; + if (!defined($cdom) || !defined($cnum)) { + $cid = $env{'request.course.id'}; + $cdom = $env{'course.'.$cid.'.domain'}; + $cnum = $env{'course.'.$cid.'.num'}; + } my $now = time; # my %classlist=&Apache::lonnet::dump('classlist',$cdom,$cnum);