elasticsearch-resources 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +12 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +201 -0
  7. data/README.md +276 -0
  8. data/Rakefile +6 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/elasticsearch-resources.gemspec +32 -0
  12. data/lib/elasticsearch/resources.rb +35 -0
  13. data/lib/elasticsearch/resources/cluster.rb +59 -0
  14. data/lib/elasticsearch/resources/clusterable.rb +34 -0
  15. data/lib/elasticsearch/resources/configurable.rb +52 -0
  16. data/lib/elasticsearch/resources/configuration.rb +11 -0
  17. data/lib/elasticsearch/resources/configuration/cluster.rb +67 -0
  18. data/lib/elasticsearch/resources/configuration/index.rb +45 -0
  19. data/lib/elasticsearch/resources/configuration/settings.rb +25 -0
  20. data/lib/elasticsearch/resources/configuration/type.rb +29 -0
  21. data/lib/elasticsearch/resources/describable.rb +49 -0
  22. data/lib/elasticsearch/resources/document.rb +73 -0
  23. data/lib/elasticsearch/resources/document_factory.rb +49 -0
  24. data/lib/elasticsearch/resources/identifiable.rb +34 -0
  25. data/lib/elasticsearch/resources/index.rb +108 -0
  26. data/lib/elasticsearch/resources/indexable.rb +34 -0
  27. data/lib/elasticsearch/resources/locales/en.yml +29 -0
  28. data/lib/elasticsearch/resources/nameable.rb +28 -0
  29. data/lib/elasticsearch/resources/queryable.rb +36 -0
  30. data/lib/elasticsearch/resources/resource.rb +39 -0
  31. data/lib/elasticsearch/resources/response_factory.rb +49 -0
  32. data/lib/elasticsearch/resources/type.rb +99 -0
  33. data/lib/elasticsearch/resources/typeable.rb +34 -0
  34. data/lib/elasticsearch/resources/version.rb +5 -0
  35. metadata +188 -0
