nobrainer 0.17.0 → 0.18.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/lib/no_brainer/config.rb +42 -16
  3. data/lib/no_brainer/connection.rb +1 -0
  4. data/lib/no_brainer/connection_manager.rb +1 -1
  5. data/lib/no_brainer/criteria.rb +1 -1
  6. data/lib/no_brainer/criteria/aggregate.rb +8 -5
  7. data/lib/no_brainer/criteria/core.rb +8 -7
  8. data/lib/no_brainer/criteria/count.rb +1 -1
  9. data/lib/no_brainer/criteria/delete.rb +1 -1
  10. data/lib/no_brainer/criteria/extend.rb +31 -0
  11. data/lib/no_brainer/criteria/first.rb +1 -1
  12. data/lib/no_brainer/criteria/index.rb +1 -1
  13. data/lib/no_brainer/criteria/limit.rb +0 -1
  14. data/lib/no_brainer/criteria/order_by.rb +8 -9
  15. data/lib/no_brainer/criteria/pluck.rb +1 -1
  16. data/lib/no_brainer/criteria/raw.rb +1 -1
  17. data/lib/no_brainer/criteria/scope.rb +6 -6
  18. data/lib/no_brainer/criteria/update.rb +3 -3
  19. data/lib/no_brainer/criteria/where.rb +24 -32
  20. data/lib/no_brainer/document/association.rb +5 -5
  21. data/lib/no_brainer/document/association/belongs_to.rb +6 -6
  22. data/lib/no_brainer/document/association/core.rb +11 -11
  23. data/lib/no_brainer/document/association/eager_loader.rb +1 -1
  24. data/lib/no_brainer/document/association/has_many.rb +7 -7
  25. data/lib/no_brainer/document/association/has_many_through.rb +1 -1
  26. data/lib/no_brainer/document/association/has_one.rb +1 -1
  27. data/lib/no_brainer/document/atomic_ops.rb +26 -18
  28. data/lib/no_brainer/document/attributes.rb +9 -8
  29. data/lib/no_brainer/document/callbacks.rb +1 -1
  30. data/lib/no_brainer/document/core.rb +1 -1
  31. data/lib/no_brainer/document/criteria.rb +9 -2
  32. data/lib/no_brainer/document/dirty.rb +1 -3
  33. data/lib/no_brainer/document/index.rb +13 -79
  34. data/lib/no_brainer/document/index/index.rb +83 -0
  35. data/lib/no_brainer/document/index/meta_store.rb +31 -0
  36. data/lib/no_brainer/document/index/synchronizer.rb +68 -0
  37. data/lib/no_brainer/document/lazy_fetch.rb +5 -5
  38. data/lib/no_brainer/document/persistance.rb +27 -7
  39. data/lib/no_brainer/document/polymorphic.rb +1 -1
  40. data/lib/no_brainer/document/types.rb +6 -4
  41. data/lib/no_brainer/document/uniqueness.rb +3 -3
  42. data/lib/no_brainer/document/validation.rb +13 -4
  43. data/lib/no_brainer/fork.rb +1 -0
  44. data/lib/no_brainer/query_runner/database_on_demand.rb +6 -5
  45. data/lib/no_brainer/query_runner/logger.rb +10 -6
  46. data/lib/no_brainer/query_runner/missing_index.rb +5 -4
  47. data/lib/no_brainer/query_runner/reconnect.rb +20 -17
  48. data/lib/no_brainer/query_runner/run_options.rb +3 -0
  49. data/lib/no_brainer/query_runner/table_on_demand.rb +11 -8
  50. data/lib/no_brainer/railtie.rb +5 -5
  51. data/lib/no_brainer/railtie/database.rake +12 -12
  52. data/lib/no_brainer/rql.rb +9 -0
  53. data/lib/nobrainer.rb +5 -3
  54. metadata +8 -8
  55. data/lib/no_brainer/index_manager.rb +0 -9
@@ -7,13 +7,14 @@ class NoBrainer::QueryRunner::MissingIndex < NoBrainer::QueryRunner::Middleware
7
7
  database_name = $2
8
8
  table_name = $3
9
9
 
10
- klass = NoBrainer::Document.all.select { |m| m.table_name == table_name }.first
11
- index_name = klass.get_index_alias_reverse_map[index_name.to_sym]
10
+ model = NoBrainer::Document.all.select { |m| m.table_name == table_name }.first
11
+ index = model.indexes.values.select { |i| i.aliased_name == index_name.to_sym }.first if model
12
+ index_name = index.name if index
12
13
 
