From 1dfc58e58e333eb5ccc28b1aaafda4aeeeccaeb3 Mon Sep 17 00:00:00 2001 From: Peter Staab Date: Sat, 2 Mar 2024 07:21:55 -0500 Subject: [PATCH] Continued removal of old dbLayouts This removes all references to dbLayoutName and cases where the dbLayouts hash is used. With this, there is only the standard dbLayout, which is now defined in `WeBWorK::DB::Layout`. --- bin/addcourse | 18 +- bin/old_scripts/wwaddindexing | 9 +- bin/upgrade-database-to-utf8mb4.pl | 2 +- conf/README.md | 3 +- conf/defaults.config | 10 +- conf/localOverrides.conf.dist | 25 ++ conf/site.conf.dist | 2 - conf/webwork2.mojolicious.dist.yml | 16 +- courses.dist/modelCourse/course.conf | 11 - lib/Mojolicious/WeBWorK.pm | 4 +- lib/WeBWorK/Authen.pm | 16 +- lib/WeBWorK/ContentGenerator/CourseAdmin.pm | 169 +++++----- lib/WeBWorK/CourseEnvironment.pm | 25 +- lib/WeBWorK/DB/Layout.pm | 298 ++++++++++++++++++ lib/WeBWorK/DB/Utils.pm | 272 ---------------- lib/WeBWorK/Utils/CourseIntegrityCheck.pm | 3 +- lib/WeBWorK/Utils/CourseManagement.pm | 185 ++--------- .../Utils/CourseManagement/sql_moodle.pm | 33 -- .../Utils/CourseManagement/sql_single.pm | 275 ---------------- lib/WebworkWebservice/CourseActions.pm | 2 +- .../ContentGenerator/Base/admin_links.html.ep | 1 - .../CourseAdmin/add_course_form.html.ep | 1 - .../CourseAdmin/upgrade_course_form.html.ep | 1 - 23 files changed, 465 insertions(+), 916 deletions(-) create mode 100644 lib/WeBWorK/DB/Layout.pm delete mode 100644 lib/WeBWorK/Utils/CourseManagement/sql_moodle.pm delete mode 100644 lib/WeBWorK/Utils/CourseManagement/sql_single.pm diff --git a/bin/addcourse b/bin/addcourse index 0eeb844de3..3c1abd528a 100755 --- a/bin/addcourse +++ b/bin/addcourse @@ -90,7 +90,6 @@ sub usage_error { warn "@_\n"; warn "usage: $0 [options] COURSEID\n"; warn "Options:\n"; - warn " [--db-layout=LAYOUT]\n"; warn " [--users=FILE [--professors=USERID[,USERID]...] ]\n"; exit; } @@ -99,7 +98,6 @@ my ($dbLayout, $users, $templates_from) = ('', '', ''); my @professors; GetOptions( - "db-layout=s" => \$dbLayout, "users=s" => \$users, "professors=s" => \@professors, "templates-from=s" => \$templates_from, @@ -114,23 +112,15 @@ $ce = WeBWorK::CourseEnvironment->new({ courseName => $courseID }); die "Aborting addcourse: Course ID cannot exceed $ce->{maxCourseIdLength} characters." if length($courseID) > $ce->{maxCourseIdLength}; -if ($dbLayout) { - die "Database layout $dbLayout does not exist in the course environment.", - " (It must be defined in defaults.config.)\n" - unless exists $ce->{dbLayouts}{$dbLayout}; -} else { - $dbLayout = $ce->{dbLayoutName}; -} - usage_error("Can't specify --professors without also specifying --users.") if @professors && !$users; my @users; if ($users) { # This is a hack to create records without bringing up a DB object - my $userClass = $ce->{dbLayouts}{$dbLayout}{user}{record}; - my $passwordClass = $ce->{dbLayouts}{$dbLayout}{password}{record}; - my $permissionClass = $ce->{dbLayouts}{$dbLayout}{permission}{record}; + my $userClass = $ce->{dbLayout}{user}{record}; + my $passwordClass = $ce->{dbLayout}{password}{record}; + my $permissionClass = $ce->{dbLayout}{permission}{record}; runtime_use($userClass); runtime_use($passwordClass); @@ -190,7 +180,7 @@ eval { addCourse( courseID => $courseID, ce => $ce, - courseOptions => { dbLayoutName => $dbLayout }, + courseOptions => {}, users => \@users, %optional_arguments, ); diff --git a/bin/old_scripts/wwaddindexing b/bin/old_scripts/wwaddindexing index 9319a9d933..d2600d1a52 100755 --- a/bin/old_scripts/wwaddindexing +++ b/bin/old_scripts/wwaddindexing @@ -16,7 +16,7 @@ =head1 NAME -wwaddindexing - add indices to an existing sql_single course. +wwaddindexing - add indices to an existing course. =head1 SYNOPSIS @@ -24,8 +24,7 @@ wwaddindexing - add indices to an existing sql_single course. =head1 DESCRIPTION -Adds indices to the course named COURSEID. The course must use the sql_single -database layout. +Adds indices to the course named COURSEID. =cut @@ -74,10 +73,6 @@ my $ce = WeBWorK::CourseEnvironment->new({ courseName => $courseID, }); -# make sure the course actually uses the 'sql_single' layout -usage_error("$courseID: does not use 'sql_single' database layout.") - unless $ce->{dbLayoutName} eq "sql_single"; - # get database layout source data my %sources = dbLayoutSQLSources($ce->{dbLayout}); diff --git a/bin/upgrade-database-to-utf8mb4.pl b/bin/upgrade-database-to-utf8mb4.pl index a79eb98a06..24347b0754 100755 --- a/bin/upgrade-database-to-utf8mb4.pl +++ b/bin/upgrade-database-to-utf8mb4.pl @@ -212,7 +212,7 @@ BEGIN }, ); -my $db = new WeBWorK::DB($ce->{dbLayouts}{ $ce->{dbLayoutName} }); +my $db = new WeBWorK::DB($ce->{dbLayout}); my @table_types = sort(grep { !$db->{$_}{params}{non_native} } keys %$db); sub checkAndUpdateTableColumnTypes { diff --git a/conf/README.md b/conf/README.md index aeaeebfb4e..e439baeabb 100644 --- a/conf/README.md +++ b/conf/README.md @@ -28,7 +28,8 @@ Configuration extension files. Server configuration files. - `webwork2.mojolicious.dist.yml` contains the webwork2 Mojolicious app configuration settings. Copy this file to - `webwork2.mojolicious.yml` if you need to change those settings. You usually will need to do this. This file contains server settings, database settings and paths to external programs. + `webwork2.mojolicious.yml` if you need to change those settings. You usually will need to do this. This file + contains server settings, database settings and paths to external programs. - `webwork2.dist.service` is a systemd configuration file for linux systems that serves the webwork2 app via the Mojolicious hypnotoad server. If you need to change it, then copy it to `webwork2.service`. - `webwork2-job-queue.dist.service` is a systemd configuration file for linux systems that runs the webwork2 job queue diff --git a/conf/defaults.config b/conf/defaults.config index 4f58f0ddd7..c9c390cc99 100644 --- a/conf/defaults.config +++ b/conf/defaults.config @@ -1017,12 +1017,10 @@ $pg{displayModeOptions}{images} = { # as 'baseline' or 'middle'. dvipng_align => 'baseline', - # If dbsource is set to a nonempty value, then this database connection information will be used to store dvipng - # depths. It is assumed that the 'depths' table exists in the database. - # These are set in the CourseEnvironment. - dvipng_depth_db => {} - }, -}; + # The dvipng_depth_db will be used to store dvipng depths. It is assumed that the 'depths' + # table exists in the database. If you wish to override using the standard database connections + # see localOverrides.conf +}, ##### Directories used by PG diff --git a/conf/localOverrides.conf.dist b/conf/localOverrides.conf.dist index 453d6197ae..33d6bd625e 100644 --- a/conf/localOverrides.conf.dist +++ b/conf/localOverrides.conf.dist @@ -404,6 +404,31 @@ $mail{feedbackRecipients} = [ #push (@{${pg}{modules}}, [qw(LaTeXImage)]); + +############################## +# Additional Database options +############################### + +# If dbsource is set to a nonempty value, then this database connection information will be used to store dvipng +# depths. It is assumed that the 'depths' table exists in the database. + +# $pg{displayModeOptions}{images}{dvipng_depth_db} => { +# dbsource => 'dsn_database_string', +# user => 'dsn_database_username', +# passwd => 'dsn_database_password', +# }, + +# Problem Library SQL database connection information + +# $problemLibrary_db = { +# dbsource => 'database_dsn', +# user => 'database_username', +# passwd => 'database_password', +# storage_engine => 'myisam', +# }; + + + ################################################################################ # Using R with WeBWorK ################################################################################ diff --git a/conf/site.conf.dist b/conf/site.conf.dist index b1e2725c02..5e14d97f5c 100644 --- a/conf/site.conf.dist +++ b/conf/site.conf.dist @@ -93,8 +93,6 @@ $admin_course_id = 'admin'; # status. #$new_courses_hidden_status = 'hidden'; -# External Programs and database settings are now defined in webwork2.mojolicious.yml - ################################################################################# # These variables describe the locations of various components of WeBWorK on your # server. You may use the defaults unless you have things in different places. diff --git a/conf/webwork2.mojolicious.dist.yml b/conf/webwork2.mojolicious.dist.yml index b715857b79..b4a7d9af0e 100644 --- a/conf/webwork2.mojolicious.dist.yml +++ b/conf/webwork2.mojolicious.dist.yml @@ -252,7 +252,7 @@ externalPrograms: mkdir: /bin/mkdir tar: /bin/tar gzip: /bin/gzip - git: /bin/git + git: /usr/bin/git curl: /usr/bin/curl mysql: /usr/bin/mysql mysqldump: /usr/bin/mysqldump @@ -266,8 +266,13 @@ externalPrograms: # use polyglossia and fontspec packages (which require xelatex or lualatex). # pdflatex: /usr/bin/xelatex --no-shell-escape - dvipng: /usr/bin/dvipng + + # In order to use imagemagick convert you need to change the rights for PDF files from + # "none" to "read" in the policy file /etc/ImageMagick-6/policy.xml. This has possible + # security implications for the server. convert: /usr/bin/convert + + dvipng: /usr/bin/dvipng dvisvgm: /usr/bin/dvisvgm pdf2svg: /usr/bin/pdf2svg @@ -296,15 +301,12 @@ database: # Standard permissions command used to initialize the webwork database # GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, INDEX, LOCK TABLES ON webwork.* TO webworkWrite@localhost IDENTIFIED BY 'passwordRW'; # where webworkWrite and passwordRW must match the corresponding variables in the next section. - username: '' - password: '' + username: webworkWrite + password: passwordRW # For a DB on localhost - default to using Unix socket. Change to 0 to use a TCP connection to 127.0.0.1. use_socket_if_localhost: 1 - # Need to add the code in lines 209-217 to a perl file - # Add line 234 to same file - # The default storange engine to use is set here: storage_engine: myisam diff --git a/courses.dist/modelCourse/course.conf b/courses.dist/modelCourse/course.conf index fb80c242a5..ff74987a9a 100644 --- a/courses.dist/modelCourse/course.conf +++ b/courses.dist/modelCourse/course.conf @@ -2,17 +2,6 @@ # This file is used to override the global WeBWorK course environment for this course. -# Database Layout (global value typically defined in global.conf) -# Several database are defined in the file conf/database.conf and stored in the -# hash %dbLayouts. -# The database layout is always set here, since one should be able to change the -# default value in global.conf without disrupting existing courses. -# global.conf values: -# $dbLayoutName = 'sql_single'; -# *dbLayout = $dbLayouts{$dbLayoutName}; -$dbLayoutName = 'sql_single'; -*dbLayout = $dbLayouts{$dbLayoutName}; - # Users for whom to label problems with the PG file name # For users in this list, PG will display the source file name when rendering a problem. #$pg{specialPGEnvironmentVars}{PRINT_FILE_NAMES_FOR} = ['user_id1']; diff --git a/lib/Mojolicious/WeBWorK.pm b/lib/Mojolicious/WeBWorK.pm index 596d9cefd1..1079e4fc19 100644 --- a/lib/Mojolicious/WeBWorK.pm +++ b/lib/Mojolicious/WeBWorK.pm @@ -172,9 +172,7 @@ sub startup ($app) { writeTimingLogEntry( $c->ce, '[' . $c->url_for . ']', - sprintf('runTime = %.3f sec', $c->timing->elapsed('content_generator_rendering')) . ' ' - . $c->ce->{dbLayoutName}, - '' + sprintf('runTime = %.3f sec', $c->timing->elapsed('content_generator_rendering')), '' ); } } diff --git a/lib/WeBWorK/Authen.pm b/lib/WeBWorK/Authen.pm index 299bba9e6c..6d7ebbb5d9 100644 --- a/lib/WeBWorK/Authen.pm +++ b/lib/WeBWorK/Authen.pm @@ -93,26 +93,22 @@ sub class { if (exists $ce->{authen}{$type}) { if (ref $ce->{authen}{$type} eq "ARRAY") { my $authen_type = shift @{ $ce->{authen}{$type} }; + + #debug("ref of authen_type = |" . ref($authen_type) . "|"); if (ref($authen_type) eq "HASH") { - if (exists $authen_type->{ $ce->{dbLayoutName} }) { - return $authen_type->{ $ce->{dbLayoutName} }; - } elsif (exists $authen_type->{"*"}) { + if (exists $authen_type->{"*"}) { return $authen_type->{"*"}; } else { - die "authentication type '$type' in the course environment has no entry for db layout '", - $ce->{dbLayoutName}, "' and no default entry (*)"; + die "authentication type '$type' in the course environment has no default entry (*)"; } } else { return $authen_type; } } elsif (ref $ce->{authen}{$type} eq "HASH") { - if (exists $ce->{authen}{$type}{ $ce->{dbLayoutName} }) { - return $ce->{authen}{$type}{ $ce->{dbLayoutName} }; - } elsif (exists $ce->{authen}{$type}{"*"}) { + if (exists $ce->{authen}{$type}{"*"}) { return $ce->{authen}{$type}{"*"}; } else { - die "authentication type '$type' in the course environment has no entry for db layout '", - $ce->{dbLayoutName}, "' and no default entry (*)"; + die "authentication type '$type' in the course environment has no default entry (*)"; } } else { return $ce->{authen}{$type}; diff --git a/lib/WeBWorK/ContentGenerator/CourseAdmin.pm b/lib/WeBWorK/ContentGenerator/CourseAdmin.pm index f30be1fca9..8b16ac92fc 100644 --- a/lib/WeBWorK/ContentGenerator/CourseAdmin.pm +++ b/lib/WeBWorK/ContentGenerator/CourseAdmin.pm @@ -52,7 +52,7 @@ sub pre_header_initialize ($c) { # Check that the non-native tables are present in the database. # These are the tables which are not course specific. - my @table_update_messages = initNonNativeTables($ce, $ce->{dbLayoutName}); + my @table_update_messages = initNonNativeTables($ce); $c->addgoodmessage($c->c(@table_update_messages)->join($c->tag('br'))) if @table_update_messages; my @errors; @@ -237,7 +237,6 @@ sub add_course_validate ($c) { my $add_initial_firstName = trim_spaces($c->param('add_initial_firstName')) || ''; my $add_initial_lastName = trim_spaces($c->param('add_initial_lastName')) || ''; my $add_initial_email = trim_spaces($c->param('add_initial_email')) || ''; - my $add_dbLayout = trim_spaces($c->param('add_dbLayout')) || ''; my @errors; @@ -275,17 +274,6 @@ sub add_course_validate ($c) { } } - if ($add_dbLayout eq '') { - push @errors, 'You must select a database layout.'; - } else { - if (exists $ce->{dbLayouts}{$add_dbLayout}) { - # we used to check for layout-specific fields here, but there aren't any layouts that require them - # anymore. (in the future, we'll probably deal with this in layout-specific modules.) - } else { - push @errors, "The database layout $add_dbLayout doesn't exist."; - } - } - return @errors; } @@ -307,12 +295,8 @@ sub do_add_course ($c) { my $copy_from_course = trim_spaces($c->param('copy_from_course')) // ''; - my $add_dbLayout = trim_spaces($c->param('add_dbLayout')) || ''; - my $ce2 = WeBWorK::CourseEnvironment->new({ courseName => $add_courseID }); - my %courseOptions = (dbLayoutName => $add_dbLayout); - my @users; # copy users from current (admin) course if desired @@ -357,7 +341,7 @@ sub do_add_course ($c) { ); push @users, [ $User, $Password, $PermissionLevel ]; } - + my %courseOptions = (); push @{ $courseOptions{PRINT_FILE_NAMES_FOR} }, map { $_->[0]->user_id } @users; # Include any optional arguments, including a template course and the course title and course institution. @@ -496,9 +480,8 @@ sub rename_course_confirm ($c) { # Create strings confirming title and institution change. # Connect to the database to get old title and institution. - my $dbLayoutName = $ce->{dbLayoutName}; - my $db = WeBWorK::DB->new($ce->{dbLayouts}{$dbLayoutName}); - my $oldDB = WeBWorK::DB->new($ce2->{dbLayouts}{$dbLayoutName}); + my $db = WeBWorK::DB->new($ce->{dbLayout}); + my $oldDB = WeBWorK::DB->new($ce2->{dbLayout}); my $rename_oldCourseTitle = $oldDB->getSettingValue('courseTitle') // ''; my $rename_oldCourseInstitution = $oldDB->getSettingValue('courseInstitution') // ''; @@ -522,49 +505,46 @@ sub rename_course_confirm ($c) { rename_oldCourseID => $rename_oldCourseID ) unless $c->param('rename_newCourseID_checkbox'); - if ($ce2->{dbLayoutName}) { - my $CIchecker = WeBWorK::Utils::CourseIntegrityCheck->new(ce => $ce2); - - # Check database - my ($tables_ok, $dbStatus) = $CIchecker->checkCourseTables($rename_oldCourseID); + my $CIchecker = WeBWorK::Utils::CourseIntegrityCheck->new(ce => $ce2); - # Upgrade the database if requested. - my @upgrade_report; - if ($c->param('upgrade_course_tables')) { - my @schema_table_names = keys %$dbStatus; - my @tables_to_create = - grep { $dbStatus->{$_}->[0] == WeBWorK::Utils::CourseIntegrityCheck::ONLY_IN_A } @schema_table_names; - my @tables_to_alter = - grep { $dbStatus->{$_}->[0] == WeBWorK::Utils::CourseIntegrityCheck::DIFFER_IN_A_AND_B } - @schema_table_names; - push(@upgrade_report, $CIchecker->updateCourseTables($rename_oldCourseID, [@tables_to_create])); - for my $table_name (@tables_to_alter) { - push(@upgrade_report, $CIchecker->updateTableFields($rename_oldCourseID, $table_name)); - } + # Check database + my ($tables_ok, $dbStatus) = $CIchecker->checkCourseTables($rename_oldCourseID); - ($tables_ok, $dbStatus) = $CIchecker->checkCourseTables($rename_oldCourseID); + # Upgrade the database if requested. + my @upgrade_report; + if ($c->param('upgrade_course_tables')) { + my @schema_table_names = keys %$dbStatus; + my @tables_to_create = + grep { $dbStatus->{$_}->[0] == WeBWorK::Utils::CourseIntegrityCheck::ONLY_IN_A } @schema_table_names; + my @tables_to_alter = + grep { $dbStatus->{$_}->[0] == WeBWorK::Utils::CourseIntegrityCheck::DIFFER_IN_A_AND_B } + @schema_table_names; + push(@upgrade_report, $CIchecker->updateCourseTables($rename_oldCourseID, [@tables_to_create])); + for my $table_name (@tables_to_alter) { + push(@upgrade_report, $CIchecker->updateTableFields($rename_oldCourseID, $table_name)); } - # Check directories - my ($directories_ok, $directory_report) = $CIchecker->checkCourseDirectories($ce2); - - return $c->include( - 'ContentGenerator/CourseAdmin/rename_course_confirm', - upgrade_report => \@upgrade_report, - tables_ok => $tables_ok, - dbStatus => $dbStatus, - directory_report => $directory_report, - directories_ok => $directories_ok, - rename_oldCourseTitle => $rename_oldCourseTitle, - change_course_title_str => $change_course_title_str, - rename_oldCourseInstitution => $rename_oldCourseInstitution, - change_course_institution_str => $change_course_institution_str, - rename_oldCourseID => $rename_oldCourseID, - rename_newCourseID => $rename_newCourseID - ); - } else { - return $c->tag('p', class => 'text-danger fw-bold', "Unable to find database layout for $rename_oldCourseID"); + ($tables_ok, $dbStatus) = $CIchecker->checkCourseTables($rename_oldCourseID); } + + # Check directories + my ($directories_ok, $directory_report) = $CIchecker->checkCourseDirectories($ce2); + + return $c->include( + 'ContentGenerator/CourseAdmin/rename_course_confirm', + upgrade_report => \@upgrade_report, + tables_ok => $tables_ok, + dbStatus => $dbStatus, + directory_report => $directory_report, + directories_ok => $directories_ok, + rename_oldCourseTitle => $rename_oldCourseTitle, + change_course_title_str => $change_course_title_str, + rename_oldCourseInstitution => $rename_oldCourseInstitution, + change_course_institution_str => $change_course_institution_str, + rename_oldCourseID => $rename_oldCourseID, + rename_newCourseID => $rename_newCourseID + ); + return; } sub rename_course_validate ($c) { @@ -1002,48 +982,45 @@ sub archive_course_confirm ($c) { my $ce2 = WeBWorK::CourseEnvironment->new({ courseName => $archive_courseID }); - if ($ce2->{dbLayoutName}) { - my $CIchecker = WeBWorK::Utils::CourseIntegrityCheck->new(ce => $ce2); - - # Check database - my ($tables_ok, $dbStatus) = $CIchecker->checkCourseTables($archive_courseID); + my $CIchecker = WeBWorK::Utils::CourseIntegrityCheck->new(ce => $ce2); - # Upgrade the database if requested. - my @upgrade_report; - if ($c->param('upgrade_course_tables')) { - my @schema_table_names = keys %$dbStatus; - my @tables_to_create = - grep { $dbStatus->{$_}->[0] == WeBWorK::Utils::CourseIntegrityCheck::ONLY_IN_A } @schema_table_names; - my @tables_to_alter = - grep { $dbStatus->{$_}->[0] == WeBWorK::Utils::CourseIntegrityCheck::DIFFER_IN_A_AND_B } - @schema_table_names; - push(@upgrade_report, $CIchecker->updateCourseTables($archive_courseID, [@tables_to_create])); - for my $table_name (@tables_to_alter) { - push(@upgrade_report, $CIchecker->updateTableFields($archive_courseID, $table_name)); - } + # Check database + my ($tables_ok, $dbStatus) = $CIchecker->checkCourseTables($archive_courseID); - ($tables_ok, $dbStatus) = $CIchecker->checkCourseTables($archive_courseID); + # Upgrade the database if requested. + my @upgrade_report; + if ($c->param('upgrade_course_tables')) { + my @schema_table_names = keys %$dbStatus; + my @tables_to_create = + grep { $dbStatus->{$_}->[0] == WeBWorK::Utils::CourseIntegrityCheck::ONLY_IN_A } @schema_table_names; + my @tables_to_alter = + grep { $dbStatus->{$_}->[0] == WeBWorK::Utils::CourseIntegrityCheck::DIFFER_IN_A_AND_B } + @schema_table_names; + push(@upgrade_report, $CIchecker->updateCourseTables($archive_courseID, [@tables_to_create])); + for my $table_name (@tables_to_alter) { + push(@upgrade_report, $CIchecker->updateTableFields($archive_courseID, $table_name)); } - # Update and check directories. - my $dir_update_messages = $c->param('upgrade_course_tables') ? $CIchecker->updateCourseDirectories : []; - my ($directories_ok, $directory_report) = $CIchecker->checkCourseDirectories($ce2); - - return $c->include( - 'ContentGenerator/CourseAdmin/archive_course_confirm', - ce2 => $ce2, - upgrade_report => \@upgrade_report, - tables_ok => $tables_ok, - dbStatus => $dbStatus, - dir_update_messages => $dir_update_messages, - directory_report => $directory_report, - directories_ok => $directories_ok, - archive_courseID => $archive_courseID, - archive_courseIDs => \@archive_courseIDs - ); - } else { - return $c->tag('p', class => 'text-danger fw-bold', "Unable to find database layout for $archive_courseID"); + ($tables_ok, $dbStatus) = $CIchecker->checkCourseTables($archive_courseID); } + + # Update and check directories. + my $dir_update_messages = $c->param('upgrade_course_tables') ? $CIchecker->updateCourseDirectories : []; + my ($directories_ok, $directory_report) = $CIchecker->checkCourseDirectories($ce2); + + return $c->include( + 'ContentGenerator/CourseAdmin/archive_course_confirm', + ce2 => $ce2, + upgrade_report => \@upgrade_report, + tables_ok => $tables_ok, + dbStatus => $dbStatus, + dir_update_messages => $dir_update_messages, + directory_report => $directory_report, + directories_ok => $directories_ok, + archive_courseID => $archive_courseID, + archive_courseIDs => \@archive_courseIDs + ); + return; } sub do_archive_course ($c) { diff --git a/lib/WeBWorK/CourseEnvironment.pm b/lib/WeBWorK/CourseEnvironment.pm index 703cf96745..36a399dfcf 100644 --- a/lib/WeBWorK/CourseEnvironment.pm +++ b/lib/WeBWorK/CourseEnvironment.pm @@ -59,7 +59,7 @@ use YAML::XS qw(LoadFile); use WeBWorK::WWSafe; use WeBWorK::Utils qw(readFile); use WeBWorK::Debug; -use WeBWorK::DB::Utils qw(databaseParams); +use WeBWorK::DB::Layout qw(layout); =head1 CONSTRUCTION @@ -396,10 +396,9 @@ sub set_server_settings { $ce->{database_dsn} = "DBI:$config->{database}{driver}:database=$config->{database}{name};" . "host=$config->{database}{host};port=$config->{database}{port}"; } - $ce->{dbLayoutName} = 'sql_single'; $config->{database}{dsn} = $ce->{database_dsn}; $config->{database}{character_set} = $config->{database}{ENABLE_UTF8MB4} ? 'utf8mb4' : 'utf8'; - $ce->{dbLayout} = databaseParams($ce->{courseName}, $config->{database}, $config->{externalPrograms}); + $ce->{dbLayout} = layout($ce->{courseName}, $config->{database}, $config->{externalPrograms}); $ce->{maxCourseIdLength} = $config->{database}{maxCourseIdLength}; @@ -409,12 +408,20 @@ sub set_server_settings { $ce->{pg}{displayModeOptions}{images}{dvipng_depth_db}{dbsource} //= $ce->{database_dsn}; # Problem Library SQL database connection information - $c->{problemLibrary_db} = { - dbsource => $ce->{database_dsn}, - user => $ce->{database_username}, - passwd => $ce->{database_password}, - storage_engine => 'MYISAM', - }; + $ce->{problemLibrary_db}{dbsource} //= $ce->{database_dsn}; + $ce->{problemLibrary_db}{user} //= $ce->{database_username}; + $ce->{problemLibrary_db}{passwd} //= $ce->{database_password}; + $ce->{problemLibrary_db}{storage_engine} //= 'myisam'; + + # image conversions utiltiies + # the source file is given on stdin, and the output expected on stdout. + + $config->{externalPrograms}{gif2eps} = $config->{externalPrograms}{giftopnm} + // $config->{externalPrograms}{ppmtopgm} // "$config->{externalPrograms}{pnmtops} -noturn 2 > /dev/null"; + $config->{externalPrograms}{png2eps} = $config->{externalPrograms}{pngtopnm} + // $config->{externalPrograms}{ppmtopgm} // "$config->{externalPrograms}{pnmtops} -noturn 2 > /dev/null"; + $config->{externalPrograms}{gif2png} = $config->{externalPrograms}{giftopnm} + // $config->{externalPrograms}{pnmtopng}; $ce->{externalPrograms} = $config->{externalPrograms}; return; diff --git a/lib/WeBWorK/DB/Layout.pm b/lib/WeBWorK/DB/Layout.pm new file mode 100644 index 0000000000..ab7abd301d --- /dev/null +++ b/lib/WeBWorK/DB/Layout.pm @@ -0,0 +1,298 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2023 The WeBWorK Project, https://github.com/openwebwork +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + +package WeBWorK::DB::Layout; +use base qw(Exporter); + +=head1 NAME + +WeBWorK::DB::Layout - returns the database layout given server parameters. + +=cut + +use strict; +use warnings; + +our @EXPORT = (); +our @EXPORT_OK = qw(layout); + +sub layout { + my ($courseName, $db_params, $externalPrograms) = @_; + + my %sqlParams = ( + username => $db_params->{username}, + password => $db_params->{password}, + debug => $db_params->{database_debug} // 0, + # kinda hacky, but needed for table dumping + mysql_path => $externalPrograms->{mysql}, + mysqldump_path => $externalPrograms->{mysqldump}, + ); + + if ($db_params->{driver} =~ /^mysql$/i) { + # The extra UTF8 connection setting is ONLY needed for older DBD:mysql driver + # and forbidden by the newer DBD::MariaDB driver + if ($db_params->{ENABLE_UTF8MB4}) { + $sqlParams{mysql_enable_utf8mb4} = 1; # Full 4-bit UTF-8 + } else { + $sqlParams{mysql_enable_utf8} = 1; # Only the partial 3-bit mySQL UTF-8 + } + } + return { + locations => { + record => "WeBWorK::DB::Record::Locations", + schema => "WeBWorK::DB::Schema::NewSQL::Std", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, non_native => 1 }, + }, + location_addresses => { + record => "WeBWorK::DB::Record::LocationAddresses", + schema => "WeBWorK::DB::Schema::NewSQL::Std", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, non_native => 1 }, + }, + depths => { + record => "WeBWorK::DB::Record::Depths", + schema => "WeBWorK::DB::Schema::NewSQL::Std", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + params => { %sqlParams, non_native => 1 }, + }, + password => { + record => "WeBWorK::DB::Record::Password", + schema => "WeBWorK::DB::Schema::NewSQL::Std", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, tableOverride => "${courseName}_password" }, + }, + permission => { + record => "WeBWorK::DB::Record::PermissionLevel", + schema => "WeBWorK::DB::Schema::NewSQL::Std", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, tableOverride => "${courseName}_permission" }, + }, + key => { + record => "WeBWorK::DB::Record::Key", + schema => "WeBWorK::DB::Schema::NewSQL::Std", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, tableOverride => "${courseName}_key" }, + }, + user => { + record => "WeBWorK::DB::Record::User", + schema => "WeBWorK::DB::Schema::NewSQL::Std", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, tableOverride => "${courseName}_user" }, + }, + set => { + record => "WeBWorK::DB::Record::Set", + schema => "WeBWorK::DB::Schema::NewSQL::Std", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, tableOverride => "${courseName}_set" }, + }, + set_user => { + record => "WeBWorK::DB::Record::UserSet", + schema => "WeBWorK::DB::Schema::NewSQL::NonVersioned", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, tableOverride => "${courseName}_set_user" }, + }, + set_merged => { + record => "WeBWorK::DB::Record::UserSet", + schema => "WeBWorK::DB::Schema::NewSQL::Merge", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + depend => [qw/set_user set/], + params => { + %sqlParams, + non_native => 1, + merge => [qw/set_user set/], + }, + }, + set_version => { + record => "WeBWorK::DB::Record::SetVersion", + schema => "WeBWorK::DB::Schema::NewSQL::Versioned", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + params => { + %sqlParams, + non_native => 1, + tableOverride => "${courseName}_set_user", + + }, + }, + set_version_merged => { + record => "WeBWorK::DB::Record::SetVersion", + schema => "WeBWorK::DB::Schema::NewSQL::Merge", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + depend => [qw/set_version set_user set/], + params => { + %sqlParams, + non_native => 1, + merge => [qw/set_version set_user set/], + }, + }, + set_locations => { + record => "WeBWorK::DB::Record::SetLocations", + schema => "WeBWorK::DB::Schema::NewSQL::Std", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, tableOverride => "${courseName}_set_locations" }, + }, + set_locations_user => { + record => "WeBWorK::DB::Record::UserSetLocations", + schema => "WeBWorK::DB::Schema::NewSQL::Std", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, tableOverride => "${courseName}_set_locations_user" }, + }, + problem => { + record => "WeBWorK::DB::Record::Problem", + schema => "WeBWorK::DB::Schema::NewSQL::Std", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, tableOverride => "${courseName}_problem" }, + }, + problem_user => { + record => "WeBWorK::DB::Record::UserProblem", + schema => "WeBWorK::DB::Schema::NewSQL::NonVersioned", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, tableOverride => "${courseName}_problem_user" }, + }, + problem_merged => { + record => "WeBWorK::DB::Record::UserProblem", + schema => "WeBWorK::DB::Schema::NewSQL::Merge", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + depend => [qw/problem_user problem/], + params => { + %sqlParams, + non_native => 1, + merge => [qw/problem_user problem/], + }, + }, + problem_version => { + record => "WeBWorK::DB::Record::ProblemVersion", + schema => "WeBWorK::DB::Schema::NewSQL::Versioned", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { + %sqlParams, + non_native => 1, + tableOverride => "${courseName}_problem_user", + }, + }, + problem_version_merged => { + record => "WeBWorK::DB::Record::ProblemVersion", + schema => "WeBWorK::DB::Schema::NewSQL::Merge", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + depend => [qw/problem_version problem_user problem/], + params => { + %sqlParams, + non_native => 1, + merge => [qw/problem_version problem_user problem/], + }, + }, + setting => { + record => "WeBWorK::DB::Record::Setting", + schema => "WeBWorK::DB::Schema::NewSQL::Std", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, tableOverride => "${courseName}_setting" }, + }, + achievement => { + record => "WeBWorK::DB::Record::Achievement", + schema => "WeBWorK::DB::Schema::NewSQL::Std", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, tableOverride => "${courseName}_achievement" }, + }, + past_answer => { + record => "WeBWorK::DB::Record::PastAnswer", + schema => "WeBWorK::DB::Schema::NewSQL::Std", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, tableOverride => "${courseName}_past_answer" }, + }, + + achievement_user => { + record => "WeBWorK::DB::Record::UserAchievement", + schema => "WeBWorK::DB::Schema::NewSQL::Std", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, tableOverride => "${courseName}_achievement_user" }, + }, + global_user_achievement => { + record => "WeBWorK::DB::Record::GlobalUserAchievement", + schema => "WeBWorK::DB::Schema::NewSQL::Std", + driver => "WeBWorK::DB::Driver::SQL", + source => $db_params->{dsn}, + engine => $db_params->{storage_engine}, + character_set => $db_params->{character_set}, + params => { %sqlParams, tableOverride => "${courseName}_global_user_achievement" }, + }, + }; +} diff --git a/lib/WeBWorK/DB/Utils.pm b/lib/WeBWorK/DB/Utils.pm index e467e64088..2a6476c0c7 100644 --- a/lib/WeBWorK/DB/Utils.pm +++ b/lib/WeBWorK/DB/Utils.pm @@ -35,7 +35,6 @@ our @EXPORT_OK = qw( grok_vsetID grok_setID_from_vsetID_sql grok_versionID_from_vsetID_sql - databaseParams ); sub global2user($$) { @@ -109,275 +108,4 @@ sub grok_versionID_from_vsetID_sql($) { return "(SUBSTRING($field,INSTR($field,',v')+2)+0)"; } -# This function fills database fields of the CourseEnvironment - -sub databaseParams { - my ($courseName, $db_params, $externalPrograms) = @_; - - my %sqlParams = ( - username => $db_params->{username}, - password => $db_params->{password}, - debug => $db_params->{database_debug} // 0, - # kinda hacky, but needed for table dumping - mysql_path => $externalPrograms->{mysql}, - mysqldump_path => $externalPrograms->{mysqldump}, - ); - - if ($db_params->{driver} =~ /^mysql$/i) { - # The extra UTF8 connection setting is ONLY needed for older DBD:mysql driver - # and forbidden by the newer DBD::MariaDB driver - if ($db_params->{ENABLE_UTF8MB4}) { - $sqlParams{mysql_enable_utf8mb4} = 1; # Full 4-bit UTF-8 - } else { - $sqlParams{mysql_enable_utf8} = 1; # Only the partial 3-bit mySQL UTF-8 - } - } - return { - locations => { - record => "WeBWorK::DB::Record::Locations", - schema => "WeBWorK::DB::Schema::NewSQL::Std", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, non_native => 1 }, - }, - location_addresses => { - record => "WeBWorK::DB::Record::LocationAddresses", - schema => "WeBWorK::DB::Schema::NewSQL::Std", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, non_native => 1 }, - }, - depths => { - record => "WeBWorK::DB::Record::Depths", - schema => "WeBWorK::DB::Schema::NewSQL::Std", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - params => { %sqlParams, non_native => 1 }, - }, - password => { - record => "WeBWorK::DB::Record::Password", - schema => "WeBWorK::DB::Schema::NewSQL::Std", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, tableOverride => "${courseName}_password" }, - }, - permission => { - record => "WeBWorK::DB::Record::PermissionLevel", - schema => "WeBWorK::DB::Schema::NewSQL::Std", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, tableOverride => "${courseName}_permission" }, - }, - key => { - record => "WeBWorK::DB::Record::Key", - schema => "WeBWorK::DB::Schema::NewSQL::Std", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, tableOverride => "${courseName}_key" }, - }, - user => { - record => "WeBWorK::DB::Record::User", - schema => "WeBWorK::DB::Schema::NewSQL::Std", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, tableOverride => "${courseName}_user" }, - }, - set => { - record => "WeBWorK::DB::Record::Set", - schema => "WeBWorK::DB::Schema::NewSQL::Std", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, tableOverride => "${courseName}_set" }, - }, - set_user => { - record => "WeBWorK::DB::Record::UserSet", - schema => "WeBWorK::DB::Schema::NewSQL::NonVersioned", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, tableOverride => "${courseName}_set_user" }, - }, - set_merged => { - record => "WeBWorK::DB::Record::UserSet", - schema => "WeBWorK::DB::Schema::NewSQL::Merge", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - depend => [qw/set_user set/], - params => { - %sqlParams, - non_native => 1, - merge => [qw/set_user set/], - }, - }, - set_version => { - record => "WeBWorK::DB::Record::SetVersion", - schema => "WeBWorK::DB::Schema::NewSQL::Versioned", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - params => { - %sqlParams, - non_native => 1, - tableOverride => "${courseName}_set_user", - - }, - }, - set_version_merged => { - record => "WeBWorK::DB::Record::SetVersion", - schema => "WeBWorK::DB::Schema::NewSQL::Merge", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - depend => [qw/set_version set_user set/], - params => { - %sqlParams, - non_native => 1, - merge => [qw/set_version set_user set/], - }, - }, - set_locations => { - record => "WeBWorK::DB::Record::SetLocations", - schema => "WeBWorK::DB::Schema::NewSQL::Std", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, tableOverride => "${courseName}_set_locations" }, - }, - set_locations_user => { - record => "WeBWorK::DB::Record::UserSetLocations", - schema => "WeBWorK::DB::Schema::NewSQL::Std", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, tableOverride => "${courseName}_set_locations_user" }, - }, - problem => { - record => "WeBWorK::DB::Record::Problem", - schema => "WeBWorK::DB::Schema::NewSQL::Std", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, tableOverride => "${courseName}_problem" }, - }, - problem_user => { - record => "WeBWorK::DB::Record::UserProblem", - schema => "WeBWorK::DB::Schema::NewSQL::NonVersioned", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, tableOverride => "${courseName}_problem_user" }, - }, - problem_merged => { - record => "WeBWorK::DB::Record::UserProblem", - schema => "WeBWorK::DB::Schema::NewSQL::Merge", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - depend => [qw/problem_user problem/], - params => { - %sqlParams, - non_native => 1, - merge => [qw/problem_user problem/], - }, - }, - problem_version => { - record => "WeBWorK::DB::Record::ProblemVersion", - schema => "WeBWorK::DB::Schema::NewSQL::Versioned", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { - %sqlParams, - non_native => 1, - tableOverride => "${courseName}_problem_user", - }, - }, - problem_version_merged => { - record => "WeBWorK::DB::Record::ProblemVersion", - schema => "WeBWorK::DB::Schema::NewSQL::Merge", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - depend => [qw/problem_version problem_user problem/], - params => { - %sqlParams, - non_native => 1, - merge => [qw/problem_version problem_user problem/], - }, - }, - setting => { - record => "WeBWorK::DB::Record::Setting", - schema => "WeBWorK::DB::Schema::NewSQL::Std", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, tableOverride => "${courseName}_setting" }, - }, - achievement => { - record => "WeBWorK::DB::Record::Achievement", - schema => "WeBWorK::DB::Schema::NewSQL::Std", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, tableOverride => "${courseName}_achievement" }, - }, - past_answer => { - record => "WeBWorK::DB::Record::PastAnswer", - schema => "WeBWorK::DB::Schema::NewSQL::Std", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, tableOverride => "${courseName}_past_answer" }, - }, - - achievement_user => { - record => "WeBWorK::DB::Record::UserAchievement", - schema => "WeBWorK::DB::Schema::NewSQL::Std", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, tableOverride => "${courseName}_achievement_user" }, - }, - global_user_achievement => { - record => "WeBWorK::DB::Record::GlobalUserAchievement", - schema => "WeBWorK::DB::Schema::NewSQL::Std", - driver => "WeBWorK::DB::Driver::SQL", - source => $db_params->{dsn}, - engine => $db_params->{storage_engine}, - character_set => $db_params->{character_set}, - params => { %sqlParams, tableOverride => "${courseName}_global_user_achievement" }, - }, - }; -} - 1; diff --git a/lib/WeBWorK/Utils/CourseIntegrityCheck.pm b/lib/WeBWorK/Utils/CourseIntegrityCheck.pm index 2b43290814..5e920a392f 100644 --- a/lib/WeBWorK/Utils/CourseIntegrityCheck.pm +++ b/lib/WeBWorK/Utils/CourseIntegrityCheck.pm @@ -66,8 +66,7 @@ sub init { $self->{verbose_sub} = $options{verbose_sub} || \&debug; $self->{confirm_sub} = $options{confirm_sub} || \&ask_permission_stdio; $self->{ce} = $options{ce}; - my $dbLayoutName = $self->{ce}->{dbLayoutName}; - $self->{db} = WeBWorK::DB->new($self->{ce}{dbLayouts}->{$dbLayoutName}); + $self->{db} = WeBWorK::DB->new($self->{ce}{dbLayout}); return; } diff --git a/lib/WeBWorK/Utils/CourseManagement.pm b/lib/WeBWorK/Utils/CourseManagement.pm index 3816a58d09..357e8936b9 100644 --- a/lib/WeBWorK/Utils/CourseManagement.pm +++ b/lib/WeBWorK/Utils/CourseManagement.pm @@ -171,10 +171,9 @@ environment. $courseOptions is a reference to a hash containing the following options: - dbLayoutName => $dbLayoutName - PRINT_FILE_NAMES_FOR => $pg{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR} + PRINT_FILE_NAMES_FOR => $pg{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR} -C is required. C is a reference to an array. +C is a reference to an array. $users is a list of arrayrefs, each containing a User, Password, and PermissionLevel record for a single user: @@ -215,9 +214,6 @@ sub addCourse { debug \@users; - # get the database layout out of the options hash - my $dbLayoutName = $courseOptions{dbLayoutName}; - # collect some data my $coursesDir = $ce->{webworkDirs}->{courses}; my $courseDir = "$coursesDir/$courseID"; @@ -241,16 +237,6 @@ sub addCourse { croak "Course ID cannot exceed " . $ce->{maxCourseIdLength} . " characters." if (length($courseID) > $ce->{maxCourseIdLength}); - # if we didn't get a database layout, use the default one - if (not defined $dbLayoutName) { - $dbLayoutName = $ce->{dbLayoutName}; - } - - # fail if the database layout is invalid - if (not exists $ce->{dbLayouts}->{$dbLayoutName}) { - croak "$dbLayoutName: not found in \%dbLayouts"; - } - ##### step 1: create course directory structure ##### my %courseDirs = %{ $ce->{courseDirs} }; @@ -320,7 +306,7 @@ sub addCourse { ##### step 2: create course database ##### - my $db = new WeBWorK::DB($ce->{dbLayouts}->{$dbLayoutName}); + my $db = new WeBWorK::DB($ce->{dbLayout}); my $create_db_result = $db->create_tables; die "$courseID: course database creation failed.\n" unless $create_db_result; @@ -339,11 +325,11 @@ sub addCourse { ) { $ce0 = WeBWorK::CourseEnvironment->new({ courseName => $sourceCourse }); - $db0 = WeBWorK::DB->new($ce0->{dbLayouts}{$dbLayoutName}); + $db0 = WeBWorK::DB->new($ce0->{dbLayout}); } # add users (users that were directly passed to addCourse() as well as those copied from a source course) - if ($ce->{dbLayouts}{$dbLayoutName}{user}{params}{non_native}) { + if ($ce->{dbLayout}{user}{params}{non_native}) { debug("not adding users to the course database: 'user' table is non-native.\n"); } else { if ($db0 && $options{copyNonStudents}) { @@ -541,16 +527,12 @@ sub renameCourse { # $fromCE ($oldCE) # $toCourseID ($newCourseID) # $toCE (construct from $oldCE) - # $dbLayoutName ($oldCE->{dbLayoutName}) my $oldCourseID = $options{courseID}; my $oldCE = $options{ce}; my $newCourseID = $options{newCourseID}; my $skipDBRename = $options{skipDBRename} || 0; - # get the database layout out of the options hash - my $dbLayoutName = $oldCE->{dbLayoutName}; - # collect some data my $coursesDir = $oldCE->{webworkDirs}->{courses}; my $oldCourseDir = "$coursesDir/$oldCourseID"; @@ -640,12 +622,12 @@ sub renameCourse { ##### step 2: rename database ##### unless ($skipDBRename) { - my $oldDB = new WeBWorK::DB($oldCE->{dbLayouts}{$dbLayoutName}); + my $oldDB = new WeBWorK::DB($oldCE->{dbLayout}); - my $rename_db_result = $oldDB->rename_tables($newCE->{dbLayouts}{$dbLayoutName}); + my $rename_db_result = $oldDB->rename_tables($newCE->{dbLayout}); die "$oldCourseID: course database renaming failed.\n" unless $rename_db_result; #update title and institution - my $newDB = new WeBWorK::DB($newCE->{dbLayouts}{$dbLayoutName}); + my $newDB = new WeBWorK::DB($newCE->{dbLayout}); eval { if (exists($options{courseTitle}) and $options{courseTitle}) { $newDB->setSettingValue('courseTitle', $options{courseTitle}); @@ -680,15 +662,13 @@ sub retitleCourse { # renameCourseHelper needs: # $courseID ($oldCourseID) # $ce ($oldCE) - # $dbLayoutName ($ce->{dbLayoutName}) # courseTitle # courseInstitution my $courseID = $options{courseID}; my $ce = $options{ce}; # get the database layout out of the options hash - my $dbLayoutName = $ce->{dbLayoutName}; - my $db = new WeBWorK::DB($ce->{dbLayouts}{$dbLayoutName}); + my $db = new WeBWorK::DB($ce->{dbLayout}); eval { if (exists($options{courseTitle}) and $options{courseTitle}) { $db->setSettingValue('courseTitle', $options{courseTitle}); @@ -755,8 +735,7 @@ sub deleteCourse { ##### step 1: delete course database (if necessary) ##### - my $dbLayoutName = $ce->{dbLayoutName}; - my $db = new WeBWorK::DB($ce->{dbLayouts}->{$dbLayoutName}); + my $db = new WeBWorK::DB($ce->{dbLayout}); my $create_db_result = $db->delete_tables; die "$courseID: course database deletion failed.\n" unless $create_db_result; @@ -1001,10 +980,9 @@ sub unarchiveCourse { my $ce2 = WeBWorK::CourseEnvironment->new({ get_SeedCE($ce), courseName => $currCourseID }); # pull out some useful stuff - my $course_dir = $ce2->{courseDirs}{root}; - my $data_dir = $ce2->{courseDirs}{DATA}; - my $dump_dir = "$data_dir/mysqldump"; - my $old_dump_file = "$data_dir/${currCourseID}_mysql.database"; + my $course_dir = $ce2->{courseDirs}{root}; + my $data_dir = $ce2->{courseDirs}{DATA}; + my $dump_dir = "$data_dir/mysqldump"; ##### step 4: restore the database tables ##### @@ -1013,24 +991,9 @@ sub unarchiveCourse { if (-e $dump_dir) { my $db = new WeBWorK::DB($ce2->{dbLayout}); $restore_db_result = $db->restore_tables($dump_dir); - } elsif (-e $old_dump_file) { - my $dbLayoutName = $ce2->{dbLayoutName}; - if (ref getHelperRef("unarchiveCourseHelper", $dbLayoutName)) { - eval { - $restore_db_result = - unarchiveCourseHelper($currCourseID, $ce2, $dbLayoutName, unarchiveDatabasePath => $old_dump_file); - }; - if ($@) { - warn "failed to unarchive course database from dump file '$old_dump_file: $@\n"; - } - } else { - warn "course '$currCourseID' uses dbLayout '$dbLayoutName', which doesn't support " - . "restoring database tables. database tables will not be restored.\n"; - $no_database = 1; - } } else { warn "course '$currCourseID' has no database dump in its data directory " - . "(checked for $dump_dir and $old_dump_file). database tables will not be restored.\n"; + . "(checked for $dump_dir). database tables will not be restored.\n"; $no_database = 1; } @@ -1040,16 +1003,9 @@ sub unarchiveCourse { ##### step 5: delete dump_dir and/or old_dump_file ##### - if (-e $dump_dir) { - _archiveCourse_remove_dump_dir($ce, $dump_dir); - } - if (-e $old_dump_file) { - eval { Mojo::File->new($old_dump_file)->remove }; - warn "Failed to unlink course database dump file '$old_dump_file: $@" if $@; - } + _archiveCourse_remove_dump_dir($ce, $dump_dir) if -e $dump_dir; - # Create the html_temp folder (since it isn't included in the - # tarball + # Create the html_temp folder (since it isn't included in the tarball) my $tmpDir = $ce2->{courseDirs}->{html_temp}; if (!-e $tmpDir) { eval { Mojo::File->new($tmpDir)->make_path }; @@ -1201,46 +1157,7 @@ sub dbLayoutSQLSources { =cut -################################################################################ -# database helpers -################################################################################ - -=head1 DATABASE-LAYOUT SPECIFIC HELPER FUNCTIONS - -These functions are used to perform database-layout specific operations. - -The implementations in this class do nothing, but if an appropriate function -exists in a class with the name -WeBWorK::Utils::CourseManagement::I<$dbLayoutName>, it will be used instead. - -=over - -=item archiveCourseHelper($courseID, $ce, $dbLayoutName, %options) - -Perform database-layout specific operations for archiving the data in a course. - -=cut - -sub archiveCourseHelper { - my ($courseID, $ce, $dbLayoutName, %options) = @_; - my $result = callHelperIfExists("archiveCourseHelper", $dbLayoutName, @_); - return $result; -} - -=item unarchiveCourseHelper($courseID, $ce, $dbLayoutName, %options) - -Perform database-layout specific operations for unarchiving the data in a course -and placing it in the database. - -=cut - -sub unarchiveCourseHelper { - my ($courseID, $ce, $dbLayoutName, %options) = @_; - my $result = callHelperIfExists("unarchiveCourseHelper", $dbLayoutName, @_); - return $result; -} - -=item initNonNativeTables($ce, $db, $dbLayoutName, %options) +=item initNonNativeTables($ce, $db, %options) Perform database-layout specific operations for initializing non-native database tables that are not associated with a particular course @@ -1250,10 +1167,10 @@ that are not associated with a particular course =cut sub initNonNativeTables { - my ($ce, $dbLayoutName, %options) = @_; + my ($ce, %options) = @_; my @messages; # Create a database handler - my $db = new WeBWorK::DB($ce->{dbLayouts}->{$dbLayoutName}); + my $db = new WeBWorK::DB($ce->{dbLayout}); # lock database @@ -1329,7 +1246,7 @@ called directly. =over -=item callHelperIfExists($helperName, $dbLayoutName, @args) +=item callHelperIfExists($helperName, @args) Call a database-specific helper function, if a database-layout specific helper class exists and contains a function named "${helperName}Helper". @@ -1337,9 +1254,9 @@ class exists and contains a function named "${helperName}Helper". =cut sub callHelperIfExists { - my ($helperName, $dbLayoutName, @args) = @_; + my ($helperName, @args) = @_; - my $helperRef = getHelperRef($helperName, $dbLayoutName); + my $helperRef = getHelperRef($helperName); if (ref $helperRef) { return $helperRef->(@args); } else { @@ -1347,43 +1264,6 @@ sub callHelperIfExists { } } -=item getHelperRef($helperName, $dbLayoutName) - -Call a database-specific helper function, if a database-layout specific helper -class exists and contains a function named "${helperName}Helper". - -=cut - -sub getHelperRef { - my ($helperName, $dbLayoutName) = @_; - - my $result; - - my $package = __PACKAGE__ . "::$dbLayoutName"; - - eval { runtime_use $package }; - if ($@) { - if ($@ =~ /^Can't locate/) { - debug("No database-layout specific library for layout '$dbLayoutName'.\n"); - $result = 1; - } else { - warn "Failed to load database-layout specific library: $@\n"; - $result = 0; - } - } else { - my %syms = do { no strict 'refs'; %{ $package . "::" } }; - if (exists $syms{$helperName}) { - $result = do { no strict 'refs'; \&{ $package . "::" . $helperName } }; - } else { - debug("No helper defined for operation '$helperName'.\n"); - $result = 1; - } - } - - #warn "getHelperRef = '$result'\n"; - return $result; -} - =item protectQString($string) Protects the contents of a single-quoted Perl string. @@ -1409,9 +1289,6 @@ the pairs accepted in %courseOptions by addCourse(), above. sub writeCourseConf { my ($fh, $ce, %options) = @_; - # several options should be defined no matter what - $options{dbLayoutName} = $ce->{dbLayoutName} unless defined $options{dbLayoutName}; - print $fh <<'EOF'; #!perl @@ -1419,24 +1296,6 @@ sub writeCourseConf { EOF - print $fh <<'EOF'; -# Database Layout (global value typically defined in defaults.config) -# Several database are defined in the file conf/database.conf and stored in the -# hash %dbLayouts. -# The database layout is always set here, since one should be able to change the -# default value in localOverrides.conf without disrupting existing courses. -# defaults.config values: -EOF - - print $fh "# \t", '$dbLayoutName = \'', protectQString($ce->{dbLayoutName}), '\';', "\n"; - print $fh "# \t", '*dbLayout = $dbLayouts{$dbLayoutName};', "\n"; - - if (defined $options{dbLayoutName}) { - print $fh '$dbLayoutName = \'', protectQString($options{dbLayoutName}), '\';', "\n"; - print $fh '*dbLayout = $dbLayouts{$dbLayoutName};', "\n"; - } - print $fh "\n"; - print $fh <<'EOF'; # Users for whom to label problems with the PG file name (global value typically "professor") # For users in this list, PG will display the source file name when rendering a problem. diff --git a/lib/WeBWorK/Utils/CourseManagement/sql_moodle.pm b/lib/WeBWorK/Utils/CourseManagement/sql_moodle.pm deleted file mode 100644 index 007a35a1e0..0000000000 --- a/lib/WeBWorK/Utils/CourseManagement/sql_moodle.pm +++ /dev/null @@ -1,33 +0,0 @@ -################################################################################ -# WeBWorK Online Homework Delivery System -# Copyright © 2000-2023 The WeBWorK Project, https://github.com/openwebwork -# -# This program is free software; you can redistribute it and/or modify it under -# the terms of either: (a) the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any later -# version, or (b) the "Artistic License" which comes with this package. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the -# Artistic License for more details. -################################################################################ - -package WeBWorK::Utils::CourseManagement::sql_moodle; - -=head1 NAME - -WeBWorK::Utils::CourseManagement::sql_moodle - create and delete courses using -the sql_moodle database layout. Delegates functionality to -WeBWorK::Utils::CourseManagement::sql_single. - -=cut - -use strict; -use warnings; -use WeBWorK::Utils::CourseManagement::sql_single; - -*archiveCourseHelper = \&WeBWorK::Utils::CourseManagement::sql_single::archiveCourseHelper; -*unarchiveCourseHelper = \&WeBWorK::Utils::CourseManagement::sql_single::unarchiveCourseHelper; - -1; diff --git a/lib/WeBWorK/Utils/CourseManagement/sql_single.pm b/lib/WeBWorK/Utils/CourseManagement/sql_single.pm deleted file mode 100644 index f79b8071e0..0000000000 --- a/lib/WeBWorK/Utils/CourseManagement/sql_single.pm +++ /dev/null @@ -1,275 +0,0 @@ -################################################################################ -# WeBWorK Online Homework Delivery System -# Copyright © 2000-2023 The WeBWorK Project, https://github.com/openwebwork -# -# This program is free software; you can redistribute it and/or modify it under -# the terms of either: (a) the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any later -# version, or (b) the "Artistic License" which comes with this package. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the -# Artistic License for more details. -################################################################################ - -package WeBWorK::Utils::CourseManagement::sql_single; - -=head1 NAME - -WeBWorK::Utils::CourseManagement::sql_single - create and delete courses using -the sql_single database layout. - -=cut - -use strict; -use warnings; -#use Data::Dumper; -#use DBI; -use File::Temp; -use String::ShellQuote; -use WeBWorK::Debug; -use WeBWorK::Utils qw/runtime_use/; -#use WeBWorK::Utils::CourseManagement qw/dbLayoutSQLSources/; - -=for comment - -# DBFIXME this whole process should be through an abstraction layer -# DBFIXME (we shouldn't be calling mysqldump here -sub archiveCourseHelper { - my ($courseID, $ce, $dbLayoutName, %options) = @_; - debug("courseID=$courseID, ce=$ce dbLayoutName=$dbLayoutName\n"); - - ##### get list of tables to archive ##### - - my $dbLayout = $ce->{dbLayouts}->{$dbLayoutName}; - debug("dbLayout=$dbLayout\n"); - my %sources = dbLayoutSQLSources($dbLayout); - debug("fSources: ", Dumper(\%sources)); - my $source = mostPopularSource(%sources); - debug("source=$source\n"); - my %source = %{ $sources{$source} }; - my @tables = @{ $source{tables} }; - my $username = $source{username}; - my $password = $source{password}; - my $archiveDatabasePath = $options{archiveDatabasePath}; - - ##### construct SQL statements to copy the data in each table ##### - - my @stmts; - my @dataTables = (); - foreach my $table (@tables) { - debug("Table: $table\n"); - - if ($dbLayout->{$table}{params}{non_native}) { - debug("$table: marked non-native, skipping\n"); - next; - } - - my $table = do { - my $paramsRef = $dbLayout->{$table}->{params}; - if ($paramsRef) { - if (exists $paramsRef->{tableOverride}) { - $paramsRef->{tableOverride} - } else { - ""; # no override - } - } else { - ""; # no params - } - } || $table; - debug("sql \"real\" table name: $table\n"); - - - # this method would be mysql specific but it's a start - # mysqldump --user=$username --password=$password database tables -# my $stmt = "DUMP SELECT * FROM `$fromTable`"; -# debug("stmt = $stmt\n"); -# push @stmts, $stmt; - push @dataTables, $table; - } - debug("Database tables to export are ",join(" ", @dataTables)); - # this method would be mysql specific but it's a start - my $mysqldumpCommand = $ce->{externalPrograms}{mysqldump}; - my $exportStatement = " $mysqldumpCommand --user=$username ". - "--password=$password " . - " webwork ". - join(" ", @dataTables). - " >$archiveDatabasePath"; - debug($exportStatement); - my $exportResult = system $exportStatement; - $exportResult and die "Failed to export database with command: '$exportStatement ' (errno: $exportResult): $! - \n\n Check server error log for more information."; - - ##### issue SQL statements ##### - -# my $dbh = DBI->connect($source, $username, $password); -# unless (defined $dbh) { -# die "sql_single: failed to connect to DBI source '$source': $DBI::errstr\n"; -# } -# -# foreach my $stmt (@stmts) { -# my $rows = $dbh->do($stmt); -# unless (defined $rows) { -# die "sql_single: failed to execute SQL statement '$stmt': $DBI::errstr\n"; -# } -# } -# -# $dbh->disconnect; - - return 1; -} - -=cut - -=for comment - -# DBFIXME this whole process should be through an abstraction layer -# DBFIXME (we shouldn't be calling mysqldump here!) -sub unarchiveCourseHelper { - my ($courseID, $ce, $dbLayoutName, %options) = @_; - debug("courseID=$courseID, ce=$ce dbLayoutName=$dbLayoutName\n"); - - ##### get list of tables to archive ##### - - my $dbLayout = $ce->{dbLayouts}->{$dbLayoutName}; - debug("dbLayout=$dbLayout\n"); - my %sources = dbLayoutSQLSources($dbLayout); - debug("fSources: ", Dumper(\%sources)); - my $source = mostPopularSource(%sources); - debug("source=$source\n"); - my %source = %{ $sources{$source} }; - my @tables = @{ $source{tables} }; - my $username = $source{username}; - my $password = $source{password}; - my $unarchiveDatabasePath = $options{unarchiveDatabasePath}; - debug( "unarchive database Path is $unarchiveDatabasePath"); - ##### construct SQL statements to copy the data in each table ##### - - - # this method would be mysql specific but it's a start - my $mysqlCommand = $ce->{externalPrograms}{mysql}; - my $importStatement = " $mysqlCommand --user=$username ". - "--password=$password " . - "-D webwork". # specifies database name - " <$unarchiveDatabasePath"; - debug($importStatement); - my $importResult = system $importStatement; - $importResult and die "
Failed to import database with command: \n
-	'$importStatement ' \n
-	(errno: $importResult): $!
-	\n Check server error log for more information.\n
"; - #FIXME -- what should the return be?? - return 1; -} - -=cut - -# TOTALLY STOLEN FROM NewSQL::Std. -sub unarchiveCourseHelper { - my ($courseID, $ce, $dbLayoutName, %options) = @_; - my $dumpfile_path = $options{unarchiveDatabasePath}; - - my ($my_cnf, $database) = _get_db_info($ce); - my $mysql = $ce->{externalPrograms}{mysql}; - - my $restore_cmd = "2>&1 " - . shell_quote($mysql) - . " --defaults-extra-file=" - . shell_quote($my_cnf->filename) . " " - . shell_quote($database) . " < " - . shell_quote($dumpfile_path); - my $restore_out = readpipe $restore_cmd; - if ($?) { - my $exit = $? >> 8; - my $signal = $? & 127; - my $core = $? & 128; - die - "Failed to restore database for course '$courseID' with command '$restore_cmd' (exit=$exit signal=$signal core=$core): $restore_out\n"; - } - - return 1; -} - -# TOTALLY STOLEN FROM NewSQL::Std. -sub _get_db_info { - my ($ce) = @_; - my $dsn = $ce->{database_dsn}; - my $username = $ce->{database_username}; - my $password = $ce->{database_password}; - - my %dsn; - if ($dsn =~ m/^dbi:mariadb:/i || $dsn =~ m/^dbi:mysql:/i) { - # Expect DBI:MariaDB:database=webwork;host=db;port=3306 - # or DBI:mysql:database=webwork;host=db;port=3306 - # The host and port are optional. - my ($dbi, $dbtype, $dsn_opts) = split(':', $dsn); - while (length($dsn_opts)) { - if ($dsn_opts =~ /^([^=]*)=([^;]*);(.*)$/) { - $dsn{$1} = $2; - $dsn_opts = $3; - } else { - my ($var, $val) = $dsn_opts =~ /^([^=]*)=([^;]*)$/; - $dsn{$var} = $val; - $dsn_opts = ''; - } - } - } else { - die "Can't call dump_table or restore_table on a table with a non-MySQL/MariaDB source"; - } - - die "no database specified in DSN!" unless defined $dsn{database}; - - my $mysqldump = $self->{params}{mysqldump_path}; -# Conditionally add column-statistics=0 as MariaDB databases do not support it -# see: https://serverfault.com/questions/912162/mysqldump-throws-unknown-table-column-statistics-in-information-schema-1109 -# https://github.com/drush-ops/drush/issues/4410 - - my $column_statistics_off = ""; - my $test_for_column_statistics = `$mysqldump_command --help | grep 'column-statistics'`; - if ($test_for_column_statistics) { - $column_statistics_off = "[mysqldump]\ncolumn-statistics=0\n"; - #warn "Setting in the temporary mysql config file for table dump/restore:\n$column_statistics_off\n\n"; - } - - # doing this securely is kind of a hassle... - my $my_cnf = new File::Temp; - $my_cnf->unlink_on_destroy(1); - chmod 0600, $my_cnf or die "failed to chmod 0600 $my_cnf: $!"; # File::Temp objects stringify with ->filename - print $my_cnf "[client]\n"; - print $my_cnf "user=$username\n" if defined $username and length($username) > 0; - print $my_cnf "password=$password\n" if defined $password and length($password) > 0; - print $my_cnf "host=$dsn{host}\n" if defined $dsn{host} and length($dsn{host}) > 0; - print $my_cnf "port=$dsn{port}\n" if defined $dsn{port} and length($dsn{port}) > 0; - print $my_cnf "$column_statistics_off" if $test_for_column_statistics; - - return ($my_cnf, $dsn{database}); -} - -=for comment - -# returns the name of the source with the most tables -sub mostPopularSource { - my (%sources) = @_; - - my $source; - if (keys %sources > 1) { - # more than one -- warn and select the most popular source - debug("more than one SQL source defined.\n"); - foreach my $curr (keys %sources) { - $source = $curr if not defined $source or @{ $sources{$curr}->{tables} } > @{ $sources{$source}->{tables} }; - } - debug("only handling tables with source \"$source\".\n"); - debug("others will have to be handled manually (or not at all).\n"); - } else { - # there's only one - ($source) = keys %sources; - } - - return $source; -} - -=cut - -1; - diff --git a/lib/WebworkWebservice/CourseActions.pm b/lib/WebworkWebservice/CourseActions.pm index 9590a2e205..0d16718b41 100644 --- a/lib/WebworkWebservice/CourseActions.pm +++ b/lib/WebworkWebservice/CourseActions.pm @@ -62,7 +62,7 @@ sub createCourse { addCourse( courseID => $params->{name}, ce => $ce, - courseOptions => { dbLayoutName => $ce->{dbLayoutName} }, + courseOptions => {}, users => \@users ); addLog($ce, "New course created: $params->{name}"); diff --git a/templates/ContentGenerator/Base/admin_links.html.ep b/templates/ContentGenerator/Base/admin_links.html.ep index 3a242b28c3..33266a8cb1 100644 --- a/templates/ContentGenerator/Base/admin_links.html.ep +++ b/templates/ContentGenerator/Base/admin_links.html.ep @@ -18,7 +18,6 @@ % add_admin_users => 1, % copy_from_course => $ce->{siteDefaults}{default_copy_from_course} || '', % copy_component => 'copyTemplatesHtml', - % add_dbLayout => 'sql_single' % } % ], % [ 'rename_course', maketext('Rename Courses') ], diff --git a/templates/ContentGenerator/CourseAdmin/add_course_form.html.ep b/templates/ContentGenerator/CourseAdmin/add_course_form.html.ep index d7e898bdc4..e975441e49 100644 --- a/templates/ContentGenerator/CourseAdmin/add_course_form.html.ep +++ b/templates/ContentGenerator/CourseAdmin/add_course_form.html.ep @@ -189,6 +189,5 @@ - <%= hidden_field add_dbLayout => 'sql_single' =%> <%= submit_button maketext('Add Course'), name => 'add_course', class => 'btn btn-primary' =%> <% end =%> diff --git a/templates/ContentGenerator/CourseAdmin/upgrade_course_form.html.ep b/templates/ContentGenerator/CourseAdmin/upgrade_course_form.html.ep index 6b9df08fbc..21c8805687 100644 --- a/templates/ContentGenerator/CourseAdmin/upgrade_course_form.html.ep +++ b/templates/ContentGenerator/CourseAdmin/upgrade_course_form.html.ep @@ -42,7 +42,6 @@ % } <%= link_to $courseID => 'set_list' => { courseID => $courseID } =%> - <%= $tempCE->{dbLayoutName} %> % if (!$directories_ok) { <%= maketext('Directory structure or permissions need to be repaired.') =%>