Description:
added number (auto generated when submitting) to submissions git-svn-id: http://theory.cpe.ku.ac.th/grader/web/trunk@73 6386c4cd-e34a-4fa8-8920-d93eb39b512e
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r35:3d41a77d4876 - - 6 files changed: 62 inserted, 18 deleted

@@ -0,0 +1,33
1 + class AddNumberToSubmissions < ActiveRecord::Migration
2 + def self.up
3 + add_column :submissions, :number, :integer
4 +
5 + # add number field for all records
6 + Submission.reset_column_information
7 +
8 + last_user_id = nil
9 + last_problem_id = nil
10 + current_number = 0
11 +
12 + Submission.find(:all,
13 + :order => 'user_id, problem_id, submitted_at').each do |submission|
14 + if submission.user_id==last_user_id and submission.problem_id==last_problem_id
15 + current_number += 1
16 + else
17 + current_number = 1
18 + end
19 + submission.number = current_number
20 + submission.save
21 +
22 + last_user_id = submission.user_id
23 + last_problem_id = submission.problem_id
24 + end
25 +
26 + add_index :submissions, [:user_id, :problem_id, :number], :unique => true
27 + end
28 +
29 + def self.down
30 + remove_index :submissions, :column => [:user_id, :problem_id, :number]
31 + remove_column :submissions, :number
32 + end
33 + end
@@ -36,31 +36,35
36 prepare_list_information
36 prepare_list_information
37 render :action => 'list' and return
37 render :action => 'list' and return
38 end
38 end
39 redirect_to :action => 'list'
39 redirect_to :action => 'list'
40 end
40 end
41
41
42 def get_source
42 def get_source
43 submission = Submission.find(params[:id])
43 submission = Submission.find(params[:id])
44 if submission.user_id == session[:user_id]
44 if submission.user_id == session[:user_id]
45 fname = submission.problem.name + '.' + submission.language.ext
45 fname = submission.problem.name + '.' + submission.language.ext
46 send_data(submission.source,
46 send_data(submission.source,
47 {:filename => fname,
47 {:filename => fname,
48 :type => 'text/plain'})
48 :type => 'text/plain'})
49 else
49 else
50 flash[:notice] = 'Error viewing source'
50 flash[:notice] = 'Error viewing source'
51 end
51 end
52 end
52 end
53
53
54 protected
54 protected
55 def prepare_list_information
55 def prepare_list_information
56 @problems = Problem.find_available_problems
56 @problems = Problem.find_available_problems
57 @prob_submissions = Array.new
57 @prob_submissions = Array.new
58 @user = User.find(session[:user_id])
58 @user = User.find(session[:user_id])
59 @problems.each do |p|
59 @problems.each do |p|
60 - c, sub = Submission.find_by_user_and_problem(@user.id,p.id)
60 + sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
61 - @prob_submissions << { :count => c, :submission => sub }
61 + if sub!=nil
62 + @prob_submissions << { :count => sub.number, :submission => sub }
63 + else
64 + @prob_submissions << { :count => 0, :submission => nil }
65 + end
62 end
66 end
63 end
67 end
64
68
65 end
69 end
66
70
@@ -44,27 +44,27
44 def update
44 def update
45 @problem = Problem.find(params[:id])
45 @problem = Problem.find(params[:id])
46 if @problem.update_attributes(params[:problem])
46 if @problem.update_attributes(params[:problem])
47 flash[:notice] = 'Problem was successfully updated.'
47 flash[:notice] = 'Problem was successfully updated.'
48 redirect_to :action => 'show', :id => @problem
48 redirect_to :action => 'show', :id => @problem
49 else
49 else
50 render :action => 'edit'
50 render :action => 'edit'
51 end
51 end
52 end
52 end
53
53
54 def destroy
54 def destroy
55 Problem.find(params[:id]).destroy
55 Problem.find(params[:id]).destroy
56 redirect_to :action => 'list'
56 redirect_to :action => 'list'
57 end
57 end
58
58
59 def toggle_avail
59 def toggle_avail
60 problem = Problem.find(params[:id])
60 problem = Problem.find(params[:id])
61 problem.available = !(problem.available)
61 problem.available = !(problem.available)
62 problem.save
62 problem.save
63 redirect_to :action => 'list'
63 redirect_to :action => 'list'
64 end
64 end
65
65
66 def stat
66 def stat
67 @problem = Problem.find(params[:id])
67 @problem = Problem.find(params[:id])
68 - @submissions = Submission.find_last_by_problem(params[:id])
68 + @submissions = Submission.find_all_last_by_problem(params[:id])
69 end
69 end
70 end
70 end
@@ -56,35 +56,35
56
56
57 def update
57 def update
58 @user = User.find(params[:id])
58 @user = User.find(params[:id])
59 if @user.update_attributes(params[:user])
59 if @user.update_attributes(params[:user])
60 flash[:notice] = 'User was successfully updated.'
60 flash[:notice] = 'User was successfully updated.'
61 redirect_to :action => 'show', :id => @user
61 redirect_to :action => 'show', :id => @user
62 else
62 else
63 render :action => 'edit'
63 render :action => 'edit'
64 end
64 end
65 end
65 end
66
66
67 def destroy
67 def destroy
68 User.find(params[:id]).destroy
68 User.find(params[:id]).destroy
69 redirect_to :action => 'list'
69 redirect_to :action => 'list'
70 end
70 end
71
71
72 def user_stat
72 def user_stat
73 @problems = Problem.find_available_problems
73 @problems = Problem.find_available_problems
74 @users = User.find(:all)
74 @users = User.find(:all)
75 @scorearray = Array.new
75 @scorearray = Array.new
76 @users.each do |u|
76 @users.each do |u|
77 ustat = Array.new
77 ustat = Array.new
78 ustat[0] = u.login
78 ustat[0] = u.login
79 @problems.each do |p|
79 @problems.each do |p|
80 - c, sub = Submission.find_by_user_and_problem(u.id,p.id)
80 + sub = Submission.find_last_by_user_and_problem(u.id,p.id)
81 - if (c!=0) and (sub.points!=nil)
81 + if (sub!=nil) and (sub.points!=nil)
82 ustat << [sub.points, (sub.points>=p.full_score)]
82 ustat << [sub.points, (sub.points>=p.full_score)]
83 else
83 else
84 ustat << [0,false]
84 ustat << [0,false]
85 end
85 end
86 end
86 end
87 @scorearray << ustat
87 @scorearray << ustat
88 end
88 end
89 end
89 end
90 end
90 end
@@ -1,59 +1,58
1 class Submission < ActiveRecord::Base
1 class Submission < ActiveRecord::Base
2
2
3 belongs_to :language
3 belongs_to :language
4 belongs_to :problem
4 belongs_to :problem
5 belongs_to :user
5 belongs_to :user
6
6
7 validates_presence_of :source
7 validates_presence_of :source
8 validates_length_of :source, :maximum => 100_000, :allow_blank => true, :message => 'too long'
8 validates_length_of :source, :maximum => 100_000, :allow_blank => true, :message => 'too long'
9 validates_length_of :source, :minimum => 1, :allow_blank => true, :message => 'too short'
9 validates_length_of :source, :minimum => 1, :allow_blank => true, :message => 'too short'
10 validate :must_specify_language
10 validate :must_specify_language
11 validate :must_have_valid_problem
11 validate :must_have_valid_problem
12
12
13 - def self.find_by_user_and_problem(user_id, problem_id)
13 + before_save :assign_latest_number
14 - subcount = count(:conditions => "user_id = #{user_id} AND problem_id = #{problem_id}")
14 +
15 - if subcount != 0
15 + def self.find_last_by_user_and_problem(user_id, problem_id)
16 - last_sub = find(:first,
16 + last_sub = find(:first,
17 - :conditions => {:user_id => user_id,
17 + :conditions => {:user_id => user_id,
18 - :problem_id => problem_id},
18 + :problem_id => problem_id},
19 - :order => 'submitted_at DESC')
19 + :order => 'submitted_at DESC')
20 - else
20 + return last_sub
21 - last_sub = nil
22 - end
23 - return subcount, last_sub
24 end
21 end
25
22
26 - def self.find_last_by_problem(problem_id)
23 + def self.find_all_last_by_problem(problem_id)
27 # need to put in SQL command, maybe there's a better way
24 # need to put in SQL command, maybe there's a better way
28 Submission.find_by_sql("SELECT * FROM submissions " +
25 Submission.find_by_sql("SELECT * FROM submissions " +
29 "WHERE id = " +
26 "WHERE id = " +
30 "(SELECT MAX(id) FROM submissions AS subs " +
27 "(SELECT MAX(id) FROM submissions AS subs " +
31 "WHERE subs.user_id = submissions.user_id AND " +
28 "WHERE subs.user_id = submissions.user_id AND " +
32 "problem_id = " + problem_id.to_s + " " +
29 "problem_id = " + problem_id.to_s + " " +
33 "GROUP BY user_id)")
30 "GROUP BY user_id)")
34 end
31 end
35
32
33 + protected
34 +
36 def self.find_option_in_source(option, source)
35 def self.find_option_in_source(option, source)
37 if source==nil
36 if source==nil
38 return nil
37 return nil
39 end
38 end
40 i = 0
39 i = 0
41 source.each_line do |s|
40 source.each_line do |s|
42 if s =~ option
41 if s =~ option
43 words = s.split
42 words = s.split
44 return words[1]
43 return words[1]
45 end
44 end
46 i = i + 1
45 i = i + 1
47 if i==10
46 if i==10
48 return nil
47 return nil
49 end
48 end
50 end
49 end
51 return nil
50 return nil
52 end
51 end
53
52
54 def self.find_language_in_source(source)
53 def self.find_language_in_source(source)
55 langopt = find_option_in_source(/^LANG:/,source)
54 langopt = find_option_in_source(/^LANG:/,source)
56 if language = Language.find_by_name(langopt)
55 if language = Language.find_by_name(langopt)
57 return language
56 return language
58 elsif language = Language.find_by_pretty_name(langopt)
57 elsif language = Language.find_by_pretty_name(langopt)
59 return language
58 return language
@@ -71,25 +70,31
71 end
70 end
72 end
71 end
73
72
74 # validation codes
73 # validation codes
75 def must_specify_language
74 def must_specify_language
76 return if self.source==nil
75 return if self.source==nil
77 self.language = Submission.find_language_in_source(self.source)
76 self.language = Submission.find_language_in_source(self.source)
78 errors.add_to_base("must specify programming language") unless self.language!=nil
77 errors.add_to_base("must specify programming language") unless self.language!=nil
79 end
78 end
80
79
81 def must_have_valid_problem
80 def must_have_valid_problem
82 return if self.source==nil
81 return if self.source==nil
83 if self.problem_id!=-1
82 if self.problem_id!=-1
84 problem = Problem.find(self.problem_id)
83 problem = Problem.find(self.problem_id)
85 else
84 else
86 problem = Submission.find_problem_in_source(self.source)
85 problem = Submission.find_problem_in_source(self.source)
87 end
86 end
88 if problem==nil
87 if problem==nil
89 errors.add_to_base("must specify problem")
88 errors.add_to_base("must specify problem")
90 elsif !problem.available
89 elsif !problem.available
91 errors.add_to_base("must specify valid problem")
90 errors.add_to_base("must specify valid problem")
92 end
91 end
93 end
92 end
94
93
94 + # callbacks
95 + def assign_latest_number
96 + latest = Submission.find_last_by_user_and_problem(self.user_id, self.problem_id)
97 + self.number = (latest==nil) ? 1 : latest.number + 1;
98 + end
99 +
95 end
100 end
@@ -1,36 +1,36
1 # This file is auto-generated from the current state of the database. Instead of editing this file,
1 # This file is auto-generated from the current state of the database. Instead of editing this file,
2 # please use the migrations feature of ActiveRecord to incrementally modify your database, and
2 # please use the migrations feature of ActiveRecord to incrementally modify your database, and
3 # then regenerate this schema definition.
3 # then regenerate this schema definition.
4 #
4 #
5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
6 # to create the application database on another system, you should be using db:schema:load, not running
6 # to create the application database on another system, you should be using db:schema:load, not running
7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
8 # you'll amass, the slower it'll run and the greater likelihood for issues).
8 # you'll amass, the slower it'll run and the greater likelihood for issues).
9 #
9 #
10 # It's strongly recommended to check this file into your version control system.
10 # It's strongly recommended to check this file into your version control system.
11
11
12 - ActiveRecord::Schema.define(:version => 17) do
12 + ActiveRecord::Schema.define(:version => 18) do
13
13
14 create_table "grader_processes", :force => true do |t|
14 create_table "grader_processes", :force => true do |t|
15 t.string "host", :limit => 20
15 t.string "host", :limit => 20
16 t.integer "pid"
16 t.integer "pid"
17 t.string "mode"
17 t.string "mode"
18 t.boolean "active"
18 t.boolean "active"
19 t.datetime "created_at"
19 t.datetime "created_at"
20 t.datetime "updated_at"
20 t.datetime "updated_at"
21 t.integer "task_id"
21 t.integer "task_id"
22 end
22 end
23
23
24 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
24 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
25
25
26 create_table "languages", :force => true do |t|
26 create_table "languages", :force => true do |t|
27 t.string "name", :limit => 10
27 t.string "name", :limit => 10
28 t.string "pretty_name"
28 t.string "pretty_name"
29 t.string "ext", :limit => 10
29 t.string "ext", :limit => 10
30 end
30 end
31
31
32 create_table "problems", :force => true do |t|
32 create_table "problems", :force => true do |t|
33 t.string "name", :limit => 30
33 t.string "name", :limit => 30
34 t.string "full_name"
34 t.string "full_name"
35 t.integer "full_score"
35 t.integer "full_score"
36 t.date "date_added"
36 t.date "date_added"
@@ -62,47 +62,49
62
62
63 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
63 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
64
64
65 create_table "sessions", :force => true do |t|
65 create_table "sessions", :force => true do |t|
66 t.string "session_id"
66 t.string "session_id"
67 t.text "data"
67 t.text "data"
68 t.datetime "updated_at"
68 t.datetime "updated_at"
69 end
69 end
70
70
71 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
71 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
72 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
72 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
73
73
74 create_table "submissions", :force => true do |t|
74 create_table "submissions", :force => true do |t|
75 t.integer "user_id"
75 t.integer "user_id"
76 t.integer "problem_id"
76 t.integer "problem_id"
77 t.integer "language_id"
77 t.integer "language_id"
78 t.text "source"
78 t.text "source"
79 t.binary "binary"
79 t.binary "binary"
80 t.datetime "submitted_at"
80 t.datetime "submitted_at"
81 t.datetime "compiled_at"
81 t.datetime "compiled_at"
82 t.text "compiler_message"
82 t.text "compiler_message"
83 t.datetime "graded_at"
83 t.datetime "graded_at"
84 t.integer "points"
84 t.integer "points"
85 t.text "grader_comment"
85 t.text "grader_comment"
86 + t.integer "number"
86 end
87 end
87
88
89 + add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
88 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
90 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
89
91
90 create_table "tasks", :force => true do |t|
92 create_table "tasks", :force => true do |t|
91 t.integer "submission_id"
93 t.integer "submission_id"
92 t.datetime "created_at"
94 t.datetime "created_at"
93 t.integer "status"
95 t.integer "status"
94 t.datetime "updated_at"
96 t.datetime "updated_at"
95 end
97 end
96
98
97 create_table "users", :force => true do |t|
99 create_table "users", :force => true do |t|
98 t.string "login", :limit => 10
100 t.string "login", :limit => 10
99 t.string "full_name"
101 t.string "full_name"
100 t.string "hashed_password"
102 t.string "hashed_password"
101 t.string "salt", :limit => 5
103 t.string "salt", :limit => 5
102 t.string "alias"
104 t.string "alias"
103 t.string "email"
105 t.string "email"
104 end
106 end
105
107
106 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
108 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
107
109
108 end
110 end
You need to be logged in to leave comments. Login now