13
- if klass && klass.pk_name.to_s == index_name
14
+ if model.try(:pk_name).try(:to_s) == index_name
14
15
  err_msg = "Please update the primary key `#{index_name}` in the table `#{database_name}.#{table_name}`."
15
16
  else
16
- err_msg = "Please run `NoBrainer.update_indexes' or `rake db:update_indexes' to create the index `#{index_name}`"
17
+ err_msg = "Please run `NoBrainer.sync_indexes' or `rake nobrainer:sync_indexes' to create the index `#{index_name}`"
17
18
  err_msg += " in the table `#{database_name}.#{table_name}`."
18
19
  err_msg += " Read http://nobrainer.io/docs/indexes for more information."
19
20
  end
@@ -2,31 +2,34 @@ class NoBrainer::QueryRunner::Reconnect < NoBrainer::QueryRunner::Middleware
2
2
  def call(env)
3
3
  @runner.call(env)
4
4
  rescue StandardError => e
5
- # TODO test that thing
5
+ context ||= { :retries => NoBrainer::Config.max_retries_on_connection_failure }
6
6
  if is_connection_error_exception?(e)
7
- retry if reconnect(e)
7
+ if NoBrainer::Config.max_retries_on_connection_failure == 0
8
+ NoBrainer.disconnect
9
+ else
10
+ # XXX Possibly dangerous, as we could reexecute a non idempotent operation
11
+ # Check the semantics of the db
12
+ retry if reconnect(e, context)
13
+ end
8
14
  end
9
15
  raise
10
16
  end
11
17
 
12
18
  private
13
19
 
14
- def reconnect(e)
15
- # FIXME thread safety? perhaps we need to use a connection pool
16
- # XXX Possibly dangerous, as we could reexecute a non idempotent operation
17
- # Check the semantics of the db
18
- NoBrainer::Config.max_reconnection_tries.times do
19
- begin
20
- warn_reconnect(e)
21
- sleep 1
22
- NoBrainer.connection.reconnect(:noreply_wait => false)
23
- return true
24
- rescue StandardError => e
25
- retry if is_connection_error_exception?(e)
26
- raise
27
- end
20
+ def reconnect(e, context)
21
+ begin
22
+ return false if context[:retries].zero?
23
+ context[:retries] -= 1
24
+
25
+ warn_reconnect(e)
26
+ sleep 1
27
+ NoBrainer.connection.reconnect(:noreply_wait => false)
28
+ return true
29
+ rescue StandardError => e
30
+ retry if is_connection_error_exception?(e)
31
+ raise
28
32
  end
29
- false
30
33
  end
31
34
 
32
35
  def is_connection_error_exception?(e)
@@ -30,6 +30,9 @@ class NoBrainer::QueryRunner::RunOptions < NoBrainer::QueryRunner::Middleware
30
30
 
31
31
  env[:criteria] = env[:options].delete(:criteria)
32
32
 
33
+ env[:auto_create_tables] = env[:options].delete(:auto_create_tables)
34
+ env[:auto_create_databases] = env[:options].delete(:auto_create_databases)
35
+
33
36
  @runner.call(env)
34
37
  end
35
38
  end
@@ -2,32 +2,35 @@ class NoBrainer::QueryRunner::TableOnDemand < NoBrainer::QueryRunner::Middleware
2
2
  def call(env)
3
3
  @runner.call(env)
4
4
  rescue RuntimeError => e
5
- if table_info = table_on_demand_exception?(e)
5
+ if table_info = handle_table_on_demand_exception?(env, e)
6
6
  auto_create_table(env, *table_info)
7
7
  retry
8
8
  end
9
9
  raise
10
10
  end
11
11
 
12
- def table_on_demand_exception?(e)
13
- NoBrainer::Config.auto_create_tables && e.message =~ /^Table `(.+)\.(.+)` does not exist\.$/ && [$1, $2]
12
+ def handle_table_on_demand_exception?(env, e)
13
+ (NoBrainer::Config.auto_create_tables || env[:auto_create_tables]) &&
14
+ e.message =~ /^Table `(.+)\.(.+)` does not exist\.$/ && [$1, $2]
14
15
  end
15
16
 
16
17
  private
17
18
 
18
19
  def auto_create_table(env, database_name, table_name)
19
- klass = NoBrainer::Document.all.select { |m| m.table_name == table_name }.first
20
- if klass.nil?
20
+ model = NoBrainer::Document::Index::MetaStore if table_name == 'nobrainer_index_meta'
21
+ model ||= NoBrainer::Document.all.select { |m| m.table_name == table_name }.first
22
+
23
+ if model.nil?
21
24
  raise "Auto table creation is not working for `#{database_name}.#{table_name}` -- Can't find the corresponding model."
