Description:
added submission_status to store grading results, first page shows only unpassed problems.
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r216:fa11dca6b078 - - 10 files changed: 149 inserted, 74 deleted

@@ -0,0 +1,6
1 + class SubmissionStatus < ActiveRecord::Base
2 +
3 + belongs_to :user
4 + belongs_to :problem
5 +
6 + end
@@ -0,0 +1,18
1 + .problem-panel{:id => "problem-panel-#{problem.id}", :style => "display:none"}
2 + .problem-form{:id => "problem-form-#{problem.id}"}
3 + - form_tag({ :action => 'download_input', :id => problem.id }, :method => :post) do
4 + %b Input:
5 + %input{:type => "submit", :value => "Download input"}
6 + - form_tag({ :action => 'submit_solution', :id => problem.id }, :method => :post, :multipart => true) do
7 + %b Submit output:
8 + %input{:type => "file", :name => "file"}
9 + %input{:type => "submit", :value => "Submit solution"}
10 +
11 + .problem-description
12 + - if problem.description!=nil
13 + - if problem.description.markdowned
14 + = markdown(problem.description.body)
15 + - else
16 + = problem.description.body
17 + - else
18 + (not available)
@@ -0,0 +1,16
1 + class CreateSubmissionStatuses < ActiveRecord::Migration
2 + def self.up
3 + create_table :submission_statuses do |t|
4 + t.integer :user_id
5 + t.integer :problem_id
6 + t.boolean :passed
7 + t.integer :submission_count
8 +
9 + t.timestamps
10 + end
11 + end
12 +
13 + def self.down
14 + drop_table :submission_statuses
15 + end
16 + end
@@ -0,0 +1,13
1 + # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 +
3 + one:
4 + user_id: 1
5 + problem_id: 1
6 + passed: false
7 + submission_count: 1
8 +
9 + two:
10 + user_id: 1
11 + problem_id: 1
12 + passed: false
13 + submission_count: 1
@@ -0,0 +1,8
1 + require 'test_helper'
2 +
3 + class SubmissionStatusTest < ActiveSupport::TestCase
4 + # Replace this with your real tests.
5 + test "the truth" do
6 + assert true
7 + end
8 + end
@@ -1,59 +1,59
1 1 class MainController < ApplicationController
2 2
3 3 SYSTEM_MODE_CONF_KEY = 'system.mode'
4 4
5 5 before_filter :authenticate, :except => [:index, :login]
6 6 before_filter :check_viewability, :except => [:index, :login]
7 7
8 8 # COMMENTED OUT: filter in each action instead
9 9 # before_filter :verify_time_limit, :only => [:submit]
10 10
11 - verify :method => :post, :only => [:submit, :new_input, :download_input, :submit_solution],
11 + verify :method => :post, :only => [:submit, :download_input, :submit_solution],
12 12 :redirect_to => { :action => :index }
13 13
14 14 # COMMENT OUT: only need when having high load
15 15 # caches_action :index, :login
16 16
17 17 # NOTE: This method is not actually needed, 'config/routes.rb' has
18 18 # assigned action login as a default action.
19 19 def index
20 20 redirect_to :action => 'login'
21 21 end
22 22
23 23 def login
24 24 saved_notice = flash[:notice]
25 25 reset_session
26 26 flash[:notice] = saved_notice
27 27
28 28 # EXPERIMENT:
29 29 # Hide login if in single user mode and the url does not
30 30 # explicitly specify /login
31 31 #
32 32 # logger.info "PATH: #{request.path}"
33 33 # if Configuration['system.single_user_mode'] and
34 34 # request.path!='/main/login'
35 35 # @hidelogin = true
36 36 # end
37 37
38 38 @announcements = Announcement.find_for_frontpage
39 39 render :action => 'login', :layout => 'empty'
40 40 end
41 41
42 42 def list
43 43 prepare_list_information
44 44 end
45 45
46 46 def help
47 47 @user = User.find(session[:user_id])
48 48 end
49 49
50 50 def submit
51 51 user = User.find(session[:user_id])
52 52
53 53 @submission = Submission.new(params[:submission])
54 54 @submission.user = user
55 55 @submission.language_id = 0
56 56 if (params['file']) and (params['file']!='')
57 57 @submission.source = params['file'].read
58 58 @submission.source_filename = params['file'].original_filename
59 59 end
@@ -131,183 +131,205
131 131 end
132 132 prepare_grading_result(@submission)
133 133 end
134 134
135 135 def load_output
136 136 if !Configuration.show_grading_result or params[:num]==nil
137 137 redirect_to :action => 'list' and return
138 138 end
139 139 @user = User.find(session[:user_id])
140 140 @submission = Submission.find(params[:id])
141 141 if @submission.user!=@user
142 142 flash[:notice] = 'You are not allowed to view result of other users.'
143 143 redirect_to :action => 'list' and return
144 144 end
145 145 case_num = params[:num].to_i
146 146 out_filename = output_filename(@user.login,
147 147 @submission.problem.name,
148 148 @submission.id,
149 149 case_num)
150 150 if !FileTest.exists?(out_filename)
151 151 flash[:notice] = 'Output not found.'
152 152 redirect_to :action => 'list' and return
153 153 end
154 154
155 155 response.headers['Content-Type'] = "application/force-download"
156 156 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
157 157 response.headers["X-Sendfile"] = out_filename
158 158 response.headers['Content-length'] = File.size(out_filename)
159 159 render :nothing => true
160 160 end
161 161
162 162 def error
163 163 @user = User.find(session[:user_id])
164 164 end
165 165
166 166 # announcement refreshing and hiding methods
167 167
168 168 def announcements
169 169 if params.has_key? 'recent'
170 170 prepare_announcements(params[:recent])
171 171 else
172 172 prepare_announcements
173 173 end
174 174 render(:partial => 'announcement',
175 175 :collection => @announcements,
176 176 :locals => {:announcement_effect => true})
177 177 end
178 178
179 + #
179 180 # actions for Code Jom
180 - def new_input
181 + #
182 + def download_input
181 183 problem = Problem.find(params[:id])
182 184 user = User.find(session[:user_id])
183 185 if user.can_request_new_test_pair_for? problem
184 186 assignment = user.get_new_test_pair_assignment_for problem
185 187 assignment.save
186 188
187 189 send_data(assignment.test_pair.input,
188 190 { :filename => "#{problem.name}-#{assignment.request_number}.in",
189 191 :type => 'text/plain' })
190 - else
191 - flash[:notice] = 'You cannot request new input now.'
192 - redirect_to :action => 'list'
193 - end
194 - end
195 -
196 - def download_input
197 - problem = Problem.find(params[:id])
198 - user = User.find(session[:user_id])
199 - recent_assignment = user.get_recent_test_pair_assignment_for problem
200 - if recent_assignment != nil
192 + else
193 + recent_assignment = user.get_recent_test_pair_assignment_for problem
201 194 send_data(recent_assignment.test_pair.input,
202 195 { :filename => "#{problem.name}-#{recent_assignment.request_number}.in",
203 196 :type => 'text/plain' })
204 - else
205 - flash[:notice] = 'You have not requested for any input data for this problem.'
206 - redirect_to :action => 'list'
207 197 end
208 198 end
209 199
210 200 def submit_solution
211 201 problem = Problem.find(params[:id])
212 202 user = User.find(session[:user_id])
213 203 recent_assignment = user.get_recent_test_pair_assignment_for problem
214 - if recent_assignment != nil
215 - submitted_solution = params[:file].read
216 - test_pair = recent_assignment.test_pair
217 - passed = test_pair.grade(submitted_solution)
218 - points = passed ? 100 : 0
219 - submission = Submission.new(:user => user,
220 - :problem => problem,
221 - :source => params[:file].read,
222 - :source_filename => params['file'].original_filename,
223 - :language_id => 0,
224 - :submitted_at => Time.new.gmtime,
225 - :graded_at => Time.new.gmtime,
226 - :points => points)
227 - submission.save
228 - recent_assignment.submitted = true
229 - recent_assignment.save
230 - if passed
231 - flash[:notice] = 'Correct solution'
232 - else
233 - flash[:notice] = 'Incorrect solution'
234 - end
235 - redirect_to :action => 'list'
204 + if recent_assignment == nil
205 + flash[:notice] = 'You have not requested for any input data for this problem. Please download an input first.'
206 + redirect_to :action => 'list' and return
207 + end
208 +
209 + if recent_assignment.submitted
210 + flash[:notice] = 'You have already submitted an incorrect solution for this input. Please download a new input data.'
211 + redirect_to :action => 'list' and return
212 + end
213 +
214 + if params[:file] == nil
215 + flash[:notice] = 'You have not submitted any output.'
216 + redirect_to :action => 'list' and return
217 + end
218 +
219 + submitted_solution = params[:file].read
220 + test_pair = recent_assignment.test_pair
221 + passed = test_pair.grade(submitted_solution)
222 + points = passed ? 100 : 0
223 + submission = Submission.new(:user => user,
224 + :problem => problem,
225 + :source => submitted_solution,
226 + :source_filename => params['file'].original_filename,
227 + :language_id => 0,
228 + :submitted_at => Time.new.gmtime,
229 + :graded_at => Time.new.gmtime,
230 + :points => points)
231 + submission.save
232 + recent_assignment.submitted = true
233 + recent_assignment.save
234 +
235 + status = user.get_submission_status_for(problem)
236 + if status == nil
237 + status = SubmissionStatus.new :user => user, :problem => problem, :submission_count => 0
238 + end
239 +
240 + status.submission_count += 1
241 + status.passed = passed
242 + status.save
243 +
244 + if passed
245 + flash[:notice] = 'Correct solution.'
236 246 else
237 - flash[:notice] = 'You have not requested for any input data for this problem.'
238 - redirect_to :action => 'list'
247 + flash[:notice] = 'Incorrect solution.'
239 248 end
249 + redirect_to :action => 'list'
240 250 end
241 251
242 252 protected
243 253
244 254 def prepare_announcements(recent=nil)
245 255 if Configuration.show_tasks_to?(@user)
246 256 @announcements = Announcement.find_published(true)
247 257 else
248 258 @announcements = Announcement.find_published
249 259 end
250 260 if recent!=nil
251 261 recent_id = recent.to_i
252 262 @announcements = @announcements.find_all { |a| a.id > recent_id }
253 263 end
254 264 end
255 265
256 266 def prepare_list_information
257 - @problems = Problem.find_available_problems
267 + @user = User.find(session[:user_id])
268 +
269 + all_problems = Problem.find_available_problems
270 +
271 + passed = {}
272 + sub_count = {}
273 + @user.submission_statuses.each do |status|
274 + if status.passed
275 + passed[status.problem_id] = true
276 + end
277 + sub_count[status.problem_id] = status.submission_count
278 + end
279 +
280 + @problems = all_problems.reject { |problem| passed.has_key? problem.id }
281 +
258 282 @prob_submissions = Array.new
259 - @user = User.find(session[:user_id])
260 283 @problems.each do |p|
261 - sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
262 - if sub!=nil
263 - @prob_submissions << { :count => sub.number, :submission => sub }
284 + if sub_count.has_key? p.id
285 + @prob_submissions << { :count => sub_count[p.id] }
264 286 else
265 - @prob_submissions << { :count => 0, :submission => nil }
287 + @prob_submissions << { :count => 0 }
266 288 end
267 289 end
268 290 prepare_announcements
269 291 end
270 292
271 293 def check_viewability
272 294 @user = User.find(session[:user_id])
273 295 if (!Configuration.show_tasks_to?(@user)) and
274 296 ((action_name=='submission') or (action_name=='submit'))
275 297 redirect_to :action => 'list' and return
276 298 end
277 299 end
278 300
279 301 def prepare_grading_result(submission)
280 302 if Configuration.task_grading_info.has_key? submission.problem.name
281 303 grading_info = Configuration.task_grading_info[submission.problem.name]
282 304 else
283 305 # guess task info from problem.full_score
284 306 cases = submission.problem.full_score / 10
285 307 grading_info = {
286 308 'testruns' => cases,
287 309 'testcases' => cases
288 310 }
289 311 end
290 312 @test_runs = []
291 313 if grading_info['testruns'].is_a? Integer
292 314 trun_count = grading_info['testruns']
293 315 trun_count.times do |i|
294 316 @test_runs << [ read_grading_result(@user.login,
295 317 submission.problem.name,
296 318 submission.id,
297 319 i+1) ]
298 320 end
299 321 else
300 322 grading_info['testruns'].keys.sort.each do |num|
301 323 run = []
302 324 testrun = grading_info['testruns'][num]
303 325 testrun.each do |c|
304 326 run << read_grading_result(@user.login,
305 327 submission.problem.name,
306 328 submission.id,
307 329 c)
308 330 end
309 331 @test_runs << run
310 332 end
311 333 end
312 334 end
313 335
@@ -1,62 +1,62
1 1 class Submission < ActiveRecord::Base
2 2
3 3 belongs_to :language
4 4 belongs_to :problem
5 5 belongs_to :user
6 6
7 7 before_validation :assign_problem
8 8 before_validation :assign_language
9 9
10 10 validates_presence_of :source
11 11 validates_length_of :source, :maximum => 100_000, :allow_blank => true, :message => 'too long'
12 12 validates_length_of :source, :minimum => 1, :allow_blank => true, :message => 'too short'
13 13 validate :must_have_valid_problem
14 - validate :must_specify_language
14 + #validate :must_specify_language
15 15
16 16 before_save :assign_latest_number_if_new_recond
17 17
18 18 def self.find_last_by_user_and_problem(user_id, problem_id)
19 19 last_sub = find(:first,
20 20 :conditions => {:user_id => user_id,
21 21 :problem_id => problem_id},
22 22 :order => 'number DESC')
23 23 return last_sub
24 24 end
25 25
26 26 def self.find_all_last_by_problem(problem_id)
27 27 # need to put in SQL command, maybe there's a better way
28 28 Submission.find_by_sql("SELECT * FROM submissions " +
29 29 "WHERE id = " +
30 30 "(SELECT MAX(id) FROM submissions AS subs " +
31 31 "WHERE subs.user_id = submissions.user_id AND " +
32 32 "problem_id = " + problem_id.to_s + " " +
33 33 "GROUP BY user_id) " +
34 34 "ORDER BY user_id")
35 35 end
36 36
37 37 def self.find_last_for_all_available_problems(user_id)
38 38 submissions = Array.new
39 39 problems = Problem.find_available_problems
40 40 problems.each do |problem|
41 41 sub = Submission.find_last_by_user_and_problem(user_id, problem.id)
42 42 submissions << sub if sub!=nil
43 43 end
44 44 submissions
45 45 end
46 46
47 47 def self.find_by_user_problem_number(user_id, problem_id, number)
48 48 Submission.find(:first,
49 49 :conditions => {
50 50 :user_id => user_id,
51 51 :problem_id => problem_id,
52 52 :number => number
53 53 })
54 54 end
55 55
56 56 def self.find_all_by_user_problem(user_id, problem_id)
57 57 Submission.find(:all,
58 58 :conditions => {
59 59 :user_id => user_id,
60 60 :problem_id => problem_id,
61 61 })
62 62 end
@@ -1,161 +1,170
1 1 require 'digest/sha1'
2 2
3 3 class User < ActiveRecord::Base
4 4
5 5 has_and_belongs_to_many :roles
6 6
7 7 has_many :test_requests, :order => "submitted_at DESC"
8 8
9 9 has_many :messages,
10 10 :class_name => "Message",
11 11 :foreign_key => "sender_id",
12 12 :order => 'created_at DESC'
13 13
14 14 has_many :replied_messages,
15 15 :class_name => "Message",
16 16 :foreign_key => "receiver_id",
17 17 :order => 'created_at DESC'
18 18
19 19 has_many :test_pair_assignments, :dependent => :delete_all
20 + has_many :submission_statuses
20 21
21 22 belongs_to :site
22 23 belongs_to :country
23 24
24 25 named_scope :activated_users, :conditions => {:activated => true}
25 26
26 27 validates_presence_of :login
27 28 validates_uniqueness_of :login
28 29 validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
29 30 validates_length_of :login, :within => 3..30
30 31
31 32 validates_presence_of :full_name
32 33 validates_length_of :full_name, :minimum => 1
33 34
34 35 validates_presence_of :password, :if => :password_required?
35 36 validates_length_of :password, :within => 4..20, :if => :password_required?
36 37 validates_confirmation_of :password, :if => :password_required?
37 38
38 39 validates_format_of :email,
39 40 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
40 41 :if => :email_validation?
41 42 validate :uniqueness_of_email_from_activated_users,
42 43 :if => :email_validation?
43 44 validate :enough_time_interval_between_same_email_registrations,
44 45 :if => :email_validation?
45 46
46 47 # these are for ytopc
47 48 # disable for now
48 49 #validates_presence_of :province
49 50
50 51 attr_accessor :password
51 52
52 53 before_save :encrypt_new_password
53 54 before_save :assign_default_site
54 55
55 56 def self.authenticate(login, password)
56 57 user = find_by_login(login)
57 58 return user if user && user.authenticated?(password)
58 59 end
59 60
60 61 def authenticated?(password)
61 62 if self.activated
62 63 hashed_password == User.encrypt(password,self.salt)
63 64 else
64 65 false
65 66 end
66 67 end
67 68
68 69 def admin?
69 70 self.roles.detect {|r| r.name == 'admin' }
70 71 end
71 72
72 73 # These are methods related to test pairs
73 74
74 75 def get_test_pair_assignments_for(problem)
75 76 test_pair_assignments.find_all { |a| a.problem_id == problem.id }
76 77 end
77 78
78 79 def get_recent_test_pair_assignment_for(problem)
79 80 assignments = get_test_pair_assignments_for problem
80 81 if assignments.length == 0
81 82 return nil
82 83 else
83 84 recent = assignments[0]
84 85 assignments.each do |a|
85 86 recent = a if a.request_number > recent.request_number
86 87 end
87 88 return recent
88 89 end
89 90 end
90 91
91 92 def can_request_new_test_pair_for?(problem)
92 93 recent = get_recent_test_pair_assignment_for problem
93 94 return (recent == nil or recent.submitted)
94 95 end
95 96
96 97 def get_new_test_pair_assignment_for(problem)
97 98 previous_assignment_numbers =
98 99 get_test_pair_assignments_for(problem).collect {|a| a.test_pair_number }
99 100 test_pair = problem.random_test_pair(previous_assignment_numbers)
100 101 if test_pair
101 102 assignment = TestPairAssignment.new(:user => self,
102 103 :problem => problem,
103 104 :test_pair => test_pair,
104 105 :test_pair_number => test_pair.number,
105 106 :request_number =>
106 107 previous_assignment_numbers.length + 1,
107 108 :submitted => false)
108 109 return assignment
109 110 else
110 111 return nil
111 112 end
112 113 end
113 114
115 + def get_submission_status_for(problem)
116 + SubmissionStatus.find(:first,
117 + :conditions => {
118 + :user_id => id,
119 + :problem_id => problem.id
120 + })
121 + end
122 +
114 123 def email_for_editing
115 124 if self.email==nil
116 125 "(unknown)"
117 126 elsif self.email==''
118 127 "(blank)"
119 128 else
120 129 self.email
121 130 end
122 131 end
123 132
124 133 def email_for_editing=(e)
125 134 self.email=e
126 135 end
127 136
128 137 def alias_for_editing
129 138 if self.alias==nil
130 139 "(unknown)"
131 140 elsif self.alias==''
132 141 "(blank)"
133 142 else
134 143 self.alias
135 144 end
136 145 end
137 146
138 147 def alias_for_editing=(e)
139 148 self.alias=e
140 149 end
141 150
142 151 def activation_key
143 152 if self.hashed_password==nil
144 153 encrypt_new_password
145 154 end
146 155 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
147 156 end
148 157
149 158 def verify_activation_key(key)
150 159 key == activation_key
151 160 end
152 161
153 162 def self.random_password(length=5)
154 163 chars = 'abcdefghjkmnopqrstuvwxyz'
155 164 password = ''
156 165 length.times { password << chars[rand(chars.length - 1)] }
157 166 password
158 167 end
159 168
160 169 def self.find_non_admin_with_prefix(prefix='')
161 170 users = User.find(:all)
@@ -1,60 +1,60
1 1 # This file is auto-generated from the current state of the database. Instead of editing this file,
2 2 # please use the migrations feature of Active Record to incrementally modify your database, and
3 3 # then regenerate this schema definition.
4 4 #
5 5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
6 6 # to create the application database on another system, you should be using db:schema:load, not running
7 7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
8 8 # you'll amass, the slower it'll run and the greater likelihood for issues).
9 9 #
10 10 # It's strongly recommended to check this file into your version control system.
11 11
12 - ActiveRecord::Schema.define(:version => 20100118174404) do
12 + ActiveRecord::Schema.define(:version => 20100123154326) do
13 13
14 14 create_table "announcements", :force => true do |t|
15 15 t.string "author"
16 16 t.text "body"
17 17 t.boolean "published"
18 18 t.datetime "created_at"
19 19 t.datetime "updated_at"
20 20 t.boolean "frontpage", :default => false
21 21 t.boolean "contest_only", :default => false
22 22 t.string "title"
23 23 end
24 24
25 25 create_table "configurations", :force => true do |t|
26 26 t.string "key"
27 27 t.string "value_type"
28 28 t.string "value"
29 29 t.datetime "created_at"
30 30 t.datetime "updated_at"
31 31 end
32 32
33 33 create_table "countries", :force => true do |t|
34 34 t.string "name"
35 35 t.datetime "created_at"
36 36 t.datetime "updated_at"
37 37 end
38 38
39 39 create_table "descriptions", :force => true do |t|
40 40 t.text "body"
41 41 t.boolean "markdowned"
42 42 t.datetime "created_at"
43 43 t.datetime "updated_at"
44 44 end
45 45
46 46 create_table "grader_processes", :force => true do |t|
47 47 t.string "host", :limit => 20
48 48 t.integer "pid"
49 49 t.string "mode"
50 50 t.boolean "active"
51 51 t.datetime "created_at"
52 52 t.datetime "updated_at"
53 53 t.integer "task_id"
54 54 t.string "task_type"
55 55 t.boolean "terminated"
56 56 end
57 57
58 58 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
59 59
60 60 create_table "languages", :force => true do |t|
@@ -84,96 +84,105
84 84 t.integer "description_id"
85 85 t.boolean "test_allowed"
86 86 t.boolean "output_only"
87 87 end
88 88
89 89 create_table "rights", :force => true do |t|
90 90 t.string "name"
91 91 t.string "controller"
92 92 t.string "action"
93 93 end
94 94
95 95 create_table "rights_roles", :id => false, :force => true do |t|
96 96 t.integer "right_id"
97 97 t.integer "role_id"
98 98 end
99 99
100 100 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
101 101
102 102 create_table "roles", :force => true do |t|
103 103 t.string "name"
104 104 end
105 105
106 106 create_table "roles_users", :id => false, :force => true do |t|
107 107 t.integer "role_id"
108 108 t.integer "user_id"
109 109 end
110 110
111 111 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
112 112
113 113 create_table "sessions", :force => true do |t|
114 114 t.string "session_id"
115 115 t.text "data"
116 116 t.datetime "updated_at"
117 117 end
118 118
119 119 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
120 120 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
121 121
122 122 create_table "sites", :force => true do |t|
123 123 t.string "name"
124 124 t.boolean "started"
125 125 t.datetime "start_time"
126 126 t.datetime "created_at"
127 127 t.datetime "updated_at"
128 128 t.integer "country_id"
129 129 t.string "password"
130 130 end
131 131
132 + create_table "submission_statuses", :force => true do |t|
133 + t.integer "user_id"
134 + t.integer "problem_id"
135 + t.boolean "passed"
136 + t.integer "submission_count"
137 + t.datetime "created_at"
138 + t.datetime "updated_at"
139 + end
140 +
132 141 create_table "submissions", :force => true do |t|
133 142 t.integer "user_id"
134 143 t.integer "problem_id"
135 144 t.integer "language_id"
136 145 t.text "source"
137 146 t.binary "binary"
138 147 t.datetime "submitted_at"
139 148 t.datetime "compiled_at"
140 149 t.text "compiler_message"
141 150 t.datetime "graded_at"
142 151 t.integer "points"
143 152 t.text "grader_comment"
144 153 t.integer "number"
145 154 t.string "source_filename"
146 155 end
147 156
148 157 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
149 158 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
150 159
151 160 create_table "tasks", :force => true do |t|
152 161 t.integer "submission_id"
153 162 t.datetime "created_at"
154 163 t.integer "status"
155 164 t.datetime "updated_at"
156 165 end
157 166
158 167 create_table "test_pair_assignments", :force => true do |t|
159 168 t.integer "user_id"
160 169 t.integer "problem_id"
161 170 t.integer "test_pair_id"
162 171 t.integer "test_pair_number"
163 172 t.integer "request_number"
164 173 t.datetime "created_at"
165 174 t.datetime "updated_at"
166 175 t.boolean "submitted"
167 176 end
168 177
169 178 create_table "test_pairs", :force => true do |t|
170 179 t.integer "problem_id"
171 180 t.text "input"
172 181 t.text "solution"
173 182 t.datetime "created_at"
174 183 t.datetime "updated_at"
175 184 t.integer "number"
176 185 end
177 186
178 187 create_table "test_requests", :force => true do |t|
179 188 t.integer "user_id"
deleted file
You need to be logged in to leave comments. Login now