[LON-CAPA-cvs] cvs: loncom /interface loncoursedata.pm
matthew
lon-capa-cvs@mail.lon-capa.org
Fri, 26 Sep 2003 18:31:31 -0000
This is a MIME encoded message
--matthew1064601091
Content-Type: text/plain
matthew Fri Sep 26 14:31:31 2003 EDT
Modified files:
/loncom/interface loncoursedata.pm
Log:
Implement storing of student performance data in the MySQL cache database.
Added 3 tables: $fulldump_part_table, $fulldump_response_table, and
$fulldump_timestamp_table. Added &update_full_student_data to do a
lonnet::dump, load the data into the new tables, and then update the old
tables used for Chart, Spreadsheet, and the current implementation of
Statistics. Reworked some existing code to avoid duplication.
--matthew1064601091
Content-Type: text/plain
Content-Disposition: attachment; filename="matthew-20030926143131.txt"
Index: loncom/interface/loncoursedata.pm
diff -u loncom/interface/loncoursedata.pm:1.88 loncom/interface/loncoursedata.pm:1.89
--- loncom/interface/loncoursedata.pm:1.88 Wed Sep 24 14:01:01 2003
+++ loncom/interface/loncoursedata.pm Fri Sep 26 14:31:31 2003
@@ -1,6 +1,6 @@
# The LearningOnline Network with CAPA
#
-# $Id: loncoursedata.pm,v 1.88 2003/09/24 18:01:01 matthew Exp $
+# $Id: loncoursedata.pm,v 1.89 2003/09/26 18:31:31 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -371,6 +371,13 @@
=over 4
+=item Tables used to store meta information
+
+The following tables hold data required to keep track of the current status
+of a students data in the tables or to look up the students data in the tables.
+
+=over 4
+
=item $symb_table
The symb_table has two columns. The first is a 'symb_id' and the second
@@ -398,10 +405,20 @@
=item $studentdata_table
-The studentdata_table has four columns. The first is 'student_id', the unique
-id of the student. The second is the time the students data was last updated.
-The third is the students section. The fourth is the students current
-classification. This table has its PRIMARY KEY on 'student_id'.
+The studentdata_table has four columns: 'student_id' (the unique id of
+the student), 'updatetime' (the time the students data was last updated),
+'fullupdatetime' (the time the students full data was last updated),
+'section', and 'classification'( the students current classification).
+This table has its PRIMARY KEY on 'student_id'.
+
+=back
+
+=item Tables used to store current status data
+
+The following tables store data only about the students current status on
+a problem, meaning only the data related to the last attempt on a problem.
+
+=over 4
=item $performance_table
@@ -425,6 +442,45 @@
=back
+=item Tables used for storing historic data
+
+The following tables are used to store almost all of the transactions a student
+has made on a homework problem. See loncapa/docs/homework/datastorage for
+specific information about each of the parameters stored.
+
+=over 4
+
+=item $fulldump_response_table
+
+The response table holds data (documented in loncapa/docs/homework/datastorage)
+associated with a particular response id which is stored when a student
+attempts a problem. The following are the columns of the table, in order:
+'symb_id','part_id','response_id','student_id','transaction','tries',
+'awarddetail', 'awarded','response_specific' (data particular to the response
+type), 'response_specific_value', and 'submission (the text of the students
+submission). The primary key is based on the first five columns listed above.
+
+=item $fulldump_part_table
+
+The part table holds data (documented in loncapa/docs/homework/datastorage)
+associated with a particular part id which is stored when a student attempts
+a problem. The following are the columns of the table, in order:
+'symb_id','part_id','student_id','transaction','tries','award','awarded',
+and 'previous'. The primary key is based on the first five columns listed
+above.
+
+=item $fulldump_timestamp_table
+
+The timestamp table holds the timestamps of the transactions which are
+stored in $fulldump_response_table and $fulldump_part_table. This data is
+about both the response and part data. Columns: 'symb_id','student_id',
+'transaction', and 'timestamp'.
+The primary key is based on the first 3 columns.
+
+=back
+
+=back
+
=head3 Important Subroutines
Here is a brief overview of the subroutines which are likely to be of
@@ -453,7 +509,7 @@
################################################
################################################
-{
+{ # Begin scope of table identifiers
my $current_course ='';
my $symb_table;
@@ -462,7 +518,11 @@
my $studentdata_table;
my $performance_table;
my $parameters_table;
+my $fulldump_response_table;
+my $fulldump_part_table;
+my $fulldump_timestamp_table;
+my @Tables;
################################################
################################################
@@ -486,9 +546,7 @@
&setup_table_names($courseid);
#
# Drop any of the existing tables
- foreach my $table ($symb_table,$part_table,$student_table,
- $studentdata_table,$performance_table,
- $parameters_table) {
+ foreach my $table (@Tables) {
&Apache::lonmysql::drop_table($table);
}
#
@@ -548,8 +606,9 @@
type => 'MEDIUMINT UNSIGNED',
restrictions => 'NOT NULL UNIQUE',},
{ name => 'updatetime',
- type => 'INT UNSIGNED',
- restrictions => 'NOT NULL' },
+ type => 'INT UNSIGNED'},
+ { name => 'fullupdatetime',
+ type => 'INT UNSIGNED'},
{ name => 'section',
type => 'VARCHAR(100)'},
{ name => 'classification',
@@ -591,6 +650,112 @@
{ columns=>['symb_id'] },],
};
#
+ my $fulldump_part_table_def = {
+ id => $fulldump_part_table,
+ permanent => 'no',
+ columns => [
+ { name => 'symb_id',
+ type => 'MEDIUMINT UNSIGNED',
+ restrictions => 'NOT NULL' },
+ { name => 'part_id',
+ type => 'MEDIUMINT UNSIGNED',
+ restrictions => 'NOT NULL' },
+ { name => 'student_id',
+ type => 'MEDIUMINT UNSIGNED',
+ restrictions => 'NOT NULL' },
+ { name => 'transaction',
+ type => 'MEDIUMINT UNSIGNED',
+ restrictions => 'NOT NULL' },
+ { name => 'tries',
+ type => 'SMALLINT UNSIGNED',
+ restrictions => 'NOT NULL' },
+ { name => 'award',
+ type => 'TINYTEXT' },
+ { name => 'awarded',
+ type => 'TINYTEXT' },
+ { name => 'previous',
+ type => 'SMALLINT UNSIGNED' },
+# { name => 'regrader',
+# type => 'TINYTEXT' },
+# { name => 'afterduedate',
+# type => 'TINYTEXT' },
+ ],
+ 'PRIMARY KEY' => ['symb_id','part_id','student_id','transaction'],
+ 'KEY' => [
+ { columns=>['symb_id'] },
+ { columns=>['part_id'] },
+ { columns=>['student_id'] },
+ ],
+ };
+ #
+ my $fulldump_response_table_def = {
+ id => $fulldump_response_table,
+ permanent => 'no',
+ columns => [
+ { name => 'symb_id',
+ type => 'MEDIUMINT UNSIGNED',
+ restrictions => 'NOT NULL' },
+ { name => 'part_id',
+ type => 'MEDIUMINT UNSIGNED',
+ restrictions => 'NOT NULL' },
+ { name => 'response_id',
+ type => 'MEDIUMINT UNSIGNED',
+ restrictions => 'NOT NULL' },
+ { name => 'student_id',
+ type => 'MEDIUMINT UNSIGNED',
+ restrictions => 'NOT NULL' },
+ { name => 'transaction',
+ type => 'MEDIUMINT UNSIGNED',
+ restrictions => 'NOT NULL' },
+ { name => 'tries',
+ type => 'SMALLINT UNSIGNED',
+ restrictions => 'NOT NULL' },
+ { name => 'awarddetail',
+ type => 'TINYTEXT' },
+ { name => 'awarded',
+ type => 'TINYTEXT' },
+# { name => 'message',
+# type => 'CHAR' },
+ { name => 'response_specific',
+ type => 'TINYTEXT' },
+ { name => 'response_specific_value',
+ type => 'TINYTEXT' },
+ { name => 'submission',
+ type => 'TEXT'},
+ ],
+ 'PRIMARY KEY' => ['symb_id','part_id','response_id','student_id',
+ 'transaction'],
+ 'KEY' => [
+ { columns=>['symb_id'] },
+ { columns=>['part_id','response_id'] },
+ { columns=>['student_id'] },
+ ],
+ };
+ my $fulldump_timestamp_table_def = {
+ id => $fulldump_timestamp_table,
+ permanent => 'no',
+ columns => [
+ { name => 'symb_id',
+ type => 'MEDIUMINT UNSIGNED',
+ restrictions => 'NOT NULL' },
+ { name => 'student_id',
+ type => 'MEDIUMINT UNSIGNED',
+ restrictions => 'NOT NULL' },
+ { name => 'transaction',
+ type => 'MEDIUMINT UNSIGNED',
+ restrictions => 'NOT NULL' },
+ { name => 'timestamp',
+ type => 'INT UNSIGNED'},
+ ],
+ 'PRIMARY KEY' => ['symb_id','student_id','transaction'],
+ 'KEY' => [
+ { columns=>['symb_id'] },
+ { columns=>['student_id'] },
+ { columns=>['transaction'] },
+ ],
+ };
+
+ #
my $parameters_table_def = {
id => $parameters_table,
permanent => 'no',
@@ -652,6 +817,26 @@
&Apache::lonmysql::get_error());
return 6;
}
+ #
+ $tableid = &Apache::lonmysql::create_table($fulldump_part_table_def);
+ if (! defined($tableid)) {
+ &Apache::lonnet::logthis("error creating fulldump_part_table: ".
+ &Apache::lonmysql::get_error());
+ return 7;
+ }
+ #
+ $tableid = &Apache::lonmysql::create_table($fulldump_response_table_def);
+ if (! defined($tableid)) {
+ &Apache::lonnet::logthis("error creating fulldump_response_table: ".
+ &Apache::lonmysql::get_error());
+ return 8;
+ }
+ $tableid = &Apache::lonmysql::create_table($fulldump_timestamp_table_def);
+ if (! defined($tableid)) {
+ &Apache::lonnet::logthis("error creating fulldump_timestamp_table: ".
+ &Apache::lonmysql::get_error());
+ return 9;
+ }
return 0;
}
@@ -673,9 +858,7 @@
&setup_table_names($courseid);
#
my $dbh = &Apache::lonmysql::get_dbh();
- foreach my $table ($symb_table,$part_table,$student_table,
- $studentdata_table,$performance_table,
- $parameters_table ){
+ foreach my $table (@Tables) {
my $command = 'DROP TABLE '.$table.';';
$dbh->do($command);
if ($dbh->err) {
@@ -887,6 +1070,210 @@
=pod
+=item &update_full_student_data($sname,$sdom,$courseid)
+
+Does a lonnet::dump on a student to populate the courses tables.
+
+Input: $sname, $sdom, $courseid
+
+Output: $returnstatus
+
+$returnstatus is a string describing any errors that occured. 'okay' is the
+default.
+
+This subroutine loads a students data using lonnet::dump and inserts
+it into the MySQL database. The inserts are done on three tables,
+$fulldump_response_table, $fulldump_part_table, and $fulldump_timestamp_table.
+The INSERT calls are made directly by this subroutine, not through lonmysql
+because we do a 'bulk'insert which takes advantage of MySQLs non-SQL
+compliant INSERT command to insert multiple rows at a time.
+If anything has gone wrong during this process, $returnstatus is updated with
+a description of the error.
+
+Once the "fulldump" tables are updated, the tables used for chart and
+spreadsheet (which hold only the current state of the student on their
+homework, not historical data) are updated. If all updates have occured
+successfully, the studentdata table is updated to reflect the time of the
+update.
+
+Notice we do not insert the data and immediately query it. This means it
+is possible for there to be data returned this first time that is not
+available the second time. CYA.
+
+=cut
+
+################################################
+################################################
+sub update_full_student_data {
+ my ($sname,$sdom,$courseid) = @_;
+ #
+ # Set up database names
+ &setup_table_names($courseid);
+ #
+ my $student_id = &get_student_id($sname,$sdom);
+ my $student = $sname.':'.$sdom;
+ #
+ my $returnstatus = 'okay';
+ #
+ # Download students data
+ my $time_of_retrieval = time;
+ my @tmp = &Apache::lonnet::dump($courseid,$sdom,$sname);
+ if (@tmp && $tmp[0] =~ /^error/) {
+ $returnstatus = 'error retrieving full student data';
+ return $returnstatus;
+ } elsif (! @tmp) {
+ $returnstatus = 'okay: no student data';
+ return $returnstatus;
+ }
+ my %studentdata = @tmp;
+ #
+ # Get database handle and clean out the tables
+ my $dbh = &Apache::lonmysql::get_dbh();
+ $dbh->do('DELETE FROM '.$fulldump_response_table.' WHERE student_id='.
+ $student_id);
+ $dbh->do('DELETE FROM '.$fulldump_part_table.' WHERE student_id='.
+ $student_id);
+ $dbh->do('DELETE FROM '.$fulldump_timestamp_table.' WHERE student_id='.
+ $student_id);
+ #
+ # Parse and store the data into a form we can handle
+ my $partdata;
+ my $respdata;
+ while (my ($key,$value) = each(%studentdata)) {
+ next if ($key =~ /^(\d+):(resource$|subnum$|keys:)/);
+ my ($transaction,$symb,$parameter) = split(':',$key);
+ my $symb_id = &get_symb_id($symb);
+ if ($parameter eq 'timestamp') {
+ # We can deal with 'timestamp' right away
+ my @timestamp_storage = ($symb_id,$student_id,
+ $transaction,$value);
+ my $store_command = 'INSERT INTO '.$fulldump_timestamp_table.
+ " VALUES ('".join("','",@timestamp_storage)."');";
+ $dbh->do($store_command);
+ if ($dbh->err()) {
+ &Apache::lonnet::logthis('unable to execute '.$store_command);
+ &Apache::lonnet::logthis($dbh->errstr());
+ }
+ next;
+ } elsif ($parameter eq 'version') {
+ next;
+ } elsif ($parameter =~ /^resource\.(.*)\.(tries|award|awarded|previous|solved|awarddetail|submission)\s*$/){
+ # we do not have enough information to store an
+ # entire row, so we save it up until later.
+ my ($part_and_resp_id,$field) = ($1,$2);
+ my ($part,$part_id,$resp,$resp_id);
+ if ($part_and_resp_id =~ /\./) {
+ ($part,$resp) = split(/\./,$part_and_resp_id);
+ $part_id = &get_part_id($part);
+ $resp_id = &get_part_id($resp);
+ } else {
+ $part_id = &get_part_id($part_and_resp_id);
+ }
+ if ($field =~ /^(tries|award|awarded|previous)$/) {
+ $partdata->{$symb_id}->{$part_id}->{$transaction}->{$field}=$value;
+ }
+ if (defined($resp_id) &&
+ $field =~ /^(tries|awarddetail|awarded|submission)$/) {
+ if ($field eq 'submission') {
+ # We have to be careful with user supplied input.
+ # most of the time we are okay because it is escaped.
+ # However, there is one wrinkle: submissions which end in
+ # and odd number of '\' cause insert errors to occur.
+ # Best trap this somehow...
+ my ($offensive_string) = ($value =~ /(\\+)$/);
+ if (length($offensive_string) % 2) {
+ $value =~ s/\\$/\\\\/;
+ }
+ }
+ $respdata->{$symb_id}->{$part_id}->{$resp_id}->{$transaction}->{$field}=$value;
+ }
+ }
+ }
+ ##
+ ## Store the part data
+ my $store_command = 'INSERT INTO '.$fulldump_part_table.
+ ' VALUES '."\n";
+ my $store_rows = 0;
+ while (my ($symb_id,$hash1) = each (%$partdata)) {
+ while (my ($part_id,$hash2) = each (%$hash1)) {
+ while (my ($transaction,$data) = each (%$hash2)) {
+ $store_command .= "('".join("','",$symb_id,$part_id,
+ $student_id,
+ $transaction,
+ $data->{'tries'},
+ $data->{'award'},
+ $data->{'awarded'},
+ $data->{'previous'})."'),";
+ $store_rows++;
+ }
+ }
+ }
+ if ($store_rows) {
+ chop($store_command);
+ $dbh->do($store_command);
+ if ($dbh->err) {
+ $returnstatus = 'error storing part data';
+ &Apache::lonnet::logthis('insert error '.$dbh->errstr());
+ &Apache::lonnet::logthis("While attempting\n".$store_command);
+ }
+ }
+ ##
+ ## Store the response data
+ $store_command = 'INSERT INTO '.$fulldump_response_table.
+ ' VALUES '."\n";
+ $store_rows = 0;
+ while (my ($symb_id,$hash1) = each (%$respdata)) {
+ while (my ($part_id,$hash2) = each (%$hash1)) {
+ while (my ($resp_id,$hash3) = each (%$hash2)) {
+ while (my ($transaction,$data) = each (%$hash3)) {
+ $store_command .= "('".join("','",$symb_id,$part_id,
+ $resp_id,$student_id,
+ $transaction,
+ $data->{'tries'},
+ $data->{'awarddetail'},
+ $data->{'awarded'},
+ '','',
+ $data->{'submission'})."'),";
+ $store_rows++;
+ }
+ }
+ }
+ }
+ if ($store_rows) {
+ chop($store_command);
+ $dbh->do($store_command);
+ if ($dbh->err) {
+ $returnstatus = 'error storing response data';
+ &Apache::lonnet::logthis('insert error '.$dbh->errstr());
+ &Apache::lonnet::logthis("While attempting\n".$store_command);
+ }
+ }
+ ##
+ ## Update the students "current" data in the performance
+ ## and parameters tables.
+ my ($status,undef) = &store_student_data
+ ($sname,$sdom,$courseid,
+ &Apache::lonnet::convert_dump_to_currentdump(\%studentdata));
+ if ($returnstatus eq 'okay' && $status ne 'okay') {
+ $returnstatus = 'error storing current data:'.$status;
+ } elsif ($status ne 'okay') {
+ $returnstatus .= ' error storing current data:'.$status;
+ }
+ ##
+ ## Update the students time......
+ if ($returnstatus eq 'okay') {
+ &Apache::lonmysql::replace_row
+ ($studentdata_table,
+ [$student_id,$time_of_retrieval,$time_of_retrieval,undef,undef]);
+ }
+ return $returnstatus;
+}
+
+################################################
+################################################
+
+=pod
+
=item &update_student_data()
Input: $sname, $sdom, $courseid
@@ -941,6 +1328,22 @@
return ('no data',undef);
}
my %student_data = @tmp;
+ my @Results = &store_student_data($sname,$sdom,$courseid,\%student_data);
+ #
+ # Set the students update time
+ &Apache::lonmysql::replace_row($studentdata_table,
+ [$student_id,$time_of_retrieval,undef,undef,undef]);
+ #
+ return @Results;
+}
+
+sub store_student_data {
+ my ($sname,$sdom,$courseid,$student_data) = @_;
+ #
+ my $student_id = &get_student_id($sname,$sdom);
+ my $student = $sname.':'.$sdom;
+ #
+ my $returnstatus = 'okay';
#
# Remove all of the students data from the table
my $dbh = &Apache::lonmysql::get_dbh();
@@ -960,7 +1363,7 @@
my $store_performance_command = 'INSERT INTO '.$performance_table.
' VALUES '."\n";
return ('error',undef) if (! defined($dbh));
- while (my ($current_symb,$param_hash) = each(%student_data)) {
+ while (my ($current_symb,$param_hash) = each(%{$student_data})) {
#
# make sure the symb is set up properly
my $symb_id = &get_symb_id($current_symb);
@@ -1015,48 +1418,37 @@
&Apache::lonnet::logthis('rows_stored = '.$rows_stored);
&Apache::lonnet::logthis('student_id = '.$student_id);
$returnstatus = 'error: unable to insert parameters into database';
- return ($returnstatus,\%student_data);
+ return ($returnstatus,$student_data);
}
$dbh->do($store_performance_command);
if ($dbh->err()) {
&Apache::lonnet::logthis(' bigass insert error:'.$dbh->errstr());
&Apache::lonnet::logthis('command = '.$store_performance_command);
$returnstatus = 'error: unable to insert performance into database';
- return ($returnstatus,\%student_data);
+ return ($returnstatus,$student_data);
}
$elapsed += Time::HiRes::time - $start;
- #
- # Set the students update time
- &Apache::lonmysql::replace_row($studentdata_table,
- [$student_id,$time_of_retrieval,undef,undef]);
- return ($returnstatus,\%student_data);
+ return ($returnstatus,$student_data);
}
-################################################
-################################################
+######################################
+######################################
=pod
-=item &ensure_current_data()
+=item &ensure_tables_are_set_up($courseid)
-Input: $sname, $sdom, $courseid
+Checks to be sure the MySQL tables for the given class are set up.
+If $courseid is omitted it will be obtained from the environment.
-Output: $status, $data
-
-This routine ensures the data for a given student is up to date. It calls
-&init_dbs() if the tables do not exist. The $studentdata_table is queried
-to determine the time of the last update. If the students data is out of
-date, &update_student_data() is called. The return values from the call
-to &update_student_data() are returned.
+Returns nothing on success and 'error' on failure
=cut
-################################################
-################################################
-sub ensure_current_data {
- my ($sname,$sdom,$courseid) = @_;
- my $status = 'okay'; # return value
- #
+######################################
+######################################
+sub ensure_tables_are_set_up {
+ my ($courseid) = @_;
$courseid = $ENV{'request.course.id'} if (! defined($courseid));
#
# Clean out package variables
@@ -1065,7 +1457,8 @@
# if the tables do not exist, make them
my @CurrentTable = &Apache::lonmysql::tables_in_db();
my ($found_symb,$found_student,$found_part,$found_studentdata,
- $found_performance,$found_parameters);
+ $found_performance,$found_parameters,$found_fulldump_part,
+ $found_fulldump_response,$found_fulldump_timestamp);
foreach (@CurrentTable) {
$found_symb = 1 if ($_ eq $symb_table);
$found_student = 1 if ($_ eq $student_table);
@@ -1073,14 +1466,47 @@
$found_studentdata = 1 if ($_ eq $studentdata_table);
$found_performance = 1 if ($_ eq $performance_table);
$found_parameters = 1 if ($_ eq $parameters_table);
+ $found_fulldump_part = 1 if ($_ eq $fulldump_part_table);
+ $found_fulldump_response = 1 if ($_ eq $fulldump_response_table);
+ $found_fulldump_timestamp = 1 if ($_ eq $fulldump_timestamp_table);
}
if (!$found_symb || !$found_studentdata ||
!$found_student || !$found_part ||
- !$found_performance || !$found_parameters) {
+ !$found_performance || !$found_parameters ||
+ !$found_fulldump_part || !$found_fulldump_response ||
+ !$found_fulldump_timestamp ) {
if (&init_dbs($courseid)) {
- return ('error',undef);
+ return 'error';
}
}
+}
+
+################################################
+################################################
+
+=pod
+
+=item &ensure_current_data()
+
+Input: $sname, $sdom, $courseid
+
+Output: $status, $data
+
+This routine ensures the data for a given student is up to date.
+The $studentdata_table is queried to determine the time of the last update.
+If the students data is out of date, &update_student_data() is called.
+The return values from the call to &update_student_data() are returned.
+
+=cut
+
+################################################
+################################################
+sub ensure_current_data {
+ my ($sname,$sdom,$courseid) = @_;
+ my $status = 'okay'; # return value
+ #
+ $courseid = $ENV{'request.course.id'} if (! defined($courseid));
+ &ensure_tables_are_set_up($courseid);
#
# Get the update time for the user
my $updatetime = 0;
@@ -1106,6 +1532,54 @@
=pod
+=item &ensure_current_full_data($sname,$sdom,$courseid)
+
+Input: $sname, $sdom, $courseid
+
+Output: $status
+
+This routine ensures the fulldata (the data from a lonnet::dump, not a
+lonnet::currentdump) for a given student is up to date.
+The $studentdata_table is queried to determine the time of the last update.
+If the students fulldata is out of date, &update_full_student_data() is
+called.
+
+The return value from the call to &update_full_student_data() is returned.
+
+=cut
+
+################################################
+################################################
+sub ensure_current_full_data {
+ my ($sname,$sdom,$courseid) = @_;
+ my $status = 'okay'; # return value
+ #
+ $courseid = $ENV{'request.course.id'} if (! defined($courseid));
+ &ensure_tables_are_set_up($courseid);
+ #
+ # Get the update time for the user
+ my $modifiedtime = &Apache::lonnet::GetFileTimestamp
+ ($sdom,$sname,$courseid.'.db',
+ $Apache::lonnet::perlvar{'lonUsersDir'});
+ #
+ my $student_id = &get_student_id($sname,$sdom);
+ my @Result = &Apache::lonmysql::get_rows($studentdata_table,
+ "student_id ='$student_id'");
+ my $updatetime;
+ if (@Result && ref($Result[0]) eq 'ARRAY') {
+ $updatetime = $Result[0]->[2];
+ }
+ if (! defined($updatetime) || $modifiedtime > $updatetime) {
+ $status = &update_full_student_data($sname,$sdom,$courseid);
+ }
+ return $status;
+}
+
+################################################
+################################################
+
+=pod
+
=item &get_student_data_from_performance_cache()
Input: $sname, $sdom, $symb, $courseid
@@ -1482,6 +1956,21 @@
$studentdata_table = $base_id.'_'.'studentdata';
$performance_table = $base_id.'_'.'performance';
$parameters_table = $base_id.'_'.'parameters';
+ $fulldump_part_table = $base_id.'_'.'partdata';
+ $fulldump_response_table = $base_id.'_'.'responsedata';
+ $fulldump_timestamp_table = $base_id.'_'.'timestampdata';
+ #
+ @Tables = (
+ $symb_table,
+ $part_table,
+ $student_table,
+ $studentdata_table,
+ $performance_table,
+ $parameters_table,
+ $fulldump_part_table,
+ $fulldump_response_table,
+ $fulldump_timestamp_table,
+ );
return;
}
@@ -1499,8 +1988,8 @@
################################################
################################################
+} # End scope of table identifiers
-}
################################################
################################################
--matthew1064601091--