Merge pull request #1023 from okriuchykhin/ok_SCI_2108

Refactor search to support repository list items [SCI-2108]
This commit is contained in:
okriuchykhin 2018-03-09 16:23:34 +01:00 committed by GitHub
commit f8fb5cca75
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 72 deletions

View file

@ -111,7 +111,6 @@ class SearchController < ApplicationController
def count_by_repository
count_total = 0
search_results = Repository.search(current_user,
true,
@search_query,
Constants::SEARCH_NO_LIMIT,
nil,
@ -243,7 +242,8 @@ class SearchController < ApplicationController
@repository_results = []
if @repository_search_count_total > 0
@repository_results =
RepositoryRow.search(@repository, @search_query, @search_page,
Repository.search(current_user, @search_query, @search_page,
@repository,
match_case: @search_case,
whole_word: @search_whole_word,
whole_phrase: @search_whole_phrase)

View file

@ -23,40 +23,34 @@ class Repository < ApplicationRecord
def self.search(
user,
_include_archived,
query = nil,
page = 1,
current_team = nil,
repository = nil,
options = {}
)
team_ids =
if current_team
current_team.id
else
Team.joins(:user_teams)
.where('user_teams.user_id = ?', user.id)
.distinct
.pluck(:id)
end
repositories = repository ? repository : Repository.where(team: user.teams)
row_ids = RepositoryRow
.search(nil, query, Constants::SEARCH_NO_LIMIT, options)
.select(:id)
includes_json = { repository_cells: Extends::REPOSITORY_SEARCH_INCLUDES }
searchable_attributes = ['repository_rows.name', 'users.full_name'] +
Extends::REPOSITORY_EXTRA_SEARCH_ATTR
new_query = Repository
.select('repositories.*, COUNT(repository_rows.id) AS counter')
.joins(:team)
.joins('LEFT OUTER JOIN repository_rows ON ' \
'repositories.id = repository_rows.repository_id')
.where(team: team_ids)
.where('repository_rows.id IN (?)', row_ids)
.group('repositories.id')
new_query = RepositoryRow
.left_outer_joins(:created_by)
.left_outer_joins(includes_json)
.where(repository: repositories)
.where_attributes_like(searchable_attributes, query, options)
# Show all results if needed
if page == Constants::SEARCH_NO_LIMIT
new_query
.joins(:repository)
.select(
'repositories.id AS id, COUNT(DISTINCT repository_rows.id) AS counter'
)
.group('repositories.id')
else
new_query
.distinct
.limit(Constants::SEARCH_LIMIT)
.offset((page - 1) * Constants::SEARCH_LIMIT)
end

View file

@ -2,6 +2,21 @@ class RepositoryCell < ActiveRecord::Base
belongs_to :repository_row
belongs_to :repository_column
belongs_to :value, polymorphic: true, dependent: :destroy
belongs_to :repository_text_value,
(lambda do
where(repository_cells: { value_type: 'RepositoryTextValue' })
end),
optional: true, foreign_key: :value_id
belongs_to :repository_date_value,
(lambda do
where(repository_cells: { value_type: 'RepositoryDateValue' })
end),
optional: true, foreign_key: :value_id
belongs_to :repository_list_value,
(lambda do
where(repository_cells: { value_type: 'RepositoryListValue' })
end),
optional: true, foreign_key: :value_id
validates :repository_column, presence: true
validate :repository_column_data_type

View file

@ -21,47 +21,4 @@ class RepositoryRow < ApplicationRecord
presence: true,
length: { maximum: Constants::NAME_MAX_LENGTH }
validates :created_by, presence: true
def self.search(repository, query, page = 1, options)
new_query = distinct
.joins(:created_by)
.joins(
"LEFT OUTER JOIN (
SELECT repository_cells.repository_row_id,
repository_text_values.data AS text_value,
to_char(repository_date_values.data, 'DD.MM.YYYY HH24:MI')
AS date_value
FROM repository_cells
INNER JOIN repository_text_values
ON repository_text_values.id = repository_cells.value_id
FULL OUTER JOIN repository_date_values
ON repository_date_values.id = repository_cells.value_id
) AS values
ON values.repository_row_id = repository_rows.id"
)
.where_attributes_like(
['repository_rows.name', 'users.full_name',
'values.text_value', 'values.date_value'],
query, options
)
if repository
new_query = new_query
.preload(
:repository_columns,
:created_by,
repository_cells: :value
)
.where(repository: repository)
end
# Show all results if needed
if page == Constants::SEARCH_NO_LIMIT
new_query
else
new_query
.limit(Constants::SEARCH_LIMIT)
.offset((page - 1) * Constants::SEARCH_LIMIT)
end
end
end

View file

@ -43,6 +43,14 @@ class Extends
REPOSITORY_DATA_TYPES = { RepositoryTextValue: 0,
RepositoryDateValue: 1,
RepositoryListValue: 2 }
# Extra attributes used for search in repositories, text columns
# are only supported
REPOSITORY_EXTRA_SEARCH_ATTR = ['repository_text_values.data',
'repository_list_items.data']
# Array of includes used in search query for repository rows
REPOSITORY_SEARCH_INCLUDES = [:repository_text_value,
repository_list_value: :repository_list_item]
# List of implemented core API versions
API_VERSIONS = ['20170715']

View file

@ -1,9 +1,13 @@
require File.expand_path('app/helpers/database_helper')
class CreateRepositoryListValues < ActiveRecord::Migration[5.1]
def change
include DatabaseHelper
def up
create_table :repository_list_items do |t|
t.references :repository, index: true, foreign_key: true
t.references :repository_column, index: true, foreign_key: true
t.text :data, index: true, using: :gin, null: false
t.text :data, null: false
t.references :created_by,
index: true,
foreign_key: { to_table: :users }
@ -13,6 +17,8 @@ class CreateRepositoryListValues < ActiveRecord::Migration[5.1]
t.timestamps
end
add_gin_index_without_tags :repository_list_items, :data
create_table :repository_list_values do |t|
t.references :repository_list_item, index: true
t.references :created_by,
@ -24,4 +30,9 @@ class CreateRepositoryListValues < ActiveRecord::Migration[5.1]
t.timestamps
end
end
def down
drop_table :repository_list_items
drop_table :repository_list_values
end
end