nobrainer 0.18.0 → 0.22.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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/lib/no_brainer/autoload.rb +0 -5
  3. data/lib/no_brainer/config.rb +73 -39
  4. data/lib/no_brainer/connection.rb +2 -4
  5. data/lib/no_brainer/criteria/after_find.rb +3 -11
  6. data/lib/no_brainer/criteria/aggregate.rb +2 -2
  7. data/lib/no_brainer/criteria/cache.rb +15 -10
  8. data/lib/no_brainer/criteria/core.rb +46 -11
  9. data/lib/no_brainer/criteria/delete.rb +2 -2
  10. data/lib/no_brainer/criteria/eager_load.rb +51 -0
  11. data/lib/no_brainer/criteria/extend.rb +4 -16
  12. data/lib/no_brainer/criteria/find.rb +27 -0
  13. data/lib/no_brainer/criteria/index.rb +7 -13
  14. data/lib/no_brainer/criteria/limit.rb +5 -12
  15. data/lib/no_brainer/criteria/order_by.rb +20 -36
  16. data/lib/no_brainer/criteria/pluck.rb +16 -22
  17. data/lib/no_brainer/criteria/raw.rb +4 -10
  18. data/lib/no_brainer/criteria/scope.rb +6 -19
  19. data/lib/no_brainer/criteria/update.rb +8 -6
  20. data/lib/no_brainer/criteria/where.rb +252 -138
  21. data/lib/no_brainer/criteria.rb +3 -2
  22. data/lib/no_brainer/document/aliases.rb +3 -3
  23. data/lib/no_brainer/document/association/belongs_to.rb +9 -5
  24. data/lib/no_brainer/document/association/core.rb +6 -5
  25. data/lib/no_brainer/document/association/eager_loader.rb +9 -9
  26. data/lib/no_brainer/document/association/has_many.rb +23 -9
  27. data/lib/no_brainer/document/association/has_many_through.rb +12 -3
  28. data/lib/no_brainer/document/atomic_ops.rb +79 -78
  29. data/lib/no_brainer/document/attributes.rb +24 -20
  30. data/lib/no_brainer/document/callbacks.rb +1 -1
  31. data/lib/no_brainer/document/core.rb +5 -2
  32. data/lib/no_brainer/document/criteria.rb +14 -19
  33. data/lib/no_brainer/document/dirty.rb +11 -16
  34. data/lib/no_brainer/document/index/index.rb +2 -1
  35. data/lib/no_brainer/document/index/meta_store.rb +1 -1
  36. data/lib/no_brainer/document/index.rb +14 -10
  37. data/lib/no_brainer/document/persistance.rb +24 -13
  38. data/lib/no_brainer/document/primary_key/generator.rb +83 -0
  39. data/lib/no_brainer/document/{id.rb → primary_key.rb} +9 -36
  40. data/lib/no_brainer/document/store_in.rb +2 -2
  41. data/lib/no_brainer/document/timestamps.rb +4 -2
  42. data/lib/no_brainer/document/types/binary.rb +2 -7
  43. data/lib/no_brainer/document/types/boolean.rb +2 -4
  44. data/lib/no_brainer/document/types/date.rb +2 -2
  45. data/lib/no_brainer/document/types/float.rb +2 -2
  46. data/lib/no_brainer/document/types/geo.rb +1 -0
  47. data/lib/no_brainer/document/types/integer.rb +2 -2
  48. data/lib/no_brainer/document/types/set.rb +2 -2
  49. data/lib/no_brainer/document/types/string.rb +5 -2
  50. data/lib/no_brainer/document/types/symbol.rb +2 -2
  51. data/lib/no_brainer/document/types/text.rb +18 -0
  52. data/lib/no_brainer/document/types/time.rb +2 -2
  53. data/lib/no_brainer/document/types.rb +17 -18
  54. data/lib/no_brainer/document/validation/not_null.rb +15 -0
  55. data/lib/no_brainer/document/{uniqueness.rb → validation/uniqueness.rb} +11 -11
  56. data/lib/no_brainer/document/validation.rb +35 -6
  57. data/lib/no_brainer/document.rb +1 -1
  58. data/lib/no_brainer/error.rb +21 -19
  59. data/lib/no_brainer/geo/base.rb +16 -0
  60. data/lib/no_brainer/geo/circle.rb +25 -0
  61. data/lib/no_brainer/geo/line_string.rb +11 -0
  62. data/lib/no_brainer/geo/point.rb +49 -0
  63. data/lib/no_brainer/geo/polygon.rb +11 -0
  64. data/lib/no_brainer/geo.rb +4 -0
  65. data/lib/no_brainer/locale/en.yml +1 -0
  66. data/lib/no_brainer/lock.rb +114 -0
  67. data/lib/no_brainer/query_runner/connection_lock.rb +1 -1
  68. data/lib/no_brainer/query_runner/database_on_demand.rb +0 -1
  69. data/lib/no_brainer/query_runner/missing_index.rb +1 -1
  70. data/lib/no_brainer/query_runner/reconnect.rb +9 -11
  71. data/lib/no_brainer/query_runner/run_options.rb +0 -3
  72. data/lib/no_brainer/query_runner/table_on_demand.rb +3 -4
  73. data/lib/no_brainer/railtie/database.rake +2 -2
  74. data/lib/no_brainer/rql.rb +1 -5
  75. data/lib/nobrainer.rb +2 -6
  76. data/lib/rails/generators/nobrainer.rb +1 -1
  77. metadata +34 -9
  78. data/lib/no_brainer/criteria/preload.rb +0 -50
  79. data/lib/no_brainer/decorated_symbol.rb +0 -17
