module Qa::Authorities class Local::TableBasedAuthority < Base class_attribute :table_name, :table_index self.table_name = "qa_local_authority_entries" self.table_index = "index_qa_local_authority_entries_on_lower_label" class << self def check_for_index @checked_for_index ||= begin conn = ActiveRecord::Base.connection if table_or_view_exists? && !conn.indexes(table_name).find { |i| i.name == table_index } Rails.logger.error "You've installed local authority tables, but you haven't indexed the label. " \ "Rails doesn't support functional indexes in migrations, so you'll have to add this manually:\n" \ "CREATE INDEX \"#{table_index}\" ON \"#{table_name}\" (local_authority_id, lower(label))\n" \ " OR on Sqlite: \n" \ "CREATE INDEX \"#{table_index}\" ON \"#{table_name}\" (local_authority_id, label collate nocase)\n" \ " OR for MySQL use the MSQLTableBasedAuthority instead, since mysql does not support functional indexes." end end end private def table_or_view_exists? conn = ActiveRecord::Base.connection if conn.respond_to?(:data_source_exists?) conn.data_source_exists?(table_name) else conn.table_exists?(table_name) end end end attr_reader :subauthority def initialize(subauthority) super() self.class.check_for_index @subauthority = subauthority end def search(q) return [] if q.blank? output_set(base_relation.where('lower(label) like ?', "#{q.downcase}%").limit(25)) end def all output_set(base_relation.limit(1000)) end def find(uri) record = base_relation.find_by(uri: uri) return unless record output(record) end private def base_relation Qa::LocalAuthorityEntry.where(local_authority: local_authority) end def output_set(set) set.map { |item| output(item) } end def output(item) { id: item[:uri], label: item[:label] }.with_indifferent_access end def local_authority Qa::LocalAuthority.find_by_name(subauthority) end end end