elasticsearch-resources 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1c756ac85260a4494ea636097f1822781c5f77ae
4
- data.tar.gz: 524f47bf9a8e792ff20ae9bdec1b2d815731d279
3
+ metadata.gz: 3786ed62f711a0d0d59098488e1e5ec2246af673
4
+ data.tar.gz: 954ed10b4e4d57570479061093996b59292984ac
5
5
  SHA512:
6
- metadata.gz: 76593313dc578db22da8674d09a8ab42553fc0884ecfe6240cba92bc849f008f2581fe235b5288bb283bf242afcb49e1584e37080d57406329784256897e735d
7
- data.tar.gz: eb77c111636f06b98c0fc55c2325c220986898997ed6655b7fb60c39e96919f67484c32f396615ee564138e9e85e46f9aeb25c9d4ce7c7ab5a4176f0170b9db6
6
+ metadata.gz: a921d3ed57b997a9c6c579615a8f03915aa922fbe26e2ab803ac371588a14e7b08b19c36e36e59ef596cfbd74c211daa589b0ce320e8447ddf894c0994d3b796
7
+ data.tar.gz: 02dfd1428fef704b47f4bd06d97904467e43823f64cad46e9dfdfece204dc6728f2866a805208b6fd5ab032ad878d03a59823e7d64a7420009d93af41d83cd83
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  Elasticsearch::Resources
2
2
  ========================
3
3
 
