# HG changeset patch # User Nattee Niparnan # Date 2020-04-04 15:21:21 # Node ID 7ddf708c67bdd37fca6a47d0ad48e823ee30bdd7 # Parent 8cd7e8db7e38bff1930f76dfac9bb0fa64f8d0fe submission report diff --git a/Gemfile b/Gemfile --- a/Gemfile +++ b/Gemfile @@ -50,7 +50,7 @@ # jquery addition gem 'jquery-rails' gem 'jquery-ui-rails' -gem 'jquery-timepicker-addon-rails' +#gem 'jquery-timepicker-addon-rails' gem 'jquery-tablesorter' gem 'jquery-countdown-rails' @@ -62,10 +62,10 @@ gem 'bootstrap-switch-rails' gem 'bootstrap-toggle-rails' gem 'autoprefixer-rails' -gem 'momentjs-rails' +gem 'momentjs-rails', '>= 2.9.0' gem 'rails_bootstrap_sortable' -gem 'bootstrap-datepicker-rails' -gem 'bootstrap3-datetimepicker-rails' +#gem 'bootstrap-datepicker-rails' +gem 'bootstrap3-datetimepicker-rails', '~> 4.17.47' #gem 'jquery-datatables-rails' #----------- user interface ----------------- @@ -75,7 +75,7 @@ #ace editor gem 'ace-rails-ap' #paginator -gem 'will_paginate', '~> 3.0.7' +#gem 'will_paginate', '~> 3.0.7' gem 'mail' gem 'rdiscount' diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -64,8 +64,6 @@ bindex (0.8.1) bootsnap (1.4.6) msgpack (~> 1.0) - bootstrap-datepicker-rails (1.8.0.1) - railties (>= 3.0) bootstrap-sass (3.4.1) autoprefixer-rails (>= 5.2.1) sassc (>= 2.0.0) @@ -122,11 +120,6 @@ jbuilder (2.10.0) activesupport (>= 5.0.0) jquery-countdown-rails (2.0.2) - jquery-datatables-rails (3.4.0) - actionpack (>= 3.1) - jquery-rails - railties (>= 3.1) - sass-rails jquery-rails (4.3.3) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) @@ -214,17 +207,6 @@ ruby_parser (3.13.1) sexp_processor (~> 4.9) rubyzip (1.3.0) - sass (3.7.4) - sass-listen (~> 4.0.0) - sass-listen (4.0.0) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - sass-rails (5.0.7) - railties (>= 4.0.0, < 6) - sass (~> 3.1) - sprockets (>= 2.8, < 4.0) - sprockets-rails (>= 2.0, < 4.0) - tilt (>= 1.1, < 3) sassc (2.2.1) ffi (~> 1.9) sassc-rails (2.1.2) @@ -272,7 +254,6 @@ websocket-driver (0.7.1) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.4) - will_paginate (3.0.12) xpath (3.2.0) nokogiri (~> 1.8) yaml_db (0.7.0) @@ -288,11 +269,10 @@ autoprefixer-rails best_in_place (~> 3.0.1) bootsnap (>= 1.1.0) - bootstrap-datepicker-rails bootstrap-sass (~> 3.4.1) bootstrap-switch-rails bootstrap-toggle-rails - bootstrap3-datetimepicker-rails + bootstrap3-datetimepicker-rails (~> 4.17.47) byebug capybara (>= 2.15) coffee-rails @@ -303,7 +283,6 @@ in_place_editing jbuilder (~> 2.5) jquery-countdown-rails - jquery-datatables-rails jquery-rails jquery-tablesorter jquery-timepicker-addon-rails @@ -311,7 +290,7 @@ listen (>= 3.0.5, < 3.2) mail minitest-reporters - momentjs-rails + momentjs-rails (>= 2.9.0) mysql2 puma rails (~> 5.2) @@ -329,8 +308,7 @@ uglifier web-console (>= 3.3.0) webdriver - will_paginate (~> 3.0.7) yaml_db BUNDLED WITH - 1.16.2 + 1.17.2 diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -44,7 +44,7 @@ //= require best_in_place //= require best_in_place.jquery-ui //= require brython -//= require bootstrap-datepicker +//= re quire bootstrap-datepicker //= require bootstrap-datetimepicker // since this is after blank line, it is not downloaded diff --git a/app/assets/javascripts/custom.js.coffee b/app/assets/javascripts/custom.js.coffee --- a/app/assets/javascripts/custom.js.coffee +++ b/app/assets/javascripts/custom.js.coffee @@ -12,7 +12,8 @@ # document ready $ -> - $(".select2").select2() + $(".select2").select2({ + }) #$(".bootstrap-switch").bootstrapSwitch() #$(".bootstrap-toggle").bootstrapToggle() $('.btn-file :file').on 'fileselect', (event, numFiles, label) -> diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/stylesheets/application.css.scss --- a/app/assets/stylesheets/application.css.scss +++ b/app/assets/stylesheets/application.css.scss @@ -19,8 +19,8 @@ //@import "jquery.ui.theme"; //@import "jquery.ui.datepicker"; //@import "jquery.ui.slider"; -@import "jquery-ui-timepicker-addon"; -@import "jquery-tablesorter/theme.metro-dark"; +//@import "jquery-ui-timepicker-addon"; +//@import "jquery-tablesorter/theme.metro-dark"; @import "jquery.countdown"; @import "tablesorter-theme.cafe"; @@ -33,7 +33,7 @@ //@import bootstrap3-switch @import "bootstrap-toggle"; @import "bootstrap-sortable"; -@import "bootstrap-datepicker3"; +//@import "bootstrap-datepicker3"; @import "bootstrap-datetimepicker"; @import "datatables.net-bs/css/dataTables.bootstrap.min"; @import "datatables.net-buttons-bs/css/buttons.bootstrap.min"; diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -167,12 +167,13 @@ #function for datatable ajax query #return record,total_count,filter_count def process_query_record(record, - total_count: nil, - select: '', - global_search: [], - no_search: false, - force_order: '', - date_filter: '', date_param_since: 'date_since',date_param_until: 'date_until') + total_count: nil, + select: '', + global_search: [], + no_search: false, + force_order: '', + date_filter: '', date_param_since: 'date_since',date_param_until: 'date_until', + hard_limit: nil) arel_table = record.model.arel_table if !no_search && params['search'] @@ -192,9 +193,11 @@ end if !date_filter.blank? - date_since = Time.parse( params[:date_since] ) rescue Time.new(1,1,1) - date_until = Time.parse( params[:date_until] ) rescue Time.zone.now() - date_range = date_since..date_until + param_since = params[date_param_since] + param_until = params[date_param_until] + date_since = Time.zone.parse( param_since ) || Time.new(1,1,1) rescue Time.new(1,1,1) + date_until = Time.zone.parse( param_until ) || Time.zone.now() rescue Time.zone.now() + date_range = date_since..(date_until.end_of_day) record = record.where(date_filter.to_sym => date_range) end @@ -217,7 +220,14 @@ filterCount = filterCount.count end - record = record.offset(params['start'] || 0).limit(params['length'] || 100) + + record = record.offset(params['start'] || 0) + record = record.limit(hard_limit) + if (params['length']) + limit = params['length'].to_i + limit == hard_limit if (hard_limit && hard_limit < limit) + record = record.limit(limit) + end if (!select.blank?) record = record.select(select) end diff --git a/app/controllers/report_controller.rb b/app/controllers/report_controller.rb --- a/app/controllers/report_controller.rb +++ b/app/controllers/report_controller.rb @@ -4,7 +4,7 @@ before_action :check_valid_login - before_action :admin_authorization, only: [:login_stat,:submission_stat, :stuck, :cheat_report, :cheat_scruntinize, :show_max_score, :current_score] + before_action :admin_authorization, only: [:login_stat,:submission, :submission_query, :stuck, :cheat_report, :cheat_scruntinize, :show_max_score, :current_score] before_action(only: [:problem_hof]) { |c| return false unless check_valid_login @@ -143,34 +143,33 @@ end def submission - date_and_time = '%Y-%m-%d %H:%M' - begin - @since_time = DateTime.strptime(params[:since_datetime],date_and_time) - rescue - @since_time = DateTime.new(1000,1,1) - end - begin - @until_time = DateTime.strptime(params[:until_datetime],date_and_time) - rescue - @until_time = DateTime.new(3000,1,1) - end - - @submissions = Submission - .joins(:problem).joins(:user) end def submission_query @submissions = Submission - .joins(:problem).joins(:user) + .includes(:problem).includes(:user).includes(:language) + + if params[:problem] + @submission = @submission.where(problem_id: params[:problem]) + end + + case params[:users] + when 'enabled' + @submissions = @submissions.where('user.enabled': true) + when 'group' + @submissions = @submissions.joins(user: :groups).where(user: {groups: {id: params[:groups]}}) if params[:groups] + end + + #set default + params[:since_datetime] = Date.today.to_s if params[:since_datetime].blank? @submissions, @recordsTotal, @recordsFiltered = process_query_record( @submissions, global_search: ['user.login','user.full_name','problem.name','problem.full_name','points'], date_filter: 'submitted_at', date_param_since: 'since_datetime', date_param_until: 'until_datetime', + hard_limit: 100_000 ) - puts '-------------------------------' - puts @submissions end def problem_hof diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -64,7 +64,7 @@ %ul.dropdown-menu = add_menu( 'Current Score', 'report', 'current_score') = add_menu( 'Score Report', 'report', 'max_score') - = add_menu( 'Report', 'report', 'multiple_login') + = add_menu( 'Submission Report', 'report', 'submission') - if (ungraded = Submission.where('graded_at is null').where('submitted_at < ?', 1.minutes.ago).count) > 0 =link_to "#{ungraded} backlogs!", grader_list_path, diff --git a/app/views/report/submission.html.haml b/app/views/report/submission.html.haml --- a/app/views/report/submission.html.haml +++ b/app/views/report/submission.html.haml @@ -7,61 +7,71 @@ .col-md-4 = render partial: 'shared/problem_select' .col-md-4 - = render partial: 'shared/problem_select' + = render partial: 'shared/date_filter' .col-md-4 = render partial: 'shared/user_select' +.row + .col-md-6 + .alert.alert-info + %ul + %li Display a maximum of 100,000 entries to save computation power + %li You have to click refresh when changing the filter above .row - .col-12 - %table.table.table-hover.table-condense.datatable - -# - %thead - %tr - %th User - %th Problem - %th Subbmission ID - %th Submit Time - %th Score - %th detail - %tbody - - @submissions.each do |s| - %tr - %td= s.user.login - %td= s.problem.long_name - %td= s.id - %td= s.submitted_at - %td= s.points - %td= s.grader_comment + .col-sm-12 + %table.table.table-hover.table-condense.datatable{style: 'width: 100%'} :javascript - $('.datatable').DataTable({ - dom: 'Bfrtip', - buttons: [ - 'copy', 'excel', 'pdf' - ], - columns: [ - {title: 'Sub ID', data: 'id'}, - {title: 'User', data: 'user.login'}, - {title: 'Problem', data: 'problem.long_name'}, - {title: 'Language', data: 'language.pretty_name'}, - {title: 'Submit at', data: 'submitted_at'}, - {title: 'Result', data: 'grader_comment'}, - {title: 'Score', data: 'points'}, - {title: 'IP', data: 'ip_address'}, - ], - ajax: { - url: '#{submission_query_report_path}', - type: 'POST', - data: (d) => { - d.since_datetime = '1123' - d.until_datetime = 'xxx' - }, - dataType: 'json', - beforeSend: (request) => { - request.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content')); - }, - }, //end ajax - 'pageLength': 50 + $(function() { + submission_table = $('.datatable').DataTable({ + dom: "<'row'<'col-sm-3'B><'col-sm-3'l><'col-sm-6'f>>" + "<'row'<'col-sm-12'tr>>" + "<'row'<'col-sm-5'i><'col-sm-7'p>>", + autoWidth: true, + buttons: [ + { + text: 'Refresh', + action: (e,dt,node,config) => { + submission_table.clear().draw() + submission_table.ajax.reload( () => { submission_table.columns.adjust().draw() } ) + } + }, + 'copy', 'excel' + ], + columns: [ + {title: 'Sub ID', data: 'id'}, + {title: 'User', data: 'user.login'}, + {title: 'Problem', data: 'problem.long_name'}, + {title: 'Language', data: 'language.pretty_name'}, + {title: 'Submit at', data: 'submitted_at'}, + {title: 'Result', data: 'grader_comment'}, + {title: 'Score', data: 'points'}, + {title: 'IP', data: 'ip_address'}, + ], + ajax: { + url: '#{submission_query_report_path}', + type: 'POST', + data: (d) => { + d.since_datetime = $('#since_datetime').val() + d.until_datetime = $('#until_datetime').val() + d.users = $("input[name='users']:checked").val() + d.problems = $("#problem_id").select2('val') + d.groups = $("#group_id").select2('val') + }, + dataType: 'json', + beforeSend: (request) => { + request.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content')); + }, + }, //end ajax + 'pageLength': 50, + processing: true, + }); + + $('.input-group.date').datetimepicker({ + format: 'YYYY-MM-DD', + showTodayButton: true, + locale: 'en', + widgetPositioning: {horizontal: 'auto', vertical: 'bottom'}, + defaultDate: moment() + }); }); diff --git a/app/views/report/submission_query.json.jbuilder b/app/views/report/submission_query.json.jbuilder --- a/app/views/report/submission_query.json.jbuilder +++ b/app/views/report/submission_query.json.jbuilder @@ -3,13 +3,15 @@ json.recordsFiltered @recordsFiltered json.data do json.array! @submissions do |sub| - json.extract! sub, :id, :points, :grader_comment, :ip_address - json.submitted_at sub.submitted_at.to_s(:db) + json.extract! sub, :grader_comment, :ip_address + json.id "#{sub.id}" + json.submitted_at sub.submitted_at.strftime('%Y-%m-%d %H:%M') + json.points "#{sub.points}/#{sub.problem&.full_score}" json.problem do - json.long_name sub.problem&.long_name + json.long_name sub.problem ? sub.problem.long_name : '-- deleted problem --' end json.user do - json.login sub.user&.login + json.login sub.user ? "(#{sub.user&.login}) #{sub.user&.full_name}" : '-- deleted user --' end json.language do json.pretty_name sub.language&.pretty_name diff --git a/app/views/shared/_date_filter.html.haml b/app/views/shared/_date_filter.html.haml new file mode 100644 --- /dev/null +++ b/app/views/shared/_date_filter.html.haml @@ -0,0 +1,20 @@ +.panel.panel-primary + .panel-heading + Date ranges + .panel-body + .row.form-group + .col-md-4 + From Date: + .col-md-6 + .input-group.date + = text_field_tag :since_datetime, nil, class: 'form-control' + %span.input-group-addon + %span.glyphicon.glyphicon-calendar + .row.form-group + .col-md-4 + Until Date: + .col-md-6 + .input-group.date + = text_field_tag :until_datetime, nil, class: 'form-control' + %span.input-group-addon + %span.glyphicon.glyphicon-calendar diff --git a/app/views/shared/_problem_select.html.haml b/app/views/shared/_problem_select.html.haml --- a/app/views/shared/_problem_select.html.haml +++ b/app/views/shared/_problem_select.html.haml @@ -3,8 +3,8 @@ Problems .panel-body %p - Select problem(s) that we wish to know the score. + Select problem(s) to be included in the report = label_tag :problem_id, "Problems" = select_tag 'problem_id[]', options_for_select(Problem.all.collect {|p| ["[#{p.name}] #{p.full_name}", p.id]},params[:problem_id]), - { class: 'select2 form-control', multiple: "true" } + { id: :problem_id, class: 'select2 form-control', multiple: "true" } diff --git a/app/views/shared/_user_select.html.haml b/app/views/shared/_user_select.html.haml --- a/app/views/shared/_user_select.html.haml +++ b/app/views/shared/_user_select.html.haml @@ -10,3 +10,10 @@ %label = radio_button_tag 'users', 'enabled', (params[:users] == "enabled") Only enabled users + .radio + %label + = radio_button_tag 'users', 'group', (params[:users] == "group") + Only these groups + = select_tag 'group_id[]', + options_for_select(Group.all.collect {|g| ["[#{g.name}] #{g.description}", g.id]}), + { id: 'group_id', class: 'select2 form-control', multiple: "true"} diff --git a/db/migrate/20200404135714_add_index_to_submission.rb b/db/migrate/20200404135714_add_index_to_submission.rb new file mode 100644 --- /dev/null +++ b/db/migrate/20200404135714_add_index_to_submission.rb @@ -0,0 +1,5 @@ +class AddIndexToSubmission < ActiveRecord::Migration[5.2] + def change + add_index :submissions, :submitted_at + end +end diff --git a/db/migrate/20200404142959_add_id_to_group_user.rb b/db/migrate/20200404142959_add_id_to_group_user.rb new file mode 100644 --- /dev/null +++ b/db/migrate/20200404142959_add_id_to_group_user.rb @@ -0,0 +1,5 @@ +class AddIdToGroupUser < ActiveRecord::Migration[5.2] + def change + add_column :groups_users, :id, :primary_key + end +end diff --git a/db/schema.rb b/db/schema.rb --- a/db/schema.rb +++ b/db/schema.rb @@ -1,4 +1,3 @@ -# encoding: UTF-8 # This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. @@ -11,311 +10,299 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180612102327) do +ActiveRecord::Schema.define(version: 2020_04_04_142959) do - create_table "announcements", force: :cascade do |t| - t.string "author", limit: 255 - t.text "body", limit: 65535 - t.boolean "published" - t.datetime "created_at" - t.datetime "updated_at" - t.boolean "frontpage", default: false - t.boolean "contest_only", default: false - t.string "title", limit: 255 - t.string "notes", limit: 255 + create_table "announcements", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.string "author" + t.text "body", limit: 16777215 + t.boolean "published" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "frontpage", default: false + t.boolean "contest_only", default: false + t.string "title" + t.string "notes" end - create_table "contests", force: :cascade do |t| - t.string "title", limit: 255 - t.boolean "enabled" - t.datetime "created_at" - t.datetime "updated_at" - t.string "name", limit: 255 - end - - create_table "contests_problems", id: false, force: :cascade do |t| - t.integer "contest_id", limit: 4 - t.integer "problem_id", limit: 4 - end - - create_table "contests_users", id: false, force: :cascade do |t| - t.integer "contest_id", limit: 4 - t.integer "user_id", limit: 4 + create_table "contests", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.string "title" + t.boolean "enabled" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "name" end - create_table "countries", force: :cascade do |t| - t.string "name", limit: 255 - t.datetime "created_at" - t.datetime "updated_at" + create_table "contests_problems", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.integer "contest_id" + t.integer "problem_id" end - create_table "descriptions", force: :cascade do |t| - t.text "body", limit: 65535 - t.boolean "markdowned" - t.datetime "created_at" - t.datetime "updated_at" + create_table "contests_users", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.integer "contest_id" + t.integer "user_id" end - create_table "grader_configurations", force: :cascade do |t| - t.string "key", limit: 255 - t.string "value_type", limit: 255 - t.string "value", limit: 255 - t.datetime "created_at" - t.datetime "updated_at" - t.text "description", limit: 65535 + create_table "countries", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "grader_processes", force: :cascade do |t| - t.string "host", limit: 255 - t.integer "pid", limit: 4 - t.string "mode", limit: 255 - t.boolean "active" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "task_id", limit: 4 - t.string "task_type", limit: 255 - t.boolean "terminated" + create_table "descriptions", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.text "body", limit: 16777215 + t.boolean "markdowned" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "grader_configurations", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.string "key" + t.string "value_type" + t.string "value" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.text "description", limit: 16777215 end - add_index "grader_processes", ["host", "pid"], name: "index_grader_processes_on_host_and_pid", using: :btree - - create_table "groups", force: :cascade do |t| - t.string "name", limit: 255 - t.string "description", limit: 255 - end - - create_table "groups_problems", id: false, force: :cascade do |t| - t.integer "problem_id", limit: 4, null: false - t.integer "group_id", limit: 4, null: false + create_table "grader_processes", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.string "host" + t.integer "pid" + t.string "mode" + t.boolean "active" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "task_id" + t.string "task_type" + t.boolean "terminated" + t.index ["host", "pid"], name: "index_grader_processes_on_ip_and_pid" end - add_index "groups_problems", ["group_id", "problem_id"], name: "index_groups_problems_on_group_id_and_problem_id", using: :btree - - create_table "groups_users", id: false, force: :cascade do |t| - t.integer "group_id", limit: 4, null: false - t.integer "user_id", limit: 4, null: false + create_table "groups", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t| + t.string "name" + t.string "description" end - add_index "groups_users", ["user_id", "group_id"], name: "index_groups_users_on_user_id_and_group_id", using: :btree + create_table "groups_problems", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t| + t.integer "problem_id", null: false + t.integer "group_id", null: false + t.index ["group_id", "problem_id"], name: "index_groups_problems_on_group_id_and_problem_id" + end - create_table "heart_beats", force: :cascade do |t| - t.integer "user_id", limit: 4 - t.string "ip_address", limit: 255 - t.datetime "created_at" - t.datetime "updated_at" - t.string "status", limit: 255 + create_table "groups_users", options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t| + t.integer "group_id", null: false + t.integer "user_id", null: false + t.index ["user_id", "group_id"], name: "index_groups_users_on_user_id_and_group_id" end - add_index "heart_beats", ["updated_at"], name: "index_heart_beats_on_updated_at", using: :btree - - create_table "languages", force: :cascade do |t| - t.string "name", limit: 10 - t.string "pretty_name", limit: 255 - t.string "ext", limit: 10 - t.string "common_ext", limit: 255 + create_table "heart_beats", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t| + t.integer "user_id" + t.string "ip_address" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "status" + t.index ["updated_at"], name: "index_heart_beats_on_updated_at" end - create_table "logins", force: :cascade do |t| - t.integer "user_id", limit: 4 - t.string "ip_address", limit: 255 - t.datetime "created_at" - t.datetime "updated_at" + create_table "languages", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.string "name", limit: 10 + t.string "pretty_name" + t.string "ext", limit: 10 + t.string "common_ext" end - create_table "messages", force: :cascade do |t| - t.integer "sender_id", limit: 4 - t.integer "receiver_id", limit: 4 - t.integer "replying_message_id", limit: 4 - t.text "body", limit: 65535 - t.boolean "replied" - t.datetime "created_at" - t.datetime "updated_at" + create_table "logins", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t| + t.integer "user_id" + t.string "ip_address" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "problems", force: :cascade do |t| - t.string "name", limit: 30 - t.string "full_name", limit: 255 - t.integer "full_score", limit: 4 - t.date "date_added" + create_table "messages", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.integer "sender_id" + t.integer "receiver_id" + t.integer "replying_message_id" + t.text "body", limit: 16777215 + t.boolean "replied" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "problems", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.string "name", limit: 100 + t.string "full_name" + t.integer "full_score" + t.date "date_added" t.boolean "available" - t.string "url", limit: 255 - t.integer "description_id", limit: 4 + t.string "url" + t.integer "description_id" t.boolean "test_allowed" t.boolean "output_only" - t.string "description_filename", limit: 255 + t.string "description_filename" t.boolean "view_testcase" end - create_table "problems_tags", force: :cascade do |t| - t.integer "problem_id", limit: 4 - t.integer "tag_id", limit: 4 + create_table "problems_tags", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t| + t.integer "problem_id" + t.integer "tag_id" + t.index ["problem_id", "tag_id"], name: "index_problems_tags_on_problem_id_and_tag_id", unique: true + t.index ["problem_id"], name: "index_problems_tags_on_problem_id" + t.index ["tag_id"], name: "index_problems_tags_on_tag_id" end - add_index "problems_tags", ["problem_id", "tag_id"], name: "index_problems_tags_on_problem_id_and_tag_id", unique: true, using: :btree - add_index "problems_tags", ["problem_id"], name: "index_problems_tags_on_problem_id", using: :btree - add_index "problems_tags", ["tag_id"], name: "index_problems_tags_on_tag_id", using: :btree - - create_table "rights", force: :cascade do |t| - t.string "name", limit: 255 - t.string "controller", limit: 255 - t.string "action", limit: 255 + create_table "rights", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.string "name" + t.string "controller" + t.string "action" end - create_table "rights_roles", id: false, force: :cascade do |t| - t.integer "right_id", limit: 4 - t.integer "role_id", limit: 4 + create_table "rights_roles", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.integer "right_id" + t.integer "role_id" + t.index ["role_id"], name: "index_rights_roles_on_role_id" end - add_index "rights_roles", ["role_id"], name: "index_rights_roles_on_role_id", using: :btree - - create_table "roles", force: :cascade do |t| - t.string "name", limit: 255 + create_table "roles", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.string "name" end - create_table "roles_users", id: false, force: :cascade do |t| - t.integer "role_id", limit: 4 - t.integer "user_id", limit: 4 + create_table "roles_users", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.integer "role_id" + t.integer "user_id" + t.index ["user_id"], name: "index_roles_users_on_user_id" end - add_index "roles_users", ["user_id"], name: "index_roles_users_on_user_id", using: :btree - - create_table "sessions", force: :cascade do |t| - t.string "session_id", limit: 255 - t.text "data", limit: 65535 + create_table "sessions", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.string "session_id" + t.text "data", limit: 16777215 t.datetime "updated_at" + t.index ["session_id"], name: "index_sessions_on_session_id" + t.index ["updated_at"], name: "index_sessions_on_updated_at" end - add_index "sessions", ["session_id"], name: "index_sessions_on_session_id", using: :btree - add_index "sessions", ["updated_at"], name: "index_sessions_on_updated_at", using: :btree + create_table "sites", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.string "name" + t.boolean "started" + t.datetime "start_time" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "country_id" + t.string "password" + end - create_table "sites", force: :cascade do |t| - t.string "name", limit: 255 - t.boolean "started" - t.datetime "start_time" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "country_id", limit: 4 - t.string "password", limit: 255 + create_table "submission_view_logs", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t| + t.integer "user_id" + t.integer "submission_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "submission_view_logs", force: :cascade do |t| - t.integer "user_id", limit: 4 - t.integer "submission_id", limit: 4 - t.datetime "created_at" - t.datetime "updated_at" - end - - create_table "submissions", force: :cascade do |t| - t.integer "user_id", limit: 4 - t.integer "problem_id", limit: 4 - t.integer "language_id", limit: 4 - t.text "source", limit: 16777215 - t.binary "binary", limit: 65535 + create_table "submissions", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.integer "user_id" + t.integer "problem_id" + t.integer "language_id" + t.text "source", limit: 16777215 + t.binary "binary" t.datetime "submitted_at" t.datetime "compiled_at" - t.text "compiler_message", limit: 65535 + t.text "compiler_message", limit: 16777215 t.datetime "graded_at" - t.integer "points", limit: 4 - t.text "grader_comment", limit: 65535 - t.integer "number", limit: 4 - t.string "source_filename", limit: 255 - t.float "max_runtime", limit: 24 - t.integer "peak_memory", limit: 4 - t.integer "effective_code_length", limit: 4 - t.string "ip_address", limit: 255 + t.integer "points" + t.text "grader_comment", limit: 16777215 + t.integer "number" + t.string "source_filename" + t.float "max_runtime" + t.integer "peak_memory" + t.integer "effective_code_length" + t.string "ip_address" + t.index ["submitted_at"], name: "index_submissions_on_submitted_at" + t.index ["user_id", "problem_id", "number"], name: "index_submissions_on_user_id_and_problem_id_and_number", unique: true + t.index ["user_id", "problem_id"], name: "index_submissions_on_user_id_and_problem_id" end - add_index "submissions", ["user_id", "problem_id", "number"], name: "index_submissions_on_user_id_and_problem_id_and_number", unique: true, using: :btree - add_index "submissions", ["user_id", "problem_id"], name: "index_submissions_on_user_id_and_problem_id", using: :btree - - create_table "tags", force: :cascade do |t| - t.string "name", limit: 255, null: false - t.text "description", limit: 65535 - t.boolean "public" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table "tags", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t| + t.string "name", null: false + t.text "description" + t.boolean "public" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "tasks", force: :cascade do |t| - t.integer "submission_id", limit: 4 + create_table "tasks", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.integer "submission_id" t.datetime "created_at" - t.integer "status", limit: 4 + t.integer "status" t.datetime "updated_at" + t.index ["submission_id"], name: "index_tasks_on_submission_id" end - add_index "tasks", ["submission_id"], name: "index_tasks_on_submission_id", using: :btree - - create_table "test_pairs", force: :cascade do |t| - t.integer "problem_id", limit: 4 - t.text "input", limit: 16777215 - t.text "solution", limit: 16777215 - t.datetime "created_at" - t.datetime "updated_at" + create_table "test_pairs", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.integer "problem_id" + t.text "input", limit: 4294967295 + t.text "solution", limit: 4294967295 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "test_requests", force: :cascade do |t| - t.integer "user_id", limit: 4 - t.integer "problem_id", limit: 4 - t.integer "submission_id", limit: 4 - t.string "input_file_name", limit: 255 - t.string "output_file_name", limit: 255 - t.string "running_stat", limit: 255 - t.integer "status", limit: 4 - t.datetime "updated_at" + create_table "test_requests", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.integer "user_id" + t.integer "problem_id" + t.integer "submission_id" + t.string "input_file_name" + t.string "output_file_name" + t.string "running_stat" + t.integer "status" + t.datetime "updated_at", null: false t.datetime "submitted_at" t.datetime "compiled_at" - t.text "compiler_message", limit: 65535 + t.text "compiler_message", limit: 16777215 t.datetime "graded_at" - t.string "grader_comment", limit: 255 - t.datetime "created_at" - t.float "running_time", limit: 24 - t.string "exit_status", limit: 255 - t.integer "memory_usage", limit: 4 + t.string "grader_comment" + t.datetime "created_at", null: false + t.float "running_time" + t.string "exit_status" + t.integer "memory_usage" + t.index ["user_id", "problem_id"], name: "index_test_requests_on_user_id_and_problem_id" end - add_index "test_requests", ["user_id", "problem_id"], name: "index_test_requests_on_user_id_and_problem_id", using: :btree - - create_table "testcases", force: :cascade do |t| - t.integer "problem_id", limit: 4 - t.integer "num", limit: 4 - t.integer "group", limit: 4 - t.integer "score", limit: 4 - t.text "input", limit: 4294967295 - t.text "sol", limit: 4294967295 - t.datetime "created_at" - t.datetime "updated_at" + create_table "testcases", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t| + t.integer "problem_id" + t.integer "num" + t.integer "group" + t.integer "score" + t.text "input", limit: 4294967295 + t.text "sol", limit: 4294967295 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["problem_id"], name: "index_testcases_on_problem_id" end - add_index "testcases", ["problem_id"], name: "index_testcases_on_problem_id", using: :btree - - create_table "user_contest_stats", force: :cascade do |t| - t.integer "user_id", limit: 4 + create_table "user_contest_stats", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.integer "user_id" t.datetime "started_at" - t.datetime "created_at" - t.datetime "updated_at" - t.boolean "forced_logout" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "forced_logout" end - create_table "users", force: :cascade do |t| - t.string "login", limit: 50 - t.string "full_name", limit: 255 - t.string "hashed_password", limit: 255 - t.string "salt", limit: 5 - t.string "alias", limit: 255 - t.string "email", limit: 255 - t.integer "site_id", limit: 4 - t.integer "country_id", limit: 4 - t.boolean "activated", default: false + create_table "users", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.string "login", limit: 50 + t.string "full_name" + t.string "hashed_password" + t.string "salt", limit: 5 + t.string "alias" + t.string "email" + t.integer "site_id" + t.integer "country_id" + t.boolean "activated", default: false t.datetime "created_at" t.datetime "updated_at" - t.string "section", limit: 255 - t.boolean "enabled", default: true - t.string "remark", limit: 255 - t.string "last_ip", limit: 255 + t.string "section" + t.boolean "enabled", default: true + t.string "remark" + t.string "last_ip" + t.index ["login"], name: "index_users_on_login", unique: true end - add_index "users", ["login"], name: "index_users_on_login", unique: true, using: :btree - add_foreign_key "problems_tags", "problems" add_foreign_key "problems_tags", "tags" end