rapids 0.1.3 → 0.1.4

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.
@@ -4,8 +4,9 @@ module Rapids
4
4
  include Enumerable
5
5
  include ModelExtensions
6
6
 
7
- def initialize(model,find_or_creates)
8
- @hash = generate_columns_hash(model,find_or_creates)
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.find_or_creates)
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 |association_name|
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.find_or_creates)
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.find_or_creates)}
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,find_or_creates, recursion_path = [])
45
- columns_helper = ColumnsHelper.new(model,find_or_creates)
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.find_or_creates)
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,association|
32
- if memo.respond_to?(association)
33
- memo.send(association)
34
- elsif memo.is_a?(Hash) && memo[association.to_s]
35
- memo[association.to_s]
36
- elsif association.is_a?(String)
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? ? "" : "foc$"
14
- association_list = (hash_path + [column.name]).map(&:to_s).join("$")
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
 
@@ -0,0 +1,15 @@
1
+ module Rapids
2
+ module Batch
3
+ class Update
4
+ attr_reader :name
5
+
6
+ def initialize(name)
7
+ @name = name
8
+ end
9
+
10
+ def path
11
+ [{:type => :update, :name => name}]
12
+ end
13
+ end
14
+ end
15
+ end
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 = {})
@@ -1,3 +1,3 @@
1
1
  module Rapids
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
@@ -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
- ColumnsHelper.new(Post,[])
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
- find_or_creates = [FindOrCreate.new(:author,[:name],[])]
11
- columns_helper = ColumnsHelper.new(Post,find_or_creates)
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
- find_or_creates = [FindOrCreate.new("Category",[:category],[])]
19
- columns_helper = ColumnsHelper.new(Post,find_or_creates)
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
- find_or_creates = [FindOrCreate.new(:post,[:name,{:post_tags => [:tag_id]}],[])]
29
- columns_helper = ColumnsHelper.new(Comment,find_or_creates)
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
@@ -2,6 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  class RapidsBatchTestCase < ActiveRecord::Base
4
4
  extend Rapids::Batch
5
+
6
+ belongs_to :a_belongs_to
7
+
8
+ batch do
9
+ update :a_belongs_to
10
+ end
5
11
  end
6
12
 
7
13
  describe Rapids::Batch do
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: 29
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 3
10
- version: 0.1.3
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-26 00:00:00 -04:00
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