4
- [![Build Status](https://travis-ci.org/delner/elasticsearch-resources.svg?branch=master)](https://travis-ci.org/delner/elasticsearch-resources) ![Gem Version](https://img.shields.io/gem/v/elasticsearch-resources.svg?maxAge=2592000)
4
+ [![Build Status](https://travis-ci.org/delner/elasticsearch-resources.svg?branch=master)](https://travis-ci.org/delner/elasticsearch-resources) [![Gem Version](https://badge.fury.io/rb/elasticsearch-resources.svg)](https://badge.fury.io/rb/elasticsearch-resources)
5
5
  ###### *For Ruby 2.3+*
6
6
 
7
7
  `Elasticsearch::Resources` is a wrapper for the [Elasticsearch gem](https://github.com/elastic/elasticsearch-ruby) that provides a strongly typed interface for accessing your indexes, types, and documents.
@@ -11,7 +11,7 @@ Elasticsearch::Resources
11
11
  documents = film.search({ query: { match: { title: 'Tron' } } })
12
12
  documents # [#<Movie @title='Tron'>, #<Documentary @title='Making Tron'>]
13
13
 
14
- # Get a specific document: e.g. get { index: 'film', type: 'movie', id: 'tron' }
14
+ # Get a specific document: e.g. get { index: 'film', type: 'movies', id: 'tron' }
15
15
  document = movies.get(id: 'tron') # #<Movie @title='Tron'>
16
16
  document.id # => 'tron'
17
17
  document.attributes # => { 'title' => 'Tron' }
@@ -44,7 +44,67 @@ gem 'elasticsearch/resources'
44
44
 
45
45
  And then `bundle install` to install the gem and its dependencies.
46
46
 
47
- ### Usage
47
+ ### Common use cases
48
+
49
+ ##### Search all indexes in a cluster
50
+
51
+ ```ruby
52
+ # Connects to default of '127.0.0.1:9200'
53
+ cluster = Elasticsearch::Resources::Cluster.new
54
+
55
+ # Hash can be any valid Elasticsearch query
56
+ documents = cluster.search({ query: { match: { title: 'Tron' } } })
57
+ ```
58
+
59
+ ##### Search all types in an index
60
+
61
+ ```ruby
62
+ # Connects to default of '127.0.0.1:9200'
63
+ cluster = Elasticsearch::Resources::Cluster.new
64
+ documents = cluster.search({ index: 'film', query: { match: { title: 'Tron' } } })
65
+
66
+ # OR using a defined index
67
+ index = Elasticsearch::Resources::Index.new(cluster: cluster) do |index|
68
+ index.name = 'film'
69
+ end
70
+
71
+ documents = index.search({ query: { match: { title: 'Tron' } } })
72
+ ```
73
+
74
+ ##### Search specific type in an index
75
+
76
+ ```ruby
77
+ # Connects to default of '127.0.0.1:9200'
78
+ cluster = Elasticsearch::Resources::Cluster.new
79
+ documents = cluster.search({ index: 'film', type: 'movies', query: { match: { title: 'Tron' } } })
80
+
81
+ # OR using a defined index & type
82
+ index = Elasticsearch::Resources::Index.new(cluster: cluster) do |index|
83
+ index.name = 'film'
84
+ end
85
+
86
+ type = Elasticsearch::Resources::Type.new(index: index) do |type|
87
+ type.name = 'movies'
88
+ end
89
+
90
+ documents = type.search({ query: { match: { title: 'Tron' } } })
91
+ ```
92
+
93
+ ##### Creating a document
94
+
95
+ ```ruby
96
+ # type: Elasticsearch::Resources::Type object
97
+ document = Elasticsearch::Resources::Document.new(type: type, id: 'tron', attributes: { title: 'Tron' })
98
+ document.create
99
+ ```
100
+
101
+ ##### Fetch a document
102
+
103
+ ```ruby
104
+ document = type.get(id: 'tron')
105
+ ```
106
+
107
+ ### Resources
48
108
 
49
109
  There are four (4) basic resources which you can query with: `Cluster`, `Index`, `Type`, and `Document`.
50
110
 
@@ -62,6 +122,15 @@ cluster = Elasticsearch::Resources::Cluster.new do |cluster|
62
122
  end
63
123
  ```
64
124
 
125
+ ##### indexes
126
+
127
+ Returns a `Hash` of well known indexes. Empty if no well-known indexes are defined (regardless of whether they actually exist in Elasticsearch.) See "Defining well known resources" and `define_indexes`.
128
+
129
+ ```ruby
130
+ cluster.indexes
131
+ # => { film: #<Elasticsearch::Resources::Index> }
132
+ ```
133
+
65
134
  ##### client
66
135
 
67
136
  Returns the underlying `Elasticsearch::Transport::Client`.
@@ -97,12 +166,30 @@ cluster.count({ query: { match: { title: 'Tron' } } })
97
166
  An `Elasticsearch::Resources::Index` represents an ElasticSearch index that contains multiple types. Requires a `Cluster` (see "Cluster" above.)
98
167
 
99
168
  ```ruby
100
- # Create an index
169
+ # Create an index. You must set `name`.
101
170
  index = Elasticsearch::Resources::Index.new(cluster: cluster) do |index|
102
171
  index.name = 'film'
103
172
  end
104
173
  ```
105
174
 
175
+ ##### name
176
+
177
+ Returns the name of the index, as it exists in Elasticsearch.
178
+
179
+ ```ruby
180
+ index.name
181
+ # => 'film'
182
+ ```
183
+
184
+ ##### types
185
+
186
+ Returns a `Hash` of well known types. Empty if no well-known types are defined (regardless of whether they actually exist in Elasticsearch.) See "Defining well known resources" and `define_types`.
187
+
188
+ ```ruby
189
+ index.types
190
+ # => { movies: #<Elasticsearch::Resources::Type> }
191
+ ```
192
+
106
193
  ##### client
107
194
 
108
195
  Returns the underlying `Elasticsearch::Transport::Client`.
@@ -177,12 +264,21 @@ index.delete
177
264
  An `Elasticsearch::Resources::Type` represents an ElasticSearch type within an index. Requires a `Index` (see "Index" above.)
178
265
 
179
266
  ```ruby
180
- # Create a type
267
+ # Create a type. You must set `name`.
181
268
  type = Elasticsearch::Resources::Type.new(index: index) do |type|
182
- type.name = 'movies'
269
+ type.name = 'movie'
183
270
  end
184
271
  ```
185
272
 
273
+ ##### name
274
+
275
+ Returns the name of the type, as it exists in Elasticsearch.
276
+
277
+ ```ruby
278
+ type.name
279
+ # => 'movie'
280
+ ```
281
+
186
282
  ##### client
187
283
 
188
284
  Returns the underlying `Elasticsearch::Transport::Client`.
@@ -263,6 +359,164 @@ type.get(id: 'tron')
263
359
  # => #<Elasticsearch::Resources::Document>
264
360
  ```
265
361
 
362
+ #### Document
363
+
364
+ An `Elasticsearch::Resources::Document` represents an ElasticSearch document within an index. Requires an `id` and `Type` (see "Type" above.)
365
+
366
+ ```ruby
367
+ # Create a document
368
+ document = Elasticsearch::Resources::Document.new(
369
+ type: type, # (Required)
370
+ id: 'tron', # (Required)
371
+ attributes: { title: 'Tron' } # (Optional)
372
+ )
373
+ ```
374
+
375
+ ##### id
376
+
377
+ Returns a `String` of the Document ID.
378
+
379
+ ```ruby
380
+ document.id
381
+ # => 'tron'
382
+ ```
383
+
384
+ ##### attributes
385
+
386
+ Returns a `Hash` of the Document body.
387
+
388
+ ```ruby
389
+ document.attributes
390
+ # => { 'title' => 'Tron' }
391
+ ```
392
+
393
+ ##### client
394
+
395
+ Returns the underlying `Elasticsearch::Transport::Client`.
396
+
397
+ ```ruby
398
+ document.client
399
+ ```
400
+
401
+ ##### exists?
402
+
403
+ Accepts `(options = {})` and calls [`exists?`](http://www.rubydoc.info/gems/elasticsearch-api/Elasticsearch/API/Actions#exists-instance_method) on the `Elasticsearch::Transport::Client`. Automatically adds the `index`, `type` and `id` option to your queries.
404
+
405
+ Returns `true` or `false`.
406
+
407
+ ```ruby
408
+ document.exists?
409
+ # => true
410
+ ```
411
+
412
+ ##### create
413
+
414
+ Accepts `(options = {})` and calls [`create`](http://www.rubydoc.info/gems/elasticsearch-api/Elasticsearch/API/Actions#create-instance_method) on the `Elasticsearch::Transport::Client`. Automatically adds the `index`, `type`, `id`, and `body` option to your queries.
415
+
416
+ Throws error if document already exists.
417
+
418
+ ```ruby
419
+ document.create
420
+ ```
421
+
422
+ ##### update
423
+
424
+ Accepts `(options = {})` and calls [`update`](http://www.rubydoc.info/gems/elasticsearch-api/Elasticsearch/API/Actions#update-instance_method) on the `Elasticsearch::Transport::Client`. Automatically adds the `index`, `type`, `id`, and `body` option to your queries.
425
+
426
+ ```ruby
427
+ document.update
428
+ ```
429
+
430
+ ##### delete
431
+
432
+ Accepts `(options = {})` and calls [`delete`](http://www.rubydoc.info/gems/elasticsearch-api/Elasticsearch/API/Actions#delete-instance_method) on the `Elasticsearch::Transport::Client`. Automatically adds the `index`, `type` and `id` option to your queries.
433
+
434
+ Throws error if document doesn't exist.
435
+
436
+ ```ruby
437
+ document.delete
438
+ ```
439
+
440
+ ##### get
441
+
442
+ Accepts `(options = {})` and calls [`get`](http://www.rubydoc.info/gems/elasticsearch-api/Elasticsearch/API/Actions#get-instance_method) on the `Elasticsearch::Transport::Client`. Automatically adds the `index`, `type` and `id` option to your queries.
443
+
444
+ Returns `Elasticsearch::Resources::Document`.
445
+
446
+ ```ruby
447
+ document.get
448
+ # => #<Elasticsearch::Resources::Document>
449
+ ```
450
+
451
+ ### Defining well known resources
452
+
453
+ #### Cluster
454
+
455
+ ```ruby
456
+ class DavesAwesomeMovies < Elasticsearch::Resources::Cluster
457
+ # Set any default configuration settings here.
458
+ define_configuration defaults: -> { |cluster|
459
+ cluster.host = 'davesawesomemovies.com:9200'
460
+ }
461
+
462
+ # Provide a hash of keys to Index class names (either constants or strings)
463
+ define_indexes film: 'Film'
464
+ end
465
+
466
+ cluster = DavesAwesomeMovies.new
467
+ cluster.indexes[:film] # => #<Film>
468
+ ```
469
+
470
+ #### Index
471
+
472
+ ```ruby
473
+ class Film < Elasticsearch::Resources::Index
474
+ # Set any default configuration settings here.
475
+ # Probably should set a name.
476
+ define_configuration defaults: -> { |index|
477
+ index.name = 'film'
478
+ }
479
+
480
+ # Provide a hash of keys to Type class names (either constants or strings)
481
+ define_type movie: 'Movie'
482
+ end
483
+
484
+ film = Film.new
485
+ film.types[:movies] # => #<Movies>
486
+ ```
487
+
488
+ #### Type
489
+
490
+ ```ruby
491
+ class Movies < Elasticsearch::Resources::Type
492
+ # Set any default configuration settings here.
493
+ # Probably should set a name.
494
+ define_configuration defaults: -> { |type|
495
+ type.name = 'movie'
496
+ }
497
+
498
+ # Provide a Document class name (either constants or strings)
499
+ # If not called, type will return Elasticsearch::Resources::Document objects instead.
500
+ define_document 'Movie'
501
+ end
502
+
503
+ movies = Movies.new
504
+ movies.get(id: 'tron') # => #<Movie>
505
+ ```
506
+
507
+ #### Document
508
+
509
+ ```ruby
510
+ class Movie < Elasticsearch::Resources::Document
511
+ # Provide a list of well known attributes
512
+ define_attributes :title, :year
513
+ end
514
+
515
+ movie = Movie.new(id: 'tron', type: movies, attributes: { title: 'Tron', year: 1982 })
516
+ movie.title # => 'Tron'
517
+ movie.year # => 1982
518
+ ```
519
+
266
520
  ## Development
267
521
 
268
522
  Install dependencies using `bundle install`. Run tests using `bundle exec rspec`
data/TODO ADDED
@@ -0,0 +1 @@
1
+ [ ] Improve README
@@ -8,6 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Elasticsearch::Resources::VERSION
9
9
  spec.authors = ["David Elner"]
10
10
  spec.email = ["david@davidelner.com"]
11
+ spec.license = 'Apache-2.0'
11
12
 
12
13
  spec.summary = %q{Access well-known Elasticsearch indexes like resources.}
13
14
  spec.description = %q{Allows you to strongly-type Elasticsearch types and query them more easily.}
@@ -4,12 +4,11 @@ module Elasticsearch
4
4
  include Resource
5
5
  include Queryable
6
6
  include Configurable
7
- include Nameable
8
7
 
9
- define_configuration class_name: Configuration::Cluster
8
+ define_configuration class_name: 'Elasticsearch::Resources::Configuration::Cluster'
10
9
 
11
10
  def initialize(&block)
12
- configure(id: self.class.configuration.id, &block)
11
+ configure(&block)
13
12
  end
14
13
 
15
14
  def setup!
@@ -22,7 +21,21 @@ module Elasticsearch
22
21
  end
23
22
 
24
23
  def indexes
25
- []
24
+ @indexes ||= self.class.indexes.collect do |key, index_class|
25
+ [
26
+ key,
27
+ build_index(key: key)
28
+ ]
29
+ end.to_h
30
+ end
31
+
32
+ def build_index(key:, index_class: nil)
33
+ index_class = self.class.indexes[key] if index_class.nil?
34
+ index_class&.new(cluster: self).tap do |index|
35
+ settings.index(key).tap do |settings|
36
+ index.settings = settings.dup unless settings.nil?
37
+ end
38
+ end
26
39
  end
27
40
 
28
41
  def search(body, options = {})
@@ -46,7 +59,7 @@ module Elasticsearch
46
59
  end
47
60
 
48
61
  def find_index(index:)
49
- indexes.find do |i|
62
+ indexes.values.find do |i|
50
63
  i.find_index(index: index)
51
64
  end
52
65
  end
@@ -54,6 +67,20 @@ module Elasticsearch
54
67
  def find_type(index:, type:)
55
68
  find_index(index: index)&.find_type(index: index, type: type)
56
69
  end
70
+
71
+ def self.indexes
72
+ (@index_names ||= {}).collect do |key, index_name|
73
+ [key, Object.const_get(index_name)]
74
+ end.to_h
75
+ end
76
+
77
+ protected
78
+
79
+ def self.define_indexes(indexes = {})
80
+ @index_names = indexes.collect do |key, index|
81
+ [key.to_sym, index.class == Class ? index.name : index]
82
+ end.to_h
83
+ end
57
84
  end
58
85
  end
59
86
  end
@@ -13,25 +13,34 @@ module Elasticsearch
13
13
 
14
14
  protected
15
15
 
16
- def define_configuration(options = {})
16
+ def define_configuration(attributes = {})
17
17
  @configuration = configuration.tap do |c|
18
- options.each do |name, value|
19
- c.send("#{name.to_s}=", value) if c.respond_to?("#{name.to_s}=") && !value.nil?
20
- end
18
+ c.set_attributes(attributes)
21
19
  end
22
20
  end
23
21
  end
24
22
 
25
23
  module InstanceMethods
26
- attr_reader :settings
24
+ attr_accessor :settings
27
25
 
28
26
  def default_settings
29
- default_expression = self.class.configuration.default
30
- default_expression ? self.instance_exec(&default_expression) : nil
27
+ self.class.configuration.configuration_class&.new.tap do |s|
28
+ defaults_block = self.class.configuration.defaults
29
+ self.instance_exec(s, &defaults_block) if defaults_block
30
+ end
31
+ end
32
+
33
+ def inherited_settings
34
+ inherit_block = self.class.configuration.inherit_from
35
+ if inherit_block
36
+ s = self.instance_exec(&inherit_block)&.dup
37
+ else
38
+ nil
39
+ end
31
40
  end
32
41
 
33
- def configure(options = {}, &block)
34
- @settings = default_settings&.dup || self.class.configuration.class_name&.new(**options)
42
+ def configure(&block)
43
+ @settings = inherited_settings || default_settings
35
44
  settings.tap do |s|
36
45
  yield(s) if block_given?
37
46
  end
@@ -39,10 +48,24 @@ module Elasticsearch
39
48
  end
40
49
 
41
50
  class Configuration
42
- ATTRIBUTES = [:id, :class_name, :default].freeze
51
+ ATTRIBUTES = [:class_name, :inherit_from, :defaults].freeze
43
52
 
44
53
  attr_accessor *ATTRIBUTES
45
54
 
55
+ def set_attributes(attributes = {})
56
+ attributes.each do |name, value|
57
+ self.send("#{name.to_s}=", value) if self.respond_to?("#{name.to_s}=")
58
+ end
59
+ end
60
+
61
+ def class_name=(class_name)
62
+ @class_name = (class_name.class == Class ? class_name.name : class_name)
63
+ end
64
+
65
+ def configuration_class
66
+ class_name ? Object.const_get(class_name) : nil
67
+ end
68
+
46
69
  def ==(obj)
47
70
  ATTRIBUTES.all? { |a| obj.send(a) == self.send(a) }
48
71
  end
@@ -1,7 +1,8 @@
1
+ require 'elasticsearch/resources/configuration/nameable'
2
+ require 'elasticsearch/resources/configuration/settings'
1
3
  require 'elasticsearch/resources/configuration/type'
2
4
  require 'elasticsearch/resources/configuration/index'
3
5
  require 'elasticsearch/resources/configuration/cluster'
4
- require 'elasticsearch/resources/configuration/settings'
5
6
 
6
7
  module Elasticsearch
7
8
  module Resources
@@ -1,13 +1,7 @@
1
1
  module Elasticsearch
2
2
  module Resources
3
3
  module Configuration
4
- class Cluster
5
- attr_reader :id, :name
6
-
7
- def initialize(id:)
8
- @id = id
9
- end
10
-
4
+ class Cluster < Settings
11
5
  def client
12
6
  @client ||= Elasticsearch::Client.new(host: host)
13
7
  end
@@ -16,17 +10,12 @@ module Elasticsearch
16
10
  @indexes ||= default_indexes
17
11
  end
18
12
 
19
- def index(id)
20
- indexes.find { |t| t.id == id.to_sym }.tap do |t|
13
+ def index(key)
14
+ indexes[key.to_sym].tap do |t|
21
15
  yield(t) if block_given?
22
16
  end
23
17
  end
24
18
 
25
- def name=(name)
26
- raise NullNameError.new if name.nil?
27
- @name = name.to_s
28
- end
29
-
30
19
  def host
31
20
  @host ||= '127.0.0.1:9200'
32
21
  end
@@ -36,16 +25,6 @@ module Elasticsearch
36
25
  @host = host
37
26
  end
38
27
 
39
- class NullNameError < ArgumentError
40
- def initialize
41
- super(message)
42
- end
43
-
44
- def message
45
- I18n.t('elasticsearch.resources.configuration.cluster.null_name_error.message')
46
- end
47
- end
48
-
49
28
  class NullHostError < ArgumentError
50
29
  def initialize
51
30
  super(message)
@@ -59,7 +38,7 @@ module Elasticsearch
59
38
  protected
60
39
 
61
40
  def default_indexes
62
- []
41
+ {}
63
42
  end
64
43
  end
65
44
  end
@@ -1,43 +1,23 @@
1
1
  module Elasticsearch
2
2
  module Resources
3
3
  module Configuration
4
- class Index
5
- attr_reader :id, :name, :cluster
6
-
7
- def initialize(id:, cluster:)
8
- @id = id
9
- @cluster = cluster
10
- end
4
+ class Index < Settings
5
+ include Nameable
11
6
 
12
7
  def types
13
8
  @types ||= default_types
14
9
  end
15
10
 
16
- def type(id)
17
- types.find { |t| t.id == id.to_sym }.tap do |t|
11
+ def type(key)
12
+ types[key.to_sym].tap do |t|
18
13
  yield(t) if block_given? && !t.nil?
19
14
  end
20
15
  end
21
16
 
22
- def name=(name)
23
- raise NullNameError.new if name.nil?
24
- @name = name.to_s
25
- end
26
-
27
- class NullNameError < ArgumentError
28
- def initialize
29
- super(message)
30
- end
31
-
32
- def message
33
- I18n.t('elasticsearch.resources.configuration.index.null_name_error.message')
34
- end
35
- end
36
-
37
17
  protected
38
18
 
39
19
  def default_types
40
- []
20
+ {}
41
21
  end
42
22
  end
43
23
  end
@@ -0,0 +1,34 @@
1
+ module Elasticsearch
2
+ module Resources
3
+ module Configuration
4
+ module Nameable
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ base.include(InstanceMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+ end
12
+
13
+ module InstanceMethods
14
+ attr_reader :name
15
+
16
+ def name=(name)
17
+ raise NullNameError.new if name.nil?
18
+ @name = name.to_s
19
+ end
20
+ end
21
+
22
+ class NullNameError < ArgumentError
23
+ def initialize
24
+ super(message)
25
+ end
26
+
27
+ def message
28
+ I18n.t('elasticsearch.resources.configuration.nameable.null_name_error.message')
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -2,23 +2,6 @@ module Elasticsearch
2
2
  module Resources
3
3
  module Configuration
4
4
  class Settings
5
- def clusters
6
- @clusters ||= default_clusters
7
- end
8
-
9
- def cluster(id)
10
- clusters.find { |t| t.id == id.to_sym }.tap do |t|
11
- yield(t) if block_given?
12
- end
13
- end
14
-
15
- protected
16
-
17
- def default_clusters
18
- [
19
- Elasticsearch::Resources::Configuration::Cluster.new(id: :default)
20
- ]
21
- end
22
5
  end
23
6
  end
24
7
  end
@@ -1,28 +1,8 @@
1
1
  module Elasticsearch
2
2
  module Resources
3
3
  module Configuration
4
- class Type
5
- attr_reader :id, :name, :index
6
-
7
- def initialize(id:, index:)
8
- @id = id
9
- @index = index
10
- end
11
-
12
- def name=(name)
13
- raise NullNameError.new if name.nil?
14
- @name = name.to_s
15
- end
16
-
17
- class NullNameError < ArgumentError
18
- def initialize
19
- super(message)
20
- end
21
-
22
- def message
23
- I18n.t('elasticsearch.resources.configuration.type.null_name_error.message')
24
- end
25
- end
4
+ class Type < Settings
5
+ include Nameable
26
6
  end
27
7
  end
28
8
  end
@@ -8,7 +8,7 @@ module Elasticsearch
8
8
 
9
9
  module ClassMethods
10
10
  def attributes
11
- @attributes ||= []
11
+ @attributes ||= superclass.respond_to?(:attributes) ? superclass.attributes.dup : []
12
12
  end
13
13
 
14
14
  protected
@@ -7,7 +7,7 @@ module Elasticsearch
7
7
  include Identifiable
8
8
  include Describable
9
9
 
10
- def initialize(id:, attributes: {}, type:)
10
+ def initialize(type:, id:, attributes: {})
11
11
  self.type = type
12
12
  self.id = id
13
13
  self.attributes = attributes
@@ -7,13 +7,11 @@ module Elasticsearch
7
7
  include Clusterable
8
8
  include Nameable
9
9
 
10
- define_configuration \
11
- class_name: Configuration::Index,
12
- default: -> { cluster.settings.index(self.class.configuration.id) }
10
+ define_configuration class_name: 'Elasticsearch::Resources::Configuration::Index'
13
11
 
14
12
  def initialize(cluster:, &block)
15
13
  self.cluster = cluster
16
- configure(id: self.class.configuration.id, cluster: cluster.settings, &block)
14
+ configure(&block)
17
15
  end
18
16
 
19
17
  def setup!
@@ -35,11 +33,25 @@ module Elasticsearch
35
33
  end
36
34
 
37
35
  def name
38
- settings.name || super
36
+ settings.name
39
37
  end
40
38
 
41
39
  def types
42
- []
40
+ @types ||= self.class.types.collect do |key, type_class|
41
+ [
42
+ key,
43
+ build_type(key: key)
44
+ ]
45
+ end.to_h
46
+ end
47
+
48
+ def build_type(key:, type_class: nil)
49
+ type_class = self.class.types[key] if type_class.nil?
50
+ type_class&.new(index: self).tap do |type|
51
+ settings.type(key).tap do |settings|
52
+ type.settings = settings.dup unless settings.nil?
53
+ end
54
+ end
43
55
  end
44
56
 
45
57
  def query_index(action, options = {})
@@ -103,6 +115,20 @@ module Elasticsearch
103
115
  t.find_type(type: type)
104
116
  end
105
117
  end
118
+
119
+ def self.types
120
+ (@type_names ||= {}).collect do |key, type_name|
121
+ [key, Object.const_get(type_name)]
122
+ end.to_h
123
+ end
124
+
125
+ protected
126
+
127
+ def self.define_types(types = {})
128
+ @type_names = types.collect do |key, type|
129
+ [key.to_sym, type.class == Class ? type.name : type]
130
+ end.to_h
131
+ end
106
132
  end
107
133
  end
108
134
  end
@@ -3,16 +3,11 @@ en:
3
3
  resources:
4
4
  configuration:
5
5
  cluster:
6
- null_name_error:
7
- message: 'Cluster cannot be assigned a nil name!'
8
6
  null_host_error:
9
7
  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:
8
+ nameable:
14
9
  null_name_error:
15
- message: 'Type cannot be assigned a nil name!'
10
+ message: 'Cannot be assigned a nil name!'
16
11
  identifiable:
17
12
  null_id_error:
18
13
  message: "ID cannot be assigned a nil value!"
@@ -7,16 +7,11 @@ module Elasticsearch
7
7
  end
8
8
 
9
9
  module ClassMethods
10
- attr_reader :default_name
11
-
12
- def define_default_name(name)
13
- @default_name = name&.to_s
14
- end
15
10
  end
16
11
 
17
12
  module InstanceMethods
18
13
  def name
19
- self.class.default_name
14
+ nil
20
15
  end
21
16
 
22
17
  def matches_name?(name)
@@ -7,9 +7,7 @@ module Elasticsearch
7
7
  include Indexable
8
8
  include Nameable
9
9
 
10
- define_configuration \
11
- class_name: Configuration::Type,
12
- default: -> { index.settings.type(self.class.configuration.id) }
10
+ define_configuration class_name: 'Elasticsearch::Resources::Configuration::Type'
13
11
 
14
12
  ACTIONS = [
15
13
  :exists?,
@@ -21,7 +19,7 @@ module Elasticsearch
21
19
 
22
20
  def initialize(index:, &block)
23
21
  self.index = index
24
- configure(id: self.class.configuration.id, index: index.settings, &block)
22
+ configure(&block)
25
23
  end
26
24
 
27
25
  def cluster
@@ -33,7 +31,7 @@ module Elasticsearch
33
31
  end
34
32
 
35
33
  def name
36
- settings.name || super
34
+ settings.name
37
35
  end
38
36
 
39
37
  def query(action, options = {})
@@ -84,16 +82,16 @@ module Elasticsearch
84
82
  end
85
83
 
86
84
  def self.document_class
87
- @document_class
85
+ Object.const_get(@document_class) if @document_class
88
86
  end
89
87
 
90
88
  protected
91
89
 
92
- def self.define_document_class(document_class)
93
- @document_class = document_class
90
+ def self.define_document(document_class)
91
+ @document_class = (document_class.class == Class ? document_class.name : document_class)
94
92
  end
95
93
 
96
- define_document_class Elasticsearch::Resources::Document
94
+ define_document 'Elasticsearch::Resources::Document'
97
95
  end
98
96
  end
99
97
  end
@@ -1,5 +1,5 @@
1
1
  module Elasticsearch
2
2
  module Resources
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elasticsearch-resources
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Elner
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-01-17 00:00:00.000000000 Z
11
+ date: 2017-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n
@@ -136,6 +136,7 @@ files:
136
136
  - LICENSE
137
137
  - README.md
138
138
  - Rakefile
139
+ - TODO
139
140
  - bin/console
140
141
  - bin/setup
141
142
  - elasticsearch-resources.gemspec
@@ -146,6 +147,7 @@ files:
146
147
  - lib/elasticsearch/resources/configuration.rb
147
148
  - lib/elasticsearch/resources/configuration/cluster.rb
148
149
  - lib/elasticsearch/resources/configuration/index.rb
150
+ - lib/elasticsearch/resources/configuration/nameable.rb
149
151
  - lib/elasticsearch/resources/configuration/settings.rb
150
152
  - lib/elasticsearch/resources/configuration/type.rb
151
153
  - lib/elasticsearch/resources/describable.rb
@@ -163,7 +165,8 @@ files:
163
165
  - lib/elasticsearch/resources/typeable.rb
164
166
  - lib/elasticsearch/resources/version.rb
165
167
  homepage: https://github.com/delner/elasticsearch-resources
166
- licenses: []
168
+ licenses:
169
+ - Apache-2.0
167
170
  metadata: {}
168
171
  post_install_message:
169
172
  rdoc_options: []