Class: TieredCategoryExpressions::Expression

Inherits:
Object
  • Object
show all
Defined in:
lib/tiered_category_expressions/expression.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.parse(str) ⇒ Expression

Parameters:

  • str (String)

    Tiered category expression to parse

Returns:

Raises:

  • (ParseError)

    Raises if TCE syntax is invalid



30
31
32
33
34
35
36
37
# File 'lib/tiered_category_expressions/expression.rb', line 30

def self.parse(str)
  tree = Parser.new.parse(str)
  Transformer.new.apply(tree)
rescue Parslet::ParseFailed => e
  deepest = Util.deepest_parse_failure_cause(e.parse_failure_cause)
  _, column = deepest.source.line_and_column(deepest.pos)
  raise ParseError, "unexpected input at character #{column}"
end

Instance Method Details

#==(other) ⇒ Boolean

Returns true if both expressions are equal. Expressions are considered equal if they match the same categories.

Parameters:

Returns:

  • (Boolean)


86
87
88
# File 'lib/tiered_category_expressions/expression.rb', line 86

def ==(other)
  to_regexp == TieredCategoryExpressions::TCE(other).to_regexp
end

#>(other) ⇒ Expression

Concatenates two expressions.

Examples:

TCE("foo") > "!bar" > TCE(">> baz")
# => TieredCategoryExpressions::Expression[foo > !bar >> baz]

Parameters:

Returns:



99
100
101
# File 'lib/tiered_category_expressions/expression.rb', line 99

def >(other)
  TieredCategoryExpressions::TCE(to_s + TieredCategoryExpressions::TCE(other).to_s(implied_root: false))
end

#as_regexpRegexp

Returns Regexp representation of the expression as a string (does not include flags).

Returns:

  • (Regexp)

    Regexp representation of the expression as a string (does not include flags)



62
63
64
# File 'lib/tiered_category_expressions/expression.rb', line 62

def as_regexp
  "^#{@tiers.map(&:as_regexp).join}#{'$' if @strict}"
end

#as_sql_like_queryObject

Returns an SQL LIKE query that may be used to speed up certain SQL queries.

SQL queries that involve matching some input against stored TCE regexps can be slow. Possibly, they can be optimized by applying a much faster LIKE query first, which reduces the number of regexps to apply. The LIKE query alone can still yield false positives, so it must be combined with the corresponding regexp.

For instance:

SELECT * FROM mappings WHERE 'foo>bar>baz>' LIKE tce_like_query AND 'foo>bar>baz>' ~ tce_regexp

Can be much faster than:

SELECT * FROM mappings WHERE 'foo>bar>baz>' ~ tce_regexp

Depending on the TCEs in the mappings table.



126
127
128
129
130
# File 'lib/tiered_category_expressions/expression.rb', line 126

def as_sql_like_query
  q = @tiers.map(&:as_sql_like_query).join
  q += "%" unless @strict || q.end_with?("%")
  q
end

#matches?(category) ⇒ Boolean Also known as: ===

Matches the expression with the given category.

Parameters:

  • category (Array<String>)

    Category to match

Returns:

  • (Boolean)


76
77
78
# File 'lib/tiered_category_expressions/expression.rb', line 76

def matches?(category)
  to_regexp.match?(Preprocessor.call(category))
end

#strict?Boolean

Returns true if the TCE object does not match categories with tiers that extend beyond those specified by the TCE. This is the case when the TCE ends with “.”.

Returns:

  • (Boolean)

    true if the TCE object does not match categories with tiers that extend beyond those specified by the TCE. This is the case when the TCE ends with “.”.



106
107
108
# File 'lib/tiered_category_expressions/expression.rb', line 106

def strict?
  @strict
end

#to_regexpString

Returns Regexp representation of the expression.

Returns:

  • (String)

    Regexp representation of the expression



67
68
69
# File 'lib/tiered_category_expressions/expression.rb', line 67

def to_regexp
  /#{as_regexp}/i
end

#to_s(implied_root: true) ⇒ String

Returns String representation of the expression.

Parameters:

  • implied_root (Boolean) (defaults to: true)

    If true no leading “>” is included.

Returns:

  • (String)

    String representation of the expression



54
55
56
57
58
59
# File 'lib/tiered_category_expressions/expression.rb', line 54

def to_s(implied_root: true)
  str = @tiers.join(" ")
  str << "." if @strict
  str = str.sub(/^>(?!>)\s*/, "") if implied_root # Initial ">" is implied (but ">>" is not)
  str
end