22
25
  end
23
26
 
24
- if env[:auto_create_table] == [database_name, table_name]
27
+ if env[:last_auto_create_table] == [database_name, table_name]
25
28
  raise "Auto table creation is not working for `#{database_name}.#{table_name}`"
26
29
  end
27
- env[:auto_create_table] = [database_name, table_name]
30
+ env[:last_auto_create_table] = [database_name, table_name]
28
31
 
29
32
  NoBrainer.with_database(database_name) do
30
- NoBrainer.table_create(table_name, :primary_key => klass.pk_name)
33
+ NoBrainer.table_create(table_name, :primary_key => model.pk_name)
31
34
  end
32
35
  rescue RuntimeError => e
33
36
  # We might have raced with another table create
@@ -5,9 +5,9 @@ class NoBrainer::Railtie < Rails::Railtie
5
5
  config.eager_load_namespaces << NoBrainer
6
6
 
7
7
  config.action_dispatch.rescue_responses.merge!(
8
- "NoBrainer::Errors::DocumentNotFound" => :not_found,
9
- "NoBrainer::Errors::DocumentInvalid" => :unprocessable_entity,
10
- "NoBrainer::Errors::InvalidType" => :bad_request,
8
+ "NoBrainer::Error::DocumentNotFound" => :not_found,
9
+ "NoBrainer::Error::DocumentInvalid" => :unprocessable_entity,
10
+ "NoBrainer::Error::InvalidType" => :bad_request,
11
11
  )
12
12
 
13
13
  rake_tasks do
@@ -27,14 +27,14 @@ class NoBrainer::Railtie < Rails::Railtie
27
27
  NoBrainer::Config.configure unless NoBrainer::Config.configured?
28
28
 
29
29
  if defined?(ActiveRecord) && NoBrainer::Config.warn_on_active_record
30
- STDERR.puts "[NoBrainer] WARNING: ActiveRecord is loaded which is probably not what you want."
30
+ STDERR.puts "[NoBrainer] ActiveRecord is loaded which is probably not what you want."
31
31
  STDERR.puts "[NoBrainer] Follow the instructions on http://nobrainer.io/docs/configuration/#removing_activerecord"
32
32
  STDERR.puts "[NoBrainer] Configure NoBrainer with 'config.warn_on_active_record = false' to disable with warning."
33
33
  end
34
34
 
35
35
  if defined?(Mongoid)
36
36
  STDERR.puts "[NoBrainer] WARNING: Mongoid is loaded, and we conflict on the symbol decorations"
37
- STDERR.puts "[NoBrainer] They are used in queries like Model.where(:tags.in => ['fun', 'stuff'])"
37
+ STDERR.puts "[NoBrainer] They are used in queries such as Model.where(:tags.in => ['fun', 'stuff'])"
38
38
  STDERR.puts "[NoBrainer] This is a problem!"
39
39
  end
40
40
 
@@ -1,27 +1,27 @@
1
- namespace :db do
1
+ namespace :nobrainer do
2
2
  desc 'Drop the database'
3
3
  task :drop => :environment do
4
4
  NoBrainer.drop!
5
5
  end
6
6
 
7
- desc 'Load seed data from db/seeds.rb'
8
- task :seed => :environment do
9
- Rails.application.load_seed
7
+ desc 'Synchronize index definitions'
8
+ task :sync_indexes => :environment do
9
+ NoBrainer.sync_indexes(:verbose => true)
10
10
  end
11
11
 
12
- desc 'Create and drop indexes on the database'
13
- task :update_indexes => :environment do
14
- NoBrainer.update_indexes(:verbose => true)
12
+ task :sync_indexes_quiet => :environment do
13
+ NoBrainer.sync_indexes
15
14
  end
16
15
 
17
- task :update_indexes_quiet => :environment do
18
- NoBrainer.update_indexes
16
+ desc 'Load seed data from db/seeds.rb'
17
+ task :seed => :environment do
18
+ Rails.application.load_seed
19
19
  end
20
20
 
21
- desc 'Equivalent to db:update_indexes + db:seed'
22
- task :setup => [ :update_indexes_quiet, :seed ]
21
+ desc 'Equivalent to :sync_indexes_quiet + :seed'
22
+ task :setup => [ :sync_indexes_quiet, :seed ]
23
23
 
24
- desc 'Equivalent to db:drop + db:setup'
24
+ desc 'Equivalent to :drop + :setup'
25
25
  task :reset => [ :drop, :setup ]
26
26
 
27
27
  task :create => :environment do
@@ -2,6 +2,15 @@ module NoBrainer::RQL
2
2
  include RethinkDB::Term::TermType
