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)


78
79
80
# File 'lib/tiered_category_expressions/expression.rb', line 78

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:



91
92
93
# File 'lib/tiered_category_expressions/expression.rb', line 91

def >(other)
  self.class.new(@tiers + TieredCategoryExpressions::TCE(other).tiers)
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)



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

def as_regexp
  "^#{@tiers.map(&:as_regexp).join}"
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 still yields 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.



111
112
113
# File 'lib/tiered_category_expressions/expression.rb', line 111

def as_sql_like_query
  @tiers.map(&:as_sql_like_query).join + "%"
end

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

Matches the expression with the given category.

Parameters:

  • category (Array<String>)

    Category to match

Returns:

  • (Boolean)


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

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

#to_regexpString

Returns Regexp representation of the expression.

Returns:

  • (String)

    Regexp representation of the expression



60
61
62
# File 'lib/tiered_category_expressions/expression.rb', line 60

def to_regexp
  /#{as_regexp}/i
end

#to_sString

Returns String representation of the expression.

Returns:

  • (String)

    String representation of the expression



50
51
52
# File 'lib/tiered_category_expressions/expression.rb', line 50

def to_s
  @tiers.join(" ").sub(/^>(?!>)\s*/, "") # Initial ">" is implied (but ">>" is not)
end