--- loncom/interface/lonmysql.pm 2005/04/11 21:36:50 1.31 +++ loncom/interface/lonmysql.pm 2011/05/31 02:40:02 1.39 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # MySQL utility functions # -# $Id: lonmysql.pm,v 1.31 2005/04/11 21:36:50 albertel Exp $ +# $Id: lonmysql.pm,v 1.39 2011/05/31 02:40:02 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -37,6 +37,7 @@ use Apache::lonnet; my $mysqluser; my $mysqlpassword; my $mysqldatabase; +my %db_config; sub set_mysql_user_and_password { # If we are running under Apache and LONCAPA, use the LON-CAPA @@ -86,14 +87,15 @@ and provide a common interface. The goa a complete reimplementation of the DBI interface. Instead we try to make using mysql as painless as possible. -Each table has a numeric ID that is a parameter to most lonmysql functions. -The table id is returned by &create_table. -If you lose the table id, it is lost forever. -The table names in MySQL correspond to -$env{'user.name'}.'_'.$env{'user.domain'}.'_'.$table_id. If the table id -is non-numeric, it is assumed to be the full name of a table. If you pass -the table id in a form, you MUST ensure that what you send to lonmysql is -numeric, otherwise you are opening up all the tables in the MySQL database. +Each table has a numeric ID that is a parameter to most lonmysql +functions. The table id is returned by &create_table. If you lose +the table id, it is lost forever. The table names in MySQL correspond +to $env{'user.name'}.'_'.$env{'user.domain'}.'_'.$table_id. (With all +non-word characters removed form user.name and user.domain) If the +table id is non-numeric, it is assumed to be the full name of a table. +If you pass the table id in a form, you MUST ensure that what you send +to lonmysql is numeric, otherwise you are opening up all the tables in +the MySQL database. =over 4 @@ -375,6 +377,22 @@ sub connect_to_db { return undef; } $debugstring = "Successfully connected to loncapa database."; + # Determine DB configuration + undef(%db_config); + my $sth = $dbh->prepare("SHOW VARIABLES"); + $sth->execute(); + if ($sth->err()) { + $debugstring = "Unable to retrieve db config variables"; + return undef; + } + foreach my $row (@{$sth->fetchall_arrayref}) { + $db_config{$row->[0]} = $row->[1]; + } + #&Apache::lonnet::logthis("MySQL configuration variables"); + #while (my ($k,$v) = each(%db_config)) { + # &Apache::lonnet::logthis(" '$k' => '$v'"); + #} + # return 1; } @@ -554,10 +572,6 @@ sub update_table_info { # # Get MySQLs table status information. # - my @tabledesc = qw/ - Name Type Row_format Rows Avg_row_length Data_length - Max_data_length Index_length Data_free Auto_increment - Create_time Update_time Check_time Create_options Comment /; my $db_command = "SHOW TABLE STATUS FROM loncapa LIKE '$tablename'"; my $sth = $dbh->prepare($db_command); $sth->execute(); @@ -567,14 +581,15 @@ sub update_table_info { &disconnect_from_db(); return undef; } + my @column_name = @{$sth->{NAME}}; # my @info=$sth->fetchrow_array; for (my $i=0;$i<= $#info ; $i++) { - if ($tabledesc[$i] !~ /^(Create_|Update_|Check_)time$/) { - $Tables{$tablename}->{$tabledesc[$i]}= + if ($column_name[$i] =~ /^(Create_|Update_|Check_)time$/) { + $Tables{$tablename}->{$column_name[$i]}= &unsqltime($info[$i]); } else { - $Tables{$tablename}->{$tabledesc[$i]}= $info[$i]; + $Tables{$tablename}->{$column_name[$i]}= $info[$i]; } } # @@ -802,7 +817,7 @@ sub build_table_creation_request { unless($table_des->{'permanent'} eq 'yes') { $request.="COMMENT = 'temporary' "; } - $request .= "TYPE=MYISAM"; + $request .= "ENGINE=MYISAM"; return $request,$table_id; } @@ -810,6 +825,25 @@ sub build_table_creation_request { =pod +=item &get_table_prefix() + +returns the cleaned version of user.name and user.domain for us in table names + +=cut + +############################### +sub get_table_prefix { + my $clean_name = $env{'user.name'}; + my $clean_domain = $env{'user.domain'}; + $clean_name =~ s/\W//g; + $clean_domain =~ s/\W//g; + return $clean_name.'_'.$clean_domain.'_'; +} + +############################### + +=pod + =item &get_new_table_id() Used internally to prevent table name collisions. @@ -820,8 +854,9 @@ Used internally to prevent table name co sub get_new_table_id { my $newid = 0; my @tables = &tables_in_db(); + my $prefix = &get_table_prefix(); foreach (@tables) { - if (/^$env{'user.name'}_$env{'user.domain'}_(\d+)$/) { + if (/^\Q$prefix\E(\d+)$/) { $newid = $1 if ($1 > $newid); } } @@ -977,6 +1012,7 @@ sub bulk_store_rows { $request .= '('.join(',',@$row).'),'; } $request =~ s/,$//; + # $debugstring = "Executed ".$/.$request; # commented out - this is big $dbh->do($request); if ($dbh->err) { $errorstring = 'Attempted '.$/.$request.$/.'Got error '.$dbh->errstr(); @@ -1059,16 +1095,29 @@ Returns undef on error. =cut ########################################### + +########## Show-Tables Cache +my $have_read_tables = 0; +my $dbh_sth; +########## + sub tables_in_db { return undef if (!defined(&connect_to_db())); - my $sth=$dbh->prepare('SHOW TABLES'); - $sth->execute(); - $sth->execute(); - my $aref = $sth->fetchall_arrayref; - if ($sth->err()) { + + ########## Show-Tables Cache + if(!$have_read_tables) { + $dbh_sth=$dbh->prepare('SHOW TABLES'); + $have_read_tables = 1; + } + $dbh_sth->execute(); + #$dbh_sth->execute(); # Removed strange execute - from release 119 + ########## + + my $aref = $dbh_sth->fetchall_arrayref; + if ($dbh_sth->err()) { $errorstring = "$dbh ATTEMPTED:\n".'fetchall_arrayref after SHOW TABLES'. - "\nRESULTING ERROR:\n".$sth->errstr; + "\nRESULTING ERROR:\n".$dbh_sth->errstr; return undef; } my @table_list; @@ -1099,7 +1148,7 @@ sub translate_id { # id should be a digit. If it is not a digit we assume the given id # is complete and does not need to be translated. return $id if ($id =~ /\D/); - return $env{'user.name'}.'_'.$env{'user.domain'}.'_'.$id; + return &get_table_prefix().$id; } ###########################################