nobrainer 0.13.1 → 0.15.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/lib/no_brainer/config.rb +20 -4
- data/lib/no_brainer/criteria/count.rb +1 -1
- data/lib/no_brainer/criteria/delete.rb +2 -2
- data/lib/no_brainer/criteria/first.rb +6 -0
- data/lib/no_brainer/criteria/order_by.rb +33 -10
- data/lib/no_brainer/criteria/update.rb +2 -2
- data/lib/no_brainer/criteria/where.rb +12 -6
- data/lib/no_brainer/decorated_symbol.rb +2 -1
- data/lib/no_brainer/document/association/belongs_to.rb +10 -5
- data/lib/no_brainer/document/association/core.rb +1 -1
- data/lib/no_brainer/document/association/has_many.rb +10 -4
- data/lib/no_brainer/document/attributes.rb +29 -3
- data/lib/no_brainer/document/callbacks.rb +2 -10
- data/lib/no_brainer/document/core.rb +5 -3
- data/lib/no_brainer/document/criteria.rb +11 -11
- data/lib/no_brainer/document/dirty.rb +11 -0
- data/lib/no_brainer/document/dynamic_attributes.rb +4 -0
- data/lib/no_brainer/document/id.rb +49 -4
- data/lib/no_brainer/document/index.rb +6 -2
- data/lib/no_brainer/document/persistance.rb +7 -6
- data/lib/no_brainer/document/readonly.rb +7 -0
- data/lib/no_brainer/document/serialization.rb +4 -0
- data/lib/no_brainer/document/types/boolean.rb +26 -0
- data/lib/no_brainer/document/types/date.rb +26 -0
- data/lib/no_brainer/document/types/float.rb +20 -0
- data/lib/no_brainer/document/types/integer.rb +18 -0
- data/lib/no_brainer/document/types/string.rb +14 -0
- data/lib/no_brainer/document/types/symbol.rb +21 -0
- data/lib/no_brainer/document/types/time.rb +41 -0
- data/lib/no_brainer/document/types.rb +64 -124
- data/lib/no_brainer/document/uniqueness.rb +4 -2
- data/lib/no_brainer/document/validation.rb +2 -1
- data/lib/no_brainer/document.rb +2 -0
- data/lib/no_brainer/error.rb +9 -9
- data/lib/no_brainer/query_runner/logger.rb +18 -12
- data/lib/no_brainer/query_runner/missing_index.rb +15 -3
- data/lib/no_brainer/query_runner/reconnect.rb +15 -4
- data/lib/no_brainer/query_runner/table_on_demand.rb +14 -25
- data/lib/no_brainer/query_runner/write_error.rb +5 -8
- data/lib/no_brainer/rql.rb +25 -0
- data/lib/nobrainer.rb +9 -6
- data/lib/rails/generators/nobrainer/model/model_generator.rb +2 -1
- data/lib/rails/generators/nobrainer/model/templates/model.rb.tt +7 -2
- metadata +18 -11
- data/lib/no_brainer/util.rb +0 -23
|
@@ -3,8 +3,8 @@ class NoBrainer::QueryRunner::TableOnDemand < NoBrainer::QueryRunner::Middleware
|
|
|
3
3
|
@runner.call(env)
|
|
4
4
|
rescue RuntimeError => e
|
|
5
5
|
if NoBrainer::Config.auto_create_tables &&
|
|
6
|
-
e.message =~ /^Table `(.+)` does not exist\.$/
|
|
7
|
-
auto_create_table(env, $1)
|
|
6
|
+
e.message =~ /^Table `(.+)\.(.+)` does not exist\.$/
|
|
7
|
+
auto_create_table(env, $1, $2)
|
|
8
8
|
retry
|
|
9
9
|
end
|
|
10
10
|
raise
|
|
@@ -12,33 +12,22 @@ class NoBrainer::QueryRunner::TableOnDemand < NoBrainer::QueryRunner::Middleware
|
|
|
12
12
|
|
|
13
13
|
private
|
|
14
14
|
|
|
15
|
-
def auto_create_table(env, table_name)
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
def auto_create_table(env, database_name, table_name)
|
|
16
|
+
klass = NoBrainer::Document.all.select { |m| m.table_name == table_name }.first
|
|
17
|
+
if klass.nil?
|
|
18
|
+
raise "Auto table creation is not working for `#{database_name}.#{table_name}` -- Can't find the corresponding model."
|
|
18
19
|
end
|
|
19
|
-
env[:auto_create_table] = table_name
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
if env[:auto_create_table] == [database_name, table_name]
|
|
22
|
+
raise "Auto table creation is not working for `#{database_name}.#{table_name}`"
|
|
23
|
+
end
|
|
24
|
+
env[:auto_create_table] = [database_name, table_name]
|
|
25
|
+
|
|
26
|
+
NoBrainer.with_database(database_name) do
|
|
27
|
+
NoBrainer.table_create(table_name, :primary_key => klass.pk_name)
|
|
27
28
|
end
|
|
28
29
|
rescue RuntimeError => e
|
|
29
30
|
# We might have raced with another table create
|
|
30
|
-
raise unless e.message =~ /Table `#{table_name}` already exists/
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def find_db_names(terms)
|
|
34
|
-
terms = terms.body.args if terms.is_a?(RethinkDB::RQL)
|
|
35
|
-
terms.map do |term|
|
|
36
|
-
next unless term.is_a?(Term)
|
|
37
|
-
if term.type == Term::TermType::DB
|
|
38
|
-
term.args.first.datum.r_str
|
|
39
|
-
else
|
|
40
|
-
find_db_names(term.args)
|
|
41
|
-
end
|
|
42
|
-
end.flatten.uniq
|
|
31
|
+
raise unless e.message =~ /Table `#{database_name}\.#{table_name}` already exists/
|
|
43
32
|
end
|
|
44
33
|
end
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
class NoBrainer::QueryRunner::WriteError < NoBrainer::QueryRunner::Middleware
|
|
2
2
|
def call(env)
|
|
3
|
-
write_query = NoBrainer::
|
|
3
|
+
write_query = NoBrainer::RQL.is_write_query?(env[:query])
|
|
4
4
|
@runner.call(env).tap do |result|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if write_query && (result['errors'].to_i != 0 || result['skipped'].to_i != 0)
|
|
10
|
-
raise_write_error(env, result['first_error'])
|
|
5
|
+
if write_query && (result['errors'].to_i != 0)
|
|
6
|
+
error_msg = result['first_error']
|
|
7
|
+
raise_write_error(env, error_msg)
|
|
11
8
|
end
|
|
12
9
|
end
|
|
13
10
|
rescue RethinkDB::RqlRuntimeError => e
|
|
@@ -23,6 +20,6 @@ class NoBrainer::QueryRunner::WriteError < NoBrainer::QueryRunner::Middleware
|
|
|
23
20
|
def raise_write_error(env, error_msg)
|
|
24
21
|
error_msg ||= "Unknown error"
|
|
25
22
|
error_msg += "\nQuery was: #{env[:query].inspect[0..1000]}"
|
|
26
|
-
raise NoBrainer::Error::
|
|
23
|
+
raise NoBrainer::Error::DocumentNotPersisted, error_msg
|
|
27
24
|
end
|
|
28
25
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module NoBrainer::RQL
|
|
2
|
+
include RethinkDB::Term::TermType
|
|
3
|
+
extend self
|
|
4
|
+
|
|
5
|
+
def is_write_query?(rql_query)
|
|
6
|
+
type_of(rql_query) == :write
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def type_of(rql_query)
|
|
10
|
+
case rql_query.body.first
|
|
11
|
+
when UPDATE, DELETE, REPLACE, INSERT
|
|
12
|
+
:write
|
|
13
|
+
when DB_CREATE,DB_DROP, DB_LIST, TABLE_CREATE, TABLE_DROP, TABLE_LIST, SYNC,
|
|
14
|
+
INDEX_CREATE, INDEX_DROP, INDEX_LIST, INDEX_STATUS, INDEX_WAIT
|
|
15
|
+
:management
|
|
16
|
+
else
|
|
17
|
+
# XXX Not sure if that's correct, but we'll be happy for logging colors.
|
|
18
|
+
:read
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def is_table?(rql)
|
|
23
|
+
rql.body.first == TABLE
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/nobrainer.rb
CHANGED
|
@@ -7,19 +7,18 @@ module NoBrainer
|
|
|
7
7
|
require 'no_brainer/autoload'
|
|
8
8
|
extend NoBrainer::Autoload
|
|
9
9
|
|
|
10
|
-
# We eager load things that could be loaded
|
|
10
|
+
# We eager load things that could be loaded when handling the first web request.
|
|
11
|
+
# Code that is loaded through the DSL of NoBrainer should not be eager loaded.
|
|
11
12
|
autoload :Document, :IndexManager, :Loader, :Fork, :DecoratedSymbol
|
|
12
|
-
eager_autoload :Config, :Connection, :Error, :QueryRunner, :Criteria, :
|
|
13
|
+
eager_autoload :Config, :Connection, :Error, :QueryRunner, :Criteria, :RQL
|
|
13
14
|
|
|
14
15
|
class << self
|
|
15
|
-
#
|
|
16
|
-
# we can refactor to return a connection depending on the context.
|
|
17
|
-
# Note that a connection is tied to a database in NoBrainer.
|
|
16
|
+
# A connection is tied to a database.
|
|
18
17
|
def connection
|
|
19
18
|
@connection ||= begin
|
|
20
19
|
url = NoBrainer::Config.rethinkdb_url
|
|
21
20
|
raise "Please specify a database connection to RethinkDB" unless url
|
|
22
|
-
Connection.new(url)
|
|
21
|
+
Connection.new(url)
|
|
23
22
|
end
|
|
24
23
|
end
|
|
25
24
|
|
|
@@ -46,6 +45,10 @@ module NoBrainer
|
|
|
46
45
|
def jruby?
|
|
47
46
|
RUBY_PLATFORM == 'java'
|
|
48
47
|
end
|
|
48
|
+
|
|
49
|
+
def user_caller
|
|
50
|
+
caller.reject { |s| s =~ /\/no_brainer\// }.first
|
|
51
|
+
end
|
|
49
52
|
end
|
|
50
53
|
|
|
51
54
|
DecoratedSymbol.hook
|
|
@@ -2,7 +2,8 @@ require "rails/generators/nobrainer"
|
|
|
2
2
|
|
|
3
3
|
module NoBrainer::Generators
|
|
4
4
|
class ModelGenerator < Base
|
|
5
|
-
argument
|
|
5
|
+
argument(:attributes, :type => :array, default: [],
|
|
6
|
+
banner: "field[:type][:index] ... field[:type][:index]")
|
|
6
7
|
|
|
7
8
|
check_class_collision
|
|
8
9
|
|
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
class <%= class_name %><%= " < #{options[:parent].classify}" if options[:parent] %>
|
|
3
3
|
<% unless options[:parent] -%>
|
|
4
4
|
include NoBrainer::Document
|
|
5
|
+
include NoBrainer::Document::Timestamps
|
|
6
|
+
|
|
5
7
|
<% end -%>
|
|
6
8
|
<% attributes.reject(&:reference?).each do |attribute| -%>
|
|
7
|
-
field :<%= attribute.name
|
|
9
|
+
field :<%= attribute.name -%>
|
|
10
|
+
<%= puts attribute; ", :type => #{attribute.type.to_s.classify}" if attribute.type != :object -%>
|
|
11
|
+
<%= ", :index => true" if attribute.has_index? %>
|
|
8
12
|
<% end -%>
|
|
9
13
|
<% attributes.select(&:reference?).each do |attribute| -%>
|
|
10
|
-
belongs_to :<%= attribute.name
|
|
14
|
+
belongs_to :<%= attribute.name -%>
|
|
15
|
+
<%= ", :index => true" if attribute.has_index? %>
|
|
11
16
|
<% end -%>
|
|
12
17
|
end
|
|
13
18
|
<% end -%>
|
metadata
CHANGED
|
@@ -1,57 +1,57 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nobrainer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.15.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-
|
|
11
|
+
date: 2014-07-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rethinkdb
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - "
|
|
17
|
+
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 1.
|
|
19
|
+
version: 1.13.0.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: 1.
|
|
26
|
+
version: 1.13.0.0
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: activesupport
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 4.
|
|
33
|
+
version: 4.1.0
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: 4.
|
|
40
|
+
version: 4.1.0
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: activemodel
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - ">="
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: 4.
|
|
47
|
+
version: 4.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.
|
|
54
|
+
version: 4.1.0
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: middleware
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -119,6 +119,13 @@ files:
|
|
|
119
119
|
- lib/no_brainer/document/store_in.rb
|
|
120
120
|
- lib/no_brainer/document/timestamps.rb
|
|
121
121
|
- lib/no_brainer/document/types.rb
|
|
122
|
+
- lib/no_brainer/document/types/boolean.rb
|
|
123
|
+
- lib/no_brainer/document/types/date.rb
|
|
124
|
+
- lib/no_brainer/document/types/float.rb
|
|
125
|
+
- lib/no_brainer/document/types/integer.rb
|
|
126
|
+
- lib/no_brainer/document/types/string.rb
|
|
127
|
+
- lib/no_brainer/document/types/symbol.rb
|
|
128
|
+
- lib/no_brainer/document/types/time.rb
|
|
122
129
|
- lib/no_brainer/document/uniqueness.rb
|
|
123
130
|
- lib/no_brainer/document/validation.rb
|
|
124
131
|
- lib/no_brainer/error.rb
|
|
@@ -137,7 +144,7 @@ files:
|
|
|
137
144
|
- lib/no_brainer/query_runner/write_error.rb
|
|
138
145
|
- lib/no_brainer/railtie.rb
|
|
139
146
|
- lib/no_brainer/railtie/database.rake
|
|
140
|
-
- lib/no_brainer/
|
|
147
|
+
- lib/no_brainer/rql.rb
|
|
141
148
|
- lib/nobrainer.rb
|
|
142
149
|
- lib/rails/generators/nobrainer.rb
|
|
143
150
|
- lib/rails/generators/nobrainer/model/model_generator.rb
|
data/lib/no_brainer/util.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
module NoBrainer::Util
|
|
2
|
-
def self.is_write_query?(rql_query)
|
|
3
|
-
rql_type(rql_query) == :write
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
def self.rql_type(rql_query)
|
|
7
|
-
case rql_query.body.type
|
|
8
|
-
when Term::TermType::UPDATE, Term::TermType::DELETE,
|
|
9
|
-
Term::TermType::REPLACE, Term::TermType::INSERT
|
|
10
|
-
:write
|
|
11
|
-
when Term::TermType::DB_CREATE, Term::TermType::DB_DROP,
|
|
12
|
-
Term::TermType::DB_LIST, Term::TermType::TABLE_CREATE,
|
|
13
|
-
Term::TermType::TABLE_DROP, Term::TermType::TABLE_LIST,
|
|
14
|
-
Term::TermType::SYNC, Term::TermType::INDEX_CREATE,
|
|
15
|
-
Term::TermType::INDEX_DROP, Term::TermType::INDEX_LIST,
|
|
16
|
-
Term::TermType::INDEX_STATUS, Term::TermType::INDEX_WAIT
|
|
17
|
-
:management
|
|
18
|
-
else
|
|
19
|
-
# XXX Not sure if that's correct, but we'll be happy for logging colors.
|
|
20
|
-
:read
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|