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.') =%>