solrbee 0.3.0 → 0.4.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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -1
  3. data/Makefile +1 -6
  4. data/README.md +1 -11
  5. data/config/api.yml +22 -45
  6. data/lib/rom/solr.rb +40 -11
  7. data/lib/{solrbee → rom/solr}/array.rb +0 -0
  8. data/lib/rom/solr/commands.rb +17 -0
  9. data/lib/rom/solr/commands/create_documents.rb +15 -0
  10. data/lib/rom/solr/commands/delete_documents.rb +15 -0
  11. data/lib/rom/solr/commands/delete_documents_by_query.rb +15 -0
  12. data/lib/rom/solr/commands/update_documents.rb +15 -0
  13. data/lib/rom/solr/dataset.rb +33 -54
  14. data/lib/rom/solr/document_repo.rb +33 -0
  15. data/lib/rom/solr/documents_dataset.rb +12 -0
  16. data/lib/rom/solr/gateway.rb +2 -13
  17. data/lib/rom/solr/relation.rb +22 -8
  18. data/lib/rom/solr/relations/documents_relation.rb +160 -0
  19. data/lib/rom/solr/relations/schema_info_relation.rb +100 -0
  20. data/lib/rom/solr/repository.rb +9 -0
  21. data/lib/rom/solr/request_handler.rb +52 -0
  22. data/lib/rom/solr/{response.rb → response_handler.rb} +2 -2
  23. data/lib/rom/solr/schema.rb +1 -3
  24. data/lib/rom/solr/schema_info_dataset.rb +11 -0
  25. data/lib/rom/solr/schema_info_repo.rb +45 -0
  26. data/lib/rom/solr/select_cursor.rb +56 -0
  27. data/lib/solrbee.rb +12 -23
  28. data/lib/solrbee/version.rb +1 -1
  29. data/solrbee.gemspec +0 -1
  30. data/test.sh +14 -0
  31. metadata +19 -24
  32. data/lib/rom/solr/datasets/select_dataset.rb +0 -53
  33. data/lib/rom/solr/paginated_dataset.rb +0 -62
  34. data/lib/rom/solr/relations/schema_relation.rb +0 -75
  35. data/lib/rom/solr/relations/select_relation.rb +0 -43
  36. data/lib/rom/solr/request.rb +0 -24
  37. data/lib/rom/solr/schemaless.rb +0 -24
@@ -1,23 +1,37 @@
1
1
  module ROM
2
2
  module Solr
3
3
  class Relation < ROM::HTTP::Relation
4
- extend Schemaless
5
4
 
6
- adapter :solr
5
+ adapter :solr
6
+ auto_struct false
7
+ auto_map false
7
8
 
8
- forward :add_param_values, :default_params, :with_enum_on
9
+ forward :with_response_key
9
10
 
10
- def fetch(key, default = nil)
11
- return self if key.nil?
12
- dataset.response.fetch(key, default)
11
+ option :output_schema, default: ->{ NOOP_OUTPUT_SCHEMA }
12
+
13
+ def wt(format)
14
+ add_params(wt: Types::Coercible::String[format])
15
+ end
16
+ alias_method :format, :wt
17
+
18
+ def log_params_list(log_params)
19
+ lplist = log_params.nil? ? nil : Array.wrap(log_params).join(',')
20
+
21
+ add_params(logParamsList: lplist)
13
22
  end
23
+ alias_method :log_params, :log_params_list
14
24
 
15
25
  def count
16
26
  to_enum.count
17
27
  end
18
28
 
19
- def all
20
- self
29
+ def response
30
+ dataset.response
31
+ end
32
+
33
+ def params
34
+ dataset.params.dup
21
35
  end
22
36
 
23
37
  end
