nobrainer 0.17.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
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