nobrainer 0.32.0 → 0.35.0

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