<commit_before>require 'active_rdf'

# TODO: support limit and offset

# Translates abstract query into SPARQL that can be executed on SPARQL-compliant
# data source.
class Query2SPARQL
  Engines_With_Keyword = [:yars2, :virtuoso]
  def self.translate(query, engine=nil)
    str = ""
    if query.select?
      distinct = query.distinct? ? "DISTINCT " : ""
			select_clauses = query.select_clauses.collect{|s| construct_clause(s)}

      str << "SELECT #{distinct}#{select_clauses.join(' ')} "
      str << "WHERE { #{where_clauses(query)} #{filter_clauses(query)}} "
      str << "LIMIT #{query.limits}" if query.limits
      str << "OFFSET #{query.offsets}" if query.offsets
    elsif query.ask?
      str << "ASK { #{where_clauses(query)} }"
    end
    
    return str
  end

  # concatenate filters in query
  def self.filter_clauses(query)
    "FILTER (#{query.filter_clauses.join(" && ")})" unless query.filter_clauses.empty?
  end

  # concatenate each where clause using space (e.g. 's p o')
  # and concatenate the clauses using dot, e.g. 's p o . s2 p2 o2 .'
  def self.where_clauses(query)
    if query.keyword?
      case sparql_engine
      when :yars2
        query.keywords.each do |term, keyword|
          query.where(term, keyword_predicate, keyword)
        end
      when :virtuoso
        query.keywords.each do |term, keyword|
          query.filter("#{keyword_predicate}(#{construct_clause(term)}, '#{keyword}')")
        end
      end
    end

		where_clauses = query.where_clauses.collect do |s,p,o,c|
			# ignore context parameter
			[s,p,o].collect {|term| construct_clause(term) }.join(' ')
		end

    "#{where_clauses.join(' . ')} ."
  end

	def self.construct_clause(term)
    if term.respond_to? :uri
      term.to_s
    else
      case term
      when Symbol
        '?' + term.to_s
      else
        term.to_s
      end
    end
	end

  def self.sparql_engine
    sparql_adapters = ConnectionPool.read_adapters.select{|adp| adp.is_a? SparqlAdapter}
    engines = sparql_adapters.collect {|adp| adp.engine}.uniq

    unless engines.all?{|eng| Engines_With_Keyword.include?(eng)}
      raise ActiveRdfError, "one or more of the specified SPARQL engines do not support keyword queries" <commit_msg>add some white spaces to the query generation, and add capability to make graph queries if querey where clause includes a context<commit_after>require 'active_rdf'

# TODO: support limit and offset

# Translates abstract query into SPARQL that can be executed on SPARQL-compliant
# data source.
class Query2SPARQL
  Engines_With_Keyword = [:yars2, :virtuoso]
  def self.translate(query, engine=nil)
    str = ""
    if query.select?
      distinct = query.distinct? ? "DISTINCT " : ""
			select_clauses = query.select_clauses.collect{|s| construct_clause(s)}

      str << "SELECT #{distinct}#{select_clauses.join(' ')} "
      str << "WHERE { #{where_clauses(query)} #{filter_clauses(query)}} "
      str << "LIMIT #{query.limits} " if query.limits
      str << "OFFSET #{query.offsets} " if query.offsets
    elsif query.ask?
      str << "ASK { #{where_clauses(query)} } "
    end
    
    return str
  end

  # concatenate filters in query
  def self.filter_clauses(query)
    "FILTER (#{query.filter_clauses.join(" && ")})" unless query.filter_clauses.empty?
  end

  # concatenate each where clause using space (e.g. 's p o')
  # and concatenate the clauses using dot, e.g. 's p o . s2 p2 o2 .'
  def self.where_clauses(query)
    if query.keyword?
      case sparql_engine
      when :yars2
        query.keywords.each do |term, keyword|
          query.where(term, keyword_predicate, keyword)
        end
      when :virtuoso
        query.keywords.each do |term, keyword|
          query.filter("#{keyword_predicate}(#{construct_clause(term)}, '#{keyword}')")
        end
      end
    end

		where_clauses = query.where_clauses.collect do |s,p,o,c|
      # does there where clause use a context ? 
		  if c.nil?
  			[s,p,o].collect {|term| construct_clause(term) }.join(' ')
  		else
  		  "GRAPH #{construct_clause(c)} { #{construct_clause(s)} #{construct_clause(p)} #{construct_clause(o)} }"
		  end
		end

    "#{where_clauses.join(' . ')} ."
  end

	def self.construct_clause(term)
    if term.respond_to? :uri
      term.to_s
    else
      case term
      when Symbol
        '?' + term.to_s
      else
        term.to_s
      end
    end
	end

  def self.sparql_engine
    sparql_adapters = ConnectionPool.read_adapters.select{|adp| adp.is_a? SparqlAdapter}
    engines = sparql_adapters.collect {|adp| adp.engine}.uniq

    unless engines.all?{|eng| Engines_With_Keyword.include?(eng)}
      raise ActiveRdfError, "one or more of the specified SPARQL engines do not support keyword queries" 
{'fraction_non_alphanumeric': 0.11901244988394176, 'fraction_numerical': 0.0025321797847647183, 'mean_word_length': 3.051282051282051, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1875371', 'n_tokens_mistral': 1642, 'n_tokens_neox': 1589, 'n_words': 400}