rapids 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rapids/batch/columns_helper.rb +14 -2
- data/lib/rapids/batch/create_table.rb +7 -2
- data/lib/rapids/batch/create_trigger.rb +22 -5
- data/lib/rapids/batch/insert_into.rb +12 -7
- data/lib/rapids/batch/model_extensions.rb +14 -2
- data/lib/rapids/batch/update.rb +15 -0
- data/lib/rapids/batch.rb +7 -1
- data/lib/rapids/version.rb +1 -1
- data/spec/batch/columns_helper_spec.rb +22 -7
- data/spec/batch/create_table_spec.rb +8 -0
- data/spec/batch/create_trigger_spec.rb +8 -0
- data/spec/batch/insert_into_spec.rb +18 -0
- data/spec/batch/update_spec.rb +15 -0
- data/spec/rapids_batch_spec.rb +6 -0
- metadata +7 -4
@@ -4,8 +4,9 @@ module Rapids
|
|
4
4
|
include Enumerable
|
5
5
|
include ModelExtensions
|
6
6
|
|
7
|
-
def initialize(model,
|
8
|
-
@hash =
|
7
|
+
def initialize(model,batch)
|
8
|
+
@hash = update_columns_hash(model,batch.updates)
|
9
|
+
@hash.merge!(generate_columns_hash(model,batch.find_or_creates))
|
9
10
|
end
|
10
11
|
|
11
12
|
def each(&block)
|
@@ -76,6 +77,17 @@ module Rapids
|
|
76
77
|
|
77
78
|
hash
|
78
79
|
end
|
80
|
+
|
81
|
+
def update_columns_hash(model,updates)
|
82
|
+
updates.inject({}) do |hash,update|
|
83
|
+
if model.reflections[update.name]
|
84
|
+
hash[{:type => :update, :name => update.name}] = generate_columns_hash(model.reflections[update.name].klass,[])
|
85
|
+
hash
|
86
|
+
else
|
87
|
+
hash
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
79
91
|
end
|
80
92
|
end
|
81
93
|
end
|
@@ -12,11 +12,16 @@ module Rapids
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def to_sql
|
15
|
-
columns_helper = ColumnsHelper.new(@model,@batch
|
15
|
+
columns_helper = ColumnsHelper.new(@model,@batch)
|
16
16
|
columns_sql = columns_helper.map do |column,path|
|
17
17
|
association = nil
|
18
18
|
model = @model
|
19
|
-
path.each do |
|
19
|
+
path.each do |association_name_or_hash|
|
20
|
+
association_name = if association_name_or_hash.is_a?(Hash)
|
21
|
+
association_name_or_hash[:name]
|
22
|
+
else
|
23
|
+
association_name_or_hash
|
24
|
+
end
|
20
25
|
if model.reflections[association_name]
|
21
26
|
association = model.reflections[association_name]
|
22
27
|
model = model.reflections[association_name].klass
|
@@ -17,7 +17,7 @@ module Rapids
|
|
17
17
|
"declare #{variable_name(find_or_create.name,[])} integer;"
|
18
18
|
end.join("\n")
|
19
19
|
|
20
|
-
columns_helper = ColumnsHelper.new(@model,@batch
|
20
|
+
columns_helper = ColumnsHelper.new(@model,@batch)
|
21
21
|
main_columns = columns_helper.find_all{|column,path| path == []}
|
22
22
|
|
23
23
|
insert_header = (main_columns.map(&:first) + criteria_columns(@model,association_find_or_creates.map(&:name))).map{|a|sql_column_name(a,[])}
|
@@ -28,10 +28,11 @@ module Rapids
|
|
28
28
|
begin
|
29
29
|
#{declares}
|
30
30
|
|
31
|
-
#{find_or_create_sql(@model,@batch
|
31
|
+
#{find_or_create_sql(@model,@batch)}
|
32
32
|
|
33
33
|
#{@options[:replace] ? "replace" : "insert"} into `#{@model.table_name}` (#{insert_header.join(",")})
|
34
34
|
values (#{insert_values.join(",")});
|
35
|
+
#{updates_sql(@model,@batch)}
|
35
36
|
end
|
36
37
|
TRIGGER_SQL
|
37
38
|
end
|
@@ -41,10 +42,10 @@ module Rapids
|
|
41
42
|
find_or_creates.reject{|foc|model.reflections[foc.name].nil?}
|
42
43
|
end
|
43
44
|
|
44
|
-
def find_or_create_sql(model,
|
45
|
-
columns_helper = ColumnsHelper.new(model,
|
45
|
+
def find_or_create_sql(model,batch,recursion_path = [])
|
46
|
+
columns_helper = ColumnsHelper.new(model,batch)
|
46
47
|
|
47
|
-
find_or_creates.map do |find_or_create|
|
48
|
+
batch.find_or_creates.map do |find_or_create|
|
48
49
|
name,criteria = find_or_create.name,find_or_create.find_columns
|
49
50
|
if model.reflections[name]
|
50
51
|
sub_model = model.reflections[name].klass
|
@@ -173,6 +174,22 @@ module Rapids
|
|
173
174
|
end
|
174
175
|
end
|
175
176
|
end
|
177
|
+
|
178
|
+
def updates_sql(model,batch)
|
179
|
+
columns_helper = ColumnsHelper.new(model,batch)
|
180
|
+
|
181
|
+
batch.updates.map do |update|
|
182
|
+
association = model.reflections[update.name]
|
183
|
+
update_model = association.klass
|
184
|
+
|
185
|
+
update_columns = columns_helper.find_all{|column,path| path == update.path}.map do |pair|
|
186
|
+
column,path = *pair
|
187
|
+
"`#{column.name}` = IFNULL(new.#{sql_column_name(*pair)},`#{column.name}`)" #TODO should later add support for setting null in this update
|
188
|
+
end
|
189
|
+
|
190
|
+
"update `#{update_model.table_name}` set #{update_columns.join(",")} where `#{update_model.table_name}`.id = new.`#{association.primary_key_name}`;"
|
191
|
+
end.join("\n")
|
192
|
+
end
|
176
193
|
end
|
177
194
|
end
|
178
195
|
end
|
@@ -14,7 +14,7 @@ module Rapids
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def to_sql
|
17
|
-
columns_helper = ColumnsHelper.new(@model,@batch
|
17
|
+
columns_helper = ColumnsHelper.new(@model,@batch)
|
18
18
|
insert_header_sql = columns_helper.map{|column,path|sql_column_name(column,path)}.join(",")
|
19
19
|
|
20
20
|
values_sql = @values.map do |row|
|
@@ -28,12 +28,17 @@ module Rapids
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
specific_object = path.inject(row) do |memo,
|
32
|
-
if
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
specific_object = path.inject(row) do |memo,hash_or_association_name|
|
32
|
+
association_name = if hash_or_association_name.is_a?(Hash)
|
33
|
+
hash_or_association_name[:name]
|
34
|
+
else
|
35
|
+
hash_or_association_name
|
36
|
+
end
|
37
|
+
if memo.respond_to?(association_name)
|
38
|
+
memo.send(association_name)
|
39
|
+
elsif memo.is_a?(Hash) && memo[association_name.to_s]
|
40
|
+
memo[association_name.to_s]
|
41
|
+
elsif association_name.is_a?(String)
|
37
42
|
memo
|
38
43
|
end
|
39
44
|
end
|
@@ -10,8 +10,20 @@ module Rapids
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def sql_column_name(column,hash_path)
|
13
|
-
prefix = hash_path.empty?
|
14
|
-
|
13
|
+
prefix = if hash_path.empty?
|
14
|
+
""
|
15
|
+
elsif path_type = hash_path.first and path_type.is_a?(Hash) and path_type[:type] == :update
|
16
|
+
"update$"
|
17
|
+
else
|
18
|
+
"foc$"
|
19
|
+
end
|
20
|
+
association_list = (hash_path + [column.name]).map do |path_type|
|
21
|
+
if path_type.is_a?(Hash)
|
22
|
+
path_type[:name]
|
23
|
+
else
|
24
|
+
path_type.to_s
|
25
|
+
end
|
26
|
+
end.join("$")
|
15
27
|
"`#{prefix+association_list}`"
|
16
28
|
end
|
17
29
|
|
data/lib/rapids/batch.rb
CHANGED
@@ -2,19 +2,25 @@ require 'rapids/batch/create_table'
|
|
2
2
|
require 'rapids/batch/insert_into'
|
3
3
|
require 'rapids/batch/create_trigger'
|
4
4
|
require 'rapids/batch/find_or_create'
|
5
|
+
require 'rapids/batch/update'
|
5
6
|
|
6
7
|
module Rapids
|
7
8
|
module Batch
|
8
9
|
class DefineBatch
|
9
|
-
attr_reader :find_or_creates
|
10
|
+
attr_reader :find_or_creates, :updates
|
10
11
|
|
11
12
|
def initialize
|
12
13
|
@find_or_creates = []
|
14
|
+
@updates = []
|
13
15
|
end
|
14
16
|
|
15
17
|
def find_or_create(name,find_columns,*fill_columns_plus_other_params)
|
16
18
|
@find_or_creates << FindOrCreate.new(name,find_columns,fill_columns_plus_other_params.first)
|
17
19
|
end
|
20
|
+
|
21
|
+
def update(name)
|
22
|
+
@updates << Update.new(name)
|
23
|
+
end
|
18
24
|
end
|
19
25
|
|
20
26
|
def batch_create(collection,options = {})
|
data/lib/rapids/version.rb
CHANGED
@@ -3,20 +3,23 @@ require 'batch/spec_helper'
|
|
3
3
|
module Rapids::Batch
|
4
4
|
describe ColumnsHelper do
|
5
5
|
it "should intialize with an empty find or create list" do
|
6
|
-
|
6
|
+
batch = Rapids::Batch::DefineBatch.new
|
7
|
+
ColumnsHelper.new(Post,batch)
|
7
8
|
end
|
8
9
|
|
9
10
|
it "should initialize with the association find or create" do
|
10
|
-
|
11
|
-
|
11
|
+
batch = Rapids::Batch::DefineBatch.new
|
12
|
+
batch.find_or_create(:author,[:name])
|
13
|
+
columns_helper = ColumnsHelper.new(Post,batch)
|
12
14
|
|
13
15
|
columns_helper.map{|a|a.first.name}.include?("name").should be_true
|
14
16
|
columns_helper.map{|a|a.first.name}.include?("author_id").should be_false, "expected author_id not to be present in this list:\n#{columns_helper.to_a.inspect}"
|
15
17
|
end
|
16
18
|
|
17
19
|
it "should initialize with the manual find or create format" do
|
18
|
-
|
19
|
-
|
20
|
+
batch = Rapids::Batch::DefineBatch.new
|
21
|
+
batch.find_or_create("Category",[:category])
|
22
|
+
columns_helper = ColumnsHelper.new(Post,batch)
|
20
23
|
|
21
24
|
columns_helper.any? do |pair|
|
22
25
|
column,path = *pair
|
@@ -25,13 +28,25 @@ module Rapids::Batch
|
|
25
28
|
end
|
26
29
|
|
27
30
|
it "should initialize with the association find or create with a has_many find or create" do
|
28
|
-
|
29
|
-
|
31
|
+
batch = Rapids::Batch::DefineBatch.new
|
32
|
+
batch.find_or_create(:post,[:name,{:post_tags => [:tag_id]}])
|
33
|
+
columns_helper = ColumnsHelper.new(Comment,batch)
|
30
34
|
|
31
35
|
columns_helper.any? do |pair|
|
32
36
|
column,path = *pair
|
33
37
|
column.name == "tag_id" && path == [:post,:post_tags]
|
34
38
|
end.should be_true, "expected to find a column named 'tag_id' and the path to be [:post,:post_tags] in the following:\n#{columns_helper.to_a.inspect}"
|
35
39
|
end
|
40
|
+
|
41
|
+
it "should initialize with the update definition and have the appropriate columns" do
|
42
|
+
batch = Rapids::Batch::DefineBatch.new
|
43
|
+
batch.update(:author)
|
44
|
+
columns_helper = ColumnsHelper.new(Post,batch)
|
45
|
+
|
46
|
+
columns_helper.any? do |pair|
|
47
|
+
column,path = *pair
|
48
|
+
column.name == "name" && path == [{:type => :update,:name => :author}]
|
49
|
+
end.should be_true, "expected to find a column named 'name' and the path to be [{:type => :update,:name => :author}] in the following:\n#{columns_helper.to_a.inspect}"
|
50
|
+
end
|
36
51
|
end
|
37
52
|
end
|
@@ -40,5 +40,13 @@ module Rapids::Batch
|
|
40
40
|
create_table = CreateTable.new(Comment,batch)
|
41
41
|
create_table.to_sql.should == "CREATE TABLE `$comments_batch` (`body` varchar(255),`foc$post$author_id` int(11),`foc$post$category` varchar(255),`foc$post$name` varchar(255),`foc$post$post_tags$tag_id` varchar(255),`title` varchar(255)) ENGINE=BLACKHOLE DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"
|
42
42
|
end
|
43
|
+
|
44
|
+
it "should generate sql for a update definition" do
|
45
|
+
batch = Rapids::Batch::DefineBatch.new
|
46
|
+
batch.update(:author)
|
47
|
+
|
48
|
+
create_table = CreateTable.new(Post,batch)
|
49
|
+
create_table.to_sql.should == "CREATE TABLE `$posts_batch` (`author_id` int(11),`category` varchar(255),`name` varchar(255),`update$author$name` varchar(255)) ENGINE=BLACKHOLE DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"
|
50
|
+
end
|
43
51
|
end
|
44
52
|
end
|
@@ -39,5 +39,13 @@ module Rapids::Batch
|
|
39
39
|
create_trigger = CreateTrigger.new(Category,batch,:replace => true)
|
40
40
|
clean_sql(create_trigger.to_sql).should == "create trigger `$categories_batch_trigger` after insert on `$categories_batch` for each row\nbegin\nreplace into `categories` (`category`)\nvalues (new.`category`);\nend"
|
41
41
|
end
|
42
|
+
|
43
|
+
it "should generate sql for a basic definition" do
|
44
|
+
batch = Rapids::Batch::DefineBatch.new
|
45
|
+
batch.update(:author)
|
46
|
+
|
47
|
+
create_trigger = CreateTrigger.new(Post,batch)
|
48
|
+
clean_sql(create_trigger.to_sql).should == "create trigger `$posts_batch_trigger` after insert on `$posts_batch` for each row\nbegin\ninsert into `posts` (`author_id`,`category`,`name`)\nvalues (new.`author_id`,new.`category`,new.`name`);\nupdate `authors` set `name` = IFNULL(new.`update$author$name`,`name`) where `authors`.id = new.`author_id`;\nend"
|
49
|
+
end
|
42
50
|
end
|
43
51
|
end
|
@@ -49,6 +49,15 @@ module Rapids::Batch
|
|
49
49
|
clean_sql(insert_into.to_sql).should == "INSERT INTO `$categories_batch` (`category`) VALUES ('food'),('politics')"
|
50
50
|
end
|
51
51
|
|
52
|
+
it "should generate sql for an update definition" do
|
53
|
+
batch = Rapids::Batch::DefineBatch.new
|
54
|
+
batch.update(:author)
|
55
|
+
collection = [Post.new(:name => "Dining at 323 Butter St",:category => "food",:author_id => 1,:author => Author.new(:name => "Joe"))]
|
56
|
+
|
57
|
+
insert_into = InsertInto.new(Post,batch,collection)
|
58
|
+
clean_sql(insert_into.to_sql).should == "INSERT INTO `$posts_batch` (`author_id`,`category`,`name`,`update$author$name`) VALUES (1,'food','Dining at 323 Butter St','Joe')"
|
59
|
+
end
|
60
|
+
|
52
61
|
describe "Without model objects" do
|
53
62
|
it "should generate sql for a simple batch definition" do
|
54
63
|
batch = Rapids::Batch::DefineBatch.new
|
@@ -95,6 +104,15 @@ module Rapids::Batch
|
|
95
104
|
create_table = InsertInto.new(Comment,batch,collection)
|
96
105
|
create_table.to_sql.should == "INSERT INTO `$comments_batch` (`body`,`foc$post$author_id`,`foc$post$category`,`foc$post$name`,`foc$post$post_tags$tag_id`,`title`) VALUES ('Im a troll',NULL,NULL,'I just did something cool','1,2','You suck')"
|
97
106
|
end
|
107
|
+
|
108
|
+
it "should generate sql for an update definition" do
|
109
|
+
batch = Rapids::Batch::DefineBatch.new
|
110
|
+
batch.update(:author)
|
111
|
+
collection = [{"name" => "Dining at 323 Butter St","category" => "food","author_id" => 1,"author" => {"name" => "Joe"}}]
|
112
|
+
|
113
|
+
insert_into = InsertInto.new(Post,batch,collection)
|
114
|
+
clean_sql(insert_into.to_sql).should == "INSERT INTO `$posts_batch` (`author_id`,`category`,`name`,`update$author$name`) VALUES (1,'food','Dining at 323 Butter St','Joe')"
|
115
|
+
end
|
98
116
|
end
|
99
117
|
end
|
100
118
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'batch/spec_helper'
|
2
|
+
|
3
|
+
module Rapids::Batch
|
4
|
+
describe Update do
|
5
|
+
it "should initialize with a name and the name should be retrievable" do
|
6
|
+
u = Update.new(:hello)
|
7
|
+
u.name.should == :hello
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should give me it's path hash" do
|
11
|
+
u = Update.new(:hello)
|
12
|
+
u.path.should == [{:type => :update, :name => :hello}]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/spec/rapids_batch_spec.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rapids
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 4
|
10
|
+
version: 0.1.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- James Smith
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-08-
|
18
|
+
date: 2011-08-31 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -89,6 +89,7 @@ files:
|
|
89
89
|
- lib/rapids/batch/find_or_create.rb
|
90
90
|
- lib/rapids/batch/insert_into.rb
|
91
91
|
- lib/rapids/batch/model_extensions.rb
|
92
|
+
- lib/rapids/batch/update.rb
|
92
93
|
- lib/rapids/version.rb
|
93
94
|
- rapids.gemspec
|
94
95
|
- spec/batch/columns_helper_spec.rb
|
@@ -96,6 +97,7 @@ files:
|
|
96
97
|
- spec/batch/create_trigger_spec.rb
|
97
98
|
- spec/batch/insert_into_spec.rb
|
98
99
|
- spec/batch/spec_helper.rb
|
100
|
+
- spec/batch/update_spec.rb
|
99
101
|
- spec/rapids_batch_spec.rb
|
100
102
|
- spec/spec_helper.rb
|
101
103
|
has_rdoc: true
|
@@ -140,5 +142,6 @@ test_files:
|
|
140
142
|
- spec/batch/create_trigger_spec.rb
|
141
143
|
- spec/batch/insert_into_spec.rb
|
142
144
|
- spec/batch/spec_helper.rb
|
145
|
+
- spec/batch/update_spec.rb
|
143
146
|
- spec/rapids_batch_spec.rb
|
144
147
|
- spec/spec_helper.rb
|