nobrainer 0.32.0 → 0.35.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 28eb4dcb91f5c381ec20a21ed37d01992a3d6eb7
4
- data.tar.gz: 395bfd26595f42e290805ebb9ebfa82dda89b99a
2
+ SHA256:
3
+ metadata.gz: c6d7ce930d1fba4a7c3e3f6368c7a9650c0a298ae1bd46517097284591ae1a22
4
+ data.tar.gz: 6d9cc4350f77a229f779acc0d88f4893f146b0fd0028f9a214c29da9e4f5e70a
5
5
  SHA512:
6
- metadata.gz: 390139f43cf843350f0c345f42b15dfef87174961123376643d193dfd0265975daf4c2b3979f6497b605d4ed08175570df76e96e907a01ab3ed8168e71d27253
7
- data.tar.gz: 5fb98fd5f37020b9bda60837a0e86d1f761953a5b0c0220a1e22e79d2f823419a39a927e1c6592791bd6e90111c1cc9bf1f33c48137a01cd6d33e40fb545792a
6
+ metadata.gz: fcb9ef68e4ce874a89761465e0b9861182feb526665cfd08a19be7019a8a0e5f716e6fdd3d940648a42fe1fe1f2e1bba277291778a3752e06c21e67bb94163d3
7
+ data.tar.gz: fa9b10e21bfd4a987821f365e840c95b6314f5bbaf32efeebe0810f9d8157fe6b0f4f9607ab1931d278f2d22beb24442b0ed2f1115e360a7f82aa8ad3c5a111b
data/CHANGELOG.md ADDED
@@ -0,0 +1,137 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+
10
+ ## [0.35.0] - 2021-08-08
11
+ ### Added
12
+ - Dockerfile, docker-compose and Earthfile
13
+ - Test Ruby 3 + Rails 6 on Travis CI
14
+ - Implements the ReQL `during` command
15
+
16
+ ## [0.34.1] - 2021-02-18
17
+ ### Fixed
18
+ - Defining attributes at class level (Rails 6.1 compatibity)
19
+ - Ruby 2.7 support
20
+
21
+ ## [0.34.0] - 2019-10-15
22
+ ### Added
23
+ - Rails 6 support
24
+ - Support for the nonvoting_replica_tags table option
25
+
26
+ ## [0.33.0] - 2016-11-27
27
+ ### Added
28
+ - Allow a run_options to be configured globally
29
+ - Support for username and password authentication
30
+
31
+ ### Changed
32
+ - Use URI.decode() for user and password in the RethinkDB URL
33
+ - Also comment active_record lines in the config/initializers/*.rb on gem installation
34
+ - Removed .unscoped when fetching belongs_to associations
35
+ - update_all() operates without ordering
36
+ - has_many dependent refactoring
37
+ - Default logger should be STDERR if the rails logger is not initialized
38
+ - Locking: changes lock key type from string to text in order to support more than 255 characters keys by default, the key type needs to be Text.
39
+ - field type for rql_function to :text
40
+
41
+ ### Fixed
42
+ - Model reloading with Rails5
43
+ - Rails 5 Strong Parameters: Strong parameters are not a Hash anymore in Rails 5, but support transforming into a hash
44
+
45
+ ## [0.32.0] - 2016-06-05
46
+ ### Added
47
+ - Compatiblity with Rails5
48
+ - order() as an alias of order_by()
49
+ - Provide attribute_will_change!() for compatibility
50
+
51
+ ### Changed
52
+ - Comments more active_record related configs during install
53
+
54
+ ### Fixed
55
+ - Rails 5 deprecation: Using ActiveSupport::Reloader instead of ActionDispatch::Reloader to be ready when Rails 5 hits
56
+ - config syntax
57
+
58
+ ### Removed
59
+ - JRuby and Rbx in travis-ci
60
+
61
+ ## [0.31.0] - 2016-02-07
62
+ ### Added
63
+ - Allow belongs_to association names to be used in upsert params
64
+ - `uniq` shorthand for the belongs_to association
65
+ - Allow self-referential belongs_to
66
+ - Prevent double loading of the same model
67
+ - Use index for where(XXX.defined => true)
68
+ - Guard against bad virtual attribute expressions
69
+ - Allow non existing attributes to be lazy fetched
70
+ - Added back update_attributes()
71
+
72
+ ### Fixed
73
+ - Fix join on keys that are undefined
74
+
75
+ ### Changed
76
+ - where() leverages the association translation abstraction
77
+ - Primary keys time offset should operate on fixed timezone
78
+
79
+ ### Removed
80
+ - Removing locking around sync_table_config
81
+
82
+ ## [0.30.0] - 2015-10-03
83
+ ### Added
84
+ - Add rbx-2 to .travis.yml
85
+ - Add the virtual attribute feature
86
+ - Lock: Allow find() to get locks by key
87
+ - Locks: Allow default expire/timeout values to be passed in new()
88
+ - NoBrainer::ReentrantLock implementation
89
+ - Allow compound indexes to be declared with an implicit name
90
+ - Allow polymorphic queries with first_or_create under certain conditions
91
+
92
+ ### Changed
93
+ - Prevent first_or_create() to accept block with arguments
94
+
95
+ ### Fixed
96
+ - Fix rails issue with tests and profiler
97
+ - Fix where() .include modifier with type checking
98
+ - Virtual attribute option fix
99
+ - Discard documents when join() encounter a nil join key
100
+ - Locks: bug fix: allow small timeouts in lock()
101
+ - Fix reentrant lock counter on steals
102
+
103
+ [Unreleased]: https://github.com/nobrainerorm/nobrainer/compare/v0.35.0...HEAD
104
+ [0.35.0]: https://github.com/nobrainerorm/nobrainer/compare/v0.34.1...v0.35.0
105
+ [0.34.1]: https://github.com/nobrainerorm/nobrainer/compare/v0.34.0...v0.34.1
106
+ [0.34.0]: https://github.com/nobrainerorm/nobrainer/compare/v0.33.0...v0.34.0
107
+ [0.33.0]: https://github.com/nobrainerorm/nobrainer/compare/v0.32.0...v0.33.0
108
+ [0.32.0]: https://github.com/nobrainerorm/nobrainer/compare/v0.31.0...v0.32.0
109
+ [0.31.0]: https://github.com/nobrainerorm/nobrainer/compare/v0.30.0...v0.31.0
110
+ [0.30.0]: https://github.com/nobrainerorm/nobrainer/compare/v0.29.0...v0.30.0
111
+ [0.29.0]: https://github.com/nobrainerorm/nobrainer/compare/0.28.0...0.29.0
112
+ [0.28.0]: https://github.com/nobrainerorm/nobrainer/compare/0.27.0...0.28.0
113
+ [0.27.0]: https://github.com/nobrainerorm/nobrainer/compare/0.26.0...0.27.0
114
+ [0.26.0]: https://github.com/nobrainerorm/nobrainer/compare/0.25.1...0.26.0
115
+ [0.25.1]: https://github.com/nobrainerorm/nobrainer/compare/0.25.0...0.25.1
116
+ [0.25.0]: https://github.com/nobrainerorm/nobrainer/compare/0.24.0...0.25.0
117
+ [0.24.0]: https://github.com/nobrainerorm/nobrainer/compare/0.23.0...0.24.0
118
+ [0.23.0]: https://github.com/nobrainerorm/nobrainer/compare/0.22.0...0.23.0
119
+ [0.22.0]: https://github.com/nobrainerorm/nobrainer/compare/0.21.0...0.22.0
120
+ [0.21.0]: https://github.com/nobrainerorm/nobrainer/compare/0.20.0...0.21.0
121
+ [0.20.0]: https://github.com/nobrainerorm/nobrainer/compare/0.19.0...0.20.0
122
+ [0.19.0]: https://github.com/nobrainerorm/nobrainer/compare/0.18.1...0.19.0
123
+ [0.18.1]: https://github.com/nobrainerorm/nobrainer/compare/0.18.0...0.18.1
124
+ [0.18.0]: https://github.com/nobrainerorm/nobrainer/compare/0.17.0...0.18.0
125
+ [0.17.0]: https://github.com/nobrainerorm/nobrainer/compare/0.16.0...0.17.0
126
+ [0.16.0]: https://github.com/nobrainerorm/nobrainer/compare/0.15.0...0.16.0
127
+ [0.15.0]: https://github.com/nobrainerorm/nobrainer/compare/0.14.0...0.15.0
128
+ [0.15.0]: https://github.com/nobrainerorm/nobrainer/compare/0.14.0...0.15.0
129
+ [0.14.0]: https://github.com/nobrainerorm/nobrainer/compare/0.13.1...0.14.0
130
+ [0.13.1]: https://github.com/nobrainerorm/nobrainer/compare/0.13.0...0.13.1
131
+ [0.13.0]: https://github.com/nobrainerorm/nobrainer/compare/0.12.0...0.13.0
132
+ [0.12.0]: https://github.com/nobrainerorm/nobrainer/compare/0.11.0...0.12.0
133
+ [0.11.0]: https://github.com/nobrainerorm/nobrainer/compare/0.10.0...0.11.0
134
+ [0.10.0]: https://github.com/nobrainerorm/nobrainer/compare/0.9.1...0.10.0
135
+ [0.9.1]: https://github.com/nobrainerorm/nobrainer/compare/0.9.0...0.9.1
136
+ [0.9.0]: https://github.com/nobrainerorm/nobrainer/compare/0.8.0...0.9.0
137
+ [0.8.0]: https://github.com/nobrainerorm/nobrainer/releases/tag/0.8.0
@@ -10,9 +10,10 @@ module NoBrainer::Config
10
10
  :logger => { :default => ->{ default_logger } },
11
11
  :colorize_logger => { :default => ->{ true }, :valid_values => [true, false] },
12
12
  :warn_on_active_record => { :default => ->{ true }, :valid_values => [true, false] },
13
- :durability => { :default => ->{ default_durability }, :valid_values => [:hard, :soft] },
13
+ :durability => { :default => ->{ nil } }, # legacy
14
14
  :table_options => { :default => ->{ {:shards => 1, :replicas => 1, :write_acks => :majority} },
15
- :valid_keys => [:shards, :replicas, :primary_replica_tag, :write_acks, :durability] },
15
+ :valid_keys => [:durability, :shards, :replicas, :primary_replica_tag, :nonvoting_replica_tags, :write_acks] },
16
+ :run_options => { :default => ->{ {:durability => default_durability} } },
16
17
  :max_string_length => { :default => ->{ 255 } },
17
18
  :user_timezone => { :default => ->{ :local }, :valid_values => [:unchanged, :utc, :local] },
18
19
  :db_timezone => { :default => ->{ :utc }, :valid_values => [:unchanged, :utc, :local] },
@@ -51,6 +52,10 @@ module NoBrainer::Config
51
52
  @geo_options = value.try(:symbolize_keys)
52
53
  end
53
54
 
55
+ def run_options=(value)
56
+ @run_options = value.try(:symbolize_keys)
57
+ end
58
+
54
59
  def assert_valid_options
55
60
  SETTINGS.each do |k,v|
56
61
  assert_value_in(k, v[:valid_values]) if v[:valid_values]
@@ -102,7 +107,10 @@ module NoBrainer::Config
102
107
  end
103
108
 
104
109
  def default_app_name
105
- defined?(Rails) ? Rails.application.class.parent_name.underscore.presence : nil rescue nil
110
+ return unless defined?(Rails)
111
+ NoBrainer.rails6? ?
112
+ Rails.application.class.module_parent_name.underscore.presence :
113
+ Rails.application.class.parent_name.underscore.presence rescue nil
106
114
  end
107
115
 
108
116
  def default_environment
@@ -119,9 +127,10 @@ module NoBrainer::Config
119
127
  db ||= "#{self.app_name}_#{self.environment}" if self.app_name && self.environment
120
128
  host = ENV['RETHINKDB_HOST'] || ENV['RDB_HOST'] || 'localhost'
121
129
  port = ENV['RETHINKDB_PORT'] || ENV['RDB_PORT']
122
- auth = ENV['RETHINKDB_AUTH'] || ENV['RDB_AUTH']
130
+ user = ENV['RETHINKDB_USER'] || ENV['RDB_USER']
131
+ pass = ENV['RETHINKDB_PASSWORD'] || ENV['RDB_PASSWORD'] || ENV['RETHINKDB_AUTH'] || ENV['RDB_AUTH']
123
132
  url = ENV['RETHINKDB_URL'] || ENV['RDB_URL']
124
- url ||= "rethinkdb://#{":#{auth}@" if auth}#{host}#{":#{port}" if port}/#{db}" if db
133
+ url ||= "rethinkdb://#{"#{user}:#{pass}@" if (user || pass)}#{host}#{":#{port}" if port}/#{db}" if db
125
134
  url
126
135
  end
127
136
 
@@ -133,7 +142,8 @@ module NoBrainer::Config
133
142
  end
134
143
 
135
144
  def default_logger
136
- defined?(Rails.logger) ? Rails.logger : Logger.new(STDERR).tap { |l| l.level = Logger::WARN }
145
+ (Rails.logger if defined?(Rails.logger)) ||
146
+ Logger.new(STDERR).tap { |l| l.level = Logger::WARN }
137
147
  end
138
148
 
139
149
  def default_durability
@@ -18,7 +18,9 @@ class NoBrainer::Connection
18
18
  "Invalid URI. Expecting something like rethinkdb://host:port/database. Got #{uri}"
19
19
  end
20
20
 
21
- { :auth_key => uri.password,
21
+ {
22
+ :user => uri.user && CGI.unescape(uri.user),
23
+ :password => uri.password && CGI.unescape(uri.password),
22
24
  :host => uri.host,
23
25
  :port => uri.port || 28015,
24
26
  :db => uri.path.gsub(/^\//, ''),
@@ -27,7 +29,7 @@ class NoBrainer::Connection
27
29
  end
28
30
 
29
31
  def uri
30
- "rethinkdb://#{'****@' if parsed_uri[:auth_key]}#{parsed_uri[:host]}:#{parsed_uri[:port]}/#{parsed_uri[:db]}"
32
+ "rethinkdb://#{'****@' if parsed_uri[:password]}#{parsed_uri[:host]}:#{parsed_uri[:port]}/#{parsed_uri[:db]}"
31
33
  end
32
34
 
33
35
  def raw
@@ -45,6 +47,6 @@ class NoBrainer::Connection
45
47
  end
46
48
 
47
49
  def current_db
48
- NoBrainer.current_run_options.try(:[], :db) || default_db
50
+ NoBrainer.current_run_options[:db] || default_db
49
51
  end
50
52
  end
@@ -16,6 +16,6 @@ module NoBrainer::Criteria::Update
16
16
  # can't use without_distinct when passed a block as the operation may be
17
17
  # performed many times, which might not be idempotent.
18
18
  clause = block ? self : without_distinct
19
- run { clause.without_plucking.to_rql.__send__(type, *args, &block) }
19
+ run { clause.without_plucking.without_ordering.to_rql.__send__(type, *args, &block) }
20
20
  end
21
21
  end
@@ -104,6 +104,7 @@ module NoBrainer::Criteria::Where
104
104
  when :between then [key_modifier, op, (cast_value(value.min)..cast_value(value.max))]
105
105
  when :include then ensure_scalar_for(op); [:any, :eq, cast_value(value)]
106
106
  when :defined, :undefined then ensure_scalar_for(op); [key_modifier, op, cast_value(value)]
107
+ when :during then [key_modifier, op, [cast_value(value.first), cast_value(value.last)]]
107
108
  else [key_modifier, op, cast_value(value)]
108
109
  end
109
110
  BinaryOperator.new(new_key_path, new_key_modifier, new_op, new_value, model, true)
@@ -132,6 +133,7 @@ module NoBrainer::Criteria::Where
132
133
  when :between then (lvalue >= value.min) & (lvalue <= value.max)
133
134
  when :in then RethinkDB::RQL.new.expr(value).contains(lvalue)
134
135
  when :intersects then lvalue.intersects(value.to_rql)
136
+ when :during then lvalue.during(value.first, value.last)
135
137
  when :near
136
138
  # XXX options[:max_results] is not used, seems to be a workaround of rethinkdb index implementation.
137
139
  circle = value[:circle]
@@ -244,6 +246,7 @@ module NoBrainer::Criteria::Where
244
246
  when Symbol::Decoration
245
247
  case clause.args.size
246
248
  when 1 then parse_clause_stub(clause, clause.args.first, options)
249
+ when 2 then parse_clause_stub(clause, clause.args, options)
247
250
  else raise "Invalid argument: #{clause}"
248
251
  end
249
252
  else raise "Invalid clause: #{clause}"
@@ -263,6 +266,11 @@ module NoBrainer::Criteria::Where
263
266
  else instantiate_binary_op(key.to_sym, :eq, value, options)
264
267
  end
265
268
  when Symbol::Decoration then
269
+ # The :eq operator can have only one arg
270
+ if key.decorator == :eq && value.is_a?(Array) && value.size > 1
271
+ raise "Invalid key: #{key}"
272
+ end
273
+
266
274
  case key.decorator
267
275
  when :any, :all, :not then instantiate_binary_op(key, :eq, value, options)
268
276
  when :gte then instantiate_binary_op(key.symbol, :ge, value, options)
@@ -35,7 +35,7 @@ class NoBrainer::Document::Association::BelongsTo
35
35
  end
36
36
 
37
37
  def base_criteria
38
- target_model.without_ordering.unscoped
38
+ target_model.without_ordering
39
39
  end
40
40
 
41
41
  def hook
@@ -51,7 +51,8 @@ module NoBrainer::Document::Association::Core
51
51
  return model_name if model_name.is_a?(Module)
52
52
 
53
53
  model_name = model_name.to_s
54
- current_module = @owner_model.parent
54
+ current_module = NoBrainer.rails6? ? @owner_model.module_parent : @owner_model.parent
55
+
55
56
  return model_name.constantize if current_module == Object
56
57
  return model_name.constantize if model_name =~ /^::/
57
58
  return model_name.constantize if !current_module.const_defined?(model_name)
@@ -97,13 +97,16 @@ class NoBrainer::Document::Association::HasMany
97
97
  ->(target){ set_inverses_of([target]) if target.is_a?(NoBrainer::Document) }
98
98
  end
99
99
 
100
+ def dependent_criteria
101
+ target_criteria.unscoped
102
+ end
103
+
100
104
  def before_destroy_callback
101
- criteria = target_criteria.unscoped.without_cache
102
105
  case metadata.options[:dependent]
103
- when :destroy then criteria.destroy_all
104
- when :delete then criteria.delete_all
105
- when :nullify then criteria.update_all(foreign_key => nil)
106
- when :restrict then raise NoBrainer::Error::ChildrenExist unless criteria.count.zero?
106
+ when :destroy then dependent_criteria.destroy_all
107
+ when :delete then dependent_criteria.delete_all
108
+ when :nullify then dependent_criteria.update_all(foreign_key => nil)
109
+ when :restrict then raise NoBrainer::Error::ChildrenExist unless dependent_criteria.empty?
107
110
  end
108
111
  end
109
112
  end
@@ -70,6 +70,7 @@ module NoBrainer::Document::Attributes
70
70
  end
71
71
 
72
72
  def assign_attributes(attrs, options={})
73
+ attrs = attrs.to_h if !attrs.is_a?(Hash) && attrs.respond_to?(:to_h)
73
74
  raise ArgumentError, "To assign attributes, please pass a hash instead of `#{attrs.class}'" unless attrs.is_a?(Hash)
74
75
 
75
76
  if options[:pristine]
@@ -10,7 +10,7 @@ class NoBrainer::Document::Index::MetaStore
10
10
 
11
11
  field :table_name, :type => String, :required => true
12
12
  field :index_name, :type => String, :required => true
13
- field :rql_function, :type => String, :required => true
13
+ field :rql_function, :type => Text, :required => true
14
14
 
15
15
  def rql_function=(value)
16
16
  super(JSON.dump(value))
@@ -6,7 +6,7 @@ module NoBrainer::Document::TableConfig
6
6
 
7
7
  autoload :Synchronizer
8
8
 
9
- VALID_TABLE_CONFIG_OPTIONS = [:name, :durability, :shards, :replicas, :primary_replica_tag, :write_acks]
9
+ VALID_TABLE_CONFIG_OPTIONS = [:name, :durability, :shards, :replicas, :primary_replica_tag, :nonvoting_replica_tags, :write_acks]
10
10
 
11
11
  included do
12
12
  cattr_accessor :table_config_options, :instance_accessor => false
@@ -78,7 +78,7 @@ module NoBrainer::Document::TableConfig
78
78
  def sync_table_config(options={})
79
79
  c = table_create_options
80
80
  table_config.update!(c.slice(:durability, :primary_key, :write_acks))
81
- NoBrainer.run { rql_table.reconfigure(c.slice(:shards, :replicas, :primary_replica_tag)) }
81
+ NoBrainer.run { rql_table.reconfigure(c.slice(:shards, :replicas, :primary_replica_tag, :nonvoting_replica_tags)) }
82
82
  true
83
83
  end
84
84
 
@@ -1 +1 @@
1
- # Look in lib/no_brainer/geo.rb instead
1
+ # Look in lib/no_brainer/geo/*.rb instead
@@ -1,6 +1,9 @@
1
1
  module NoBrainer::Document::Types
2
2
  extend ActiveSupport::Concern
3
3
 
4
+ mattr_accessor :loaded_extensions
5
+ self.loaded_extensions = Set.new
6
+
4
7
  included { before_validation :add_type_errors }
5
8
 
6
9
  def add_type_errors
@@ -111,8 +114,6 @@ module NoBrainer::Document::Types
111
114
  end
112
115
 
113
116
  class << self
114
- mattr_accessor :loaded_extensions
115
- self.loaded_extensions = Set.new
116
117
  def load_type_extensions(model)
117
118
  unless loaded_extensions.include?(model)
118
119
  begin
@@ -8,7 +8,7 @@ class NoBrainer::Lock
8
8
  # Since PKs are limited to 127 characters, we can't use the user's key as a PK
9
9
  # as it could be arbitrarily long.
10
10
  field :key_hash, :type => String, :primary_key => true, :default => ->{ Digest::SHA1.base64digest(key.to_s) }
11
- field :key, :type => String
11
+ field :key, :type => Text
12
12
  field :instance_token, :type => String, :default => ->{ get_new_instance_token }
13
13
  field :expires_at, :type => Time
14
14
 
@@ -27,6 +27,7 @@ class NoBrainer::Lock
27
27
  @default_options = options.slice(:expire, :timeout)
28
28
  options.delete(:expire); options.delete(:timeout);
29
29
 
30
+ key = key.to_s if key.is_a?(Symbol)
30
31
  super(options.merge(:key => key))
31
32
  raise ArgumentError unless valid?
32
33
  end
@@ -16,7 +16,8 @@ class NoBrainer::QueryRunner::Reconnect < NoBrainer::QueryRunner::Middleware
16
16
  when RethinkDB::RqlError
17
17
  e.message =~ /lost contact/ ||
18
18
  e.message =~ /(P|p)rimary .* not available/||
19
- e.message =~ /Connection.*closed/
19
+ e.message =~ /Connection.*closed/ ||
20
+ e.message =~ /Connection.*refused/
20
21
  else
21
22
  false
22
23
  end
@@ -10,7 +10,10 @@ class NoBrainer::QueryRunner::RunOptions < NoBrainer::QueryRunner::Middleware
10
10
  end
11
11
 
12
12
  def self.current_run_options
13
- Thread.current[:nobrainer_run_with] || {}
13
+ options = NoBrainer::Config.run_options
14
+ options = options.merge(:durability => NoBrainer::Config.durability) if NoBrainer::Config.durability
15
+ options = options.merge(Thread.current[:nobrainer_run_with]) if Thread.current[:nobrainer_run_with]
16
+ options
14
17
  end
15
18
 
16
19
  def self.run_with(options={}, &block)
@@ -29,17 +32,9 @@ class NoBrainer::QueryRunner::RunOptions < NoBrainer::QueryRunner::Middleware
29
32
  end
30
33
 
31
34
  def call(env)
32
- options = env[:options].symbolize_keys
33
- options = self.class.current_run_options.merge(options)
34
-
35
- if NoBrainer::Config.durability.to_s != 'hard'
36
- options[:durability] ||= NoBrainer::Config.durability
37
- end
38
-
39
- options[:db] = options[:db].to_s if options[:db]
40
- if options[:db].blank? || options[:db] == NoBrainer.default_db
41
- options.delete(:db)
42
- end
35
+ options = self.class.current_run_options
36
+ options = options.merge(env[:options].symbolize_keys)
37
+ options = prune_default_run_options(options)
43
38
 
44
39
  env[:criteria] = options.delete(:criteria)
45
40
 
@@ -52,4 +47,14 @@ class NoBrainer::QueryRunner::RunOptions < NoBrainer::QueryRunner::Middleware
52
47
  env[:options] = options
53
48
  @runner.call(env)
54
49
  end
50
+
51
+ def prune_default_run_options(options)
52
+ options = options.dup
53
+ options.delete(:durability) if options[:durability].to_s == 'hard'
54
+
55
+ options[:db] = options[:db].to_s if options[:db]
56
+ options.delete(:db) if options[:db].blank? || options[:db] == NoBrainer.default_db
57
+
58
+ options
59
+ end
55
60
  end
@@ -34,6 +34,16 @@ class NoBrainer::QueryRunner::TableOnDemand < NoBrainer::QueryRunner::Middleware
34
34
  r.table_create(table_name, create_options.reject { |k,_| k.in? [:name, :write_acks] })
35
35
  end
36
36
 
37
+ # Prevent duplicate table errors on a cluster.
38
+ # Workaround from https://github.com/rethinkdb/rethinkdb/issues/4898#issuecomment-270267740
39
+ NoBrainer.run(:db => 'rethinkdb') do |r|
40
+ r.table('table_config')
41
+ .filter({db: db_name, name: table_name})
42
+ .order_by('id')
43
+ .slice(1)
44
+ .delete
45
+ end
46
+
37
47
  if create_options[:write_acks] && create_options[:write_acks] != 'single'
38
48
  NoBrainer.run(:db => db_name) do |r|
39
49
  r.table(table_name).config().update(:write_acks => create_options[:write_acks])
@@ -26,8 +26,10 @@ class NoBrainer::Railtie < Rails::Railtie
26
26
  config.after_initialize do
27
27
  NoBrainer::Config.configure unless NoBrainer::Config.configured?
28
28
 
29
- (NoBrainer.rails5? ? ActiveSupport::Reloader : ActionDispatch::Reloader).to_prepare do
30
- NoBrainer::Loader.cleanup
29
+ if NoBrainer.rails5?
30
+ ActiveSupport::Reloader.before_class_unload { NoBrainer::Loader.cleanup }
31
+ else
32
+ ActionDispatch::Reloader.to_prepare { NoBrainer::Loader.cleanup }
31
33
  end
32
34
  end
33
35
 
@@ -1,5 +1,5 @@
1
1
  module NoBrainer::SymbolDecoration
2
- NON_CHAINABLE_OPERATORS = %w(in eq gt ge gte lt le lte defined undefined near intersects include).map(&:to_sym)
2
+ NON_CHAINABLE_OPERATORS = %w(in eq gt ge gte lt le lte defined undefined near intersects include during).map(&:to_sym)
3
3
  CHAINABLE_OPERATORS = %w(not any all).map(&:to_sym)
4
4
  OPERATORS = CHAINABLE_OPERATORS + NON_CHAINABLE_OPERATORS
5
5
 
@@ -7,4 +7,5 @@ class NoBrainer::System::TableConfig
7
7
  field :primary_key
8
8
  field :shards
9
9
  field :write_acks
10
+ field :indexes
10
11
  end
data/lib/nobrainer.rb CHANGED
@@ -41,6 +41,10 @@ module NoBrainer
41
41
  Gem.loaded_specs['activesupport'].version >= Gem::Version.new('5.0.0.beta')
42
42
  end
43
43
 
44
+ def rails6?
45
+ Gem.loaded_specs['activesupport'].version >= Gem::Version.new('6.0.0')
46
+ end
47
+
44
48
  def eager_load!
45
49
  # XXX This forces all the NoBrainer code to be loaded in memory.
46
50
  # Not to be confused with eager_load() that operates on documents.
@@ -34,7 +34,9 @@ module NoBrainer::Generators
34
34
  end
35
35
 
36
36
  def remove_active_record
37
- (Dir['config/environments/*'] + ['config/application.rb']).each do |config_file|
37
+ (Dir['config/environments/*'] +
38
+ Dir['config/initializers/*'] +
39
+ ['config/application.rb']).each do |config_file|
38
40
  comment_lines(config_file, /active_record/)
39
41
  end
40
42
 
@@ -13,9 +13,8 @@ NoBrainer.configure do |config|
13
13
  # The default is to use localhost, with a database name matching the
14
14
  # application name and the environment.
15
15
  # NoBrainer also reads environment variables when defined:
16
- # * RETHINKDB_URL, RDB_URL
17
- # * RETHINKDB_HOST, RETHINKDB_PORT, RETHINKDB_DB, RETHINKDB_AUTH
18
- # * RDB_HOST, RDB_PORT, RDB_DB, RDB_AUTH
16
+ # * RDB_URL, RDB_USER, RDB_PASSWORD, RDB_HOST, RDB_PORT, RDB_DB
17
+ # * All the above, but with RETHINKDB instead of RDB
19
18
  # config.rethinkdb_urls = [config.default_rethinkdb_url]
20
19
 
21
20
  # ssl_options may be set to {:ca_certs => '/path/to/ca.crt'} to establish
@@ -43,9 +42,10 @@ NoBrainer.configure do |config|
43
42
  # You can turn off the warning if you want to use both.
44
43
  # config.warn_on_active_record = true
45
44
 
46
- # Configures the durability for database writes.
47
- # The default is :soft for development or test environment, otherwise :hard.
48
- # config.durability = config.default_durability
45
+ # Configures the run options passed to r.run() when executing queries.
46
+ # The options are listed in the RethinkDB run() documentation.
47
+ # The default durability is :soft for development or test environments, otherwise :hard.
48
+ # config.run_options = { :durability => config.default_durability }
49
49
 
50
50
  # Configures the default table configuration options. These values are
51
51
  # reflected to the database when running `rake nobrainer:sync_schema'.
@@ -56,17 +56,17 @@ NoBrainer.configure do |config|
56
56
  # config.max_string_length = 255
57
57
 
58
58
  # user_timezone can be configured with :utc, :local, or :unchanged.
59
- # When reading an attribute from a model which type is Time, the timezone
60
- # of that time is translated according to this setting.
59
+ # When reading a Time attribute from a model, the timezone of that attribute
60
+ # is set according to the following setting.
61
61
  # config.user_timezone = :local
62
62
 
63
63
  # db_timezone can be configured with :utc, :local, or :unchanged.
64
- # When writting to the database, the timezone of Time attributes are
65
- # translated according to this setting.
64
+ # When writing a Time attribute into the database, the timezone of that
65
+ # attribute is set according to the following setting.
66
66
  # config.db_timezone = :utc
67
67
 
68
68
  # Default options used when compiling geo queries.
69
- # config.geo_options => { :geo_system => 'WGS84', :unit => 'm' }
69
+ # config.geo_options = { :geo_system => 'WGS84', :unit => 'm' }
70
70
 
71
71
  # Configures which mechanism to use in order to perform non-racy uniqueness
72
72
  # validations. More about this behavior in the Distributed Locks section.
@@ -90,7 +90,7 @@ NoBrainer.configure do |config|
90
90
  # generated without conflicts.
91
91
  # config.machine_id = config.default_machine_id
92
92
 
93
- # Criteria cache elements. For example, the result of a has_many association
93
+ # Criteria cache documents. For example, the result of a has_many association
94
94
  # is cached. The per criteria cache is disabled if it grows too big to avoid
95
95
  # out of memory issues.
96
96
  # config.criteria_cache_max_entries = 10_000
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nobrainer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.32.0
4
+ version: 0.35.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: 2016-06-05 00:00:00.000000000 Z
11
+ date: 2021-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rethinkdb
14
+ name: activemodel
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 2.1.0
19
+ version: 4.1.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 2.1.0
26
+ version: 4.1.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activesupport
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -39,33 +39,33 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: 4.1.0
41
41
  - !ruby/object:Gem::Dependency
42
- name: activemodel
42
+ name: middleware
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 4.1.0
47
+ version: 0.1.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 4.1.0
54
+ version: 0.1.0
55
55
  - !ruby/object:Gem::Dependency
56
- name: middleware
56
+ name: rethinkdb
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 0.1.0
61
+ version: 2.3.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 0.1.0
68
+ version: 2.3.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: symbol_decoration
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -80,13 +80,15 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.1'
83
- description: ORM for RethinkDB
83
+ description: The goal of NoBrainer is to provide a similar interface compared to ActiveRecord
84
+ and Mongoid to build data models on top of RethinkDB while providing precise semantics.
84
85
  email:
85
86
  - nicolas@viennot.biz
86
87
  executables: []
87
88
  extensions: []
88
89
  extra_rdoc_files: []
89
90
  files:
91
+ - CHANGELOG.md
90
92
  - LICENSE
91
93
  - README.md
92
94
  - lib/no_brainer/autoload.rb
@@ -236,10 +238,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
236
238
  - !ruby/object:Gem::Version
237
239
  version: '0'
238
240
  requirements: []
239
- rubyforge_project:
240
- rubygems_version: 2.5.1
241
+ rubygems_version: 3.1.6
241
242
  signing_key:
242
243
  specification_version: 4
243
- summary: ORM for RethinkDB
244
+ summary: A Ruby ORM for RethinkDB
244
245
  test_files: []
245
- has_rdoc: false