flex 0.4.2 → 1.0.1

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 (78) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +46 -7
  3. data/VERSION +1 -1
  4. data/flex.gemspec +13 -19
  5. data/lib/flex.rb +66 -392
  6. data/lib/flex/api_stubs.rb +1268 -0
  7. data/lib/flex/api_templates/cluster_api.yml +94 -0
  8. data/lib/flex/api_templates/core_api.yml +202 -0
  9. data/lib/flex/api_templates/indices_api.yml +304 -0
  10. data/lib/flex/class_proxy/base.rb +20 -6
  11. data/lib/flex/class_proxy/templates.rb +97 -0
  12. data/lib/flex/class_proxy/templates/doc.rb +91 -0
  13. data/lib/flex/class_proxy/templates/search.rb +72 -0
  14. data/lib/flex/configuration.rb +17 -49
  15. data/lib/flex/deprecation.rb +153 -0
  16. data/lib/flex/errors.rb +2 -1
  17. data/lib/flex/http_clients/base.rb +15 -0
  18. data/lib/flex/http_clients/loader.rb +51 -0
  19. data/lib/flex/http_clients/patron.rb +9 -7
  20. data/lib/flex/http_clients/rest_client.rb +6 -8
  21. data/lib/flex/logger.rb +24 -3
  22. data/lib/flex/prog_bar.rb +11 -6
  23. data/lib/flex/rails.rb +1 -13
  24. data/lib/flex/result.rb +8 -2
  25. data/lib/flex/result/document.rb +42 -13
  26. data/lib/flex/result/multi_get.rb +24 -0
  27. data/lib/flex/result/search.rb +1 -24
  28. data/lib/flex/struct/array.rb +25 -0
  29. data/lib/flex/struct/hash.rb +105 -0
  30. data/lib/flex/{result/collection.rb → struct/paginable.rb} +16 -9
  31. data/lib/flex/struct/prunable.rb +60 -0
  32. data/lib/flex/struct/symbolize.rb +27 -0
  33. data/lib/flex/tasks.rb +26 -86
  34. data/lib/flex/template.rb +60 -120
  35. data/lib/flex/template/common.rb +42 -0
  36. data/lib/flex/template/logger.rb +66 -0
  37. data/lib/flex/template/partial.rb +12 -15
  38. data/lib/flex/template/search.rb +6 -6
  39. data/lib/flex/template/slim_search.rb +1 -1
  40. data/lib/flex/template/tags.rb +19 -9
  41. data/lib/flex/templates.rb +20 -0
  42. data/lib/flex/utility_methods.rb +80 -89
  43. data/lib/flex/utils.rb +68 -25
  44. data/lib/flex/variables.rb +55 -4
  45. data/lib/tasks.rake +28 -0
  46. metadata +61 -85
  47. data/bin/flexes +0 -174
  48. data/lib/flex/api_methods.yml +0 -108
  49. data/lib/flex/class_proxy/loader.rb +0 -102
  50. data/lib/flex/class_proxy/model.rb +0 -45
  51. data/lib/flex/class_proxy/model_sync.rb +0 -23
  52. data/lib/flex/class_proxy/related_model.rb +0 -23
  53. data/lib/flex/instance_proxy/base.rb +0 -29
  54. data/lib/flex/instance_proxy/model.rb +0 -102
  55. data/lib/flex/instance_proxy/related_model.rb +0 -7
  56. data/lib/flex/loader.rb +0 -18
  57. data/lib/flex/manager.rb +0 -61
  58. data/lib/flex/model.rb +0 -24
  59. data/lib/flex/rails/engine.rb +0 -23
  60. data/lib/flex/rails/helper.rb +0 -16
  61. data/lib/flex/related_model.rb +0 -16
  62. data/lib/flex/result/indifferent_access.rb +0 -11
  63. data/lib/flex/result/source_document.rb +0 -63
  64. data/lib/flex/result/source_search.rb +0 -32
  65. data/lib/flex/structure/indifferent_access.rb +0 -44
  66. data/lib/flex/structure/mergeable.rb +0 -21
  67. data/lib/flex/template/base.rb +0 -41
  68. data/lib/flex/template/info.rb +0 -68
  69. data/lib/generators/flex/setup/setup_generator.rb +0 -48
  70. data/lib/generators/flex/setup/templates/flex_config.yml +0 -16
  71. data/lib/generators/flex/setup/templates/flex_dir/es.rb.erb +0 -18
  72. data/lib/generators/flex/setup/templates/flex_dir/es.yml.erb +0 -19
  73. data/lib/generators/flex/setup/templates/flex_dir/es_extender.rb.erb +0 -17
  74. data/lib/generators/flex/setup/templates/flex_initializer.rb.erb +0 -44
  75. data/lib/tasks/index.rake +0 -17
  76. data/test/flex.irt +0 -143
  77. data/test/flex/configuration.irt +0 -53
  78. data/test/irt_helper.rb +0 -12
