CloudSesame 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +3 -0
  5. data/Gemfile.lock +76 -0
  6. data/Guardfile +70 -0
  7. data/cloud_sesame.gemspec +25 -0
  8. data/lib/abstract_object.rb +67 -0
  9. data/lib/cloud_sesame.rb +77 -0
  10. data/lib/cloud_sesame/config/credential.rb +8 -0
  11. data/lib/cloud_sesame/domain/base.rb +70 -0
  12. data/lib/cloud_sesame/domain/client.rb +28 -0
  13. data/lib/cloud_sesame/domain/config.rb +8 -0
  14. data/lib/cloud_sesame/domain/context.rb +35 -0
  15. data/lib/cloud_sesame/query/ast/and.rb +9 -0
  16. data/lib/cloud_sesame/query/ast/compound_array.rb +73 -0
  17. data/lib/cloud_sesame/query/ast/leaf.rb +8 -0
  18. data/lib/cloud_sesame/query/ast/literal.rb +27 -0
  19. data/lib/cloud_sesame/query/ast/multi_branch.rb +27 -0
  20. data/lib/cloud_sesame/query/ast/not.rb +13 -0
  21. data/lib/cloud_sesame/query/ast/operator.rb +24 -0
  22. data/lib/cloud_sesame/query/ast/or.rb +9 -0
  23. data/lib/cloud_sesame/query/ast/prefix_literal.rb +17 -0
  24. data/lib/cloud_sesame/query/ast/root.rb +24 -0
  25. data/lib/cloud_sesame/query/ast/single_branch.rb +24 -0
  26. data/lib/cloud_sesame/query/ast/value.rb +38 -0
  27. data/lib/cloud_sesame/query/builder.rb +78 -0
  28. data/lib/cloud_sesame/query/dsl.rb +62 -0
  29. data/lib/cloud_sesame/query/dsl/and.rb +19 -0
  30. data/lib/cloud_sesame/query/dsl/base.rb +23 -0
  31. data/lib/cloud_sesame/query/dsl/filter_query.rb +47 -0
  32. data/lib/cloud_sesame/query/dsl/literal.rb +41 -0
  33. data/lib/cloud_sesame/query/dsl/or.rb +19 -0
  34. data/lib/cloud_sesame/query/dsl/range.rb +41 -0
  35. data/lib/cloud_sesame/query/dsl/scope.rb +24 -0
  36. data/lib/cloud_sesame/query/error/missing_operator_symbol.rb +8 -0
  37. data/lib/cloud_sesame/query/error/missing_query.rb +8 -0
  38. data/lib/cloud_sesame/query/node/abstract.rb +14 -0
  39. data/lib/cloud_sesame/query/node/facet.rb +14 -0
  40. data/lib/cloud_sesame/query/node/filter_query.rb +17 -0
  41. data/lib/cloud_sesame/query/node/page.rb +27 -0
  42. data/lib/cloud_sesame/query/node/query.rb +29 -0
  43. data/lib/cloud_sesame/query/node/query_options.rb +37 -0
  44. data/lib/cloud_sesame/query/node/query_options_field.rb +20 -0
  45. data/lib/cloud_sesame/query/node/query_parser.rb +27 -0
  46. data/lib/cloud_sesame/query/node/request.rb +71 -0
  47. data/lib/cloud_sesame/query/node/sort.rb +37 -0
  48. data/spec/abstract_object_spec.rb +103 -0
  49. data/spec/cloud_sesame/domain/base_spec.rb +27 -0
  50. data/spec/cloud_sesame/domain/context_spec.rb +24 -0
  51. data/spec/cloud_sesame/query/ast/and_spec.rb +13 -0
  52. data/spec/cloud_sesame/query/ast/literal_spec.rb +37 -0
  53. data/spec/cloud_sesame/query/ast/multi_branch_spec.rb +65 -0
  54. data/spec/cloud_sesame/query/ast/operator_spec.rb +30 -0
  55. data/spec/cloud_sesame/query/ast/or_spec.rb +13 -0
  56. data/spec/cloud_sesame/query/ast/root_spec.rb +43 -0
  57. data/spec/cloud_sesame/query/ast/value_spec.rb +40 -0
  58. data/spec/cloud_sesame/query/builder_spec.rb +12 -0
  59. data/spec/cloud_sesame/query/dsl/base_spec.rb +31 -0
  60. data/spec/cloud_sesame/query/dsl/filter_query_spec.rb +158 -0
  61. data/spec/cloud_sesame/query/dsl_spec.rb +96 -0
  62. data/spec/cloud_sesame/query/node/abstract_spec.rb +19 -0
  63. data/spec/cloud_sesame/query/node/facet_spec.rb +42 -0
  64. data/spec/cloud_sesame/query/node/filter_query_spec.rb +29 -0
  65. data/spec/cloud_sesame/query/node/page_spec.rb +58 -0
  66. data/spec/cloud_sesame/query/node/query_options_field_spec.rb +27 -0
  67. data/spec/cloud_sesame/query/node/query_options_spec.rb +56 -0
  68. data/spec/cloud_sesame/query/node/query_parser_spec.rb +37 -0
  69. data/spec/cloud_sesame/query/node/query_spec.rb +46 -0
  70. data/spec/cloud_sesame/query/node/request_spec.rb +71 -0
  71. data/spec/cloud_sesame/query/node/sort_spec.rb +76 -0
  72. data/spec/cloud_sesame_spec.rb +58 -0
  73. data/spec/spec_helper.rb +12 -0
  74. metadata +218 -0