3
3
  extend self
4
4
 
5
+ def reset_lambda_var_counter
6
+ RethinkDB::RQL.class_variable_set(:@@gensym_cnt, 0)
7
+ end
8
+
9
+ def rql_proc_as_json(block)
10
+ reset_lambda_var_counter
11
+ RethinkDB::RQL.new.new_func(&block).as_json
12
+ end
13
+
5
14
  def is_write_query?(rql_query)
6
15
  type_of(rql_query) == :write
7
16
  end
data/lib/nobrainer.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  require 'set'
2
2
  require 'active_support'
3
- %w(module/delegation module/attribute_accessors class/attribute object/blank object/inclusion object/deep_dup
4
- object/try hash/keys hash/indifferent_access hash/reverse_merge hash/deep_merge array/extract_options)
3
+ %w(module/delegation module/attribute_accessors module/introspection
4
+ class/attribute object/blank object/inclusion object/deep_dup
5
+ object/try hash/keys hash/indifferent_access hash/reverse_merge
6
+ hash/deep_merge array/extract_options)
5
7
  .each { |dep| require "active_support/core_ext/#{dep}" }
6
8
 
7
9
  module NoBrainer
@@ -23,7 +25,7 @@ module NoBrainer
23
25
 
24
26
  delegate :configure, :logger, :to => 'NoBrainer::Config'
25
27
  delegate :run, :to => 'NoBrainer::QueryRunner'
26
- delegate :update_indexes, :to => 'NoBrainer::IndexManager'
28
+ delegate :sync_indexes, :to => 'NoBrainer::Document::Index::Synchronizer'
27
29
  delegate :with, :with_database, :to => 'NoBrainer::QueryRunner::RunOptions'
28
30
 
29
31
  def jruby?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nobrainer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.0
4
+ version: 0.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicolas Viennot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-25 00:00:00.000000000 Z
11
+ date: 2014-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rethinkdb
@@ -87,6 +87,7 @@ files:
87
87
  - lib/no_brainer/criteria/count.rb
88
88
  - lib/no_brainer/criteria/delete.rb
89
89
  - lib/no_brainer/criteria/enumerable.rb
90
+ - lib/no_brainer/criteria/extend.rb
90
91
  - lib/no_brainer/criteria/first.rb
91
92
  - lib/no_brainer/criteria/index.rb
92
93
  - lib/no_brainer/criteria/limit.rb
@@ -117,6 +118,9 @@ files:
117
118
  - lib/no_brainer/document/dynamic_attributes.rb
118
119
  - lib/no_brainer/document/id.rb
119
120
  - lib/no_brainer/document/index.rb
121
+ - lib/no_brainer/document/index/index.rb
122
+ - lib/no_brainer/document/index/meta_store.rb
123
+ - lib/no_brainer/document/index/synchronizer.rb
120
124
  - lib/no_brainer/document/injection_layer.rb
121
125
  - lib/no_brainer/document/lazy_fetch.rb
122
126
  - lib/no_brainer/document/missing_attributes.rb
@@ -140,7 +144,6 @@ files:
140
144
  - lib/no_brainer/document/validation.rb
141
145
  - lib/no_brainer/error.rb
142
146
  - lib/no_brainer/fork.rb
143
- - lib/no_brainer/index_manager.rb
144
147
  - lib/no_brainer/loader.rb
145
148
  - lib/no_brainer/locale/en.yml
146
149
  - lib/no_brainer/query_runner.rb
@@ -164,10 +167,7 @@ homepage: http://nobrainer.io
164
167
  licenses:
165
168
  - LGPLv3
166
169
  metadata: {}
167
- post_install_message: |2
168
-
169
- WARNING [NoBrainer] API change: save() is now save?() and save!() is now save()
170
- WARNING [NoBrainer] Same for update_attributes
170
+ post_install_message:
171
171
  rdoc_options: []
172
172
  require_paths:
173
173
  - lib
@@ -183,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
183
  version: '0'
184
184
  requirements: []
185
185
  rubyforge_project:
186
- rubygems_version: 2.2.2
186
+ rubygems_version: 2.4.2
187
187
  signing_key:
188
188
  specification_version: 4
189
189
  summary: ORM for RethinkDB
@@ -1,9 +0,0 @@
1
- module NoBrainer::IndexManager
2
- def self.update_indexes(options={})
3
- NoBrainer::Document.all.each { |model| model.perform_update_indexes(options.merge(:wait => false)) }
4
- unless options[:wait] == false
5
- NoBrainer::Document.all.each { |model| model.wait_for_index(nil) }
6
- end
7
- true
8
- end
9
- end