@@ -0,0 +1,73 @@
1
+ module Elasticsearch
2
+ module Resources
3
+ class Document
4
+ include Resource
5
+ include Queryable
6
+ include Typeable
7
+ include Identifiable
8
+ include Describable
9
+
10
+ def initialize(id:, attributes: {}, type:)
11
+ self.type = type
12
+ self.id = id
13
+ self.attributes = attributes
14
+ end
15
+
16
+ def cluster
17
+ index.cluster
18
+ end
19
+
20
+ def index
21
+ type.index
22
+ end
23
+
24
+ def client
25
+ type.client
26
+ end
27
+
28
+ def query(action, options = {})
29
+ params = {
30
+ index: index.name,
31
+ type: type.name,
32
+ id: id
33
+ }.merge(options)
34
+
35
+ super(action, **params)
36
+ end
37
+
38
+ def create(options = {})
39
+ params = {
40
+ body: attributes
41
+ }.merge(options)
42
+
43
+ query(:create, params)
44
+ end
45
+
46
+ def update(options = {})
47
+ params = {
48
+ body: attributes
49
+ }.merge(options)
50
+
51
+ query(:update, params)
52
+ end
53
+
54
+ [:exists?, :delete, :get].each do |action|
55
+ define_method action do |options = {}|
56
+ query(action, options)
57
+ end
58
+ end
59
+
60
+ def find_cluster
61
+ self.cluster
62
+ end
63
+
64
+ def find_index(index: nil)
65
+ self.index
66
+ end
67
+
68
+ def find_type(index: nil, type: nil)
69
+ self.type
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,49 @@
1
+ module Elasticsearch
2
+ module Resources
3
+ class DocumentFactory
4
+ attr_reader :content, :resources
5
+
6
+ def initialize(content:, resources: {})
7
+ @content = content
8
+ @resources = resources
9
+ end
10
+
11
+ def build
12
+ type = get_type
13
+ type.document_class.new(
14
+ type: type,
15
+ id: content['_id'],
16
+ attributes: content['_source']
17
+ )
18
+ end
19
+
20
+ def get_type
21
+ resources[:type] || build_type
22
+ end
23
+
24
+ def build_type
25
+ Elasticsearch::Resources::Type.new(index: get_index) do |type|
26
+ type.name = content['_type']
27
+ end
28
+ end
29
+
30
+ def get_index
31
+ resources[:index] || build_index
32
+ end
33
+
34
+ def build_index
35
+ Elasticsearch::Resources::Index.new(cluster: get_cluster) do |index|
36
+ index.name = content['_index']
37
+ end
38
+ end
39
+
40
+ def get_cluster
41
+ resources[:cluster] || build_cluster
42
+ end
43
+
44
+ def build_cluster
45
+ Elasticsearch::Resources::Cluster.new
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,34 @@
1
+ module Elasticsearch
2
+ module Resources
3
+ module Identifiable
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ base.include(InstanceMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ end
11
+
12
+ module InstanceMethods
13
+ attr_reader :id
14
+
15
+ protected
16
+
17
+ def id=(id)
18
+ raise NullIdError.new if id.nil?
19
+ @id = id.to_s
20
+ end
21
+ end
22
+
23
+ class NullIdError < ArgumentError
24
+ def initialize
25
+ super(message)
26
+ end
27
+
28
+ def message
29
+ I18n.t('elasticsearch.resources.identifiable.null_id_error.message')
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,108 @@
1
+ module Elasticsearch
2
+ module Resources
3
+ class Index
4
+ include Resource
5
+ include Queryable
6
+ include Configurable
7
+ include Clusterable
8
+ include Nameable
9
+
10
+ define_configuration \
11
+ class_name: Configuration::Index,
12
+ default: -> { cluster.settings.index(self.class.configuration.id) }
13
+
14
+ def initialize(cluster:, &block)
15
+ self.cluster = cluster
16
+ configure(id: self.class.configuration.id, cluster: cluster.settings, &block)
17
+ end
18
+
19
+ def setup!
20
+ unless exists?
21
+ create
22
+ super
23
+ end
24
+ end
25
+
26
+ def teardown!
27
+ if exists?
28
+ delete
29
+ super
30
+ end
31
+ end
32
+
33
+ def client
34
+ cluster.client
35
+ end
36
+
37
+ def name
38
+ settings.name || super
39
+ end
40
+
41
+ def types
42
+ []
43
+ end
44
+
45
+ def query_index(action, options = {})
46
+ params = {
47
+ index: name
48
+ }.merge(options)
49
+
50
+ client.indices.send(action, **params)
51
+ end
52
+
53
+ def query(action, options = {})
54
+ params = {
55
+ index: name
56
+ }.merge(options)
57
+
58
+ super(action, **params)
59
+ end
60
+
61
+ def exists?
62
+ query_index(:exists?)
63
+ end
64
+
65
+ def create
66
+ query_index(:create)
67
+ end
68
+
69
+ def put_mapping(options = {})
70
+ query_index(:put_mapping, options)
71
+ end
72
+
73
+ def delete
74
+ query_index(:delete)
75
+ end
76
+
77
+ def search(body, options = {})
78
+ params = {
79
+ body: body
80
+ }.merge(options)
81
+
82
+ query(:search, params)
83
+ end
84
+
85
+ def count(body, options = {})
86
+ params = {
87
+ body: body
88
+ }.merge(options)
89
+
90
+ query(:count, params)
91
+ end
92
+
93
+ def find_cluster
94
+ self.cluster
95
+ end
96
+
97
+ def find_index(index: nil)
98
+ matches_name?(index) ? self : nil
99
+ end
100
+
101
+ def find_type(index: nil, type:)
102
+ types.find do |t|
103
+ t.find_type(type: type)
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,34 @@
1
+ module Elasticsearch
2
+ module Resources
3
+ module Indexable
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ base.include(InstanceMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ end
11
+
12
+ module InstanceMethods
13
+ attr_reader :index
14
+
15
+ protected
16
+
17
+ def index=(index)
18
+ raise NullIndexError.new if index.nil?
19
+ @index = index
20
+ end
21
+ end
22
+
23
+ class NullIndexError < ArgumentError
24
+ def initialize
25
+ super(message)
26
+ end
27
+
28
+ def message
29
+ I18n.t('elasticsearch.resources.indexable.null_index_error.message')
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,29 @@
1
+ en:
2
+ elasticsearch:
3
+ resources:
4
+ configuration:
5
+ cluster:
6
+ null_name_error:
7
+ message: 'Cluster cannot be assigned a nil name!'
8
+ null_host_error:
9
+ message: 'Cluster cannot be assigned a nil host!'
10
+ index:
11
+ null_name_error:
12
+ message: 'Index cannot be assigned a nil name!'
13
+ type:
14
+ null_name_error:
15
+ message: 'Type cannot be assigned a nil name!'
16
+ identifiable:
17
+ null_id_error:
18
+ message: "ID cannot be assigned a nil value!"
19
+ indexable:
20
+ null_index_error:
21
+ message: "Index cannot be nil!"
22
+ queryable:
23
+ client:
24
+ not_implemented_error: 'This resource does not implement #client.'
25
+ null_client_error:
26
+ message: "No client set. Cannot query!"
27
+ typeable:
28
+ null_type_error:
29
+ message: "Type cannot be nil!"
@@ -0,0 +1,28 @@
1
+ module Elasticsearch
2
+ module Resources
3
+ module Nameable
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ base.include(InstanceMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ attr_reader :default_name
11
+
12
+ def define_default_name(name)
13
+ @default_name = name&.to_s
14
+ end
15
+ end
16
+
17
+ module InstanceMethods
18
+ def name
19
+ self.class.default_name
20
+ end
21
+
22
+ def matches_name?(name)
23
+ name.to_s == self.name.to_s
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,36 @@
1
+ module Elasticsearch
2
+ module Resources
3
+ module Queryable
4
+ def self.included(base)
5
+ base.include(Resource)
6
+ base.extend(ClassMethods)
7
+ base.include(InstanceMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+ end
12
+
13
+ module InstanceMethods
14
+ def client
15
+ raise NotImplementedError.new(I18n.t('elasticsearch.resources.queryable.client.not_implemented_error'))
16
+ end
17
+
18
+ def query(action, params = {})
19
+ raise NullClientError.new if client.nil?
20
+ response = client.send(action, **params)
21
+ ResponseFactory.new(resource: self, action: action, response: response).build
22
+ end
23
+ end
24
+
25
+ class NullClientError < ArgumentError
26
+ def initialize
27
+ super(message)
28
+ end
29
+
30
+ def message
31
+ I18n.t('elasticsearch.resources.queryable.null_client_error.message')
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,39 @@
1
+ module Elasticsearch
2
+ module Resources
3
+ module Resource
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ base.include(InstanceMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ end
11
+
12
+ module InstanceMethods
13
+ def find_cluster
14
+ nil
15
+ end
16
+
17
+ def find_index(index: nil)
18
+ nil
19
+ end
20
+
21
+ def find_type(index: nil, type: nil)
22
+ nil
23
+ end
24
+
25
+ def setup!
26
+ nil
27
+ end
28
+
29
+ def populate!
30
+ nil
31
+ end
32
+
33
+ def teardown!
34
+ nil
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,49 @@
1
+ module Elasticsearch
2
+ module Resources
3
+ class ResponseFactory
4
+ attr_reader :resource, :action, :response
5
+
6
+ def initialize(resource:, action:, response:)
7
+ @resource = resource
8
+ @action = action
9
+ @response = response
10
+ end
11
+
12
+ def build
13
+ case action
14
+ when :get
15
+ build_get
16
+ when :search
17
+ build_search
18
+ else
19
+ response
20
+ end
21
+ end
22
+
23
+ def build_get
24
+ DocumentFactory.new(
25
+ content: response,
26
+ resources: resources_for(response)
27
+ ).build
28
+ end
29
+
30
+ def build_search
31
+ raw_documents = response['hits']['hits']
32
+ raw_documents.collect do |raw_document|
33
+ DocumentFactory.new(
34
+ content: raw_document,
35
+ resources: resources_for(raw_document)
36
+ ).build
37
+ end
38
+ end
39
+
40
+ def resources_for(content)
41
+ {
42
+ cluster: resource.find_cluster,
43
+ index: resource.find_index(index: content['_index']),
44
+ type: resource.find_type(index: content['_index'], type: content['_type'])
45
+ }
46
+ end
47
+ end
48
+ end
49
+ end