diff --git a/Gemfile.lock b/Gemfile.lock
index 166109fe..67860f20 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -443,6 +443,3 @@ DEPENDENCIES
uglifier (>= 1.3.0)
web-console (~> 2.0)
will_paginate (~> 3.0)
-
-BUNDLED WITH
- 1.13.6
diff --git a/app/assets/remote_scripts/macos.sh b/app/assets/remote_scripts/macos.sh
new file mode 100644
index 00000000..4632d421
--- /dev/null
+++ b/app/assets/remote_scripts/macos.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+
+# run like this:
+# cd path/to/project_root
+# .scripts/macos.sh .
+
+# CodeOcean Remote Client v0.6
+
+#file_info format: = (src/frog.java=34)
+#file_path format:
+
+
+project_root="${1%/}"
+declare -a file_array
+
+function get_valid_file_path {
+ file_path="$project_root/$1"
+ if [ -e "$file_path" ]; then
+ valid_file_path="$file_path"
+ else
+ file_name="${1##*/}"
+ valid_file_path="$(find "$project_root" -name "$file_name" | head -1)"
+ if ! [ "$valid_file_path" ]; then
+ path_to_file="$(echo "$1" | pcregrep -o '^.+/')"
+ echo "Error: $file_name is not in $project_root/$path_to_file and could not be found under $project_root."
+ exit 1
+ fi
+ fi
+ echo "$valid_file_path"
+}
+
+function get_escaped_file_content {
+ file_path="$1"
+ cat "$file_path" |
+ perl -p -e 's@\\@\\\\@g' |
+ perl -p -e 's@\r\n@\\n@g' |
+ perl -p -e 's@\n@\\n@g' |
+ perl -p -e 's@"@\\"@g'
+}
+
+function get_file_attributes {
+ file_info="$1"
+ file_path="$(get_valid_file_path "${file_info%=*}")"
+ escaped_file_content="$(get_escaped_file_content "$file_path")"
+ file_id="${file_info##*=}"
+ echo "{\"file_id\": $file_id,\"content\": \"$escaped_file_content\"}"
+}
+
+function read_file_to_array {
+ let i=0
+ while IFS=$'\n' read -r line_data; do
+ file_array[i]="${line_data}"
+ ((++i))
+ done < $1
+}
+
+
+co_file_path="$(get_valid_file_path '.co')"
+read_file_to_array $co_file_path
+
+validation_token="${file_array[0]}"
+
+target_url="${file_array[1]}"
+
+files_attributes="$(get_file_attributes "${file_array[2]}")"
+
+for ((i = 3; i < ${#file_array[@]}; i++)); do
+ files_attributes+=", $(get_file_attributes "${file_array[i]}")"
+done
+
+post_data="{\"remote_evaluation\": {\"validation_token\": \"$validation_token\",\"files_attributes\": [$files_attributes]}}"
+
+curl -H 'Content-Type: application/json' --data "$post_data" "$target_url"
+echo
diff --git a/app/assets/remote_scripts/ubuntu.sh b/app/assets/remote_scripts/ubuntu.sh
new file mode 100644
index 00000000..db5a970d
--- /dev/null
+++ b/app/assets/remote_scripts/ubuntu.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+# run like this:
+# cd path/to/project_root
+# .scripts/ubuntu.sh .
+
+# CodeOcean Remote Client v0.6
+
+#file_info format: = (src/frog.java=34)
+#file_path format:
+
+
+project_root="${1%/}"
+
+function get_valid_file_path {
+ file_path="$project_root/$1"
+ if [ -e "$file_path" ]; then
+ valid_file_path="$file_path"
+ else
+ file_name="${1##*/}"
+ valid_file_path="$(find "$project_root" -name "$file_name" | head -1)"
+ if ! [ "$valid_file_path" ]; then
+ path_to_file="$(echo "$1" | grep -oP '^.+/')"
+ echo "Error: $file_name is not in $project_root/$path_to_file and could not be found under $project_root."
+ exit 1
+ fi
+ fi
+ echo "$valid_file_path"
+}
+
+function get_escaped_file_content {
+ file_path="$1"
+ cat "$file_path" |
+ perl -p -e 's@\\@\\\\@g' |
+ perl -p -e 's@\r\n@\\n@g' |
+ perl -p -e 's@\n@\\n@g' |
+ perl -p -e 's@"@\\"@g'
+}
+
+function get_file_attributes {
+ file_info="$1"
+ file_path="$(get_valid_file_path "${file_info%=*}")"
+ escaped_file_content="$(get_escaped_file_content "$file_path")"
+ file_id="${file_info##*=}"
+ echo "{\"file_id\": $file_id,\"content\": \"$escaped_file_content\"}"
+}
+
+
+co_file_path="$(get_valid_file_path '.co')"
+mapfile -t file_array < "$co_file_path"
+
+validation_token="${file_array[0]}"
+
+target_url="${file_array[1]}"
+
+files_attributes="$(get_file_attributes "${file_array[2]}")"
+
+for ((i = 3; i < ${#file_array[@]}; i++)); do
+ files_attributes+=", $(get_file_attributes "${file_array[i]}")"
+done
+
+post_data="{\"remote_evaluation\": {\"validation_token\": \"$validation_token\",\"files_attributes\": [$files_attributes]}}"
+
+curl -H 'Content-Type: application/json' --data "$post_data" "$target_url"
+echo
diff --git a/app/assets/remote_scripts/windows.ps1 b/app/assets/remote_scripts/windows.ps1
new file mode 100644
index 00000000..9647d2e5
--- /dev/null
+++ b/app/assets/remote_scripts/windows.ps1
@@ -0,0 +1,93 @@
+# run like this:
+# cd path\to\project_root
+# powershell.exe -noprofile -executionpolicy bypass -file .scripts\windows.ps1 .
+
+# CodeOcean Remote Client v0.6
+
+#file_info format: = (src/frog.java=34)
+#file_path format:
+
+param (
+ [string]$project_root
+)
+if ( !($project_root | select-string -pattern '[/\\]$') ){
+ $project_root += '/'
+}
+
+
+function post_web_request ($content_type, $data, $url){
+ $buffer = [System.Text.Encoding]::UTF8.GetBytes($data)
+ [System.Net.HttpWebRequest] $web_request = [System.Net.WebRequest]::Create($url)
+ $web_request.Method = 'POST'
+ $web_request.ContentType = $content_type
+ $web_request.ContentLength = $buffer.Length;
+
+ $request_stream = $web_request.GetRequestStream()
+ $request_stream.Write($buffer, 0, $buffer.Length)
+ $request_stream.Flush()
+ $request_stream.Close()
+
+ [System.Net.HttpWebResponse] $web_response = $web_request.GetResponse()
+ $stream_reader = new-object System.IO.StreamReader($web_response.GetResponseStream())
+ $result = $stream_reader.ReadToEnd()
+ return $result
+}
+
+function find_file ($file_name){
+ $search_result = get-childitem -recurse -path $project_root -filter $file_name
+ if( !$search_result.exists ){
+ write-host "Error: $file_name could not be found under $project_root."
+ exit 1
+ }elseif( $search_result.gettype().name -eq 'Object[]' ){
+ $search_result = $search_result[0]
+ }
+ return $search_result
+}
+
+function get_file ($file_path){
+ $path_to_file = $project_root
+ $path_to_file += ($file_path | select-string -pattern '^.+/').matches.value
+ $file_name = ($file_path | select-string -pattern '[^/]+$').matches.value
+ $file = get-childitem -path $path_to_file -filter $file_name
+ if( !$file.exists ){
+ write-host "Warning: $file_name should be in $path_to_file, but it is not. Searching whole project..."
+ $file = find_file $file_name
+ write-host 'Using '$file.fullname'.'
+ }
+ return $file
+}
+
+function get_escaped_file_content ($file){
+ $content = [IO.File]::ReadAllText($file.fullname)
+ $content = $content.replace('\', '\\')
+ $content = $content -replace "`r`n", '\n'
+ $content = $content -replace "`n", '\n'
+ $content = $content.replace('"', '\"')
+ return $content
+}
+
+function get_file_attributes ($file_info){
+ $file = get_file ($file_info | select-string -pattern '^.*(?==)').matches.value
+ $escaped_file_content = get_escaped_file_content $file
+ $file_id = ($file_info | select-string -pattern '[^=]+$').matches.value
+ return "{`"file_id`": $file_id,`"content`": `"$escaped_file_content`"}"
+}
+
+$co_file = get_file '.co'
+
+$file_array = get-content $co_file.fullname
+
+$validation_token = $file_array[0]
+
+$target_url = $file_array[1]
+
+$files_attributes = get_file_attributes $file_array[2]
+
+for ($i = 3; $i -lt $file_array.length; $i++){
+ $files_attributes += ', '
+ $files_attributes += get_file_attributes $file_array[$i]
+}
+
+$post_data = "{`"remote_evaluation`": {`"validation_token`": `"$validation_token`",`"files_attributes`": [$files_attributes]}}"
+
+post_web_request 'application/json' $post_data $target_url
diff --git a/app/controllers/concerns/remote_evaluation_parameters.rb b/app/controllers/concerns/remote_evaluation_parameters.rb
new file mode 100644
index 00000000..4f0acab2
--- /dev/null
+++ b/app/controllers/concerns/remote_evaluation_parameters.rb
@@ -0,0 +1,8 @@
+module RemoteEvaluationParameters
+ include FileParameters
+
+ def remote_evaluation_params
+ remote_evaluation_params = params[:remote_evaluation].permit(:validation_token, files_attributes: file_attributes)
+ end
+ private :remote_evaluation_params
+end
\ No newline at end of file
diff --git a/app/controllers/remote_evaluation_controller.rb b/app/controllers/remote_evaluation_controller.rb
new file mode 100644
index 00000000..36d61f73
--- /dev/null
+++ b/app/controllers/remote_evaluation_controller.rb
@@ -0,0 +1,35 @@
+class RemoteEvaluationController < ApplicationController
+ include RemoteEvaluationParameters
+ include SubmissionScoring
+
+ skip_after_action :verify_authorized
+ skip_before_action :verify_authenticity_token
+
+ # POST /evaluate
+ # @param validation_token
+ # @param files_attributes
+ def evaluate
+
+ validation_token = remote_evaluation_params[:validation_token]
+ files_attributes = remote_evaluation_params[:files_attributes] || []
+
+ # todo extra: validiere, ob files wirklich zur Übung gehören (wenn allowNewFiles-flag nicht gesetzt ist)
+ if (remote_evaluation_mapping = RemoteEvaluationMapping.find_by(:validation_token => validation_token))
+ puts remote_evaluation_mapping.exercise_id
+ puts remote_evaluation_mapping.user_id
+
+ _params = remote_evaluation_params.except(:validation_token)
+ _params[:exercise_id] = remote_evaluation_mapping.exercise_id
+ _params[:user_id] = remote_evaluation_mapping.user_id
+ _params[:cause] = "remoteAssess"
+ _params[:user_type] = "ExternalUser"
+
+ @submission = Submission.create(_params)
+ render json: score_submission(@submission)
+ else
+ # todo: better output
+ # todo: check token expired?
+ render json: "No exercise found for this validation_token! Please keep out!"
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb
index b9a1846e..9b37fde0 100644
--- a/app/controllers/submissions_controller.rb
+++ b/app/controllers/submissions_controller.rb
@@ -61,12 +61,29 @@ class SubmissionsController < ApplicationController
# files = @submission.files.map{ }
# zipline( files, 'submission.zip')
# send_data(@file.content, filename: @file.name_with_extension)
+
+ id_file = create_remote_evaluation_mapping
+
require 'zip'
stringio = Zip::OutputStream.write_buffer do |zio|
@files.each do |file|
- zio.put_next_entry(file.name_with_extension)
+ zio.put_next_entry(file.path.to_s == '' ? file.name_with_extension : File.join(file.path, file.name_with_extension))
zio.write(file.content)
end
+
+ # zip .co file
+ zio.put_next_entry(".co")
+ zio.write(File.read id_file)
+ File.delete(id_file) if File.exist?(id_file)
+
+ # zip client scripts
+ scripts_path = 'app/assets/remote_scripts'
+ Dir.foreach(scripts_path) do |file|
+ next if file == '.' or file == '..'
+ zio.put_next_entry(File.join('.scripts', File.basename(file)))
+ zio.write(File.read File.join(scripts_path, file))
+ end
+
end
send_data(stringio.string, filename: @submission.exercise.title.tr(" ", "_") + ".zip")
end
@@ -337,4 +354,26 @@ class SubmissionsController < ApplicationController
server_sent_event.close
end
private :with_server_sent_events
+
+ def create_remote_evaluation_mapping
+ user_id = @submission.user_id
+ exercise_id = @submission.exercise_id
+
+ remote_evaluation_mapping = RemoteEvaluationMapping.create(:user_id => user_id, :exercise_id => exercise_id)
+
+ # create .co file
+ path = "tmp/" + user_id.to_s + ".co"
+ # parse validation token
+ content = "#{remote_evaluation_mapping.validation_token}\n"
+ # parse remote request url
+ content += "#{request.base_url}/evaluate\n"
+ @submission.files.each do |file|
+ file_path = file.path.to_s == '' ? file.name_with_extension : File.join(file.path, file.name_with_extension)
+ content += "#{file_path}=#{file.id.to_s}\n"
+ end
+ File.open(path, "w+") do |f|
+ f.write(content)
+ end
+ path
+ end
end
diff --git a/app/models/remote_evaluation_mapping.rb b/app/models/remote_evaluation_mapping.rb
new file mode 100644
index 00000000..be0034b1
--- /dev/null
+++ b/app/models/remote_evaluation_mapping.rb
@@ -0,0 +1,10 @@
+# todo: reference to lti_param_model
+class RemoteEvaluationMapping < ActiveRecord::Base
+ before_create :generate_token, unless: :validation_token?
+ belongs_to :exercise
+ belongs_to :user
+
+ def generate_token
+ self.validation_token = SecureRandom.urlsafe_base64
+ end
+end
\ No newline at end of file
diff --git a/app/models/submission.rb b/app/models/submission.rb
index 1abbbb84..6815eb40 100644
--- a/app/models/submission.rb
+++ b/app/models/submission.rb
@@ -2,7 +2,7 @@ class Submission < ActiveRecord::Base
include Context
include Creation
- CAUSES = %w(assess download file render run save submit test autosave requestComments)
+ CAUSES = %w(assess download file render run save submit test autosave requestComments remoteAssess)
FILENAME_URL_PLACEHOLDER = '{filename}'
belongs_to :exercise
diff --git a/config/routes.rb b/config/routes.rb
index 281af37c..fc0f9406 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -140,4 +140,6 @@ Rails.application.routes.draw do
end
end
+ post "/evaluate", to: 'remote_evaluation#evaluate', via: [:post]
+
end
diff --git a/db/migrate/20170202170437_create_remote_evaluation_mappings.rb b/db/migrate/20170202170437_create_remote_evaluation_mappings.rb
new file mode 100644
index 00000000..d102370d
--- /dev/null
+++ b/db/migrate/20170202170437_create_remote_evaluation_mappings.rb
@@ -0,0 +1,11 @@
+class CreateRemoteEvaluationMappings < ActiveRecord::Migration
+ def change
+ create_table :remote_evaluation_mappings do |t|
+ t.integer "user_id", null: false
+ t.integer "exercise_id", null: false
+ t.string "validation_token", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+ end
+end
\ No newline at end of file
diff --git a/db/schema.rb b/db/schema.rb
index 38d3f4a0..f0ecde99 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -238,6 +238,14 @@ ActiveRecord::Schema.define(version: 20170403162848) do
t.datetime "updated_at"
end
+ create_table "remote_evaluation_mappings", force: :cascade do |t|
+ t.integer "user_id", null: false
+ t.integer "exercise_id", null: false
+ t.string "validation_token", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
create_table "request_for_comments", force: :cascade do |t|
t.integer "user_id", null: false
t.integer "exercise_id", null: false
diff --git a/db/structure.sql b/db/structure.sql
index 4b290bdc..09afcb66 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -39,10 +39,9 @@ SET default_with_oids = false;
CREATE TABLE code_harbor_links (
id integer NOT NULL,
- oauth2token character varying(255),
+ oauth2token character varying,
created_at timestamp without time zone,
- updated_at timestamp without time zone,
- user_id integer
+ updated_at timestamp without time zone
);
@@ -73,7 +72,7 @@ CREATE TABLE comments (
id integer NOT NULL,
user_id integer,
file_id integer,
- user_type character varying(255),
+ user_type character varying,
"row" integer,
"column" integer,
text text,
@@ -107,11 +106,11 @@ ALTER SEQUENCE comments_id_seq OWNED BY comments.id;
CREATE TABLE consumers (
id integer NOT NULL,
- name character varying(255),
+ name character varying,
created_at timestamp without time zone,
updated_at timestamp without time zone,
- oauth_key character varying(255),
- oauth_secret character varying(255)
+ oauth_key character varying,
+ oauth_secret character varying
);
@@ -173,18 +172,18 @@ ALTER SEQUENCE errors_id_seq OWNED BY errors.id;
CREATE TABLE execution_environments (
id integer NOT NULL,
- docker_image character varying(255),
- name character varying(255),
+ docker_image character varying,
+ name character varying,
created_at timestamp without time zone,
updated_at timestamp without time zone,
- run_command character varying(255),
- test_command character varying(255),
- testing_framework character varying(255),
+ run_command character varying,
+ test_command character varying,
+ testing_framework character varying,
help text,
- exposed_ports character varying(255),
+ exposed_ports character varying,
permitted_execution_time integer,
user_id integer,
- user_type character varying(255),
+ user_type character varying,
pool_size integer,
file_type_id integer,
memory_limit integer,
@@ -219,14 +218,14 @@ CREATE TABLE exercises (
id integer NOT NULL,
description text,
execution_environment_id integer,
- title character varying(255),
+ title character varying,
created_at timestamp without time zone,
updated_at timestamp without time zone,
user_id integer,
instructions text,
public boolean,
- user_type character varying(255),
- token character varying(255),
+ user_type character varying,
+ token character varying,
hide_file_tree boolean,
allow_file_creation boolean,
allow_auto_completion boolean DEFAULT false
@@ -259,9 +258,9 @@ ALTER SEQUENCE exercises_id_seq OWNED BY exercises.id;
CREATE TABLE external_users (
id integer NOT NULL,
consumer_id integer,
- email character varying(255),
- external_id character varying(255),
- name character varying(255),
+ email character varying,
+ external_id character varying,
+ name character varying,
created_at timestamp without time zone,
updated_at timestamp without time zone
);
@@ -292,7 +291,7 @@ ALTER SEQUENCE external_users_id_seq OWNED BY external_users.id;
CREATE TABLE file_templates (
id integer NOT NULL,
- name character varying(255),
+ name character varying,
content text,
file_type_id integer,
created_at timestamp without time zone,
@@ -325,16 +324,16 @@ ALTER SEQUENCE file_templates_id_seq OWNED BY file_templates.id;
CREATE TABLE file_types (
id integer NOT NULL,
- editor_mode character varying(255),
- file_extension character varying(255),
+ editor_mode character varying,
+ file_extension character varying,
indent_size integer,
- name character varying(255),
+ name character varying,
user_id integer,
created_at timestamp without time zone,
updated_at timestamp without time zone,
executable boolean,
renderable boolean,
- user_type character varying(255),
+ user_type character varying,
"binary" boolean
);
@@ -366,20 +365,20 @@ CREATE TABLE files (
id integer NOT NULL,
content text,
context_id integer,
- context_type character varying(255),
+ context_type character varying,
file_id integer,
file_type_id integer,
hidden boolean,
- name character varying(255),
+ name character varying,
read_only boolean,
created_at timestamp without time zone,
updated_at timestamp without time zone,
- native_file character varying(255),
- role character varying(255),
- hashed_content character varying(255),
- feedback_message character varying(255),
+ native_file character varying,
+ role character varying,
+ hashed_content character varying,
+ feedback_message character varying,
weight double precision,
- path character varying(255),
+ path character varying,
file_template_id integer
);
@@ -410,10 +409,10 @@ ALTER SEQUENCE files_id_seq OWNED BY files.id;
CREATE TABLE hints (
id integer NOT NULL,
execution_environment_id integer,
- locale character varying(255),
+ locale character varying,
message text,
- name character varying(255),
- regular_expression character varying(255),
+ name character varying,
+ regular_expression character varying,
created_at timestamp without time zone,
updated_at timestamp without time zone
);
@@ -445,23 +444,23 @@ ALTER SEQUENCE hints_id_seq OWNED BY hints.id;
CREATE TABLE internal_users (
id integer NOT NULL,
consumer_id integer,
- email character varying(255),
- name character varying(255),
- role character varying(255),
+ email character varying,
+ name character varying,
+ role character varying,
created_at timestamp without time zone,
updated_at timestamp without time zone,
- crypted_password character varying(255),
- salt character varying(255),
+ crypted_password character varying,
+ salt character varying,
failed_logins_count integer DEFAULT 0,
lock_expires_at timestamp without time zone,
- unlock_token character varying(255),
- remember_me_token character varying(255),
+ unlock_token character varying,
+ remember_me_token character varying,
remember_me_token_expires_at timestamp without time zone,
- reset_password_token character varying(255),
+ reset_password_token character varying,
reset_password_token_expires_at timestamp without time zone,
reset_password_email_sent_at timestamp without time zone,
- activation_state character varying(255),
- activation_token character varying(255),
+ activation_state character varying,
+ activation_token character varying,
activation_token_expires_at timestamp without time zone
);
@@ -519,6 +518,39 @@ CREATE SEQUENCE lti_parameters_id_seq
ALTER SEQUENCE lti_parameters_id_seq OWNED BY lti_parameters.id;
+--
+-- Name: remote_evaluation_mappings; Type: TABLE; Schema: public; Owner: -
+--
+
+CREATE TABLE remote_evaluation_mappings (
+ id integer NOT NULL,
+ user_id integer NOT NULL,
+ exercise_id integer NOT NULL,
+ validation_token character varying NOT NULL,
+ created_at timestamp without time zone,
+ updated_at timestamp without time zone
+);
+
+
+--
+-- Name: remote_evaluation_mappings_id_seq; Type: SEQUENCE; Schema: public; Owner: -
+--
+
+CREATE SEQUENCE remote_evaluation_mappings_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+--
+-- Name: remote_evaluation_mappings_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
+--
+
+ALTER SEQUENCE remote_evaluation_mappings_id_seq OWNED BY remote_evaluation_mappings.id;
+
+
--
-- Name: request_for_comments; Type: TABLE; Schema: public; Owner: -
--
@@ -530,7 +562,7 @@ CREATE TABLE request_for_comments (
file_id integer NOT NULL,
created_at timestamp without time zone,
updated_at timestamp without time zone,
- user_type character varying(255),
+ user_type character varying,
question text,
solved boolean,
submission_id integer
@@ -561,7 +593,7 @@ ALTER SEQUENCE request_for_comments_id_seq OWNED BY request_for_comments.id;
--
CREATE TABLE schema_migrations (
- version character varying(255) NOT NULL
+ version character varying NOT NULL
);
@@ -576,8 +608,8 @@ CREATE TABLE submissions (
user_id integer,
created_at timestamp without time zone,
updated_at timestamp without time zone,
- cause character varying(255),
- user_type character varying(255)
+ cause character varying,
+ user_type character varying
);
@@ -725,6 +757,13 @@ ALTER TABLE ONLY internal_users ALTER COLUMN id SET DEFAULT nextval('internal_us
ALTER TABLE ONLY lti_parameters ALTER COLUMN id SET DEFAULT nextval('lti_parameters_id_seq'::regclass);
+--
+-- Name: id; Type: DEFAULT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY remote_evaluation_mappings ALTER COLUMN id SET DEFAULT nextval('remote_evaluation_mappings_id_seq'::regclass);
+
+
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
@@ -850,6 +889,14 @@ ALTER TABLE ONLY lti_parameters
ADD CONSTRAINT lti_parameters_pkey PRIMARY KEY (id);
+--
+-- Name: remote_evaluation_mappings_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY remote_evaluation_mappings
+ ADD CONSTRAINT remote_evaluation_mappings_pkey PRIMARY KEY (id);
+
+
--
-- Name: request_for_comments_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@@ -874,13 +921,6 @@ ALTER TABLE ONLY testruns
ADD CONSTRAINT testruns_pkey PRIMARY KEY (id);
---
--- Name: index_code_harbor_links_on_user_id; Type: INDEX; Schema: public; Owner: -
---
-
-CREATE INDEX index_code_harbor_links_on_user_id ON code_harbor_links USING btree (user_id);
-
-
--
-- Name: index_comments_on_file_id; Type: INDEX; Schema: public; Owner: -
--
@@ -1120,3 +1160,5 @@ INSERT INTO schema_migrations (version) VALUES ('20160907123009');
INSERT INTO schema_migrations (version) VALUES ('20170112151637');
+INSERT INTO schema_migrations (version) VALUES ('20170202170437');
+