@@ -1,8 +1,11 @@
1
1
  module NoBrainer::Document::Validation
2
+ extend NoBrainer::Autoload
2
3
  extend ActiveSupport::Concern
3
4
  include ActiveModel::Validations
4
5
  include ActiveModel::Validations::Callbacks
5
6
 
7
+ autoload_and_include :Uniqueness, :NotNull
8
+
6
9
  included do
7
10
  # We don't want before_validation returning false to halt the chain.
8
11
  define_callbacks :validation, :skip_after_callbacks_if_terminated => true,
@@ -12,7 +15,7 @@ module NoBrainer::Document::Validation
12
15
  def valid?(context=nil, options={})
13
16
  context ||= new_record? ? :create : :update
14
17
 
15
- # copy/pasted, because we need to have control on errors.clear
18
+ # XXX Monkey Patching, because we need to have control on errors.clear
16
19
  current_context, self.validation_context = validation_context, context
17
20
  errors.clear unless options[:clear_errors] == false
18
21
  run_validations!
@@ -20,15 +23,41 @@ module NoBrainer::Document::Validation
20
23
  self.validation_context = current_context
21
24
  end
22
25
 
26
+ SHORTHANDS = { :format => :format, :length => :length, :required => :presence,
27
+ :uniq => :uniqueness, :unique => :uniqueness, :in => :inclusion }
28
+
23
29
  module ClassMethods
24
30
  def _field(attr, options={})
25
31
  super
26
- validates(attr, { :format => { :with => options[:format] } }) if options.has_key?(:format)
27
- validates(attr, { :presence => options[:required] }) if options.has_key?(:required)
28
- validates(attr, { :uniqueness => options[:unique] }) if options.has_key?(:unique)
29
- validates(attr, { :uniqueness => options[:uniq] }) if options.has_key?(:uniq)
30
- validates(attr, { :inclusion => {:in => options[:in]} }) if options.has_key?(:in)
32
+
33
+ shorthands = SHORTHANDS
34
+ shorthands = shorthands.merge(:required => :not_null) if options[:type] == NoBrainer::Boolean
35
+ shorthands.each { |k,v| validates(attr, v => options[k]) if options.has_key?(k) }
36
+
31
37
  validates(attr, options[:validates]) if options[:validates]
38
+ validates(attr, :length => { :minimum => options[:min_length] }) if options[:min_length]
39
+ validates(attr, :length => { :maximum => options[:max_length] }) if options[:max_length]
40
+ end
41
+ end
42
+ end
43
+
44
+ class ActiveModel::EachValidator
45
+ def should_validate_field?(record, attribute)
46
+ return true unless record.is_a?(NoBrainer::Document)
47
+ return true if record.new_record?
48
+
49
+ attr_changed = "#{attribute}_changed?"
50
+ return record.respond_to?(attr_changed) ? record.__send__(attr_changed) : true
51
+ end
52
+
53
+ # XXX Monkey Patching :(
54
+ def validate(record)
55
+ attributes.each do |attribute|
56
+ next unless should_validate_field?(record, attribute) # <--- Added
57
+ value = record.read_attribute_for_validation(attribute)
58
+ next if value.is_a?(NoBrainer::Document::AtomicOps::PendingAtomic) # <--- Added
59
+ next if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank])
60
+ validate_each(record, attribute, value)
32
61
  end
33
62
  end
34
63
  end
@@ -5,7 +5,7 @@ module NoBrainer::Document
5
5
  extend NoBrainer::Autoload
6
6
 
7
7
  autoload_and_include :Core, :StoreIn, :InjectionLayer, :Attributes, :Readonly,
8
- :Validation, :Persistance, :Types, :Uniqueness, :Callbacks, :Dirty, :Id,
8
+ :Persistance, :Validation, :Types, :Callbacks, :Dirty, :PrimaryKey,
9
9
  :Association, :Serialization, :Criteria, :Polymorphic, :Index, :Aliases,
10
10
  :MissingAttributes, :LazyFetch, :AtomicOps
11
11
 
@@ -5,24 +5,13 @@ module NoBrainer::Error
5
5
  class ChildrenExist < RuntimeError; end
6
6
  class CannotUseIndex < RuntimeError; end
7
7
  class MissingIndex < RuntimeError; end
8
- class InvalidType < RuntimeError; end
9
8
  class AssociationNotPersisted < RuntimeError; end
10
9
  class ReadonlyField < RuntimeError; end
11
10
  class MissingAttribute < RuntimeError; end
11
+ class UnknownAttribute < RuntimeError; end
12
12
  class AtomicBlock < RuntimeError; end
13
-
14
- class CannotReadAtomic < RuntimeError
15
- attr_accessor :instance, :field, :value
16
- def initialize(instance, field, value)
17
- @instance = instance
18
- @field = field
19
- @value = value
20
- end
21
-
22
- def message
23
- "Cannot read #{field}, atomic operations are pending"
24
- end
25
- end
13
+ class LostLock < RuntimeError; end
14
+ class LockUnavailable < RuntimeError; end
26
15
 
27
16
  class DocumentInvalid < RuntimeError
28
17
  attr_accessor :instance
@@ -36,19 +25,32 @@ module NoBrainer::Error
36
25
  end
37
26
 
38
27
  class InvalidType < RuntimeError
39
- attr_accessor :attr_name, :value, :type
28
+ attr_accessor :model, :attr_name, :value, :type, :error
40
29
  def initialize(options={})
41
- @attr_name = options[:attr_name]
42
- @value = options[:value]
43
- @type = options[:type]
30
+ update(options)
31
+ end
32
+
33
+ def update(options={})
34
+ options.assert_valid_keys(:model, :attr_name, :type, :value, :error)
35
+ options.each { |k,v| instance_variable_set("@#{k}", v) }
44
36
  end
45
37
 
46
38
  def human_type_name
47
39
  type.to_s.underscore.humanize.downcase
48
40
  end
49
41
 
42
+ def error
43
+ # dup because errors.add eventually .delete() on our option.
44
+ @error.nil? ? (type && { :type => human_type_name }) : @error.dup
45
+ end
46
+
50
47
  def message
51
- "#{attr_name} should be used with a #{human_type_name}. Got `#{value}` (#{value.class})"
48
+ return super unless model && attr_name && error
49
+ value = self.value
50
+ mock = model.allocate
51
+ mock.singleton_class.send(:define_method, :read_attribute_for_validation) { |_| value }
52
+ mock.errors.add(attr_name, :invalid_type, error)
53
+ mock.errors.full_messages.first
52
54
  end
53
55
  end
54
56
 
@@ -0,0 +1,16 @@
1
+ module NoBrainer::Geo::Base
2
+ extend ActiveSupport::Concern
3
+
4
+ def self.normalize_geo_options(options)
5
+ options = options.symbolize_keys
6
+
7
+ geo_system = options.delete(:geo_system) || NoBrainer::Config.geo_options[:geo_system]
8
+ unit = options.delete(:unit) || NoBrainer::Config.geo_options[:unit]
9
+
10
+ options[:unit] = unit if unit && unit.to_s != 'm'
11
+ options[:geo_system] = geo_system if geo_system && geo_system.to_s != 'WGS84'
12
+ options[:max_dist] = options.delete(:max_distance) if options[:max_distance]
13
+
14
+ options
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ class NoBrainer::Geo::Circle < Struct.new(:center, :radius, :options)
2
+ include NoBrainer::Geo::Base
3
+
4
+ def initialize(*args)
5
+ options = args.extract_options!
6
+ options = NoBrainer::Geo::Base.normalize_geo_options(options)
7
+
8
+ raise NoBrainer::Error::InvalidType if args.size > 2
9
+ center = args[0] || options.delete(:center)
10
+ radius = args[1] || options.delete(:radius)
11
+
12
+ center = NoBrainer::Geo::Point.nobrainer_cast_user_to_model(center)
13
+ radius = Float.nobrainer_cast_user_to_model(radius)
14
+
15
+ self.center = center
16
+ self.radius = radius
17
+ self.options = options
18
+ end
19
+
20
+ def to_rql
21
+ RethinkDB::RQL.new.circle(center.to_rql, radius, options)
22
+ end
23
+
24
+ # No DB serialization, can't store circles.
25
+ end
@@ -0,0 +1,11 @@
1
+ class NoBrainer::Geo::LineString < Struct.new(:points)
2
+ include NoBrainer::Geo::Base
3
+
4
+ def initialize(*points)
5
+ self.points = points.map { |p| NoBrainer::Geo::Point.nobrainer_cast_user_to_model(p) }
6
+ end
7
+
8
+ def to_rql
9
+ RethinkDB::RQL.new.line(points.map(&:to_rql))
10
+ end
11
+ end
@@ -0,0 +1,49 @@
1
+ require 'no_brainer/document/types/float'
2
+
3
+ class NoBrainer::Geo::Point < Struct.new(:longitude, :latitude)
4
+ include NoBrainer::Geo::Base
5
+
6
+ def initialize(*args)
7
+ if args.size == 2
8
+ longitude, latitude = args
9
+ elsif args.size == 1 && args.first.is_a?(self.class)
10
+ longitude, latitude = args.first.longitude, args.first.latitude
11
+ elsif args.size == 1 && args.first.is_a?(Hash)
12
+ opt = args.first.symbolize_keys
13
+ longitude, latitude = opt[:longitude] || opt[:long], opt[:latitude] || opt[:lat]
14
+ else
15
+ raise NoBrainer::Error::InvalidType
16
+ end
17
+
18
+ longitude = Float.nobrainer_cast_user_to_model(longitude)
19
+ latitude = Float.nobrainer_cast_user_to_model(latitude)
20
+
21
+ raise NoBrainer::Error::InvalidType unless (-180..180).include?(longitude)
22
+ raise NoBrainer::Error::InvalidType unless (-90..90).include?(latitude)
23
+
24
+ self.longitude = longitude
25
+ self.latitude = latitude
26
+ end
27
+
28
+ def to_rql
29
+ RethinkDB::RQL.new.point(longitude, latitude)
30
+ end
31
+
32
+ def to_s
33
+ [longitude, latitude].inspect
34
+ end
35
+ alias_method :inspect, :to_s
36
+
37
+ def self.nobrainer_cast_user_to_model(value)
38
+ value.is_a?(Array) ? new(*value) : new(value)
39
+ end
40
+
41
+ def self.nobrainer_cast_db_to_model(value)
42
+ return value unless value.is_a?(Hash) && value['coordinates'].is_a?(Array) && value['coordinates'].size == 2
43
+ new(value['coordinates'][0], value['coordinates'][1])
44
+ end
45
+
46
+ def self.nobrainer_cast_model_to_db(value)
47
+ value.is_a?(self) ? value.to_rql : value
48
+ end
49
+ end
@@ -0,0 +1,11 @@
1
+ class NoBrainer::Geo::Polygon < Struct.new(:points)
2
+ include NoBrainer::Geo::Base
3
+
4
+ def initialize(*points)
5
+ self.points = points.map { |p| NoBrainer::Geo::Point.nobrainer_cast_user_to_model(p) }
6
+ end
7
+
8
+ def to_rql
9
+ RethinkDB::RQL.new.polygon(points.map(&:to_rql))
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ module NoBrainer::Geo
2
+ extend NoBrainer::Autoload
3
+ autoload :Base, :Point, :Circle, :LineString, :Polygon
4
+ end
@@ -3,3 +3,4 @@ en:
3
3
  messages:
4
4
  taken: "is already taken"
5
5
  invalid_type: "should be a %{type}"
6
+ undefined: "must be defined"
@@ -0,0 +1,114 @@
1
+ require 'digest/sha1'
2
+
3
+ class NoBrainer::Lock
4
+ include NoBrainer::Document
5
+
6
+ store_in :table => 'nobrainer_locks'
7
+
8
+ # Since PKs are limited to 127 characters, we can't use the user's key as a PK
9
+ # as it could be arbitrarily long.
10
+ field :key_hash, :type => String, :primary_key => true, :default => ->{ Digest::SHA1.base64digest(key) }
11
+ field :key, :type => String
12
+ field :token, :type => String
13
+ field :expires_at, :type => Time
14
+
15
+ # We always use a new token, even when reading from the DB, because that's
16
+ # what represent our instance.
17
+ after_initialize { self.token = NoBrainer::Document::PrimaryKey::Generator.generate }
18
+
19
+ scope :expired, where(:expires_at.lt(RethinkDB::RQL.new.now))
20
+
21
+ def initialize(key, options={})
22
+ return super if options[:from_db]
23
+
24
+ key = case key
25
+ when Symbol then key.to_s
26
+ when String then key
27
+ else raise ArgumentError
28
+ end
29
+
30
+ super(options.merge(:key => key))
31
+ end
32
+
33
+ def lock(options={}, &block)
34
+ if block
35
+ lock(options)
36
+ return block.call.tap { unlock }
37
+ end
38
+
39
+ options.assert_valid_keys(:expire, :timeout)
40
+ timeout = NoBrainer::Config.lock_options.merge(options)[:timeout]
41
+ sleep_amount = 0.1
42
+
43
+ start_at = Time.now
44
+ while Time.now - start_at < timeout
45
+ return if try_lock(options.select { |k,_| k == :expire })
46
+ sleep(sleep_amount)
47
+ sleep_amount = [1, sleep_amount * 2].min
48
+ end
49
+
50
+ raise NoBrainer::Error::LockUnavailable.new("Lock on `#{key}' unavailable")
51
+ end
52
+
53
+ def try_lock(options={})
54
+ options.assert_valid_keys(:expire)
55
+ raise "Lock instance `#{key}' already locked" if @locked
56
+
57
+ set_expiration(options)
58
+
59
+ result = NoBrainer.run do |r|
60
+ selector.replace do |doc|
61
+ r.branch(doc.eq(nil).or(doc[:expires_at] < r.now),
62
+ self.attributes, doc)
63
+ end
64
+ end
65
+
66
+ return @locked = (result['inserted'] + result['replaced']) == 1
67
+ end
68
+
69
+ def unlock
70
+ raise "Lock instance `#{key}' not locked" unless @locked
71
+
72
+ result = NoBrainer.run do |r|
73
+ selector.replace do |doc|
74
+ r.branch(doc[:token].eq(self.token),
75
+ nil, doc)
76
+ end
77
+ end
78
+
79
+ @locked = false
80
+ raise NoBrainer::Error::LostLock.new("Lost lock on `#{key}'") unless result['deleted'] == 1
81
+ end
82
+
83
+ def refresh(options={})
84
+ options.assert_valid_keys(:expire)
85
+ raise "Lock instance `#{key}' not locked" unless @locked
86
+
87
+ set_expiration(options)
88
+
89
+ result = NoBrainer.run do |r|
90
+ selector.update do |doc|
91
+ r.branch(doc[:token].eq(self.token),
92
+ { :expires_at => self.expires_at }, nil)
93
+ end
94
+ end
95
+
96
+ # Note: If we are too quick, expires_at may not change, and the returned
97
+ # 'replaced' won't be 1. We'll generate a spurious error. This is very
98
+ # unlikely to happen and should not harmful.
99
+ unless result['replaced'] == 1
100
+ @locked = false
101
+ raise NoBrainer::Error::LostLock.new("Lost lock on `#{key}'")
102
+ end
103
+ end
104
+
105
+ private
106
+
107
+ def set_expiration(options)
108
+ expire = NoBrainer::Config.lock_options.merge(options)[:expire]
109
+ self.expires_at = RethinkDB::RQL.new.now + expire
110
+ end
111
+
112
+ def save?; raise; end
113
+ def delete; raise; end
114
+ end
@@ -3,7 +3,7 @@ class NoBrainer::QueryRunner::ConnectionLock < NoBrainer::QueryRunner::Middlewar
3
3
 
4
4
  def call(env)
5
5
  if NoBrainer::Config.per_thread_connection
6
- @runner.call(env)
6
+ @runner.call(env)
7
7
  else
8
8
  @@lock.synchronize { @runner.call(env) }
9
9
  end
@@ -10,7 +10,6 @@ class NoBrainer::QueryRunner::DatabaseOnDemand < NoBrainer::QueryRunner::Middlew
10
10
  end
11
11
 
12
12
  def handle_database_on_demand_exception?(env, e)
13
- (NoBrainer::Config.auto_create_databases || env[:auto_create_databases]) &&
14
13
  e.message =~ /^Database `(.+)` does not exist\.$/ && $1
15
14
  end
16
15
 
@@ -11,7 +11,7 @@ class NoBrainer::QueryRunner::MissingIndex < NoBrainer::QueryRunner::Middleware
11
11
  index = model.indexes.values.select { |i| i.aliased_name == index_name.to_sym }.first if model
12
12
  index_name = index.name if index
13
13
 
14
- if model.try(:pk_name).try(:to_s) == index_name
14
+ if model.try(:pk_name).try(:to_s) == index_name.to_s
15
15
  err_msg = "Please update the primary key `#{index_name}` in the table `#{database_name}.#{table_name}`."
16
16
  else
17
17
  err_msg = "Please run `NoBrainer.sync_indexes' or `rake nobrainer:sync_indexes' to create the index `#{index_name}`"
@@ -18,18 +18,16 @@ class NoBrainer::QueryRunner::Reconnect < NoBrainer::QueryRunner::Middleware
18
18
  private
19
19
 
20
20
  def reconnect(e, context)
21
- begin
22
- return false if context[:retries].zero?
23
- context[:retries] -= 1
21
+ return false if context[:retries].zero?
22
+ context[:retries] -= 1
24
23
 
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
32
- end
24
+ warn_reconnect(e)
25
+ sleep 1
26
+ NoBrainer.connection.reconnect(:noreply_wait => false)
27
+ true
28
+ rescue StandardError => e
29
+ retry if is_connection_error_exception?(e)
30
+ raise
33
31
  end
34
32
 
35
33
  def is_connection_error_exception?(e)
@@ -30,9 +30,6 @@ 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
-
36
33
  @runner.call(env)
37
34
  end
38
35
  end
@@ -10,15 +10,14 @@ class NoBrainer::QueryRunner::TableOnDemand < NoBrainer::QueryRunner::Middleware
10
10
  end
11
11
 
12
12
  def handle_table_on_demand_exception?(env, e)
13
- (NoBrainer::Config.auto_create_tables || env[:auto_create_tables]) &&
14
13
  e.message =~ /^Table `(.+)\.(.+)` does not exist\.$/ && [$1, $2]
15
14
  end
16
15
 
17
16
  private
18
17
 
19
18
  def auto_create_table(env, database_name, table_name)
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
19
+ model ||= NoBrainer::Document::Core._all.select { |m| m.table_name == table_name }.first
20
+ model ||= NoBrainer::Document::Core._all_nobrainer.select { |m| m.table_name == table_name }.first
22
21
 
23
22
  if model.nil?
24
23
  raise "Auto table creation is not working for `#{database_name}.#{table_name}` -- Can't find the corresponding model."
@@ -30,7 +29,7 @@ class NoBrainer::QueryRunner::TableOnDemand < NoBrainer::QueryRunner::Middleware
30
29
  env[:last_auto_create_table] = [database_name, table_name]
31
30
 
32
31
  NoBrainer.with_database(database_name) do
33
- NoBrainer.table_create(table_name, :primary_key => model.pk_name)
32
+ NoBrainer.table_create(table_name, :primary_key => model.lookup_field_alias(model.pk_name))
34
33
  end
35
34
  rescue RuntimeError => e
36
35
  # We might have raced with another table create
@@ -19,10 +19,10 @@ namespace :nobrainer do
19
19
  end
20
20
 
21
21
  desc 'Equivalent to :sync_indexes_quiet + :seed'
22
- task :setup => [ :sync_indexes_quiet, :seed ]
22
+ task :setup => [:sync_indexes_quiet, :seed]
23
23
 
24
24
  desc 'Equivalent to :drop + :setup'
25
- task :reset => [ :drop, :setup ]
25
+ task :reset => [:drop, :setup]
26
26
 
27
27
  task :create => :environment do
28
28
  # noop
@@ -19,7 +19,7 @@ module NoBrainer::RQL
19
19
  case rql_query.body.first
20
20
  when UPDATE, DELETE, REPLACE, INSERT
21
21
  :write
22
- when DB_CREATE,DB_DROP, DB_LIST, TABLE_CREATE, TABLE_DROP, TABLE_LIST, SYNC,
22
+ when DB_CREATE, DB_DROP, DB_LIST, TABLE_CREATE, TABLE_DROP, TABLE_LIST, SYNC,
23
23
  INDEX_CREATE, INDEX_DROP, INDEX_LIST, INDEX_STATUS, INDEX_WAIT
24
24
  :management
25
25
  else
@@ -27,8 +27,4 @@ module NoBrainer::RQL
27
27
  :read
28
28
  end
29
29
  end
30
-
31
- def is_table?(rql)
32
- rql.body.first == TABLE
33
- end
34
30
  end
data/lib/nobrainer.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'set'
2
2
  require 'active_support'
3
+ require 'thread'
3
4
  %w(module/delegation module/attribute_accessors module/introspection
4
5
  class/attribute object/blank object/inclusion object/deep_dup
5
6
  object/try hash/keys hash/indifferent_access hash/reverse_merge
@@ -12,7 +13,7 @@ module NoBrainer
12
13
 
13
14
  # We eager load things that could be loaded when handling the first web request.
14
15
  # Code that is loaded through the DSL of NoBrainer should not be eager loaded.
15
- autoload :Document, :IndexManager, :Loader, :Fork, :DecoratedSymbol
16
+ autoload :Document, :IndexManager, :Loader, :Fork, :Geo, :Lock
16
17
  eager_autoload :Config, :Connection, :ConnectionManager, :Error,
17
18
  :QueryRunner, :Criteria, :RQL
18
19
 
@@ -31,13 +32,8 @@ module NoBrainer
31
32
  def jruby?
32
33
  RUBY_PLATFORM == 'java'
33
34
  end
34
-
35
- def user_caller
36
- caller.reject { |s| s =~ /\/no_brainer\// }.first
37
- end
38
35
  end
39
36
 
40
- DecoratedSymbol.hook
41
37
  Fork.hook unless jruby?
42
38
  end
43
39
 
@@ -12,7 +12,7 @@ module NoBrainer::Generators
12
12
  end
13
13
 
14
14
  def self.namespace
15
- super.gsub(/no_brainer/,'nobrainer')
15
+ super.gsub(/no_brainer/, 'nobrainer')
16
16
  end
17
17
  end
18
18
  end