flex 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -2,14 +2,16 @@
2
2
 
3
3
  Flex is a complete ruby client for [ElasticSearch](http://www.elasticsearch.org). It introduces a new way to send any kind of request (not just search queries) to the ES server, and to manage any kind of response. You can transparently integrate it with **ActiveRecord** and **Mongoid** models with or without automatic synchronization, with or without **Rails**. It is fast and efficient, easy to use and customize.
4
4
 
5
- Flex is currently a very new project, however it is already used in production in 5 sites, and it will be deployed to a few others soon.
6
-
7
5
  ## Useful Links
8
6
 
9
7
  * [Documentation](./flex/wiki)
10
8
  * [Issues](./flex/issues)
11
9
  * [Pull Requests](./flex/pulls)
12
10
 
11
+ ## Branches
12
+
13
+ The master branch reflects the last published gem. Then you may find a next-version branch (named after the version string), with the commits that will be merged in master just before publishing the next gem version. The next-version branch may get rebased or force pushed.
14
+
13
15
  ## Credits
14
16
 
15
17
  Special thanks for their sponsorship to [Escalate Media](http://www.escalatemedia.com) and [Barquin International](http://www.barquin.com).
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.4.0
@@ -0,0 +1,174 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'flex'
5
+
6
+ options = { }
7
+ version = File.read(File.expand_path('../../VERSION', __FILE__)).strip
8
+ copy = "flexes #{version} (c) 2012 Domizio Demichelis"
9
+ optparse = OptionParser.new do |opts|
10
+
11
+ opts.banner = <<-banner
12
+
13
+ FlexEs:
14
+ Flex tool to dump/load data from/to ElasticSearch.
15
+ Usage:
16
+ flexes <command> [options]
17
+ <command>:
18
+ dump dumps the data from one or more ElasticSearch indices
19
+ load loads a dumpfile
20
+ stats prints the full ElasticSearch stats
21
+
22
+ Notice: The load command will load the dump-file into ElasticSearch without removing any pre-existent data.
23
+ If you need fresh indices, use the flex:delete_indices and flex:create_indices rake tasks from your
24
+ application, which will also recreate the mapping.
25
+ banner
26
+
27
+
28
+ opts.separator ''
29
+ opts.separator 'Common options:'
30
+
31
+ options[:file] = './flexes.dump'
32
+ opts.on( '-f', '--file [FILE]', "The path of the dumpfile (default: '#{options[:file]}')" ) do |f|
33
+ options[:file] = f
34
+ end
35
+
36
+ opts.separator ''
37
+ opts.separator 'Dump options:'
38
+
39
+ options[:index] = nil
40
+ opts.on( '-i', '--index [INDEX_OR_INDICES]', Array, 'The index or comma separated indices to dump (default: all indices)' ) do |i|
41
+ options[:index] = i
42
+ end
43
+
44
+ options[:type] = nil
45
+ opts.on( '-t', '--type [TYPE_OR_TYPES]', Array, 'The type or comma separated types to dump (default: all types)' ) do |t|
46
+ options[:type] = t
47
+ end
48
+
49
+ options[:scroll] = '5m'
50
+ opts.on( '-s', '--scroll [TIME]', "The ElasticSearch scroll time (default: #{options[:scroll]})" ) do |s|
51
+ options[:scroll] = s
52
+ end
53
+
54
+ options[:size] = 50
55
+ opts.on( '-z', '--size [SIZE]', Integer, "The chunk size to dump per shard (default: #{options[:size]} * number of shards)" ) do |z|
56
+ options[:size] = z
57
+ end
58
+
59
+ opts.separator ''
60
+ opts.separator 'Load options:'
61
+
62
+ options[:timeout] = 20
63
+ opts.on( '-o', '--timeout [SECONDS]', Integer, "The http_client timeout for bulk loading (default: #{options[:timeout]} seconds)" ) do |o|
64
+ options[:timeout] = o
65
+ end
66
+
67
+ options[:batch_size] = 1000
68
+ opts.on( '-b', '--batch_size [BATCH_SIZE]', Integer, "The batch size to load (default: #{options[:batch_size]})" ) do |z|
69
+ options[:size] = z
70
+ end
71
+
72
+ opts.separator ''
73
+ opts.separator 'Other options:'
74
+
75
+ opts.on( '-v', '--version', 'Shows the version and exits' ) do
76
+ puts version
77
+ exit
78
+ end
79
+
80
+ opts.on_tail( '-h', '--help', 'Displays this screen' ) do
81
+ puts copy
82
+ puts opts
83
+ exit
84
+ end
85
+
86
+ end
87
+
88
+ optparse.parse!
89
+ command = ARGV.first
90
+ exec "#{$0} -h" if command.nil?
91
+ puts copy
92
+
93
+ case command
94
+
95
+ when 'dump'
96
+ search_t = Flex::Template::Search.new( {:query => {:match_all => {}}},
97
+ :params => { :search_type => 'scan',
98
+ :scroll => options[:scroll],
99
+ :size => options[:size],
100
+ :fields => '_source,*' } )
101
+ scroll_t = Flex::Template.new( :get,
102
+ '/_search/scroll',
103
+ nil,
104
+ :params => { :scroll => options[:scroll] } )
105
+ search_res = search_t.render options
106
+ scroll_id = search_res['_scroll_id']
107
+ total_hits = search_res['hits']['total']
108
+ total_count = 0
109
+ pbar = Flex::ProgBar.new(total_hits)
110
+ dump_stats = Hash.new { |hash, key| hash[key] = Hash.new{|h,k| h[k] = 0} }
111
+ file_size = 0
112
+ File.open(options[:file], 'wb') do |file|
113
+ while (result = scroll_t.render(:data => scroll_id)) do
114
+ break if result['hits']['hits'] == []
115
+ lines = result['hits']['hits'].map do |h|
116
+ dump_stats[h['_index']][h['_type']] += 1
117
+ meta = { :_index => h['_index'],
118
+ :_type => h['_type'],
119
+ :_id => h['_id'] }
120
+ if h.has_key?('fields')
121
+ h['fields'].each do |k,v|
122
+ meta[k] = v if k[0] == '_'
123
+ end
124
+ end
125
+ [ MultiJson.encode({'index' => meta}),
126
+ MultiJson.encode(h['_source']) ].join("\n")
127
+ end
128
+ file.puts lines.join("\n")
129
+ scroll_id = result['_scroll_id']
130
+ total_count += lines.size
131
+ pbar.pbar.inc(lines.size)
132
+ end
133
+ file_size = file.size
134
+ end
135
+ formatted_file_size = file_size.to_s.reverse.gsub(/...(?=.)/,'\&,').reverse
136
+ pbar.pbar.finish
137
+ puts "\n***** WARNING: Expected document to dump: #{total_hits}, dumped: #{total_count}. *****" \
138
+ unless total_hits == total_count
139
+ puts "\nDumped #{total_count} documents to #{options[:file]} (size: #{formatted_file_size} bytes)"
140
+ puts dump_stats.to_yaml
141
+
142
+ when 'load'
143
+ Flex::Configuration.http_client_options[:timeout] = options[:timeout]
144
+ chunk_size = options[:batch_size] * 2 # 2 lines per doc
145
+ lines = ''
146
+ line_count = 0
147
+ file = File.open(options[:file])
148
+ file.lines{ line_count += 1 }
149
+ file.rewind
150
+ pbar = Flex::ProgBar.new(line_count / 2, options[:batch_size])
151
+ file.lines do |line|
152
+ lines << line
153
+ if file.lineno % chunk_size == 0
154
+ result = Flex.bulk :lines => lines
155
+ lines = ''
156
+ pbar.process_result(result, options[:batch_size])
157
+ end
158
+ end
159
+ # last chunk
160
+ unless lines == ''
161
+ result = Flex.bulk :lines => lines
162
+ pbar.process_result(result, (file.lineno % chunk_size) / 2)
163
+ end
164
+ file.close
165
+ pbar.finish
166
+
167
+ when 'stats'
168
+ puts '>> puts Flex.stats.to_yaml'
169
+ puts Flex.stats.to_yaml
170
+
171
+ else
172
+ puts "unknown command: #{command.inspect}"
173
+
174
+ end
@@ -4,11 +4,12 @@ Gem::Specification.new do |s|
4
4
  s.name = 'flex'
5
5
  s.summary = 'Ruby Client for ElasticSearch'
6
6
  s.description = <<-desc
7
- Flex is an innovative ruby client for ElasticSearch. With Flex your code will be clean, easy to write and read, and very short: "poetic-short". Flex is fast and efficient, easy to use and customize, and offers ActiveRecord, MongoId and Rails integration.
7
+ Flex is an innovative ruby client for ElasticSearch. With Flex your code will be clean, easy to write and read, and very short: "poetic-short". Flex is fast and efficient, easy to use and customize, and offers ActiveRecord, Mongoid and Rails integration.
8
8
  desc
9
9
  s.homepage = 'http://github.com/ddnexus/flex'
10
10
  s.authors = ["Domizio Demichelis"]
11
11
  s.email = 'dd.nexus@gmail.com'
12
+ s.executables = ['flexes']
12
13
  s.extra_rdoc_files = %w[README.md]
13
14
  s.require_paths = %w[lib]
14
15
  s.files = `git ls-files -z`.split("\0")
@@ -19,7 +20,7 @@ Flex is an innovative ruby client for ElasticSearch. With Flex your code will be
19
20
  s.post_install_message = <<EOM
20
21
  ________________________________________________________________________________
21
22
 
22
- INSTALLATION NOTES
23
+ FLEX INSTALLATION NOTES
23
24
  ________________________________________________________________________________
24
25
 
25
26
  In order to use Flex, a supported http-client must be installed on this system.
@@ -48,6 +48,9 @@ require 'flex/http_clients/rest_client'
48
48
  require 'flex/configuration'
49
49
  require 'flex/utility_methods'
50
50
 
51
+ require 'progressbar'
52
+ require 'flex/prog_bar'
53
+
51
54
  module Flex
52
55
 
53
56
  VERSION = File.read(File.expand_path('../../VERSION', __FILE__)).strip
@@ -44,13 +44,13 @@ module Flex
44
44
  :logger => Logger.new(STDERR),
45
45
  :variables => Variables.new( :index => nil,
46
46
  :type => nil,
47
- :no_pruning => %w[match_all] ),
47
+ :no_pruning => [] ),
48
48
  :flex_models => [],
49
49
  :config_file => './config/flex.yml',
50
50
  :flex_dir => './flex',
51
51
  :http_client => load_http_client,
52
52
  :http_client_options => {},
53
- :debug => true,
53
+ :debug => false,
54
54
  :debug_result => true,
55
55
  :debug_to_curl => false,
56
56
  :raise_proc => proc{|response| response.status >= 400}
@@ -28,7 +28,8 @@ module Flex
28
28
 
29
29
  def parent_instance(raise=true)
30
30
  return unless is_child?
31
- @parent_instance ||= instance.send(class_flex.parent_association) || raise && raise(MissingParentError, "missing parent instance for document #{instance.inspect}.")
31
+ @parent_instance ||= instance.send(class_flex.parent_association) || raise &&
32
+ raise(MissingParentError, "missing parent instance for document #{instance.inspect}.")
32
33
  end
33
34
 
34
35
  # helper that iterates through the parent record chain
@@ -81,7 +82,7 @@ module Flex
81
82
 
82
83
  private
83
84
 
84
- BASE62_DIGITS = %w(0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z)
85
+ BASE62_DIGITS = ('0'..'9').to_a + ('A'..'Z').to_a + ('a'..'z').to_a
85
86
 
86
87
  def create_routing
87
88
  string = [index, type, id].join
@@ -12,7 +12,7 @@ module Flex
12
12
 
13
13
  # arrays of all the types
14
14
  def types
15
- type_class_map.keys.map{|k| k.split('/').last}
15
+ @types ||= Configuration.flex_models.map {|m| (m.is_a?(String) ? eval("::#{m}") : m).flex.type }.flatten
16
16
  end
17
17
 
18
18
  # sets the default parent/child mappings and merges with the config_file
@@ -0,0 +1,34 @@
1
+ module Flex
2
+ class ProgBar
3
+
4
+ attr_reader :pbar
5
+
6
+ def initialize(total_count, batch_size=nil, prefix_message=nil)
7
+ @total_count = total_count
8
+ @successful_count = 0
9
+ @failed_count = 0
10
+ @pbar = ::ProgressBar.new('processing...', total_count)
11
+ @pbar.clear
12
+ @pbar.bar_mark = '|'
13
+ puts '_' * @pbar.send(:get_term_width)
14
+ message = "#{prefix_message}Processing #{total_count} documents"
15
+ message << " in batches of #{batch_size}:" unless batch_size.nil?
16
+ puts message
17
+ @pbar.send(:show)
18
+ end
19
+
20
+ def process_result(result, inc)
21
+ Configuration.logger.error "[FLEX] Failed load:\n#{result.failed.to_yaml}" unless result.failed.size == 0
22
+ @failed_count += result.failed.size
23
+ @successful_count += result.successful.size
24
+ @pbar.inc(inc)
25
+ end
26
+
27
+ def finish
28
+ @pbar.finish
29
+ puts "Processed #{@total_count}. Successful #{@successful_count}. Skipped #{@total_count - @successful_count - @failed_count}. Failed #{@failed_count}."
30
+ puts "See the log for the details about the failed import." unless @failed_count == 0
31
+ end
32
+
33
+ end
34
+ end
@@ -2,11 +2,12 @@ require 'flex'
2
2
  require 'rails'
3
3
  require 'flex/rails/helper'
4
4
 
5
- if ::Rails.respond_to?(:version) && ::Rails.version.to_i == 3
5
+ if ::Rails.respond_to?(:version) && ::Rails.version.to_i >= 3
6
6
  require 'flex/rails/engine'
7
7
  else
8
8
  Flex::Configuration.configure do |c|
9
9
  c.config_file = ::Rails.root.join('config', 'flex.yml').to_s
10
10
  c.flex_dir = ::Rails.root.join('app', 'flex').to_s
11
+ c.debug = ::Rails.env.development?
11
12
  end
12
13
  end
@@ -3,11 +3,11 @@ module Flex
3
3
  class Engine < ::Rails::Engine
4
4
 
5
5
  ActiveSupport.on_load(:before_configuration) do
6
- Flex::Configuration.configure do |c|
7
- c.variables[:index] = [self.class.name.split('::').first.underscore, ::Rails.env].join('_')
8
- c.config_file = ::Rails.root.join('config', 'flex.yml').to_s
9
- c.flex_dir = ::Rails.root.join('app', 'flex').to_s
10
- end
6
+ config.flex = Flex::Configuration
7
+ config.flex.variables[:index] = [self.class.name.split('::').first.underscore, ::Rails.env].join('_')
8
+ config.flex.config_file = ::Rails.root.join('config', 'flex.yml').to_s
9
+ config.flex.flex_dir = ::Rails.root.join('app', 'flex').to_s
10
+ config.flex.debug = ::Rails.env.development?
11
11
  end
12
12
 
13
13
  ActiveSupport.on_load(:after_initialize) do
@@ -16,8 +16,6 @@ module Flex
16
16
  end
17
17
 
18
18
  def import_models
19
- require 'progressbar'
20
-
21
19
  Configuration.http_client_options[:timeout] = ENV['TIMEOUT'].to_i if ENV['TIMEOUT']
22
20
  Configuration.http_client_options[:timeout] ||= 20
23
21
  Configuration.debug = !!ENV['FLEX_DEBUG']
@@ -29,7 +27,7 @@ module Flex
29
27
  options[k.to_sym] = v
30
28
  end
31
29
  end
32
- deleted = []
30
+ deleted = []
33
31
 
34
32
  models.each do |klass|
35
33
  index = klass.flex.index
@@ -60,37 +58,19 @@ module Flex
60
58
  next
61
59
  end
62
60
 
63
- total_count = klass.count
64
- successful_count = 0
65
- failed = []
66
-
67
- pbar = ProgressBar.new('processing...', total_count)
68
- pbar.clear
69
- pbar.bar_mark = '|'
70
- puts '_' * pbar.send(:get_term_width)
71
- puts "Class #{klass}: indexing #{total_count} documents in batches of #{batch_size}:\n"
72
- pbar.send(:show)
61
+ pbar = ProgBar.new(klass.count, batch_size, "Class #{klass}: ")
73
62
 
74
63
  klass.find_in_batches(:batch_size => batch_size) do |array|
75
- opts = {:index => index}.merge(options)
64
+ opts = {:index => index}.merge(options)
76
65
  result = Flex.import_collection(array, opts) || next
77
- f = result.failed
78
- failed += f
79
- successful_count += result.successful.count
80
- pbar.inc(array.size)
66
+ pbar.process_result(result, array.size)
81
67
  end
82
68
 
83
69
  pbar.finish
84
- puts "Processed #{total_count}. Successful #{successful_count}. Skipped #{total_count - successful_count - failed.size}. Failed #{failed.size}."
85
-
86
- if failed.size > 0
87
- puts 'Failed imports:'
88
- puts failed.to_yaml
89
- end
90
70
  end
91
71
  end
92
72
 
93
- private
73
+ private
94
74
 
95
75
  def indices
96
76
  indices = ENV['INDICES'] || struct.keys
@@ -138,4 +118,5 @@ module Flex
138
118
  end
139
119
 
140
120
  end
121
+
141
122
  end
@@ -1,6 +1,8 @@
1
1
  module Flex
2
+
2
3
  # Generic Flex::Template object.
3
- # This class represents a generic Flex::Template object. It is used as the base class by all the more specific Flex::Template::* classes.
4
+ # This class represents a generic Flex::Template object.
5
+ # It is used as the base class by all the more specific Flex::Template::* classes.
4
6
  # You usually don't need to instantiate this class manually, since it is usually used internally.
5
7
  # For more details about templates, see the documentation.
6
8
  class Template
@@ -69,8 +71,9 @@ module Flex
69
71
 
70
72
  rescue NameError => e
71
73
  if e.name == :request
72
- raise MissingHttpClientError, 'you should install the gem "patron" (recommended for performances) or "rest-client", ' +
73
- 'or provide your own http-client interface and set Flex::Configuration.http_client'
74
+ raise MissingHttpClientError,
75
+ 'you should install the gem "patron" (recommended for performances) or "rest-client", ' +
76
+ 'or provide your own http-client interface and set Flex::Configuration.http_client'
74
77
  else
75
78
  raise
76
79
  end
@@ -142,40 +145,34 @@ module Flex
142
145
  merged = @variables.deep_merge sym_vars
143
146
  vars = process_vars(merged)
144
147
  obj = #{stringified}
148
+ obj = prune(obj)
149
+ obj[:path].tr_s!('/', '/') # removes empty path segments
145
150
  obj[:vars] = vars
146
- obj = prune(obj, vars[:no_pruning])
147
151
  obj
148
152
  end
149
153
  ruby
150
154
  interpolate(*args)
151
155
  end
152
156
 
153
- # prunes the branch when the leaf is nil
154
- # also removes empty path segments
157
+ # prunes the branch when the leaf is a PrunableObject
155
158
  # and compact.flatten the Array values
156
- def prune(obj, no_pruning)
159
+ def prune(obj)
157
160
  case obj
158
161
  when Array
159
- return if obj.empty?
162
+ return if obj.is_a?(PrunableObject)
160
163
  a = obj.map do |i|
161
- next if i.nil?
162
- prune(i, no_pruning)
164
+ next if i.is_a?(PrunableObject)
165
+ prune(i)
163
166
  end.compact.flatten
164
167
  a unless a.empty?
165
168
  when Hash
166
- return if obj.empty?
169
+ return if obj.is_a?(PrunableObject)
170
+ return obj if obj.empty?
167
171
  h = {}
168
172
  obj.each do |k, v|
169
- next if v.nil?
170
- v = case
171
- when k == :path
172
- v.gsub(/\/+/, '/')
173
- when no_pruning.include?(k)
174
- v
175
- else
176
- prune(v, no_pruning)
177
- end
178
- h[k] = v unless v.nil?
173
+ pruned = prune(v)
174
+ next if pruned.is_a?(PrunableObject)
175
+ h[k] = pruned
179
176
  end
180
177
  h unless h.empty?
181
178
  else
@@ -1,5 +1,8 @@
1
1
  module Flex
2
2
  class Template
3
+
4
+ module PrunableObject end
5
+
3
6
  module Base
4
7
 
5
8
  def process_vars(vars)
@@ -24,6 +27,14 @@ module Flex
24
27
  vars
25
28
  end
26
29
 
30
+ # extend obj with PrunableObject if it is nil or it is an empty Array or Hash
31
+ # called from stringified
32
+ def prunable(name, vars)
33
+ obj = vars[name]
34
+ return obj if vars[:no_pruning].include?(name)
35
+ (obj.nil? || obj == [] || obj == {}) ? obj.extend(PrunableObject) : obj
36
+ end
37
+
27
38
  end
28
39
  end
29
40
  end
@@ -10,16 +10,33 @@ module Flex
10
10
  block = ''
11
11
  temp = templates[name]
12
12
  meth_call = [host_class, name].join('.')
13
- block << "########## #{meth_call} ##########\n\n#{'-' * temp.class.to_s.length}\n#{temp.class}\n#{temp.to_flex(name)}\n"
13
+ block << <<-meth_call
14
+ ########## #{meth_call} ##########
15
+
16
+ #{'-' * temp.class.to_s.length}
17
+ #{temp.class}
18
+ #{temp.to_flex(name)}
19
+ meth_call
14
20
  temp.partials.each do |par_name|
15
21
  par = partials[par_name]
16
- block << "#{'-' * par.class.to_s.length}\n#{par.class}\n#{par.to_flex(par_name)}\n"
22
+ block << <<-partial
23
+ #{'-' * par.class.to_s.length}
24
+ #{par.class}
25
+ #{par.to_flex(par_name)}
26
+ partial
17
27
  end
18
28
  block << "\nUsage:\n"
19
29
  block << usage(meth_call, temp)
20
30
  block << "\n "
21
31
  info << block.split("\n").map{|l| '# ' + l}.join("\n")
22
- info << "\ndef #{meth_call}(vars={})\n # this is a stub, used for reference\nend\n\n\n"
32
+ info << <<-meth
33
+
34
+ def #{meth_call}(vars={})
35
+ ## this is a stub, used for reference
36
+ end
37
+
38
+
39
+ meth
23
40
  end
24
41
  info
25
42
  end
@@ -30,7 +47,8 @@ module Flex
30
47
  all_tags = temp.tags + temp.partials
31
48
  lines = all_tags.map do |t|
32
49
  comments = 'partial' if t.to_s.match(/^_/)
33
- ['', t.to_s] + (temp.variables.has_key?(t) ? ["#{temp.variables[t].inspect},", comments_to_s(comments)] : ["#{t},", comments_to_s(comments, 'required')])
50
+ ['', t.to_s] + (temp.variables.has_key?(t) ? ["#{temp.variables[t].inspect},", comments_to_s(comments)] \
51
+ : ["#{t},", comments_to_s(comments, 'required')])
34
52
  end
35
53
  lines.sort! { |a,b| b[3] <=> a[3] }
36
54
  lines.first[0] = meth_call
@@ -37,7 +37,7 @@ module Flex
37
37
  end
38
38
 
39
39
  def stringify(in_string)
40
- in_string ? "\#{vars[:#{name}]}" : "vars[:#{name}]"
40
+ in_string ? "\#{prunable(:#{name}, vars)}" : "prunable(:#{name}, vars)"
41
41
  end
42
42
 
43
43
  end
@@ -61,7 +61,7 @@ module Flex
61
61
  m['_parent'] = parent if parent
62
62
  routing = get_routing(d)
63
63
  m['_routing'] = routing if routing
64
- line = {action => meta.merge(m)}.to_json
64
+ line = MultiJson.encode({action => meta.merge(m)})
65
65
  line << "\n#{json}" unless action == 'delete'
66
66
  line
67
67
  end.compact
@@ -94,7 +94,8 @@ module Flex
94
94
  case
95
95
  when d.respond_to?(:flex) then d.flex.type
96
96
  when d.respond_to?(:_type) then d._type
97
- when d.is_a?(Hash) then d.delete(:_type) || d.delete('_type') || d.delete(:type) || d.delete('type')
97
+ when d.is_a?(Hash) then d.delete(:_type) || d.delete('_type') ||
98
+ d.delete(:type) || d.delete('type')
98
99
  when d.respond_to?(:type) then d.type
99
100
  end
100
101
  end
@@ -104,7 +105,8 @@ module Flex
104
105
  when d.respond_to?(:flex) && d.flex.parent_instance(false) then d.flex.parent_instance.id
105
106
  when d.respond_to?(:_parent) then d._parent
106
107
  when d.respond_to?(:parent) then d.parent
107
- when d.is_a?(Hash) then d.delete(:_parent) || d.delete('_parent') || d.delete(:parent) || d.delete('parent')
108
+ when d.is_a?(Hash) then d.delete(:_parent) || d.delete('_parent') ||
109
+ d.delete(:parent) || d.delete('parent')
108
110
  end
109
111
  end
110
112
 
@@ -113,13 +115,15 @@ module Flex
113
115
  when d.respond_to?(:flex) && d.flex.routing(false) then d.flex.routing
114
116
  when d.respond_to?(:_routing) then d._routing
115
117
  when d.respond_to?(:routing) then d.routing
116
- when d.is_a?(Hash) then d.delete(:_routing) || d.delete('_routing') || d.delete(:routing) || d.delete('routing')
118
+ when d.is_a?(Hash) then d.delete(:_routing) || d.delete('_routing') ||
119
+ d.delete(:routing) || d.delete('routing')
117
120
  end
118
121
  end
119
122
 
120
123
  def get_id(d)
121
124
  case
122
- when d.is_a?(Hash) then d.delete(:_id) || d.delete('_id') || d.delete(:id) || d.delete('id')
125
+ when d.is_a?(Hash) then d.delete(:_id) || d.delete('_id') ||
126
+ d.delete(:id) || d.delete('id')
123
127
  when d.respond_to?(:id) then d.id
124
128
  end
125
129
  end
@@ -128,6 +132,7 @@ module Flex
128
132
  case
129
133
  when d.respond_to?(:flex_source) then d.flex_source
130
134
  when d.respond_to?(:to_json) then d.to_json
135
+ else MultiJson.encode(d)
131
136
  end
132
137
  end
133
138
 
@@ -22,7 +22,8 @@ module Flex
22
22
  end
23
23
 
24
24
  def erb_process(source)
25
- ERB.new(File.read(source)).result
25
+ varname = "_flex_#{source.hash.to_s.tr('-', '_')}"
26
+ ERB.new(File.read(source), nil, nil, varname).result
26
27
  end
27
28
 
28
29
  def group_array_by(ary)
@@ -17,8 +17,8 @@ Flex::Configuration.configure do |config|
17
17
  # The custom url of your ElasticSearch server
18
18
  # config.base_uri = 'http://localhost:9200'
19
19
 
20
- # Set it to false to skip the logging of the debug infos
21
- # config.debug = true
20
+ # Set it to true to log the debug infos (true by default in development mode)
21
+ # config.debug = false
22
22
 
23
23
  # Debug info are actually valid curl commands
24
24
  # config.debug_to_curl = false
@@ -8,10 +8,10 @@ namespace :flex do
8
8
  desc 'imports from an ActiveRecord or Mongoid models'
9
9
  task(:import => env) { Flex::Tasks.import_models }
10
10
 
11
- desc 'create indices from the Flex::Configuration.config_file file'
11
+ desc 'creates indices from the Flex::Configuration.config_file file'
12
12
  task(:create_indices => env) { Flex::Tasks.create_indices }
13
13
 
14
- desc 'destroy indices in the Flex::Configuration.config_file file'
14
+ desc 'destroys indices in the Flex::Configuration.config_file file'
15
15
  task(:delete_indices => env) { Flex::Tasks.delete_indices }
16
16
 
17
17
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flex
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-21 00:00:00.000000000 Z
12
+ date: 2012-11-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multi_json
16
- requirement: &70249639384360 !ruby/object:Gem::Requirement
16
+ requirement: &70223266050660 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.3.4
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70249639384360
24
+ version_requirements: *70223266050660
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: progressbar
27
- requirement: &70249639383900 !ruby/object:Gem::Requirement
27
+ requirement: &70223266050000 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.11.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70249639383900
35
+ version_requirements: *70223266050000
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: prompter
38
- requirement: &70249639383440 !ruby/object:Gem::Requirement
38
+ requirement: &70223266049300 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 0.1.5
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70249639383440
46
+ version_requirements: *70223266049300
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: irt
49
- requirement: &70249639382940 !ruby/object:Gem::Requirement
49
+ requirement: &70223266048620 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.2.10
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70249639382940
57
+ version_requirements: *70223266048620
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: patron
60
- requirement: &70249639382280 !ruby/object:Gem::Requirement
60
+ requirement: &70223266048160 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 0.4.18
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70249639382280
68
+ version_requirements: *70223266048160
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rest-client
71
- requirement: &70249639381640 !ruby/object:Gem::Requirement
71
+ requirement: &70223266047620 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,15 +76,16 @@ dependencies:
76
76
  version: 1.6.7
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70249639381640
79
+ version_requirements: *70223266047620
80
80
  description: ! 'Flex is an innovative ruby client for ElasticSearch. With Flex your
81
81
  code will be clean, easy to write and read, and very short: "poetic-short". Flex
82
- is fast and efficient, easy to use and customize, and offers ActiveRecord, MongoId
82
+ is fast and efficient, easy to use and customize, and offers ActiveRecord, Mongoid
83
83
  and Rails integration.
84
84
 
85
85
  '
86
86
  email: dd.nexus@gmail.com
87
- executables: []
87
+ executables:
88
+ - flexes
88
89
  extensions: []
89
90
  extra_rdoc_files:
90
91
  - README.md
@@ -92,6 +93,7 @@ files:
92
93
  - LICENSE
93
94
  - README.md
94
95
  - VERSION
96
+ - bin/flexes
95
97
  - flex.gemspec
96
98
  - lib/flex.rb
97
99
  - lib/flex/api_methods.yml
@@ -111,6 +113,7 @@ files:
111
113
  - lib/flex/logger.rb
112
114
  - lib/flex/manager.rb
113
115
  - lib/flex/model.rb
116
+ - lib/flex/prog_bar.rb
114
117
  - lib/flex/rails.rb
115
118
  - lib/flex/rails/engine.rb
116
119
  - lib/flex/rails/helper.rb
@@ -149,7 +152,7 @@ files:
149
152
  homepage: http://github.com/ddnexus/flex
150
153
  licenses: []
151
154
  post_install_message: ! "________________________________________________________________________________\n\n
152
- \ INSTALLATION NOTES\n________________________________________________________________________________\n\nIn
155
+ \ FLEX INSTALLATION NOTES\n________________________________________________________________________________\n\nIn
153
156
  order to use Flex, a supported http-client must be installed on this system.\n\nThe
154
157
  suported http-client gems are \"patron\" and \"rest-client\".\n\nYou should install
155
158
  \"patron\" (a libcurl based gem developed in C) for best\nperformances, or install