Commit eb0afb2f by Bui Minh Duc

implement reviewcomment, fixed N + 1 problem, improve query performance

parent 91efbf55
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
// Place all the styles related to the user controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
......@@ -9,9 +9,9 @@ class MainController < ApplicationController
@repos = @repos || Repository.all
@selected_repos_name = Other.where(data_type: 0).map{ |other| other.data }
@selected_repos = Repository.where(name: @selected_repos_name)
@selected_repos = Repository.where(name: @selected_repos_name).includes(issues: [:labels]).where("issues.closed_at IS NULL").references(:issues)
@label_filter_params = Other.where(data_type: 1).map { |e| e.data }
# @label_filter_params
@data_table = []
@selected_repos.each do |repo|
......
class UserController < ApplicationController
def index
@users = User.all
end
end
module UserHelper
end
class ReviewComment < ApplicationRecord
belongs_to :issue
belongs_to :user
belongs_to :user, optional: true
end
<!-- Fixed navbar -->
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="<%= root_url %>">GHR</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><%= link_to "User", user_path %></li>
<li><%= link_to "Repository", repo_path %></li>
</ul>
</div>
</div>
</nav>
<!-- End navbar -->
......@@ -10,6 +10,7 @@
</head>
<body>
<%= render "layouts/header" %>
<%= yield %>
</body>
</html>
<div>
<!-- Fixed navbar -->
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="<%= root_url %>">GHR</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
</div>
</div>
</nav>
<!-- End navbar -->
<div class="container">
<!-- content -->
<div class="form-group">
<label>Select repository</label>
<select class="selectpicker" id="selectpicker1" multiple data-live-search="true"
multiple data-selected-text-format="count > 3" data-actions-box="true" style="display: none;">
<% @repos.each do |repo| %>
<option><%= repo.name %></option>
<% end %>
</select>
<button id="repo_apply" class="btn btn-default">Apply</button>
</div>
<div class="container">
<!-- content -->
<div class="form-group">
<label>Select repository</label>
<select class="selectpicker" id="selectpicker1" multiple data-live-search="true"
multiple data-selected-text-format="count > 3" data-actions-box="true" style="display: none;">
<% @repos.each do |repo| %>
<option><%= repo.name %></option>
<% end %>
</select>
<button id="repo_apply" class="btn btn-default">Apply</button>
</div>
<div id="toolbar">
<form class="form-inline">
<div class="form-group">
<label for="from">From</label>
<div class='input-group date' id='datetimepicker1' data-turbolinks-temporary>
<input id="from_date" type='text' class="form-control" value="<%= session[:filter_date] %>" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<div class="form-group">
<select class="selectpicker" id="selectpicker2" multiple data-live-search="true" style="display: none;">
<% @label_filter.each do |label| %>
<option><%= label %></option>
<% end %>
</select>
<div id="toolbar">
<form class="form-inline">
<div class="form-group">
<label for="from">From</label>
<div class='input-group date' id='datetimepicker1' data-turbolinks-temporary>
<input id="from_date" type='text' class="form-control" value="<%= session[:filter_date] %>" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
<!-- <input type="submit" class="btn btn-default"> -->
<button id="submit_filter" class="btn btn-default">Submit</button>
</form>
</div>
<div style="margin-top: 20px">
<table data-toolbar="#toolbar"
data-toggle="table"
data-search="true"
data-show-export="true"
data-show-columns="true"
data-show-export="true"
data-minimum-count-columns="2"
data-show-pagination-switch="true"
data-pagination="true"
data-id-field="id"
data-page-list="[10, 25, 50, 100, ALL]">
<thead>
</div>
<div class="form-group">
<select class="selectpicker" id="selectpicker2" multiple data-live-search="true" style="display: none;">
<% @label_filter.each do |label| %>
<option><%= label %></option>
<% end %>
</select>
</div>
<!-- <input type="submit" class="btn btn-default"> -->
<button id="submit_filter" class="btn btn-default">Submit</button>
</form>
</div>
<div style="margin-top: 20px">
<table data-toolbar="#toolbar"
data-toggle="table"
data-search="true"
data-show-export="true"
data-show-columns="true"
data-show-export="true"
data-minimum-count-columns="2"
data-show-pagination-switch="true"
data-pagination="true"
data-id-field="id"
data-page-list="[10, 25, 50, 100, ALL]">
<thead>
<tr>
<th></th>
<% @col_label_names.each do |label| %>
<th><%= label %></th>
<% end %>
</tr>
</thead>
<tbody>
<% @data_table.each do |row| %>
<tr>
<th></th>
<td class="col-md-2"><%= link_to row[:name], row[:link] %></td>
<% @col_label_names.each do |label| %>
<th><%= label %></th>
<% if row[label].nil? %>
<td class="col-md-1">0</td>
<% else %>
<td class="col-md-1"><a href="" data-toggle="modal" data-target="#<%= format_html_id(row[:name] + label) %>"><%= row[label][:count] %></a></td>
<% end %>
<% end %>
</tr>
</thead>
<tbody>
<% @data_table.each do |row| %>
<tr>
<td class="col-md-2"><%= link_to row[:name], row[:link] %></td>
<% @col_label_names.each do |label| %>
<% if row[label].nil? %>
<td class="col-md-1">0</td>
<% else %>
<td class="col-md-1"><a href="" data-toggle="modal" data-target="#<%= format_html_id(row[:name] + label) %>"><%= row[label][:count] %></a></td>
<% end %>
<% end %>
</tr>
<% end %>
</tbody>
</table>
<% end %>
</tbody>
</table>
</div>
</div>
<% @data_table.each do |row| %>
<% @col_label_names.each do |label| %>
<% if !row[label].nil? %>
<div id="<%= format_html_id(row[:name] + label) %>" class="modal fade bd-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title" id="myModalLabel"><%= row[:name] %></h4>
</div>
<div class="modal-body">
<table class="table">
<tbody>
<% row[label][:issues].each do |issue| %>
<tr>
<td>
<a href="<%= issue[:html_url] %>"><%= issue[:title] %></a>
<% issue.labels.each do |label| %>
<span class="label label-default" style="background-color: #<%= label[:color] %>; color: #<%= get_text_color(label[:color]) %>;"><%= label[:name] %></span>
<% end %>
</td>
<td><%= issue[:created_at] %></td>
<td><%= format_time(Time.now - issue[:created_at]) %></td>
</tr>
<% end %>
</tbody>
</table>
<% @data_table.each do |row| %>
<% @col_label_names.each do |label| %>
<% if !row[label].nil? %>
<div id="<%= format_html_id(row[:name] + label) %>" class="modal fade bd-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title" id="myModalLabel"><%= row[:name] %></h4>
</div>
<div class="modal-body">
<table class="table">
<tbody>
<% row[label][:issues].each do |issue| %>
<tr>
<td>
<a href="<%= issue[:html_url] %>"><%= issue[:title] %></a>
<% issue.labels.each do |label| %>
<span class="label label-default" style="background-color: #<%= label[:color] %>; color: #<%= get_text_color(label[:color]) %>;"><%= label[:name] %></span>
<% end %>
</td>
<td><%= issue[:created_at] %></td>
<td><%= format_time(Time.now - issue[:created_at]) %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
<% end %>
</div>
<% end %>
<% end %>
</div>
<% end %>
</div>
<script type="text/javascript">
$(document).ready(function() {
</div>
<script type="text/javascript">
$(document).ready(function() {
});
});
$("#repo_apply").click(function() {
var selected_repos = $('#selectpicker1').selectpicker('val');
$("#repo_apply").click(function() {
var selected_repos = $('#selectpicker1').selectpicker('val');
$.ajax({
method: "POST",
url: "<%= update_repo_selected_path %>",
data: { selected: selected_repos },
success: function(res) {
location.reload();
}
});
$.ajax({
method: "POST",
url: "<%= update_repo_selected_path %>",
data: { selected: selected_repos },
success: function(res) {
location.reload();
}
});
$("#submit_filter").click(function() {
var selected_labels = $('#selectpicker2').selectpicker('val');
var from_date = $("#from_date").val();
$.ajax({
method: "POST",
url: "<%= update_label_selected_path %>",
data: { selected: selected_labels, date: from_date },
success: function(res) {
location.reload();
}
});
});
$("#submit_filter").click(function() {
var selected_labels = $('#selectpicker2').selectpicker('val');
var from_date = $("#from_date").val();
$.ajax({
method: "POST",
url: "<%= update_label_selected_path %>",
data: { selected: selected_labels, date: from_date },
success: function(res) {
location.reload();
}
});
});
$(document).on('ready', function(event) {
// location.reload();
$('#datetimepicker1').datetimepicker({
format: "DD/MM/YYYY"
});
$('#datetimepicker2').datetimepicker({
format: "DD/MM/YYYY"
});
$(document).on('ready', function(event) {
// location.reload();
$('#datetimepicker1').datetimepicker({
format: "DD/MM/YYYY"
});
$('#datetimepicker2').datetimepicker({
format: "DD/MM/YYYY"
});
$('#selectpicker1').selectpicker(); // init picker
$('#selectpicker1').selectpicker('val', <%= @selected_repos_name.to_s.html_safe %>);
$('#selectpicker1').selectpicker(); // init picker
$('#selectpicker1').selectpicker('val', <%= @selected_repos_name.to_s.html_safe %>);
$('#selectpicker2').selectpicker(); // init picker
$('#selectpicker2').selectpicker('val', <%= @label_filter_params.to_s.html_safe %>);
});
$('#selectpicker2').selectpicker(); // init picker
$('#selectpicker2').selectpicker('val', <%= @label_filter_params.to_s.html_safe %>);
});
</script>
</div>
</script>
<div class="container">
<div>
<table data-toolbar="#toolbar"
data-toggle="table"
data-search="true"
data-show-export="true"
data-show-columns="true"
data-show-export="true"
data-minimum-count-columns="2"
data-show-pagination-switch="true"
data-pagination="true"
data-id-field="id"
data-page-list="[10, 25, 50, 100, ALL]">
<thead>
<tr>
<th class="col-md-4">User name</th>
<th class="col-md-2">Score 1 (80%)</th>
<th class="col-md-2">Score 2 (10%)</th>
<th class="col-md-2">Score 3 (10%)</th>
<th class="col-md-2">Arg Score</th>
</tr>
</thead>
<tbody>
<% @users.each do |user| %>
<tr>
<td><%= link_to user.login, user.html_url %></td>
<td>10</td>
<td>10</td>
<td>10</td>
<td>10</td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
......@@ -6,5 +6,7 @@ Rails.application.routes.draw do
post "/update_label_selected", to: "main#update_label_selected"
post "/load_repo_selected", to: "main#load_repo_selected"
get "/user", to: "user#index"
# resource :repository
end
class AddReviewCommentIdToReviewComment < ActiveRecord::Migration[5.0]
def change
add_column :review_comments, :rv_comment_id, :integer
end
end
class AddCommitIdToReviewComment < ActiveRecord::Migration[5.0]
def change
add_column :review_comments, :commit_id, :integer
end
end
class ChangeCommitIdForReviewComment < ActiveRecord::Migration[5.0]
def change
change_column :review_comments, :commit_id, :string
end
end
......@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20161206091833) do
ActiveRecord::Schema.define(version: 20161207022421) do
create_table "comments", force: :cascade do |t|
t.string "html_url"
......@@ -98,6 +98,8 @@ ActiveRecord::Schema.define(version: 20161206091833) do
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "rv_comment_id"
t.string "commit_id"
t.index ["issue_id"], name: "index_review_comments_on_issue_id"
t.index ["user_id"], name: "index_review_comments_on_user_id"
end
......
......@@ -189,3 +189,41 @@ I, [2016-12-06T17:09:26.069596 #20842] INFO -- : Begin task insert database fro
I, [2016-12-06T17:09:26.167977 #20842] INFO -- : Insert review comments
I, [2016-12-06T17:11:43.931030 #20946] INFO -- : Begin task insert database from github
I, [2016-12-06T17:11:44.029829 #20946] INFO -- : Insert review comments
I, [2016-12-06T17:17:34.044815 #20946] INFO -- : begin transaction
I, [2016-12-06T17:20:43.300901 #21767] INFO -- : Begin task insert database from github
I, [2016-12-06T17:20:43.399250 #21767] INFO -- : Insert review comments
I, [2016-12-06T17:20:56.502900 #21767] INFO -- : begin transaction
I, [2016-12-06T17:20:56.717225 #21767] INFO -- : Finished transaction in 0.214264615s
I, [2016-12-06T17:20:56.717281 #21767] INFO -- : Finished task import in 13.416296662s
I, [2016-12-07T08:22:20.590619 #6430] INFO -- : Begin task insert database from github
I, [2016-12-07T08:22:20.801784 #6430] INFO -- : Insert review comments
I, [2016-12-07T08:28:40.688531 #6430] INFO -- : begin transaction
I, [2016-12-07T08:30:50.208034 #7351] INFO -- : Begin task insert database from github
I, [2016-12-07T08:30:50.306618 #7351] INFO -- : Insert review comments
I, [2016-12-07T08:36:48.829043 #7351] INFO -- : begin transaction
I, [2016-12-07T08:52:46.506711 #9509] INFO -- : Begin task insert database from github
I, [2016-12-07T08:52:46.606150 #9509] INFO -- : Insert review comments
I, [2016-12-07T08:58:35.903936 #9509] INFO -- : begin transaction
I, [2016-12-07T08:58:42.184852 #9509] INFO -- : Finished transaction in 6.280831006s
I, [2016-12-07T08:58:42.184915 #9509] INFO -- : Finished task import in 355.678107086s
I, [2016-12-07T09:08:47.413900 #11009] INFO -- : Begin task insert database from github
I, [2016-12-07T09:08:47.519632 #11009] INFO -- : Insert review comments
I, [2016-12-07T09:11:19.145951 #11093] INFO -- : Begin task insert database from github
I, [2016-12-07T09:11:19.246333 #11093] INFO -- : Insert review comments
I, [2016-12-07T09:16:59.468997 #11093] INFO -- : begin transaction
I, [2016-12-07T09:26:06.328729 #12500] INFO -- : Begin task insert database from github
I, [2016-12-07T09:26:06.428844 #12500] INFO -- : Insert review comments
I, [2016-12-07T09:33:49.939673 #12500] INFO -- : begin transaction
I, [2016-12-07T09:33:54.029760 #12500] INFO -- : Finished transaction in 4.089965539s
I, [2016-12-07T09:33:54.029820 #12500] INFO -- : Finished task import in 467.70099551s
I, [2016-12-07T09:36:33.943425 #13694] INFO -- : Begin task insert database from github
I, [2016-12-07T09:36:33.943502 #13694] INFO -- : Insert repos
I, [2016-12-07T09:36:39.268134 #13694] INFO -- : Insert users
I, [2016-12-07T09:36:44.967226 #13694] INFO -- : Insert labels
I, [2016-12-07T09:40:04.417687 #13694] INFO -- : Insert issues
I, [2016-12-07T09:53:42.088805 #13694] INFO -- : Insert comments
I, [2016-12-07T09:58:57.123686 #13694] INFO -- : Size list_db_comment: 3653
I, [2016-12-07T09:58:57.123754 #13694] INFO -- : Insert review comments
I, [2016-12-07T10:04:45.465724 #13694] INFO -- : begin transaction
I, [2016-12-07T10:04:59.357685 #13694] INFO -- : Finished transaction in 13.891879991s
I, [2016-12-07T10:04:59.357747 #13694] INFO -- : Finished task import in 1705.414241185s
......@@ -12,40 +12,43 @@ namespace :github do
task insert_github_data: :environment do
$logger.info "Begin task insert database from github"
start_time = Time.now
# list_db_repo = insert_repos($client)
# list_db_user = insert_users($client)
# list_db_label = insert_labels($client, list_db_repo)
# list_db_issue = insert_issues($client, list_db_user, list_db_label, list_db_repo)
list_db_repo = Repository.all
# list_db_comment = insert_comments($client, list_db_repo)
list_db_repo = insert_repos($client)
list_db_user = insert_users($client)
list_db_label = insert_labels($client, list_db_repo)
list_db_issue = insert_issues($client, list_db_user, list_db_label, list_db_repo)
list_db_comment = insert_comments($client, list_db_repo)
list_db_rv_comment = insert_review_comments($client, list_db_repo)
$logger.info "begin transaction"
start_time_transaction = Time.now
ActiveRecord::Base.transaction do
# list_db_repo.each do |db_repo|
# db_repo.save
# end
list_db_repo.each do |db_repo|
db_repo.save
end
# list_db_user.each do |db_user|
# db_user.save
# end
list_db_user.each do |db_user|
db_user.save
end
# list_db_label.each do |db_label|
# db_label.save
# end
list_db_label.each do |db_label|
db_label.save
end
# list_db_issue.each do |db_issue|
# db_issue.save
# end
list_db_issue.each do |db_issue|
db_issue.save
end
# list_db_comment.each do |db_comment|
# db_comment.save
# end
list_db_comment.each do |db_comment|
db_comment.save
end
list_db_rv_comment.each do |db_rv_comment|
db_rv_comment.save
begin
db_rv_comment.save
rescue
byebug
end
end
end
$logger.info "Finished transaction in #{Time.now - start_time_transaction}s"
......@@ -255,10 +258,11 @@ namespace :github do
for i in (1..last_page)
rv_comments = client.pull_requests_comments($org + "/" + db_repo.name, { page: i })
rv_comments.each do |rv_comment|
db_rv_comment = ReviewComment.find_by(id: rv_comment.id)
db_rv_comment = ReviewComment.find_by(rv_comment_id: rv_comment.id, commit_id: rv_comment.commit_id)
if db_rv_comment.nil?
db_rv_comment = ReviewComment.new
db_rv_comment.id = rv_comment.id
db_rv_comment.rv_comment_id = rv_comment.id
db_rv_comment.commit_id = rv_comment.commit_id
db_rv_comment.url = rv_comment.url
db_rv_comment.diff_hunk = rv_comment.diff_hunk
db_rv_comment.path = rv_comment.path
......@@ -281,6 +285,7 @@ namespace :github do
list_db_rv_comment.append(db_rv_comment)
end
end
end
list_db_rv_comment
end
......
require 'test_helper'
class UserControllerTest < ActionDispatch::IntegrationTest
# test "the truth" do
# assert true
# end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment