nobrainer 0.10.0 → 0.13.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 +4 -4
- data/LICENSE +169 -0
- data/lib/no_brainer/autoload.rb +1 -1
- data/lib/no_brainer/criteria/after_find.rb +24 -0
- data/lib/no_brainer/criteria/{termination/cache.rb → cache.rb} +1 -1
- data/lib/no_brainer/criteria/{chainable/core.rb → core.rb} +2 -2
- data/lib/no_brainer/criteria/{termination/count.rb → count.rb} +1 -1
- data/lib/no_brainer/criteria/{termination/delete.rb → delete.rb} +2 -2
- data/lib/no_brainer/criteria/{termination/enumerable.rb → enumerable.rb} +1 -1
- data/lib/no_brainer/criteria/{termination/first.rb → first.rb} +1 -1
- data/lib/no_brainer/criteria/{chainable/limit.rb → limit.rb} +1 -1
- data/lib/no_brainer/criteria/{chainable/order_by.rb → order_by.rb} +1 -1
- data/lib/no_brainer/criteria/preload.rb +55 -0
- data/lib/no_brainer/criteria/raw.rb +25 -0
- data/lib/no_brainer/criteria/{chainable/scope.rb → scope.rb} +1 -1
- data/lib/no_brainer/criteria/update.rb +11 -0
- data/lib/no_brainer/criteria/{chainable/where.rb → where.rb} +61 -25
- data/lib/no_brainer/criteria.rb +3 -16
- data/lib/no_brainer/document/association/belongs_to.rb +10 -2
- data/lib/no_brainer/document/association/core.rb +2 -2
- data/lib/no_brainer/document/association/eager_loader.rb +7 -7
- data/lib/no_brainer/document/association/has_many.rb +1 -1
- data/lib/no_brainer/document/attributes.rb +30 -44
- data/lib/no_brainer/document/callbacks.rb +29 -0
- data/lib/no_brainer/document/core.rb +0 -2
- data/lib/no_brainer/document/criteria.rb +1 -2
- data/lib/no_brainer/document/dirty.rb +52 -52
- data/lib/no_brainer/document/dynamic_attributes.rb +11 -3
- data/lib/no_brainer/document/id.rb +1 -1
- data/lib/no_brainer/document/index.rb +7 -14
- data/lib/no_brainer/document/injection_layer.rb +2 -3
- data/lib/no_brainer/document/persistance.rb +29 -43
- data/lib/no_brainer/document/readonly.rb +19 -0
- data/lib/no_brainer/document/serialization.rb +0 -1
- data/lib/no_brainer/document/timestamps.rb +9 -9
- data/lib/no_brainer/document/types.rb +46 -41
- data/lib/no_brainer/document/validation.rb +6 -0
- data/lib/no_brainer/document.rb +4 -4
- data/lib/no_brainer/error.rb +37 -9
- data/lib/no_brainer/query_runner/connection.rb +36 -9
- data/lib/no_brainer/query_runner/missing_index.rb +1 -1
- data/lib/no_brainer/query_runner/run_options.rb +4 -2
- data/lib/no_brainer/railtie.rb +10 -0
- data/lib/nobrainer.rb +3 -7
- metadata +54 -44
- data/LICENSE.md +0 -7
- data/lib/no_brainer/criteria/chainable/raw.rb +0 -33
- data/lib/no_brainer/criteria/termination/eager_loading.rb +0 -50
- data/lib/no_brainer/criteria/termination/inc.rb +0 -14
- data/lib/no_brainer/criteria/termination/update.rb +0 -13
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
module NoBrainer::Document::Types
|
|
2
2
|
extend ActiveSupport::Concern
|
|
3
3
|
|
|
4
|
-
included do
|
|
5
|
-
# We namespace our fake Boolean class to avoid polluting the global namespace
|
|
6
|
-
class_exec { class Boolean; def initialize; raise; end; end }
|
|
7
|
-
before_validation :add_type_errors
|
|
8
|
-
end
|
|
9
|
-
|
|
10
4
|
module CastingRules
|
|
11
5
|
extend self
|
|
6
|
+
InvalidType = NoBrainer::Error::InvalidType
|
|
12
7
|
|
|
13
8
|
def String(value)
|
|
14
9
|
case value
|
|
@@ -63,67 +58,77 @@ module NoBrainer::Document::Types
|
|
|
63
58
|
else raise InvalidType
|
|
64
59
|
end
|
|
65
60
|
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def self.cast(value, type, cast_method)
|
|
69
|
-
return value if value.nil? || type.nil? || value.is_a?(type)
|
|
70
|
-
cast_method.call(value)
|
|
71
|
-
end
|
|
72
61
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
proc { raise InvalidType }
|
|
79
|
-
end
|
|
62
|
+
def lookup(type)
|
|
63
|
+
CastingRules.method(type.to_s)
|
|
64
|
+
rescue NameError
|
|
65
|
+
proc { raise InvalidType }
|
|
66
|
+
end
|
|
80
67
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
@type = type
|
|
68
|
+
def cast(value, type, type_cast_method)
|
|
69
|
+
return value if value.nil? || type.nil? || value.is_a?(type)
|
|
70
|
+
type_cast_method.call(value)
|
|
85
71
|
end
|
|
72
|
+
end
|
|
86
73
|
|
|
87
|
-
|
|
88
|
-
|
|
74
|
+
included do
|
|
75
|
+
# We namespace our fake Boolean class to avoid polluting the global namespace
|
|
76
|
+
class_exec do
|
|
77
|
+
class Boolean
|
|
78
|
+
def initialize; raise; end
|
|
79
|
+
def self.inspect; 'Boolean'; end
|
|
80
|
+
def self.to_s; inspect; end
|
|
81
|
+
def self.name; inspect; end
|
|
82
|
+
end
|
|
89
83
|
end
|
|
84
|
+
before_validation :add_type_errors
|
|
90
85
|
end
|
|
91
86
|
|
|
92
87
|
def add_type_errors
|
|
93
88
|
return unless @pending_type_errors
|
|
94
89
|
@pending_type_errors.each do |name, error|
|
|
95
|
-
errors.add(name,
|
|
90
|
+
errors.add(name, :invalid_type, :type => error.human_type_name)
|
|
96
91
|
end
|
|
97
92
|
end
|
|
98
93
|
|
|
99
94
|
module ClassMethods
|
|
100
|
-
def
|
|
95
|
+
def cast_value_for(attr, value)
|
|
96
|
+
attr = attr.to_sym
|
|
97
|
+
field_def = fields[attr]
|
|
98
|
+
return value unless field_def && field_def[:type]
|
|
99
|
+
NoBrainer::Document::Types::CastingRules.cast(value, field_def[:type], field_def[:type_cast_method])
|
|
100
|
+
rescue NoBrainer::Error::InvalidType => error
|
|
101
|
+
error.type = field_def[:type]
|
|
102
|
+
error.value = value
|
|
103
|
+
error.attr_name = attr
|
|
104
|
+
raise error
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def _field(attr, options={})
|
|
101
108
|
super
|
|
102
|
-
return unless options.has_key?(:type)
|
|
103
|
-
name = name.to_sym
|
|
104
|
-
type = options[:type]
|
|
105
|
-
cast_method = NoBrainer::Document::Types.lookup_cast_method(type)
|
|
106
109
|
|
|
107
110
|
inject_in_layer :types do
|
|
108
|
-
define_method("#{
|
|
111
|
+
define_method("#{attr}=") do |value|
|
|
109
112
|
begin
|
|
110
|
-
value =
|
|
111
|
-
@pending_type_errors.try(:delete,
|
|
112
|
-
rescue NoBrainer::
|
|
113
|
-
error.type ||= type
|
|
113
|
+
value = self.class.cast_value_for(attr, value)
|
|
114
|
+
@pending_type_errors.try(:delete, attr)
|
|
115
|
+
rescue NoBrainer::Error::InvalidType => error
|
|
114
116
|
@pending_type_errors ||= {}
|
|
115
|
-
@pending_type_errors[
|
|
117
|
+
@pending_type_errors[attr] = error
|
|
116
118
|
end
|
|
117
119
|
super(value)
|
|
118
120
|
end
|
|
121
|
+
|
|
122
|
+
define_method("#{attr}?") { !!read_attribute(attr) } if options[:type] == Boolean
|
|
119
123
|
end
|
|
120
124
|
end
|
|
121
125
|
|
|
122
|
-
def
|
|
126
|
+
def field(attr, options={})
|
|
127
|
+
if options[:type]
|
|
128
|
+
type_cast_method = NoBrainer::Document::Types::CastingRules.lookup(options[:type])
|
|
129
|
+
options = options.merge(:type_cast_method => type_cast_method)
|
|
130
|
+
end
|
|
123
131
|
super
|
|
124
|
-
inject_in_layer :types, <<-RUBY, __FILE__, __LINE__ + 1
|
|
125
|
-
undef #{name}=
|
|
126
|
-
RUBY
|
|
127
132
|
end
|
|
128
133
|
end
|
|
129
134
|
end
|
|
@@ -8,6 +8,12 @@ module NoBrainer::Document::Validation
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
module ClassMethods
|
|
11
|
+
def _field(attr, options={})
|
|
12
|
+
super
|
|
13
|
+
validates(attr, { :presence => true }) if options[:required]
|
|
14
|
+
validates(attr, options[:validates]) if options[:validates]
|
|
15
|
+
end
|
|
16
|
+
|
|
11
17
|
def validates_uniqueness_of(*attr_names)
|
|
12
18
|
validates_with UniquenessValidator, _merge_attributes(attr_names)
|
|
13
19
|
end
|
data/lib/no_brainer/document.rb
CHANGED
|
@@ -4,11 +4,11 @@ module NoBrainer::Document
|
|
|
4
4
|
extend ActiveSupport::Concern
|
|
5
5
|
extend NoBrainer::Autoload
|
|
6
6
|
|
|
7
|
-
autoload_and_include :Core, :StoreIn, :InjectionLayer, :Attributes, :Validation, :Types,
|
|
8
|
-
:Persistance, :Dirty, :Id, :Association, :Serialization,
|
|
9
|
-
:
|
|
7
|
+
autoload_and_include :Core, :StoreIn, :InjectionLayer, :Attributes, :Readonly, :Validation, :Types,
|
|
8
|
+
:Persistance, :Callbacks, :Dirty, :Id, :Association, :Serialization,
|
|
9
|
+
:Criteria, :Polymorphic, :Index
|
|
10
10
|
|
|
11
|
-
autoload :DynamicAttributes
|
|
11
|
+
autoload :DynamicAttributes, :Timestamps
|
|
12
12
|
|
|
13
13
|
singleton_class.delegate :all, :to => Core
|
|
14
14
|
end
|
data/lib/no_brainer/error.rb
CHANGED
|
@@ -1,11 +1,39 @@
|
|
|
1
1
|
module NoBrainer::Error
|
|
2
|
-
class Connection <
|
|
3
|
-
class DocumentNotFound <
|
|
4
|
-
class
|
|
5
|
-
class
|
|
6
|
-
class
|
|
7
|
-
class
|
|
8
|
-
class
|
|
9
|
-
class
|
|
10
|
-
class
|
|
2
|
+
class Connection < RuntimeError; end
|
|
3
|
+
class DocumentNotFound < RuntimeError; end
|
|
4
|
+
class DocumentNotSaved < RuntimeError; end
|
|
5
|
+
class ChildrenExist < RuntimeError; end
|
|
6
|
+
class CannotUseIndex < RuntimeError; end
|
|
7
|
+
class MissingIndex < RuntimeError; end
|
|
8
|
+
class InvalidType < RuntimeError; end
|
|
9
|
+
class AssociationNotSaved < RuntimeError; end
|
|
10
|
+
class ReadonlyField < RuntimeError; end
|
|
11
|
+
|
|
12
|
+
class DocumentInvalid < RuntimeError
|
|
13
|
+
attr_accessor :instance
|
|
14
|
+
def initialize(instance)
|
|
15
|
+
@instance = instance
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def message
|
|
19
|
+
"#{instance} is invalid: #{instance.errors.full_messages.join(", ")}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class InvalidType < RuntimeError
|
|
24
|
+
attr_accessor :attr_name, :value, :type
|
|
25
|
+
def initialize(options={})
|
|
26
|
+
@attr_name = options[:attr_name]
|
|
27
|
+
@value = options[:value]
|
|
28
|
+
@type = options[:type]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def human_type_name
|
|
32
|
+
type.to_s.underscore.humanize.downcase
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def message
|
|
36
|
+
"#{attr_name} should be used with a #{human_type_name}. Got `#{value}`"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
11
39
|
end
|
|
@@ -1,17 +1,44 @@
|
|
|
1
1
|
class NoBrainer::QueryRunner::Connection < NoBrainer::QueryRunner::Middleware
|
|
2
2
|
def call(env)
|
|
3
3
|
@runner.call(env)
|
|
4
|
-
rescue
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
rescue StandardError => e
|
|
5
|
+
# TODO test that thing
|
|
6
|
+
if is_connection_error_exception?(e)
|
|
7
|
+
retry if reconnect
|
|
8
|
+
end
|
|
9
|
+
raise
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
14
|
+
def reconnect
|
|
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
|
+
NoBrainer.logger.try(:warn, "Lost connection to #{NoBrainer::Config.rethinkdb_url}, retrying...")
|
|
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
|
|
28
|
+
end
|
|
29
|
+
false
|
|
30
|
+
end
|
|
11
31
|
|
|
12
|
-
|
|
13
|
-
|
|
32
|
+
def is_connection_error_exception?(e)
|
|
33
|
+
case e
|
|
34
|
+
when Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::EPIPE,
|
|
35
|
+
Errno::ECONNRESET, Errno::ETIMEDOUT, IOError
|
|
36
|
+
true
|
|
37
|
+
when RethinkDB::RqlRuntimeError
|
|
38
|
+
e.message =~ /cannot perform (read|write): No master available/ ||
|
|
39
|
+
e.message =~ /Error: Connection Closed/
|
|
40
|
+
else
|
|
41
|
+
false
|
|
14
42
|
end
|
|
15
|
-
raise e
|
|
16
43
|
end
|
|
17
44
|
end
|
|
@@ -3,7 +3,7 @@ class NoBrainer::QueryRunner::MissingIndex < NoBrainer::QueryRunner::Middleware
|
|
|
3
3
|
@runner.call(env)
|
|
4
4
|
rescue RethinkDB::RqlRuntimeError => e
|
|
5
5
|
if e.message =~ /^Index `(.+)` was not found\.$/
|
|
6
|
-
raise NoBrainer::Error::MissingIndex.new("Please run \"rake db:update_indexes\" to create index `#{$1}`\n" +
|
|
6
|
+
raise NoBrainer::Error::MissingIndex.new("Please run \"rake db:update_indexes\" to create the index `#{$1}`\n" +
|
|
7
7
|
"--> Read http://nobrainer.io/docs/indexes for more information.")
|
|
8
8
|
end
|
|
9
9
|
raise
|
|
@@ -16,11 +16,11 @@ class NoBrainer::QueryRunner::RunOptions < NoBrainer::QueryRunner::Middleware
|
|
|
16
16
|
def call(env)
|
|
17
17
|
env[:options].symbolize_keys!
|
|
18
18
|
if Thread.current[:nobrainer_options]
|
|
19
|
-
env[:options]
|
|
19
|
+
env[:options].reverse_merge!(Thread.current[:nobrainer_options])
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
if NoBrainer::Config.durability.to_s != 'hard'
|
|
23
|
-
env[:options]
|
|
23
|
+
env[:options].reverse_merge!(:durability => NoBrainer::Config.durability)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
if env[:options][:db] && !env[:options][:db].is_a?(RethinkDB::RQL)
|
|
@@ -28,6 +28,8 @@ class NoBrainer::QueryRunner::RunOptions < NoBrainer::QueryRunner::Middleware
|
|
|
28
28
|
env[:options][:db] = RethinkDB::RQL.new.db(env[:db_name])
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
env[:criteria] = env[:options].delete(:criteria)
|
|
32
|
+
|
|
31
33
|
@runner.call(env)
|
|
32
34
|
end
|
|
33
35
|
end
|
data/lib/no_brainer/railtie.rb
CHANGED
|
@@ -7,12 +7,22 @@ class NoBrainer::Railtie < Rails::Railtie
|
|
|
7
7
|
config.action_dispatch.rescue_responses.merge!(
|
|
8
8
|
"NoBrainer::Errors::DocumentNotFound" => :not_found,
|
|
9
9
|
"NoBrainer::Errors::DocumentInvalid" => :unprocessable_entity,
|
|
10
|
+
"NoBrainer::Errors::InvalidType" => :bad_request,
|
|
10
11
|
)
|
|
11
12
|
|
|
12
13
|
rake_tasks do
|
|
13
14
|
load "no_brainer/railtie/database.rake"
|
|
14
15
|
end
|
|
15
16
|
|
|
17
|
+
console do
|
|
18
|
+
# Send console messages to standard error like ActiveRecord.
|
|
19
|
+
# Not the cleanest behavior, but if ActiveRecord does it, why not.
|
|
20
|
+
unless defined?(ActiveRecord)
|
|
21
|
+
console = ActiveSupport::Logger.new(STDERR)
|
|
22
|
+
Rails.logger.extend ActiveSupport::Logger.broadcast(console)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
16
26
|
config.after_initialize do
|
|
17
27
|
NoBrainer::Config.configure unless NoBrainer::Config.configured?
|
|
18
28
|
|
data/lib/nobrainer.rb
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('1.9')
|
|
2
|
-
raise 'Please use Ruby 1.9 or later'
|
|
3
|
-
end
|
|
4
|
-
|
|
5
1
|
require 'active_support'
|
|
6
|
-
%w(module/delegation module/attribute_accessors class/attribute object/blank object/inclusion
|
|
7
|
-
object/
|
|
2
|
+
%w(module/delegation module/attribute_accessors class/attribute object/blank object/inclusion object/deep_dup
|
|
3
|
+
object/try hash/keys hash/indifferent_access hash/reverse_merge hash/deep_merge array/extract_options)
|
|
8
4
|
.each { |dep| require "active_support/core_ext/#{dep}" }
|
|
9
5
|
|
|
10
6
|
module NoBrainer
|
|
@@ -28,7 +24,7 @@ module NoBrainer
|
|
|
28
24
|
end
|
|
29
25
|
|
|
30
26
|
def disconnect
|
|
31
|
-
@connection.try(:disconnect)
|
|
27
|
+
@connection.try(:disconnect, :noreply_wait => true)
|
|
32
28
|
@connection = nil
|
|
33
29
|
end
|
|
34
30
|
|
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.
|
|
4
|
+
version: 0.13.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-01-
|
|
11
|
+
date: 2014-01-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rethinkdb
|
|
@@ -25,25 +25,33 @@ dependencies:
|
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: 1.11.0.1
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
28
|
+
name: activesupport
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - '>='
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
34
|
-
- - <
|
|
35
|
-
- !ruby/object:Gem::Version
|
|
36
|
-
version: '5'
|
|
33
|
+
version: 4.0.0
|
|
37
34
|
type: :runtime
|
|
38
35
|
prerelease: false
|
|
39
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
40
37
|
requirements:
|
|
41
38
|
- - '>='
|
|
42
39
|
- !ruby/object:Gem::Version
|
|
43
|
-
version:
|
|
44
|
-
|
|
40
|
+
version: 4.0.0
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: activemodel
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - '>='
|
|
45
46
|
- !ruby/object:Gem::Version
|
|
46
|
-
version:
|
|
47
|
+
version: 4.0.0
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - '>='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: 4.0.0
|
|
47
55
|
- !ruby/object:Gem::Dependency
|
|
48
56
|
name: middleware
|
|
49
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -65,75 +73,77 @@ executables: []
|
|
|
65
73
|
extensions: []
|
|
66
74
|
extra_rdoc_files: []
|
|
67
75
|
files:
|
|
68
|
-
- lib/no_brainer/document/id.rb
|
|
69
|
-
- lib/no_brainer/document/association/belongs_to.rb
|
|
70
|
-
- lib/no_brainer/document/association/has_many.rb
|
|
71
76
|
- lib/no_brainer/document/association/has_one.rb
|
|
72
77
|
- lib/no_brainer/document/association/has_one_through.rb
|
|
73
78
|
- lib/no_brainer/document/association/has_many_through.rb
|
|
79
|
+
- lib/no_brainer/document/association/has_many.rb
|
|
74
80
|
- lib/no_brainer/document/association/eager_loader.rb
|
|
75
81
|
- lib/no_brainer/document/association/core.rb
|
|
76
|
-
- lib/no_brainer/document/
|
|
77
|
-
- lib/no_brainer/document/criteria.rb
|
|
82
|
+
- lib/no_brainer/document/association/belongs_to.rb
|
|
78
83
|
- lib/no_brainer/document/polymorphic.rb
|
|
79
84
|
- lib/no_brainer/document/store_in.rb
|
|
80
85
|
- lib/no_brainer/document/core.rb
|
|
81
|
-
- lib/no_brainer/document/injection_layer.rb
|
|
82
|
-
- lib/no_brainer/document/index.rb
|
|
83
86
|
- lib/no_brainer/document/serialization.rb
|
|
84
87
|
- lib/no_brainer/document/association.rb
|
|
85
|
-
- lib/no_brainer/document/
|
|
88
|
+
- lib/no_brainer/document/callbacks.rb
|
|
89
|
+
- lib/no_brainer/document/dynamic_attributes.rb
|
|
86
90
|
- lib/no_brainer/document/timestamps.rb
|
|
87
91
|
- lib/no_brainer/document/dirty.rb
|
|
88
|
-
- lib/no_brainer/document/
|
|
92
|
+
- lib/no_brainer/document/index.rb
|
|
93
|
+
- lib/no_brainer/document/validation.rb
|
|
89
94
|
- lib/no_brainer/document/attributes.rb
|
|
95
|
+
- lib/no_brainer/document/id.rb
|
|
96
|
+
- lib/no_brainer/document/injection_layer.rb
|
|
97
|
+
- lib/no_brainer/document/persistance.rb
|
|
98
|
+
- lib/no_brainer/document/readonly.rb
|
|
90
99
|
- lib/no_brainer/document/types.rb
|
|
91
|
-
- lib/no_brainer/
|
|
100
|
+
- lib/no_brainer/document/criteria.rb
|
|
92
101
|
- lib/no_brainer/query_runner/database_on_demand.rb
|
|
93
|
-
- lib/no_brainer/query_runner/logger.rb
|
|
94
102
|
- lib/no_brainer/query_runner/table_on_demand.rb
|
|
95
103
|
- lib/no_brainer/query_runner/write_error.rb
|
|
96
104
|
- lib/no_brainer/query_runner/driver.rb
|
|
105
|
+
- lib/no_brainer/query_runner/logger.rb
|
|
97
106
|
- lib/no_brainer/query_runner/missing_index.rb
|
|
98
107
|
- lib/no_brainer/query_runner/run_options.rb
|
|
108
|
+
- lib/no_brainer/query_runner/connection.rb
|
|
99
109
|
- lib/no_brainer/railtie/database.rake
|
|
100
|
-
- lib/no_brainer/criteria/chainable/limit.rb
|
|
101
|
-
- lib/no_brainer/criteria/chainable/order_by.rb
|
|
102
|
-
- lib/no_brainer/criteria/chainable/scope.rb
|
|
103
|
-
- lib/no_brainer/criteria/chainable/raw.rb
|
|
104
|
-
- lib/no_brainer/criteria/chainable/core.rb
|
|
105
|
-
- lib/no_brainer/criteria/chainable/where.rb
|
|
106
|
-
- lib/no_brainer/criteria/termination/inc.rb
|
|
107
|
-
- lib/no_brainer/criteria/termination/count.rb
|
|
108
|
-
- lib/no_brainer/criteria/termination/first.rb
|
|
109
|
-
- lib/no_brainer/criteria/termination/enumerable.rb
|
|
110
|
-
- lib/no_brainer/criteria/termination/update.rb
|
|
111
|
-
- lib/no_brainer/criteria/termination/delete.rb
|
|
112
|
-
- lib/no_brainer/criteria/termination/eager_loading.rb
|
|
113
|
-
- lib/no_brainer/criteria/termination/cache.rb
|
|
114
|
-
- lib/no_brainer/decorated_symbol.rb
|
|
115
110
|
- lib/no_brainer/index_manager.rb
|
|
116
111
|
- lib/no_brainer/loader.rb
|
|
117
112
|
- lib/no_brainer/locale/en.yml
|
|
118
|
-
- lib/no_brainer/util.rb
|
|
119
113
|
- lib/no_brainer/fork.rb
|
|
120
|
-
- lib/no_brainer/criteria.rb
|
|
121
114
|
- lib/no_brainer/connection.rb
|
|
122
115
|
- lib/no_brainer/query_runner.rb
|
|
123
|
-
- lib/no_brainer/
|
|
116
|
+
- lib/no_brainer/util.rb
|
|
117
|
+
- lib/no_brainer/decorated_symbol.rb
|
|
118
|
+
- lib/no_brainer/criteria/scope.rb
|
|
119
|
+
- lib/no_brainer/criteria/raw.rb
|
|
120
|
+
- lib/no_brainer/criteria/preload.rb
|
|
121
|
+
- lib/no_brainer/criteria/order_by.rb
|
|
122
|
+
- lib/no_brainer/criteria/limit.rb
|
|
123
|
+
- lib/no_brainer/criteria/first.rb
|
|
124
|
+
- lib/no_brainer/criteria/enumerable.rb
|
|
125
|
+
- lib/no_brainer/criteria/count.rb
|
|
126
|
+
- lib/no_brainer/criteria/cache.rb
|
|
127
|
+
- lib/no_brainer/criteria/after_find.rb
|
|
128
|
+
- lib/no_brainer/criteria/where.rb
|
|
129
|
+
- lib/no_brainer/criteria/update.rb
|
|
130
|
+
- lib/no_brainer/criteria/delete.rb
|
|
131
|
+
- lib/no_brainer/criteria/core.rb
|
|
124
132
|
- lib/no_brainer/railtie.rb
|
|
125
133
|
- lib/no_brainer/config.rb
|
|
126
|
-
- lib/no_brainer/autoload.rb
|
|
127
134
|
- lib/no_brainer/document.rb
|
|
135
|
+
- lib/no_brainer/criteria.rb
|
|
136
|
+
- lib/no_brainer/error.rb
|
|
137
|
+
- lib/no_brainer/autoload.rb
|
|
128
138
|
- lib/rails/generators/nobrainer.rb
|
|
129
139
|
- lib/rails/generators/nobrainer/model/model_generator.rb
|
|
130
140
|
- lib/rails/generators/nobrainer/model/templates/model.rb.tt
|
|
131
141
|
- lib/nobrainer.rb
|
|
132
142
|
- README.md
|
|
133
|
-
- LICENSE
|
|
134
|
-
homepage: http://
|
|
143
|
+
- LICENSE
|
|
144
|
+
homepage: http://nobrainer.io
|
|
135
145
|
licenses:
|
|
136
|
-
-
|
|
146
|
+
- LGPLv3
|
|
137
147
|
metadata: {}
|
|
138
148
|
post_install_message:
|
|
139
149
|
rdoc_options: []
|
|
@@ -143,7 +153,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
143
153
|
requirements:
|
|
144
154
|
- - '>='
|
|
145
155
|
- !ruby/object:Gem::Version
|
|
146
|
-
version:
|
|
156
|
+
version: 1.9.0
|
|
147
157
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
158
|
requirements:
|
|
149
159
|
- - '>='
|
data/LICENSE.md
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
Copyright (C) 2012 Nicolas Viennot
|
|
2
|
-
|
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
-
|
|
5
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
-
|
|
7
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
module NoBrainer::Criteria::Chainable::Raw
|
|
2
|
-
extend ActiveSupport::Concern
|
|
3
|
-
|
|
4
|
-
included { attr_accessor :_raw, :__after_instantiate }
|
|
5
|
-
|
|
6
|
-
def raw
|
|
7
|
-
chain { |criteria| criteria._raw = true }
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def _after_instantiate(block)
|
|
11
|
-
# Just some helper for the has_many association to set the inverses on the
|
|
12
|
-
# related belongs_to. A bit hackish.
|
|
13
|
-
chain { |criteria| criteria.__after_instantiate = block }
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def merge!(criteria, options={})
|
|
17
|
-
super
|
|
18
|
-
self._raw = criteria._raw unless criteria._raw.nil?
|
|
19
|
-
self.__after_instantiate ||= criteria.__after_instantiate
|
|
20
|
-
self
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
private
|
|
24
|
-
|
|
25
|
-
def raw?
|
|
26
|
-
!!_raw
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def instantiate_doc(attrs)
|
|
30
|
-
(raw? ? attrs : klass.new_from_db(attrs))
|
|
31
|
-
.tap { |doc| __after_instantiate.call(doc) if __after_instantiate }
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
module NoBrainer::Criteria::Termination::EagerLoading
|
|
2
|
-
extend ActiveSupport::Concern
|
|
3
|
-
|
|
4
|
-
included { attr_accessor :_includes }
|
|
5
|
-
|
|
6
|
-
def initialize(options={})
|
|
7
|
-
super
|
|
8
|
-
self._includes = []
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def includes(*values)
|
|
12
|
-
chain(:keep_cache => true) { |criteria| criteria._includes = values }
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def merge!(criteria, options={})
|
|
16
|
-
super
|
|
17
|
-
self._includes = self._includes + criteria._includes
|
|
18
|
-
|
|
19
|
-
# XXX Not pretty hack
|
|
20
|
-
if criteria._includes.present? && cached?
|
|
21
|
-
perform_eager_loading(@cache)
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def each(options={}, &block)
|
|
26
|
-
return super unless should_eager_load? && !options[:no_eager_loading] && block
|
|
27
|
-
|
|
28
|
-
docs = []
|
|
29
|
-
super(options.merge(:no_eager_loading => true)) { |doc| docs << doc }
|
|
30
|
-
perform_eager_loading(docs)
|
|
31
|
-
docs.each(&block)
|
|
32
|
-
self
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
private
|
|
36
|
-
|
|
37
|
-
def should_eager_load?
|
|
38
|
-
self._includes.present? && !raw?
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def get_one(criteria)
|
|
42
|
-
super.tap { |doc| perform_eager_loading([doc]) }
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def perform_eager_loading(docs)
|
|
46
|
-
if should_eager_load? && docs.present?
|
|
47
|
-
NoBrainer::Document::Association::EagerLoader.new.eager_load(docs, self._includes)
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
module NoBrainer::Criteria::Termination::Inc
|
|
2
|
-
extend ActiveSupport::Concern
|
|
3
|
-
|
|
4
|
-
def inc_all(field, value=1)
|
|
5
|
-
# TODO The useful inc() is on a model instance.
|
|
6
|
-
# But then do we want to postpone the inc() to the next save?
|
|
7
|
-
# It might make sense (because we don't have transactions).
|
|
8
|
-
update_all { |doc| { field => doc[field] + value } }
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def dec_all(field, value=1)
|
|
12
|
-
inc_all(field, -value)
|
|
13
|
-
end
|
|
14
|
-
end
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
module NoBrainer::Criteria::Termination::Update
|
|
2
|
-
extend ActiveSupport::Concern
|
|
3
|
-
|
|
4
|
-
def update_all(attrs={}, &block)
|
|
5
|
-
block = proc { attrs } unless block_given?
|
|
6
|
-
run(to_rql.update(&block))['replaced']
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def replace_all(attrs={}, &block)
|
|
10
|
-
block = proc { attrs } unless block_given?
|
|
11
|
-
run(to_rql.replace(&block))['replaced']
|
|
12
|
-
end
|
|
13
|
-
end
|