Class: CqlRuby::CqlTermNode

Inherits:
CqlNode
  • Object
show all
Defined in:
lib/cql_ruby/cql_nodes.rb,
lib/cql_ruby/cql_to_solr.rb

Overview

Represents a terminal node in a CQL parse-tree. A term node consists of the term String itself, together with, optionally, an index string and a relation. Neither or both of these must be provided - you can’t have an index without a relation or vice versa.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from CqlNode

#check_xml, #getResultSetName, #render_prefixes, #render_sortkeys

Constructor Details

#initialize(index, relation, term) ⇒ CqlTermNode

Returns a new instance of CqlTermNode.



201
202
203
204
205
206
207
# File 'lib/cql_ruby/cql_nodes.rb', line 201

def initialize( index, relation, term )
  super()
  
  @index = index.dup
  @relation = relation.dup
  @term = term.dup
end

Instance Attribute Details

#indexObject

Returns the value of attribute index.



200
201
202
# File 'lib/cql_ruby/cql_nodes.rb', line 200

def index
  @index
end

#relationObject

Returns the value of attribute relation.



200
201
202
# File 'lib/cql_ruby/cql_nodes.rb', line 200

def relation
  @relation
end

#termObject

Returns the value of attribute term.



200
201
202
# File 'lib/cql_ruby/cql_nodes.rb', line 200

def term
  @term
end

Instance Method Details

#maybe_quote(s) ⇒ Object



241
242
243
244
245
246
# File 'lib/cql_ruby/cql_nodes.rb', line 241

def maybe_quote( s )
  if s == "" || s =~ /[" \t=<>()\/]/
    return "\"#{s.gsub( /"/, "\\\"" )}\""
  end
  s
end

#result_set_index?(qual) ⇒ Boolean

Returns:

  • (Boolean)


209
210
211
# File 'lib/cql_ruby/cql_nodes.rb', line 209

def result_set_index?( qual )
  /(srw|cql).resultSet(|Id|Name|SetName)/ =~ qual
end

#result_set_nameObject



213
214
215
216
# File 'lib/cql_ruby/cql_nodes.rb', line 213

def result_set_name
  return term if result_set_index?( @index )
  nil
end

#solr_maybe_quote(term) ⇒ Object

utility method, quotes/escapes value, if needed, for inclusion in solr lucene query parser term. wraps in double quotes if needed, backslash-escapes internal double quotes.



148
149
150
151
152
# File 'lib/cql_ruby/cql_to_solr.rb', line 148

def solr_maybe_quote(term)
  return term unless term =~ /[^a-zA-Z0-9_]/
  
  return '"' + term.gsub('"', '\\"') + '"'
end

#to_cqlObject



230
231
232
233
234
235
236
237
238
239
# File 'lib/cql_ruby/cql_nodes.rb', line 230

def to_cql
  quoted_index = maybe_quote( @index )
  quoted_term = maybe_quote( @term )
  res = quoted_term
  
  if @index && /(srw|cql)\.serverChoice/i !~ @index
    res = "#{quoted_index} #{@relation.to_cql} #{quoted_term}"
  end
  res
end

#to_solrObject

Raises:



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/cql_ruby/cql_to_solr.rb', line 80

def to_solr
  relation = @relation.modifier_set.base            

  relation = CqlRuby.to_solr_defaults[:default_relation] if  relation == "="
  # If no prefix to relation, normalize to "cql"
  relation = "cql.#{relation}" unless relation.index(".") || ["<>", "<=", ">=", "<", ">", "=", "=="].include?(relation)

  
  # What's our default index for server choice indexes? Let's call it
  # "text".
  # Otherwise, remove the namespace/"context set" prefix.
  solr_field = case @index.downcase
                 when "cql.anyindexes", "cql.serverchoice", "cql.keywords"
                   CqlRuby.to_solr_defaults[:default_index]
                 when "cql.allindexes"
                   CqlRuby.to_solr_defaults[:all_index]
                 else
                   @index.gsub(/^[^.]*\./, "")
               end
  
  raise CqlException.new("resultSet not supported") if @index.downcase == "cql.resultsetid"
  raise CqlException.new("relation modifiers not supported: #{@relation.modifier_set.to_cql}") if @relation.modifier_set.modifiers.length > 0

  if index.downcase == "cql.allrecords"
    #WARNING: Not sure if this will actually always work as intended, its
    # a bit odd. 
    return "[* TO *]"
  end

  
  negate = false
  
  value = 
  case relation
    # WARNING: Depending on how you've tokenized, <> and == semantics
    # may not be fully respected. For typical solr fields, will
    # match/exclude on partial matches too, not only complete matches. 
    when "<>"
      negate = true
      solr_maybe_quote(@term)
    when "cql.adj", "==" then   solr_maybe_quote(@term)                                
    when "cql.all" then '(' + @term.split(/\s/).collect{|a| '+'+a}.join(" ") + ')'          
    when "cql.any" then         '(' + @term.split(/\s/).join(" OR ") + ')'          
    when ">=" then              "[" + solr_maybe_quote(@term) + " TO *]"          
    when ">" then               "{" + solr_maybe_quote(@term) + " TO *}"          
    when "<=" then              "[* TO " + solr_maybe_quote(@term) + "]"          
    when "<" then               "{* TO " + solr_maybe_quote(@term) + "}"
    when "cql.within"
      bounds = @term.gsub('"', "").split(/\s/)
      raise CqlException.new("can not extract two bounding values from within relation term: #{@term}") unless bounds.length == 2

      "[" + solr_maybe_quote(bounds[0]) + " TO " + solr_maybe_quote(bounds[1]) + "]"                  
    else
      raise CqlException.new("relation not supported: #{relation}")
  end

  ret = ""
  ret += "-" if negate
  ret += "#{solr_field}:" if solr_field
  ret += value
  
  return ret     
end

#to_xcql(xml = nil, prefixes = nil, sortkeys = nil) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
# File 'lib/cql_ruby/cql_nodes.rb', line 218

def to_xcql( xml=nil, prefixes=nil, sortkeys=nil )
  xml = check_xml( xml )
  
  xml.searchClause do
    render_prefixes( xml, prefixes )
    xml.index( @index )
    @relation.to_xcql( xml )
    xml.term( @term )
    render_sortkeys( xml, sortkeys )
  end
end