version 1.88, 2003/09/24 18:01:01
|
version 1.94, 2003/09/30 15:35:56
|
Line 197 sub get_sequence_assessment_data {
|
Line 197 sub get_sequence_assessment_data {
|
my @Ids = $curRes->responseIds($part); |
my @Ids = $curRes->responseIds($part); |
$partdata{$part}->{'ResponseTypes'}= \@Responses; |
$partdata{$part}->{'ResponseTypes'}= \@Responses; |
$partdata{$part}->{'ResponseIds'} = \@Ids; |
$partdata{$part}->{'ResponseIds'} = \@Ids; |
|
# Count how many responses of each type there are in this part |
|
foreach (@Responses) { |
|
$partdata{$part}->{$_}++; |
|
} |
} |
} |
my $assessment = { title => $title, |
my $assessment = { title => $title, |
src => $src, |
src => $src, |
Line 371 interface in lonmysql.pm and I shudder a
|
Line 375 interface in lonmysql.pm and I shudder a
|
|
|
=over 4 |
=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 |
=item $symb_table |
|
|
The symb_table has two columns. The first is a 'symb_id' and the second |
The symb_table has two columns. The first is a 'symb_id' and the second |
Line 398 internally to the MySQL database and is
|
Line 409 internally to the MySQL database and is
|
|
|
=item $studentdata_table |
=item $studentdata_table |
|
|
The studentdata_table has four columns. The first is 'student_id', the unique |
The studentdata_table has four columns: 'student_id' (the unique id of |
id of the student. The second is the time the students data was last updated. |
the student), 'updatetime' (the time the students data was last updated), |
The third is the students section. The fourth is the students current |
'fullupdatetime' (the time the students full data was last updated), |
classification. This table has its PRIMARY KEY on 'student_id'. |
'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 |
=item $performance_table |
|
|
Line 425 limited to 255 characters. 'value' is l
|
Line 446 limited to 255 characters. 'value' is l
|
|
|
=back |
=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', '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 |
=head3 Important Subroutines |
|
|
Here is a brief overview of the subroutines which are likely to be of |
Here is a brief overview of the subroutines which are likely to be of |
Line 453 interest:
|
Line 513 interest:
|
|
|
################################################ |
################################################ |
################################################ |
################################################ |
{ |
{ # Begin scope of table identifiers |
|
|
my $current_course =''; |
my $current_course =''; |
my $symb_table; |
my $symb_table; |
Line 462 my $student_table;
|
Line 522 my $student_table;
|
my $studentdata_table; |
my $studentdata_table; |
my $performance_table; |
my $performance_table; |
my $parameters_table; |
my $parameters_table; |
|
my $fulldump_response_table; |
|
my $fulldump_part_table; |
|
my $fulldump_timestamp_table; |
|
|
|
my @Tables; |
################################################ |
################################################ |
################################################ |
################################################ |
|
|
Line 486 sub init_dbs {
|
Line 550 sub init_dbs {
|
&setup_table_names($courseid); |
&setup_table_names($courseid); |
# |
# |
# Drop any of the existing tables |
# Drop any of the existing tables |
foreach my $table ($symb_table,$part_table,$student_table, |
foreach my $table (@Tables) { |
$studentdata_table,$performance_table, |
|
$parameters_table) { |
|
&Apache::lonmysql::drop_table($table); |
&Apache::lonmysql::drop_table($table); |
} |
} |
# |
# |
Line 548 sub init_dbs {
|
Line 610 sub init_dbs {
|
type => 'MEDIUMINT UNSIGNED', |
type => 'MEDIUMINT UNSIGNED', |
restrictions => 'NOT NULL UNIQUE',}, |
restrictions => 'NOT NULL UNIQUE',}, |
{ name => 'updatetime', |
{ name => 'updatetime', |
type => 'INT UNSIGNED', |
type => 'INT UNSIGNED'}, |
restrictions => 'NOT NULL' }, |
{ name => 'fullupdatetime', |
|
type => 'INT UNSIGNED'}, |
{ name => 'section', |
{ name => 'section', |
type => 'VARCHAR(100)'}, |
type => 'VARCHAR(100)'}, |
{ name => 'classification', |
{ name => 'classification', |
Line 591 sub init_dbs {
|
Line 654 sub init_dbs {
|
{ columns=>['symb_id'] },], |
{ 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 => '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 = { |
my $parameters_table_def = { |
id => $parameters_table, |
id => $parameters_table, |
permanent => 'no', |
permanent => 'no', |
Line 652 sub init_dbs {
|
Line 819 sub init_dbs {
|
&Apache::lonmysql::get_error()); |
&Apache::lonmysql::get_error()); |
return 6; |
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; |
return 0; |
} |
} |
|
|
Line 673 sub delete_caches {
|
Line 860 sub delete_caches {
|
&setup_table_names($courseid); |
&setup_table_names($courseid); |
# |
# |
my $dbh = &Apache::lonmysql::get_dbh(); |
my $dbh = &Apache::lonmysql::get_dbh(); |
foreach my $table ($symb_table,$part_table,$student_table, |
foreach my $table (@Tables) { |
$studentdata_table,$performance_table, |
|
$parameters_table ){ |
|
my $command = 'DROP TABLE '.$table.';'; |
my $command = 'DROP TABLE '.$table.';'; |
$dbh->do($command); |
$dbh->do($command); |
if ($dbh->err) { |
if ($dbh->err) { |
Line 887 sub get_student {
|
Line 1072 sub get_student {
|
|
|
=pod |
=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| |
|
submissiongrading| |
|
molecule)\s*$/x){ |
|
# 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); |
|
} |
|
# Deal with part specific data |
|
if ($field =~ /^(tries|award|awarded|previous)$/) { |
|
$partdata->{$symb_id}->{$part_id}->{$transaction}->{$field}=$value; |
|
} |
|
# deal with response specific data |
|
if (defined($resp_id) && |
|
$field =~ /^(tries| |
|
awarddetail| |
|
submission| |
|
submissiongrading| |
|
molecule)$/x) { |
|
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/\\$/\\\\/; |
|
} |
|
} |
|
if ($field eq 'submissiongrading' || |
|
$field eq 'molecule') { |
|
$respdata->{$symb_id}->{$part_id}->{$resp_id}->{$transaction}->{'response_specific'}=$field; |
|
$respdata->{$symb_id}->{$part_id}->{$resp_id}->{$transaction}->{'response_specific_value'}=$value; |
|
} else { |
|
$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->{'response_specific'}, |
|
$data->{'response_specific_value'}, |
|
$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() |
=item &update_student_data() |
|
|
Input: $sname, $sdom, $courseid |
Input: $sname, $sdom, $courseid |
Line 941 sub update_student_data {
|
Line 1350 sub update_student_data {
|
return ('no data',undef); |
return ('no data',undef); |
} |
} |
my %student_data = @tmp; |
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 |
# Remove all of the students data from the table |
my $dbh = &Apache::lonmysql::get_dbh(); |
my $dbh = &Apache::lonmysql::get_dbh(); |
Line 960 sub update_student_data {
|
Line 1385 sub update_student_data {
|
my $store_performance_command = 'INSERT INTO '.$performance_table. |
my $store_performance_command = 'INSERT INTO '.$performance_table. |
' VALUES '."\n"; |
' VALUES '."\n"; |
return ('error',undef) if (! defined($dbh)); |
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 |
# make sure the symb is set up properly |
my $symb_id = &get_symb_id($current_symb); |
my $symb_id = &get_symb_id($current_symb); |
Line 1008 sub update_student_data {
|
Line 1433 sub update_student_data {
|
chop $store_performance_command; |
chop $store_performance_command; |
chop $store_performance_command; |
chop $store_performance_command; |
my $start = Time::HiRes::time; |
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); |
|
$returnstatus = 'error: unable to insert performance into database'; |
|
return ($returnstatus,$student_data); |
|
} |
$dbh->do($store_parameters_command) if ($num_parameters>0); |
$dbh->do($store_parameters_command) if ($num_parameters>0); |
if ($dbh->err()) { |
if ($dbh->err()) { |
&Apache::lonnet::logthis(' bigass insert error:'.$dbh->errstr()); |
&Apache::lonnet::logthis(' bigass insert error:'.$dbh->errstr()); |
Line 1015 sub update_student_data {
|
Line 1447 sub update_student_data {
|
&Apache::lonnet::logthis('rows_stored = '.$rows_stored); |
&Apache::lonnet::logthis('rows_stored = '.$rows_stored); |
&Apache::lonnet::logthis('student_id = '.$student_id); |
&Apache::lonnet::logthis('student_id = '.$student_id); |
$returnstatus = 'error: unable to insert parameters into database'; |
$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); |
|
} |
} |
$elapsed += Time::HiRes::time - $start; |
$elapsed += Time::HiRes::time - $start; |
# |
return ($returnstatus,$student_data); |
# Set the students update time |
|
&Apache::lonmysql::replace_row($studentdata_table, |
|
[$student_id,$time_of_retrieval,undef,undef]); |
|
return ($returnstatus,\%student_data); |
|
} |
} |
|
|
################################################ |
###################################### |
################################################ |
###################################### |
|
|
=pod |
=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 |
Returns nothing on success and 'error' on failure |
&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. |
|
|
|
=cut |
=cut |
|
|
################################################ |
###################################### |
################################################ |
###################################### |
sub ensure_current_data { |
sub ensure_tables_are_set_up { |
my ($sname,$sdom,$courseid) = @_; |
my ($courseid) = @_; |
my $status = 'okay'; # return value |
|
# |
|
$courseid = $ENV{'request.course.id'} if (! defined($courseid)); |
$courseid = $ENV{'request.course.id'} if (! defined($courseid)); |
# |
# |
# Clean out package variables |
# Clean out package variables |
Line 1065 sub ensure_current_data {
|
Line 1479 sub ensure_current_data {
|
# if the tables do not exist, make them |
# if the tables do not exist, make them |
my @CurrentTable = &Apache::lonmysql::tables_in_db(); |
my @CurrentTable = &Apache::lonmysql::tables_in_db(); |
my ($found_symb,$found_student,$found_part,$found_studentdata, |
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) { |
foreach (@CurrentTable) { |
$found_symb = 1 if ($_ eq $symb_table); |
$found_symb = 1 if ($_ eq $symb_table); |
$found_student = 1 if ($_ eq $student_table); |
$found_student = 1 if ($_ eq $student_table); |
Line 1073 sub ensure_current_data {
|
Line 1488 sub ensure_current_data {
|
$found_studentdata = 1 if ($_ eq $studentdata_table); |
$found_studentdata = 1 if ($_ eq $studentdata_table); |
$found_performance = 1 if ($_ eq $performance_table); |
$found_performance = 1 if ($_ eq $performance_table); |
$found_parameters = 1 if ($_ eq $parameters_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 || |
if (!$found_symb || !$found_studentdata || |
!$found_student || !$found_part || |
!$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)) { |
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 |
# Get the update time for the user |
my $updatetime = 0; |
my $updatetime = 0; |
Line 1106 sub ensure_current_data {
|
Line 1554 sub ensure_current_data {
|
|
|
=pod |
=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() |
=item &get_student_data_from_performance_cache() |
|
|
Input: $sname, $sdom, $symb, $courseid |
Input: $sname, $sdom, $symb, $courseid |
Line 1368 sub get_problem_statistics {
|
Line 1864 sub get_problem_statistics {
|
$stats_table); |
$stats_table); |
my ($Solved) = &execute_SQL_request($dbh,'SELECT COUNT(tries) FROM '. |
my ($Solved) = &execute_SQL_request($dbh,'SELECT COUNT(tries) FROM '. |
$stats_table. |
$stats_table. |
" WHERE solved='correct_by_student'"); |
" WHERE solved='correct_by_student' OR solved='correct_by_scantron'"); |
my ($solved) = &execute_SQL_request($dbh,'SELECT COUNT(tries) FROM '. |
my ($solved) = &execute_SQL_request($dbh,'SELECT COUNT(tries) FROM '. |
$stats_table. |
$stats_table. |
" WHERE solved='correct_by_override'"); |
" WHERE solved='correct_by_override'"); |
Line 1482 sub setup_table_names {
|
Line 1978 sub setup_table_names {
|
$studentdata_table = $base_id.'_'.'studentdata'; |
$studentdata_table = $base_id.'_'.'studentdata'; |
$performance_table = $base_id.'_'.'performance'; |
$performance_table = $base_id.'_'.'performance'; |
$parameters_table = $base_id.'_'.'parameters'; |
$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; |
return; |
} |
} |
|
|
Line 1499 sub setup_table_names {
|
Line 2010 sub setup_table_names {
|
################################################ |
################################################ |
################################################ |
################################################ |
|
|
|
} # End scope of table identifiers |
|
|
} |
|
################################################ |
################################################ |
################################################ |
################################################ |
|
|