pacer 1.4.2-java → 1.5.1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +20 -1
- data/README.md +29 -15
- data/Rakefile +0 -1
- data/lib/pacer/core/graph/edges_route.rb +5 -5
- data/lib/pacer/core/graph/vertices_route.rb +7 -7
- data/lib/pacer/core/route.rb +39 -23
- data/lib/pacer/filter/collection_filter.rb +6 -5
- data/lib/pacer/filter/empty_filter.rb +1 -0
- data/lib/pacer/filter/loop_filter.rb +13 -2
- data/lib/pacer/filter/property_filter.rb +1 -1
- data/lib/pacer/filter/property_filter/filters.rb +1 -1
- data/lib/pacer/filter/uniq_section.rb +56 -0
- data/lib/pacer/filter/where_filter/node_visitor.rb +13 -12
- data/lib/pacer/graph/graph_ml.rb +4 -2
- data/lib/pacer/graph/graph_transactions_mixin.rb +26 -0
- data/lib/pacer/graph/pacer_graph.rb +1 -1
- data/lib/pacer/loader.rb +2 -1
- data/lib/pacer/pipe/collection_filter_pipe.rb +2 -0
- data/lib/pacer/pipe/id_collection_filter_pipe.rb +12 -2
- data/lib/pacer/pipe/loop_pipe.rb +1 -1
- data/lib/pacer/pipe/property_comparison_pipe.rb +6 -6
- data/lib/pacer/pipes.rb +5 -4
- data/lib/pacer/route/mixin/bulk_operations.rb +22 -21
- data/lib/pacer/support/enumerable.rb +0 -4
- data/lib/pacer/transform/identity.rb +10 -0
- data/lib/pacer/transform/lookup_ids.rb +2 -2
- data/lib/pacer/version.rb +3 -4
- data/lib/pacer/wrappers/edge_wrapper.rb +3 -1
- data/lib/pacer/wrappers/element_wrapper.rb +5 -3
- data/lib/pacer/wrappers/vertex_wrapper.rb +8 -2
- data/pom.xml +3 -30
- data/spec/pacer/blueprints/neo4j2_spec.rb +62 -0
- data/spec/pacer/blueprints/neo4j_spec.rb +6 -4
- data/spec/pacer/core/graph/graph_route_spec.rb +11 -3
- data/spec/pacer/core/route_spec.rb +1 -1
- data/spec/pacer/filter/empty_filter_spec.rb +1 -1
- data/spec/pacer/route/mixin/bulk_operations_spec.rb +11 -3
- data/spec/pacer/wrapper/element_wrapper_spec.rb +15 -15
- data/spec/pacer/wrapper/vertex_wrapper_spec.rb +4 -4
- data/spec/spec_helper.rb +5 -4
- data/spec/support/graph_runner.rb +11 -0
- data/spec/support/use_transactions.rb +4 -0
- metadata +7 -4
- data/lib/pacer/support/array.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73b5792b368e7fd7337c32ccceeb591ed47ab3a8
|
4
|
+
data.tar.gz: cb32f1e5e53c44accced47e77ee7fe6177eafeb4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3eb2c7a98df23b0cce4a79343e601363970bb3a96deb4c4d50982daab3f683ce4d97cd7a957475b8df6ecd6fde41756383bf3fa9c5fef70ad1efd08a44944c01
|
7
|
+
data.tar.gz: aff44e7a64e456465a5e15fe093ed04410d7139f63213bdecddf1ae265cf6cd4fdab1fbcbba25d26b67d20453f3b60e79d2c31479845e795c24cf86895a0e16d
|
data/Gemfile
CHANGED
@@ -12,12 +12,31 @@ group :development do
|
|
12
12
|
# pacer-* gems are required for testing pacer.
|
13
13
|
# If you have the gem repos cloned locally, we'll use them.
|
14
14
|
#
|
15
|
-
[ 'pacer-
|
15
|
+
[ 'pacer-orient', 'pacer-dex' ].each do |lib|
|
16
16
|
if File.directory? "../#{lib}"
|
17
17
|
gem lib, :path => "../#{lib}"
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
# Neo4j versions are mutually incompatible
|
22
|
+
# To test Pacer against Neo4j 1.x when the neo2 gem is present, use:
|
23
|
+
#
|
24
|
+
# neo=1 bundle
|
25
|
+
# rspec
|
26
|
+
#
|
27
|
+
# To switch back, just use:
|
28
|
+
#
|
29
|
+
# bundle
|
30
|
+
# rspec
|
31
|
+
#
|
32
|
+
if File.directory? "../pacer-neo4j" and (ENV['neo'] == '1' or not File.directory? "../pacer-neo4j2")
|
33
|
+
gem 'pacer-neo4j', :path => "../pacer-neo4j"
|
34
|
+
end
|
35
|
+
|
36
|
+
if File.directory? "../pacer-neo4j2" and ENV['neo'] != '1'
|
37
|
+
gem 'pacer-neo4j2', :path => "../pacer-neo4j2"
|
38
|
+
end
|
39
|
+
|
21
40
|
if File.directory? "../mcfly"
|
22
41
|
gem 'pacer-mcfly', :path => "../mcfly"
|
23
42
|
end
|
data/README.md
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
Pacer is a JRuby library that enables very expressive graph traversals.
|
4
4
|
|
5
|
-
It currently supports
|
6
|
-
and [Dex](http://www.sparsity-technologies.com/dex)
|
5
|
+
It currently supports all of the major graph databases including [Neo4j](http://neo4j.org)
|
6
|
+
and [Dex](http://www.sparsity-technologies.com/dex) thanks to the
|
7
7
|
[Tinkerpop](http://tinkerpop.com) graphdb stack. Plus there's a very
|
8
8
|
convenient in-memory graph called TinkerGraph which is part of
|
9
9
|
[Blueprints](http://blueprints.tinkerpop.com).
|
@@ -17,19 +17,21 @@ it's very fast!
|
|
17
17
|
|
18
18
|
## Mailing List
|
19
19
|
|
20
|
-
|
21
|
-
group](http://groups.google.com/group/pacer-users?lnk=gcimv). Join and
|
22
|
-
let's get the conversation going!
|
20
|
+
Pacer has a [google group](http://groups.google.com/group/pacer-users?lnk=gcimv)! Join and feel free to ask questions and discuss about Pacer or graphs in general.
|
23
21
|
|
24
22
|
## Documentation
|
25
23
|
|
26
|
-
Pacer
|
24
|
+
Check out the [wiki](https://github.com/pangloss/pacer/wiki) for detailed explanations of many of Pacer's features. Please contribute to it or open issues against it if there is anything missing that you want to see.
|
25
|
+
|
26
|
+
Pacer is also documented with a comprehensive RSpec test suite and with a
|
27
27
|
thorough YARD documentation. [Dig in!](http://rubydoc.info/github/pangloss/pacer/develop/frames)
|
28
28
|
|
29
29
|
If you like, you can also use the documentation locally via
|
30
30
|
|
31
|
+
```
|
31
32
|
gem install yard
|
32
33
|
yard server
|
34
|
+
```
|
33
35
|
|
34
36
|
## JRuby 1.7 Required
|
35
37
|
|
@@ -57,20 +59,31 @@ compatible with Pacer, but I have not yet implemented the simple
|
|
57
59
|
adapters Pacer needs to use them yet. Here is the list of what's
|
58
60
|
supported so far:
|
59
61
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
[pangloss/pacer-
|
65
|
-
|
66
|
-
|
67
|
-
|
62
|
+
| Graph | Info | Gem Required | Gem address |
|
63
|
+
|------------------------------------------------|------------------------------------------|---------------------------|-----------------------------------------------------------------|
|
64
|
+
| TinkerGraph | In-memory graph db. Included with Pacer. | | |
|
65
|
+
| [Neo4J](http://neo4j.org) | The industry-leading graph db. | `gem install pacer-neo4j` | [pangloss/pacer-neo4j](https://github.com/pangloss/pacer-neo4j) |
|
66
|
+
| [Dex](http://sparsity-technologies.com) | A very fast, relatively new graph db. | `gem install pacer-dex` | [pangloss/pacer-dex](https://github.com/pangloss/pacer-dex) |
|
67
|
+
| [Titan](http://thinkaurelius.github.io/titan/) | Built on top of a pluggable nosql backend store | `gem install pacer-titan` | [pacer-titan](https://github.com/mrbotch/pacer-titan) |
|
68
|
+
|
69
|
+
|
68
70
|
|
69
71
|
You can run any or all of the above graph databases. Pacer supports
|
70
72
|
running them simultaneuosly and even supports having many of any given
|
71
73
|
type open at once.
|
72
74
|
|
73
|
-
###
|
75
|
+
### Using Pacer with Neo4j
|
76
|
+
|
77
|
+
All you need is the [pacer-neo4j](https://github.com/pangloss/pacer-neo4j) gem.
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
require 'pacer-neo4j'
|
81
|
+
graph = Pacer.neo4j("path/to/graph")
|
82
|
+
```
|
83
|
+
|
84
|
+
See the gem repository for more details on Neo4j-specific features and functionality.
|
85
|
+
|
86
|
+
#### (optional) Interoperation with the neo4j gem
|
74
87
|
|
75
88
|
Pacer can work together with other Ruby GraphDB libraries, too. The
|
76
89
|
first functioning example is with theo neo4j gem. Hopefully more will
|
@@ -82,6 +95,7 @@ as follows:
|
|
82
95
|
```ruby
|
83
96
|
require 'neo4j'
|
84
97
|
require 'pacer-neo4j'
|
98
|
+
# start neo4j via the external gem rather than using pacer-neo4j
|
85
99
|
Neo4j.db.start
|
86
100
|
graph = Pacer.neo4j(Neo4j.db.graph)
|
87
101
|
```
|
data/Rakefile
CHANGED
@@ -20,7 +20,6 @@ file 'pom.xml' => 'lib/pacer/version.rb' do
|
|
20
20
|
line.sub!(%r{<gem.version>.*</gem.version>}, "<gem.version>#{ Pacer::VERSION }</gem.version>")
|
21
21
|
line.sub!(%r{<blueprints.version>.*</blueprints.version>}, "<blueprints.version>#{ Pacer::BLUEPRINTS_VERSION }</blueprints.version>")
|
22
22
|
line.sub!(%r{<pipes.version>.*</pipes.version>}, "<pipes.version>#{ Pacer::PIPES_VERSION }</pipes.version>")
|
23
|
-
line.sub!(%r{<gremlin.version>.*</gremlin.version>}, "<gremlin.version>#{ Pacer::GREMLIN_VERSION }</gremlin.version>")
|
24
23
|
f << line
|
25
24
|
end
|
26
25
|
end
|
@@ -2,9 +2,9 @@ module Pacer::Core::Graph
|
|
2
2
|
|
3
3
|
# Basic methods for routes that contain only edges.
|
4
4
|
module EdgesRoute
|
5
|
-
import com.tinkerpop.
|
6
|
-
import com.tinkerpop.
|
7
|
-
import com.tinkerpop.
|
5
|
+
import com.tinkerpop.pipes.transform.OutVertexPipe
|
6
|
+
import com.tinkerpop.pipes.transform.InVertexPipe
|
7
|
+
import com.tinkerpop.pipes.transform.BothVerticesPipe
|
8
8
|
|
9
9
|
# Extends the route with out vertices from this route's matching edges.
|
10
10
|
#
|
@@ -56,7 +56,7 @@ module Pacer::Core::Graph
|
|
56
56
|
#
|
57
57
|
# @return [Core::Route]
|
58
58
|
def labels
|
59
|
-
chain_route(:pipe_class => com.tinkerpop.
|
59
|
+
chain_route(:pipe_class => com.tinkerpop.pipes.transform.LabelPipe,
|
60
60
|
:route_name => 'labels',
|
61
61
|
:element_type => :object)
|
62
62
|
end
|
@@ -84,7 +84,7 @@ module Pacer::Core::Graph
|
|
84
84
|
protected
|
85
85
|
|
86
86
|
def id_pipe_class
|
87
|
-
com.tinkerpop.
|
87
|
+
com.tinkerpop.pipes.transform.IdEdgePipe
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
@@ -2,12 +2,12 @@ module Pacer::Core::Graph
|
|
2
2
|
|
3
3
|
# Basic methods for routes that contain only vertices.
|
4
4
|
module VerticesRoute
|
5
|
-
import com.tinkerpop.
|
6
|
-
import com.tinkerpop.
|
7
|
-
import com.tinkerpop.
|
8
|
-
import com.tinkerpop.
|
9
|
-
import com.tinkerpop.
|
10
|
-
import com.tinkerpop.
|
5
|
+
import com.tinkerpop.pipes.transform.OutEdgesPipe
|
6
|
+
import com.tinkerpop.pipes.transform.OutPipe
|
7
|
+
import com.tinkerpop.pipes.transform.InEdgesPipe
|
8
|
+
import com.tinkerpop.pipes.transform.InPipe
|
9
|
+
import com.tinkerpop.pipes.transform.BothEdgesPipe
|
10
|
+
import com.tinkerpop.pipes.transform.BothPipe
|
11
11
|
|
12
12
|
# Extends the route with out edges from this route's matching vertices.
|
13
13
|
#
|
@@ -219,7 +219,7 @@ module Pacer::Core::Graph
|
|
219
219
|
|
220
220
|
# TODO: move id_pipe_class into the element_type object
|
221
221
|
def id_pipe_class
|
222
|
-
com.tinkerpop.
|
222
|
+
com.tinkerpop.pipes.transform.IdVertexPipe
|
223
223
|
end
|
224
224
|
end
|
225
225
|
end
|
data/lib/pacer/core/route.rb
CHANGED
@@ -308,32 +308,37 @@ HELP
|
|
308
308
|
if Pacer.hide_route_elements or hide_elements or source_iterator.nil?
|
309
309
|
description
|
310
310
|
else
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
cols = (Pacer.columns / (max + 1).to_f).floor
|
323
|
-
cols = 1 if cols < 1
|
324
|
-
if cols == 1
|
325
|
-
template_part = ['%s']
|
326
|
-
else
|
327
|
-
template_part = ["%-#{max}s"]
|
311
|
+
graph_read_transaction do
|
312
|
+
Pacer.hide_route_elements do
|
313
|
+
count = 0
|
314
|
+
limit ||= Pacer.inspect_limit
|
315
|
+
results = collect do |v|
|
316
|
+
count += 1
|
317
|
+
if count > limit
|
318
|
+
puts "Total: > #{ limit } (Pacer.inspect_limit)"
|
319
|
+
return route.inspect
|
320
|
+
end
|
321
|
+
v.inspect
|
328
322
|
end
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
323
|
+
if count > 0
|
324
|
+
lens = results.collect { |r| r.length }
|
325
|
+
max = lens.max
|
326
|
+
cols = (Pacer.columns / (max + 1).to_f).floor
|
327
|
+
cols = 1 if cols < 1
|
328
|
+
if cols == 1
|
329
|
+
template_part = ['%s']
|
330
|
+
else
|
331
|
+
template_part = ["%-#{max}s"]
|
332
|
+
end
|
333
|
+
template = (template_part * cols).join(' ')
|
334
|
+
results.each_slice(cols) do |row|
|
335
|
+
template = (template_part * row.count).join(' ') if row.count < cols
|
336
|
+
puts template % row
|
337
|
+
end
|
333
338
|
end
|
339
|
+
puts "Total: #{ count }"
|
340
|
+
description
|
334
341
|
end
|
335
|
-
puts "Total: #{ count }"
|
336
|
-
description
|
337
342
|
end
|
338
343
|
end
|
339
344
|
end
|
@@ -425,6 +430,8 @@ HELP
|
|
425
430
|
self
|
426
431
|
elsif @back
|
427
432
|
@back.get_section_route(name)
|
433
|
+
elsif @empty_back
|
434
|
+
@empty_back.get_section_route(name)
|
428
435
|
else
|
429
436
|
raise ArgumentError, "Section #{ name } not found"
|
430
437
|
end
|
@@ -601,6 +608,15 @@ HELP
|
|
601
608
|
s = "#{s} #{ info }" if info
|
602
609
|
s
|
603
610
|
end
|
611
|
+
|
612
|
+
def graph_read_transaction(&block)
|
613
|
+
if graph
|
614
|
+
graph.read_transaction &block
|
615
|
+
else
|
616
|
+
yield
|
617
|
+
end
|
618
|
+
end
|
619
|
+
|
604
620
|
end
|
605
621
|
end
|
606
622
|
end
|
@@ -26,6 +26,7 @@ module Pacer
|
|
26
26
|
module Filter
|
27
27
|
module CollectionFilter
|
28
28
|
import java.util.HashSet
|
29
|
+
import com.tinkerpop.blueprints.Contains
|
29
30
|
|
30
31
|
include Pacer::Visitors::VisitsSection
|
31
32
|
|
@@ -33,24 +34,24 @@ module Pacer
|
|
33
34
|
|
34
35
|
def except=(collection)
|
35
36
|
self.collection = collection
|
36
|
-
@comparison =
|
37
|
+
@comparison = Contains::NOT_IN
|
37
38
|
end
|
38
39
|
|
39
40
|
def except_var=(var)
|
40
41
|
@var = var
|
41
42
|
self.section = var
|
42
|
-
@comparison =
|
43
|
+
@comparison = Contains::NOT_IN
|
43
44
|
end
|
44
45
|
|
45
46
|
def only=(collection)
|
46
47
|
self.collection = collection
|
47
|
-
@comparison =
|
48
|
+
@comparison = Contains::IN
|
48
49
|
end
|
49
50
|
|
50
51
|
def only_var=(var)
|
51
52
|
@var = var
|
52
53
|
self.section = var
|
53
|
-
@comparison =
|
54
|
+
@comparison = Contains::IN
|
54
55
|
end
|
55
56
|
|
56
57
|
protected
|
@@ -96,7 +97,7 @@ module Pacer
|
|
96
97
|
end
|
97
98
|
|
98
99
|
def inspect_class_name
|
99
|
-
if @comparison ==
|
100
|
+
if @comparison == Contains::NOT_IN
|
100
101
|
'Except'
|
101
102
|
else
|
102
103
|
'Only'
|
@@ -25,9 +25,10 @@ module Pacer
|
|
25
25
|
# a pattern may be nested to varying depths.
|
26
26
|
def repeat(arg, &block)
|
27
27
|
case arg
|
28
|
+
when 0
|
29
|
+
identity
|
28
30
|
when Fixnum
|
29
|
-
|
30
|
-
arg.to_enum(:times).inject(self) do |route_end, count|
|
31
|
+
(0...arg).inject(self) do |route_end, count|
|
31
32
|
yield route_end
|
32
33
|
end
|
33
34
|
when Range
|
@@ -53,6 +54,16 @@ module Pacer
|
|
53
54
|
fail ArgumentError, "Invalid repeat range"
|
54
55
|
end
|
55
56
|
end
|
57
|
+
|
58
|
+
def breadth_first(opts = {}, &block)
|
59
|
+
min_depth = opts.fetch :min_depth, 0
|
60
|
+
max_depth = opts.fetch :max_depth, 10
|
61
|
+
(min_depth..max_depth).reduce(self) do |route, depth|
|
62
|
+
route.branch do |b|
|
63
|
+
b.repeat depth, &block
|
64
|
+
end
|
65
|
+
end.merge_exhaustive
|
66
|
+
end
|
56
67
|
end
|
57
68
|
end
|
58
69
|
|
@@ -69,7 +69,7 @@ module Pacer
|
|
69
69
|
module Filter
|
70
70
|
module PropertyFilter
|
71
71
|
#import com.tinkerpop.pipes.filter.LabelCollectionFilterPipe
|
72
|
-
import com.tinkerpop.
|
72
|
+
import com.tinkerpop.pipes.filter.PropertyFilterPipe
|
73
73
|
|
74
74
|
def filters=(f)
|
75
75
|
if f.is_a? Filters
|
@@ -125,7 +125,7 @@ module Pacer
|
|
125
125
|
when NodeVisitor::Value
|
126
126
|
# no op
|
127
127
|
else
|
128
|
-
new_pipe = PropertyFilterPipe.new(key,
|
128
|
+
new_pipe = PropertyFilterPipe.new(key, Pacer::Pipes::EQUAL, value)
|
129
129
|
end
|
130
130
|
if new_pipe
|
131
131
|
new_pipe.set_starts pipe if pipe
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Pacer
|
2
|
+
module Routes
|
3
|
+
module RouteOperations
|
4
|
+
def uniq_in_section(section = nil)
|
5
|
+
chain_route filter: Pacer::Filter::UniqueSectionFilter, section: section
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module Filter
|
11
|
+
module UniqueSectionFilter
|
12
|
+
# VisitsSection module provides:
|
13
|
+
# section=
|
14
|
+
# section_visitor
|
15
|
+
include Pacer::Visitors::VisitsSection
|
16
|
+
|
17
|
+
def attach_pipe(end_pipe)
|
18
|
+
pipe = UniqueSectionPipe.new(self, section_visitor)
|
19
|
+
pipe.setStarts end_pipe if end_pipe
|
20
|
+
pipe
|
21
|
+
end
|
22
|
+
|
23
|
+
class UniqueSectionPipe < Pacer::Pipes::RubyPipe
|
24
|
+
attr_reader :seen, :section, :route
|
25
|
+
|
26
|
+
|
27
|
+
def initialize(route, section)
|
28
|
+
super()
|
29
|
+
@seen = Set[]
|
30
|
+
@section = section
|
31
|
+
@route = route
|
32
|
+
section.visitor = self if section
|
33
|
+
end
|
34
|
+
|
35
|
+
def processNextStart
|
36
|
+
while true
|
37
|
+
element = starts.next
|
38
|
+
unless seen.include? element
|
39
|
+
seen << element
|
40
|
+
return element
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def after_element
|
46
|
+
seen.clear
|
47
|
+
end
|
48
|
+
|
49
|
+
def reset
|
50
|
+
seen.clear
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
@@ -9,7 +9,7 @@ module Pacer
|
|
9
9
|
import com.tinkerpop.pipes.filter.AndFilterPipe
|
10
10
|
import com.tinkerpop.pipes.filter.OrFilterPipe
|
11
11
|
import com.tinkerpop.pipes.filter.ObjectFilterPipe
|
12
|
-
import com.tinkerpop.
|
12
|
+
import com.tinkerpop.pipes.transform.PropertyPipe
|
13
13
|
import com.tinkerpop.pipes.transform.HasCountPipe
|
14
14
|
NeverPipe = Pacer::Pipes::NeverPipe
|
15
15
|
IdentityPipe = Pacer::Pipes::IdentityPipe
|
@@ -19,21 +19,22 @@ module Pacer
|
|
19
19
|
UnaryTransformPipe = Pacer::Pipes::UnaryTransformPipe
|
20
20
|
BlockFilterPipe = Pacer::Pipes::BlockFilterPipe
|
21
21
|
|
22
|
+
import com.tinkerpop.blueprints.Compare
|
22
23
|
Filters = {
|
23
|
-
'==' =>
|
24
|
-
'=' =>
|
25
|
-
'!=' =>
|
26
|
-
'>' =>
|
27
|
-
'<' =>
|
28
|
-
'>=' =>
|
29
|
-
'<=' =>
|
24
|
+
'==' => Compare::EQUAL,
|
25
|
+
'=' => Compare::EQUAL,
|
26
|
+
'!=' => Compare::NOT_EQUAL,
|
27
|
+
'>' => Compare::GREATER_THAN,
|
28
|
+
'<' => Compare::LESS_THAN,
|
29
|
+
'>=' => Compare::GREATER_THAN_EQUAL,
|
30
|
+
'<=' => Compare::LESS_THAN_EQUAL
|
30
31
|
}
|
31
32
|
|
32
33
|
ReverseFilters = Filters.merge(
|
33
|
-
'<' =>
|
34
|
-
'>' =>
|
35
|
-
'<=' =>
|
36
|
-
'>=' =>
|
34
|
+
'<' => Compare::GREATER_THAN,
|
35
|
+
'>' => Compare::LESS_THAN,
|
36
|
+
'<=' => Compare::GREATER_THAN_EQUAL,
|
37
|
+
'>=' => Compare::LESS_THAN_EQUAL
|
37
38
|
)
|
38
39
|
|
39
40
|
COMPARATORS = %w[ == != > < >= <= ]
|