@@ -0,0 +1,160 @@
1
+ require 'rom/solr/select_cursor'
2
+
3
+ module ROM
4
+ module Solr
5
+ class DocumentsRelation < Relation
6
+
7
+ schema(:documents) { }
8
+
9
+ # @override
10
+ def each(&block)
11
+ return to_enum unless block_given?
12
+
13
+ SelectCursor.new(dataset).each(&block)
14
+ end
15
+
16
+ # @override FIXME: Get from Solr schema unique key
17
+ def primary_key
18
+ :id
19
+ end
20
+
21
+ def by_unique_key(id)
22
+ q('%s:%s' % [ primary_key, id ])
23
+ end
24
+
25
+ def all
26
+ q('*:*')
27
+ end
28
+
29
+ # @override
30
+ def count
31
+ num_found_exact ? num_found : super
32
+ end
33
+
34
+ def num_found
35
+ response.dig(:response, :numFound)
36
+ end
37
+
38
+ def num_found_exact
39
+ response.dig(:response, :numFoundExact)
40
+ end
41
+
42
+ def insert(docs)
43
+ data = Array.wrap(docs).map do |doc|
44
+ doc.transform_keys!(&:to_sym)
45
+ doc[:id] ||= UUID[]
46
+ end
47
+
48
+ update(data)
49
+ end
50
+
51
+ def update(docs)
52
+ with_options(
53
+ base_path: 'update/json/docs',
54
+ content_type: 'application/json',
55
+ request_data: JSON.dump(docs)
56
+ )
57
+ end
58
+
59
+ def delete(docs)
60
+ ids = Array.wrap(docs).map { |doc| doc.transform_keys(&:to_sym) }.map(&:id)
61
+
62
+ with_options(
63
+ base_path: 'update',
64
+ content_type: 'application/json',
65
+ request_data: JSON.dump(delete: ids)
66
+ )
67
+ end
68
+
69
+ #
70
+ # Params
71
+ #
72
+ def q(query)
73
+ add_params(q: Types::String[query])
74
+ end
75
+ alias_method :query, :q
76
+
77
+ def fq(*filter)
78
+ add_params(fq: filter)
79
+ end
80
+ alias_method :filter, :fq
81
+
82
+ def fl(*fields)
83
+ add_params(fl: fields.join(','))
84
+ end
85
+ alias_method :fields, :fl
86
+
87
+ def cache(enabled = true)
88
+ add_params(cache: Types::Bool[enabled])
89
+ end
90
+
91
+ def segment_terminate_early(enabled = true)
92
+ add_params(segmentTerminateEarly: Types::Bool[enabled])
93
+ end
94
+
95
+ def time_allowed(millis)
96
+ add_params(timeAllowed: Types::Coercible::Integer[millis])
97
+ end
98
+
99
+ def explain_other(query)
100
+ add_params(explainOther: Types::String[query])
101
+ end
102
+
103
+ def omit_header(omit = true)
104
+ add_params(omitHeader: Types::Bool[omit])
105
+ end
106
+
107
+ def start(offset)
108
+ add_params(start: Types::Coercible::Integer[offset])
109
+ end
110
+
111
+ def sort(*criteria)
112
+ add_params(sort: criteria.join(','))
113
+ end
114
+
115
+ def rows(num)
116
+ add_params(rows: Types::Coercible::Integer[num])
117
+ end
118
+ alias_method :limit, :rows
119
+
120
+ def def_type(value)
121
+ add_params(defType: Types::Coercible::String[value])
122
+ end
123
+
124
+ def debug(setting)
125
+ type = Types::Coercible::String
126
+ .enum('query', 'timing', 'results', 'all', 'true')
127
+
128
+ add_params(debug: type[setting])
129
+ end
130
+
131
+ def echo_params(setting)
132
+ type = Types::Coercible::String.enum('explicit', 'all', 'none')
133
+ add_params(echoParams: type[setting])
134
+ end
135
+
136
+ def min_exact_count(num)
137
+ add_params(minExactCount: Types::Coercible::Integer[num])
138
+ end
139
+
140
+ def commit(value = true)
141
+ add_params(commit: Types::Bool[value])
142
+ end
143
+
144
+ def commit_within(millis)
145
+ return self if millis.nil?
146
+
147
+ add_params(commitWithin: Types::Coercible::Integer[millis])
148
+ end
149
+
150
+ def overwrite(value = true)
151
+ add_params(overwrite: Types::Bool[value])
152
+ end
153
+
154
+ def expunge_deletes(value = true)
155
+ add_params(expungeDeletes: Types::Bool[value])
156
+ end
157
+
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,100 @@
1
+ module ROM
2
+ module Solr
3
+ class SchemaInfoRelation < Relation
4
+
5
+ schema(:schema_info) do
6
+ # no-op
7
+ end
8
+
9
+ def show_defaults(show = true)
10
+ add_params(showDefaults: Types::Bool[show])
11
+ end
12
+
13
+ def include_dynamic(enabled = true)
14
+ add_params(includeDynamic: Types::Bool[enabled])
15
+ end
16
+
17
+ def info
18
+ with_response_key(:schema)
19
+ end
20
+
21
+ def copy_fields
22
+ with_options(
23
+ path: :copyfields,
24
+ response_key: :copyFields
25
+ )
26
+ end
27
+
28
+ def dynamic_fields
29
+ with_options(
30
+ path: :dynamicfields,
31
+ response_key: :dynamicFields
32
+ )
33
+ end
34
+
35
+ def dynamic_field(name)
36
+ with_options(
37
+ path: "dynamicfields/#{name}",
38
+ response_key: :dynamicField
39
+ )
40
+ end
41
+
42
+ def similarity
43
+ with_options(
44
+ path: :similarity,
45
+ response_key: :similarity
46
+ )
47
+ end
48
+
49
+ def unique_key
50
+ with_options(
51
+ path: :uniquekey,
52
+ response_key: :uniqueKey
53
+ )
54
+ end
55
+
56
+ def version
57
+ with_options(
58
+ path: :version,
59
+ response_key: :version
60
+ )
61
+ end
62
+
63
+ def schema_name
64
+ with_options(
65
+ path: :name,
66
+ response_key: :name
67
+ )
68
+ end
69
+
70
+ def fields
71
+ with_options(
72
+ path: :fields,
73
+ response_key: :fields
74
+ )
75
+ end
76
+
77
+ def field(name)
78
+ with_options(
79
+ path: "fields/#{name}",
80
+ response_key: :field
81
+ )
82
+ end
83
+
84
+ def field_types
85
+ with_options(
86
+ path: :fieldtypes,
87
+ response_key: :fieldTypes
88
+ )
89
+ end
90
+
91
+ def field_type(name)
92
+ with_options(
93
+ path: "fieldtypes/#{name}",
94
+ response_key: :fieldType
95
+ )
96
+ end
97
+
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,9 @@
1
+ module ROM
2
+ module Solr
3
+ class Repository < ROM::Repository
4
+
5
+ auto_struct false
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,52 @@
1
+ module ROM
2
+ module Solr
3
+ class RequestHandler
4
+
5
+ def self.call(dataset)
6
+ new(dataset).execute
7
+ end
8
+
9
+ attr_reader :dataset
10
+
11
+ def initialize(dataset)
12
+ @dataset = dataset
13
+ end
14
+
15
+ def execute
16
+ Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme.eql?('https')) do |http|
17
+ http.request(request)
18
+ end
19
+ end
20
+
21
+ def request
22
+ request_class.new(uri.request_uri, headers).tap do |req|
23
+ if dataset.has_request_data?
24
+ req.body = dataset.request_data
25
+ req.content_type = dataset.content_type
26
+ end
27
+ end
28
+ end
29
+
30
+ def headers
31
+ dataset.headers.transform_keys(&:to_s)
32
+ end
33
+
34
+ def uri
35
+ @uri ||= URI(dataset.uri).tap do |u|
36
+ if dataset.has_params?
37
+ u.query ||= URI.encode_www_form(dataset.params)
38
+ end
39
+ end
40
+ end
41
+
42
+ def request_class
43
+ if dataset.has_request_data?
44
+ Net::HTTP::Post
45
+ else
46
+ Net::HTTP::Get
47
+ end
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -1,10 +1,10 @@
1
1
  module ROM