@@ -1,108 +0,0 @@
1
- # These methods are available as Flex.<method>(variable_hash)
2
- # you can get the updated full reference and usage example of these methods
3
- # by just doing in the console:
4
- # >> puts Flex.info
5
-
6
- # http://www.elasticsearch.org/guide/reference/api/admin-indices-indices-exists.html
7
- indices_exists: &exist
8
- - HEAD
9
- - /<<index>>
10
-
11
- # aliased
12
- exist?: *exist
13
-
14
- # http://www.elasticsearch.org/guide/reference/api/admin-indices-create-index.html
15
- create_index: &create
16
- - PUT
17
- - /<<index>>
18
- - settings:
19
- number_of_shards: <<number_of_shards= 5 >>
20
- number_of_replicas: <<number_of_replicas= 1 >>
21
-
22
- # aliased
23
- put_index: *create
24
-
25
- post_index:
26
- - POST
27
- - /<<index>>
28
- - settings:
29
- number_of_shards: <<number_of_shards= 5 >>
30
- number_of_replicas: <<number_of_replicas= 1 >>
31
-
32
- # http://www.elasticsearch.org/guide/reference/api/admin-indices-get-settings.html
33
- get_settings:
34
- - GET
35
- - /<<index>>/_settings
36
-
37
- # http://www.elasticsearch.org/guide/reference/api/admin-indices-put-mapping.html
38
- put_mapping:
39
- - PUT
40
- - /<<index>>/<<type>>/_mapping
41
- - <<type>>:
42
- properties: <<properties>>
43
-
44
- # http://www.elasticsearch.org/guide/reference/api/admin-indices-get-mapping.html
45
- get_mapping:
46
- - GET
47
- - /<<index>>/<<type>>/_mapping
48
-
49
- # http://www.elasticsearch.org/guide/reference/api/admin-indices-delete-mapping.html
50
- delete_mapping:
51
- - DELETE
52
- - /<<index>>/<<type>>
53
-
54
- # http://www.elasticsearch.org/guide/reference/api/delete.html
55
- delete_index:
56
- - DELETE
57
- - /<<index>>
58
-
59
- # http://www.elasticsearch.org/guide/reference/api/delete-by-query.html
60
- delete_by_query:
61
- - DELETE
62
- - /<<index>>/<<type>>/_query
63
- # pass :data variable query if you need
64
-
65
- # http://www.elasticsearch.org/guide/reference/api/bulk.html
66
- bulk:
67
- - POST
68
- - /_bulk
69
- - << lines >>
70
-
71
- # http://www.elasticsearch.org/guide/reference/api/count.html
72
- count:
73
- - GET
74
- - /<<index>>/<<type>>/_count
75
- # pass :data structure if you need
76
-
77
- # http://www.elasticsearch.org/guide/reference/api/admin-indices-stats.html
78
- stats:
79
- - GET
80
- - /<<index>>/_stats/<<end_point= ~ >>
81
-
82
- # You must pass the :data variable
83
- store: &store
84
- - PUT
85
- - /<<index>>/<<type>>/<<id>>
86
-
87
- # alias for symmetry with post_store
88
- put_store: *store
89
-
90
- # id is assigned by ES; you must pass :data
91
- post_store:
92
- - POST
93
- - /<<index>>/<<type>>
94
-
95
- remove:
96
- - DELETE
97
- - /<<index>>/<<type>>/<<id>>
98
-
99
- # http://www.elasticsearch.org/guide/reference/api/get.html
100
- get:
101
- - GET
102
- - /<<index>>/<<type>>/<<id>>
103
-
104
- # http://www.elasticsearch.org/guide/reference/api/multi-get.html
105
- multi_get:
106
- - GET
107
- - /<<index>>/<<type>>/_mget
108
- - ids: << ids >>
@@ -1,102 +0,0 @@
1
- module Flex
2
- module ClassProxy
3
- class Loader < Base
4
- attr_reader :templates, :partials
5
-
6
- include Template::Info
7
-
8
- def initialize(base)
9
- super
10
- @sources = []
11
- @templates = {}
12
- @partials = {}
13
- end
14
-
15
- # accepts a path to a file or YAML string
16
- def load_source_for(klass, source, source_vars)
17
- if source.nil? || source != /\n/
18
- paths = [ "#{Configuration.flex_dir}/#{source}.yml",
19
- "#{Configuration.flex_dir}/#{Manager.class_name_to_type(host_class.name)}.yml",
20
- source.to_s ]
21
- source = paths.find {|p| File.exist?(p)}
22
- end
23
- raise ArgumentError, "expected a string (got #{source.inspect})." \
24
- unless source.is_a?(String)
25
- @sources << [klass, source, source_vars]
26
- do_load_source(klass, source, source_vars)
27
- end
28
-
29
- # loads a Generic Template source
30
- def load_source(source=nil, source_vars=nil)
31
- load_source_for(Template, source, source_vars)
32
- end
33
-
34
- # loads a Search Template source
35
- def load_search_source(source=nil, source_vars=nil)
36
- load_source_for(Template::Search, source, source_vars)
37
- end
38
-
39
- # loads a SlimSearch Template source
40
- def load_slim_search_source(source=nil, source_vars=nil)
41
- load_source_for(Template::SlimSearch, source, source_vars)
42
- end
43
-
44
- # reloads the sources (useful in the console and used internally)
45
- def reload!
46
- @sources.each {|k,s,v| do_load_source(k,s,v)}
47
- end
48
-
49
- # adds a template instance and defines the template method in the host class
50
- def add_template(name, template)
51
- templates[name] = template
52
- # no define_singleton_method in 1.8.7
53
- host_class.instance_eval <<-ruby, __FILE__, __LINE__ + 1
54
- def #{name}(vars={})
55
- raise ArgumentError, "#{host_class}.#{name} expects a Hash (got \#{vars.inspect})" unless vars.is_a?(Hash)
56
- #{host_class.respond_to?(:preprocess_variables) && 'preprocess_variables(vars)'}
57
- flex.templates[:#{name}].render(vars)
58
- end
59
- ruby
60
- end
61
-
62
- # http://www.elasticsearch.org/guide/reference/api/multi-search.html
63
- # request may be a hash with the templates names as keys and the variable hash as value
64
- # or you can also use an array of arrays.
65
- # The variables are an hash of variables that will be used to render the msearch template
66
- def multi_search(requests, variables={})
67
- lines = requests.map { |name, vars| templates[name].to_msearch(vars) }.join()
68
- template = Template.new('GET', '/<<index>>/<<type>>/_msearch')
69
- template.send(:do_render, variables.merge(:data => lines)) do |http_response|
70
- responses = []
71
- es_response = MultiJson.decode(http_response.body)
72
- es_response['responses'].each_with_index do |result, i|
73
- responses << Result.new(templates[requests[i].first], requests[i].last, http_response, result)
74
- end
75
- es_response['responses'] = responses
76
- def es_response.responses
77
- self['responses']
78
- end
79
- es_response
80
- end
81
- end
82
-
83
- private
84
-
85
- def do_load_source(klass, source, source_vars)
86
- source = Utils.erb_process(source) unless source.match("\n") # skips non-path
87
- hash = Utils.data_from_source(source)
88
- hash.delete('ANCHORS')
89
- hash.each do |name, structure|
90
- if name.to_s =~ /^_/ # partial
91
- partial = Template::Partial.new(structure, self)
92
- partials[name.to_sym] = partial
93
- else
94
- template = klass.new(*structure).setup(self, name, source_vars)
95
- add_template(name.to_sym, template)
96
- end
97
- end
98
- end
99
-
100
- end
101
- end
102
- end
@@ -1,45 +0,0 @@
1
- module Flex
2
- module ClassProxy
3
- class Model < Base
4
-
5
- include ModelSync
6
-
7
- attr_reader :parent_association, :parent_child_map
8
-
9
- def initialize(base)
10
- super
11
- variables.add :index => Configuration.variables[:index],
12
- :type => Manager.class_name_to_type(host_class.name)
13
- end
14
-
15
- def index
16
- variables[:index]
17
- end
18
-
19
- def index=(val)
20
- variables[:index] = val
21
- end
22
-
23
- def type
24
- variables[:type]
25
- end
26
-
27
- def type=(val)
28
- variables[:type] = val
29
- end
30
-
31
- def parent(parent_association, map)
32
- @parent_association = parent_association
33
- Manager.parent_types |= map.keys.map(&:to_s)
34
- self.type = map.values.map(&:to_s)
35
- @parent_child_map = map
36
- @is_child = true
37
- end
38
-
39
- def is_child?
40
- !!@is_child
41
- end
42
-
43
- end
44
- end
45
- end
@@ -1,23 +0,0 @@
1
- module Flex
2
- module ClassProxy
3
- module ModelSync
4
-
5
- def self.included(base)
6
- base.class_eval do
7
- attr_accessor :synced
8
- end
9
- end
10
-
11
- def sync(*synced)
12
- @synced = synced
13
- host_class.class_eval do
14
- raise NotImplementedError, "the class #{self} must implement :after_save and :after_destroy callbacks" \
15
- unless respond_to?(:after_save) && respond_to?(:after_destroy)
16
- after_save { flex.sync }
17
- after_destroy { flex.sync }
18
- end
19
- end
20
-
21
- end
22
- end
23
- end
@@ -1,23 +0,0 @@
1
- module Flex
2
- module ClassProxy
3
- class RelatedModel
4
-
5
- attr_reader :host_class
6
-
7
- def initialize(host_class)
8
- @host_class = host_class
9
- end
10
-
11
- include ModelSync
12
-
13
- alias_method :full_sync, :sync
14
-
15
- def sync(*synced)
16
- raise ArgumentError, 'You cannot flex.sync(self) a Flex::RelatedModel.' \
17
- if synced.any?{|s| s == host_class}
18
- full_sync
19
- end
20
-
21
- end
22
- end
23
- end
@@ -1,29 +0,0 @@
1
- module Flex
2
- module InstanceProxy
3
-
4
- class Base
5
- attr_reader :instance, :class_flex
6
-
7
- def initialize(instance)
8
- @instance = instance
9
- @class_flex = instance.class.flex
10
- end
11
-
12
- def sync
13
- class_flex.synced.each do |s|
14
- case
15
- when s == instance.class # only called for Flex::Model
16
- instance.destroyed? ? remove : store
17
- when s.is_a?(Symbol)
18
- instance.send(s).flex.sync
19
- when s.is_a?(String)
20
- parent_instance.flex.sync if s == parent_instance.flex.type
21
- else
22
- raise ArgumentError, "self, string or symbol expected, got #{s.inspect}"
23
- end
24
- end
25
- end
26
-
27
- end
28
- end
29
- end
@@ -1,102 +0,0 @@
1
- module Flex
2
- module InstanceProxy
3
- class Model < Base
4
-
5
- # indexes the document
6
- # usually called from after_save, you can eventually call it explicitly for example from another callback
7
- # or whenever the DB doesn't get updated by the model
8
- # you can also pass the :data=>flex_source explicitly (useful for example to override the flex_source in the model)
9
- def store(vars={})
10
- if instance.flex_indexable?
11
- Flex.store metainfo.merge(:data => instance.flex_source).merge(vars)
12
- else
13
- Flex.remove(metainfo.merge(vars)) if Flex.get(metainfo.merge(vars.merge(:raise => false)))
14
- end
15
- end
16
-
17
- # removes the document from the index (called from after_destroy)
18
- def remove(vars={})
19
- return unless instance.flex_indexable?
20
- Flex.remove metainfo.merge(vars)
21
- end
22
-
23
- # gets the document from ES
24
- def get(vars={})
25
- return unless instance.flex_indexable?
26
- Flex.get metainfo.merge(vars)
27
- end
28
-
29
- def parent_instance(raise=true)
30
- return unless is_child?
31
- @parent_instance ||= instance.send(class_flex.parent_association) || raise &&
32
- raise(MissingParentError, "missing parent instance for document #{instance.inspect}.")
33
- end
34
-
35
- # helper that iterates through the parent record chain
36
- # record.flex.each_parent{|p| p.do_smething }
37
- def each_parent
38
- pi = parent_instance
39
- while pi do
40
- yield pi
41
- pi = pi.flex.parent_instance
42
- end
43
- end
44
-
45
- def type
46
- @type ||= is_child? ? class_flex.parent_child_map[parent_instance.flex.type] : class_flex.type
47
- end
48
-
49
- def index
50
- class_flex.index
51
- end
52
-
53
- def id
54
- instance.id
55
- end
56
-
57
- def routing(raise=true)
58
- @routing ||= case
59
- when is_child? then parent_instance(raise).flex.routing
60
- when is_parent? then create_routing
61
- end
62
- end
63
-
64
- def is_child?
65
- @is_child ||= class_flex.is_child?
66
- end
67
-
68
- def is_parent?
69
- @is_parent ||= Manager.parent_types.include?(type)
70
- end
71
-
72
- def metainfo
73
- @metainfo ||= begin
74
- meta = { :index => index, :type => type, :id => id }
75
- params = {}
76
- params[:routing] = routing if routing
77
- params[:parent] = parent_instance.id if is_child?
78
- meta.merge!(:params => params) unless params.empty?
79
- meta
80
- end
81
- end
82
-
83
- private
84
-
85
- BASE62_DIGITS = ('0'..'9').to_a + ('A'..'Z').to_a + ('a'..'z').to_a
86
-
87
- def create_routing
88
- string = [index, type, id].join
89
- remainder = Digest::MD5.hexdigest(string).to_i(16)
90
- result = []
91
- max_power = ( Math.log(remainder) / Math.log(62) ).floor
92
- max_power.downto(0) do |power|
93
- digit, remainder = remainder.divmod(62**power)
94
- result << digit
95
- end
96
- result << remainder if remainder > 0
97
- result.map{|digit| BASE62_DIGITS[digit]}.join
98
- end
99
-
100
- end
101
- end
102
- end
@@ -1,7 +0,0 @@
1
- module Flex
2
- module InstanceProxy
3
- class RelatedModel < Base
4
-
5
- end
6
- end
7
- end