@@ -0,0 +1,19 @@
1
+ module CloudSesame
2
+ module Query
3
+ module DSL
4
+ module And
5
+
6
+ # CLAUSE: AND
7
+ # =========================================
8
+ def and(&block)
9
+ method_scope.children << AST::And.new(method_context, &block)
10
+ method_return
11
+ end
12
+
13
+ alias_method :all, :and
14
+ alias_method :and!, :and
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,23 @@
1
+ module CloudSesame
2
+ module Query
3
+ module DSL
4
+ module Base
5
+
6
+ private
7
+
8
+ def method_context
9
+ method_scope.context
10
+ end
11
+
12
+ def method_return
13
+ self
14
+ end
15
+
16
+ def method_scope
17
+ self
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,47 @@
1
+ module CloudSesame
2
+ module Query
3
+ module DSL
4
+ module FilterQuery
5
+ include Scope
6
+ include And
7
+ include Or
8
+ include Literal
9
+
10
+ # { fields: { tags: { excluded: [100] } } }
11
+ def included?(field, value = nil)
12
+ (field_options = method_scope.context[:fields][field]) && (
13
+ (value && field_includes?(field_options, value)) ||
14
+ (!value && field_included_is_not_empty?(field_options))
15
+ )
16
+ end
17
+
18
+ def excluded?(field, value = nil)
19
+ (field_options = method_scope.context[:fields][field]) && (
20
+ (value && field_excludes?(field_options, value)) ||
21
+ (!value && field_excluded_is_not_empty?(field_options))
22
+ )
23
+ end
24
+
25
+ private
26
+
27
+ def field_includes?(field_options, value)
28
+ field_options[:included] && field_options[:included].include?(value)
29
+ end
30
+
31
+ def field_included_is_not_empty?(field_options)
32
+ field_options[:included] && !field_options[:included].empty?
33
+ end
34
+
35
+ def field_excludes?(field_options, value)
36
+ field_options[:excluded] && field_options[:excluded].include?(value)
37
+ end
38
+
39
+ def field_excluded_is_not_empty?(field_options)
40
+ field_options[:excluded] && !field_options[:excluded].empty?
41
+ end
42
+
43
+
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,41 @@
1
+ module CloudSesame
2
+ module Query
3
+ module DSL
4
+ module Literal
5
+
6
+ # CLAUSE: LITERAL
7
+ # =========================================
8
+ def literal(field, value, options = {})
9
+ node = AST::Literal.new(field, value, options)
10
+ method_scope.children << node
11
+ node
12
+ end
13
+
14
+ def date(date_object)
15
+ strip date_object.strftime('%FT%TZ')
16
+ end
17
+
18
+ def strip(string)
19
+ string.gsub(/ /, '')
20
+ end
21
+
22
+ private
23
+
24
+ def fields
25
+ method_context[:fields]
26
+ end
27
+
28
+ def method_missing(field, *values, &block)
29
+ if fields && (options = fields[field])
30
+ method_scope.children.field = field
31
+ method_scope.children.insert_children(values)
32
+ method_scope.children
33
+ else
34
+ super
35
+ end
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,19 @@
1
+ module CloudSesame
2
+ module Query
3
+ module DSL
4
+ module Or
5
+
6
+ # CLAUSE: OR
7
+ # =========================================
8
+ def or(&block)
9
+ method_scope.children << AST::Or.new(method_context, &block)
10
+ method_return
11
+ end
12
+
13
+ alias_method :any, :or
14
+ alias_method :or!, :or
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,41 @@
1
+ module CloudSesame
2
+ module Query
3
+ module DSL
4
+ module Range
5
+
6
+ def >(value)
7
+ return self
8
+ end
9
+
10
+ def >=(value)
11
+ return self
12
+ end
13
+
14
+ def <(value)
15
+ return self
16
+ end
17
+
18
+ def <=(value)
19
+ return self
20
+ end
21
+
22
+ def gt(value)
23
+ return self
24
+ end
25
+
26
+ def gte(value)
27
+ return self
28
+ end
29
+
30
+ def lt(value)
31
+ return self
32
+ end
33
+
34
+ def lte(value)
35
+ return self
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,24 @@
1
+ module CloudSesame
2
+ module Query
3
+ module DSL
4
+ module Scope
5
+
6
+ def scopes
7
+ method_context[:scopes]
8
+ end
9
+
10
+ private
11
+
12
+ def method_missing(name, *args, &block)
13
+ if scopes && (callback = scopes[name])
14
+ method_scope.instance_exec *args, &callback
15
+ method_return
16
+ else
17
+ super
18
+ end
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,8 @@
1
+ module CloudSesame
2
+ module Query
3
+ module Error
4
+ class MissingOperatorSymbol < Exception
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module CloudSesame
2
+ module Query
3
+ module Error
4
+ class MissingQuery < Exception
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ module CloudSesame
2
+ module Query
3
+ module Node
4
+ class Abstract
5
+ attr_reader :context
6
+
7
+ def initialize(context)
8
+ @context = context
9
+ end
10
+
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module CloudSesame
2
+ module Query
3
+ module Node
4
+ class Facet < Abstract
5
+ def facet
6
+ @facet ||= context.table
7
+ end
8
+ def compile
9
+ { facet: JSON.dump(facet) } unless facet.empty?
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module CloudSesame
2
+ module Query
3
+ module Node
4
+ class FilterQuery < Abstract
5
+
6
+ def compile
7
+ { filter_query: root.compile }
8
+ end
9
+
10
+ def root
11
+ @root ||= CloudSesame::Query::AST::Root.new context
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ module CloudSesame
2
+ module Query
3
+ module Node
4
+ class Page < Abstract
5
+
6
+ attr_writer :page, :size
7
+
8
+ def page
9
+ @page ||= (context[:page] || 1)
10
+ end
11
+
12
+ def size
13
+ @size ||= (context[:size] || 10)
14
+ end
15
+
16
+ def start
17
+ (page - 1) * size
18
+ end
19
+
20
+ def compile
21
+ { start: start, size: size }
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ module CloudSesame
2
+ module Query
3
+ module Node
4
+ class Query < Abstract
5
+
6
+ def terms=(array)
7
+ @terms = array
8
+ end
9
+
10
+ def terms
11
+ @terms ||= (q = context[:query]) ? q.split(' ') : []
12
+ end
13
+
14
+ def query
15
+ terms.map!(&:strip).join(' ')
16
+ end
17
+
18
+ def query=(string = '')
19
+ @terms = string.split(' ')
20
+ end
21
+
22
+ def compile
23
+ { query: query }
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,37 @@
1
+ module CloudSesame
2
+ module Query
3
+ module Node
4
+ class QueryOptions < Abstract
5
+
6
+ def fields
7
+ @fields ||= default_fields
8
+ end
9
+
10
+ def compile
11
+ {
12
+ query_options: JSON.dump({
13
+ fields: compile_fields
14
+ })
15
+ } unless fields.empty?
16
+ end
17
+
18
+ private
19
+
20
+ def compile_fields
21
+ fields.map(&:compile)
22
+ end
23
+
24
+ def default_fields
25
+ if context[:fields]
26
+ context[:fields].map do |field, options|
27
+ QueryOptionsField.new field, options[:weight]
28
+ end
29
+ else
30
+ []
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,20 @@
1
+ module CloudSesame
2
+ module Query
3
+ module Node
4
+ class QueryOptionsField
5
+
6
+ attr_reader :field, :weight
7
+
8
+ def initialize(field, weight = nil)
9
+ @field = field
10
+ @weight = weight
11
+ end
12
+
13
+ def compile
14
+ "#{ field }#{ '^' + weight.to_s if weight }"
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ module CloudSesame
2
+ module Query
3
+ module Node
4
+ class QueryParser < Abstract
5
+
6
+ TYPES = %w(simple structured lucene dismax)
7
+
8
+ attr_writer :type
9
+
10
+ TYPES.each do |type|
11
+ define_method type do
12
+ self.type = type; self
13
+ end
14
+ end
15
+
16
+ def type
17
+ @type ||= (context[:query_parser] || :simple).to_s
18
+ end
19
+
20
+ def compile
21
+ { query_parser: type.to_s }
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end