2
2
  module Solr
3
- class Response
3
+ class ResponseHandler
4
4
 
5
5
  # @return [Hash] Parsed JSON object from Solr response body
6
6
  def self.call(response, dataset)
7
- JSON.parse(response.body)
7
+ JSON.parse(response.body, symbolize_names: true)
8
8
  end
9
9
 
10
10
  end
@@ -1,8 +1,6 @@
1
1
  module ROM
2
2
  module Solr
3
- class Schema < ROM::HTTP::Schema
4
-
5
-
3
+ class Schema < ROM::Schema
6
4
 
7
5
  end
8
6
  end
@@ -0,0 +1,11 @@
1
+ module ROM
2
+ module Solr
3
+ class SchemaInfoDataset < Dataset
4
+
5
+ configure do |config|
6
+ config.default_base_path = 'schema'
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,45 @@
1
+ module ROM
2
+ module Solr
3
+ class SchemaInfoRepo < Repository[:schema_info]
4
+
5
+ auto_struct false
6
+
7
+ %i[ schema_name similarity unique_key version ].each do |name|
8
+ define_method name, ->{ schema_info.send(name).one! }
9
+ end
10
+
11
+ def info
12
+ schema_info.info.one!
13
+ end
14
+
15
+ def fields(dynamic: true, defaults: true)
16
+ schema_info.fields.show_defaults(defaults).include_dynamic(dynamic)
17
+ end
18
+
19
+ def field(name, defaults: true)
20
+ schema_info.field(name).show_defaults(defaults).one
21
+ end
22
+
23
+ def field_types(defaults: true)
24
+ schema_info.field_types.show_defaults(defaults)
25
+ end
26
+
27
+ def field_type(name, defaults: true)
28
+ schema_info.field_type(name).show_defaults(defaults).one
29
+ end
30
+
31
+ def dynamic_fields
32
+ schema_info.dynamic_fields
33
+ end
34
+
35
+ def dynamic_field(name, defaults: true)
36
+ schema_info.dynamic_field(name).show_defaults(defaults).one
37
+ end
38
+
39
+ def copy_fields
40
+ schema_info.copy_fields
41
+ end
42
+
43
+ end
44
+ end
45
+ end