hydroponics 0.3.2 → 0.3.3
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.
- data/ChangeLog.markdown +5 -0
- data/VERSION +1 -1
- data/app/actions/dupe.rb +8 -5
- data/app/actions/foreigndupe.rb +37 -0
- data/app/views/foreign_dupe/index.erb +111 -0
- data/config/hydro_app.rb +8 -4
- data/hydroponics.gemspec +4 -2
- data/spec/hydro_app_spec.rb +19 -3
- data/spec/hydroponics_spec.rb +44 -4
- data/spec/spec_helper.rb +8 -0
- metadata +6 -4
data/ChangeLog.markdown
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# hydroponics 0.3.3
|
2
|
+
|
3
|
+
* Generalized the routes, so new actions can be added without changing them
|
4
|
+
* Added an action, Foreign Dupe for duplicating rows in a table while incrementing a foreign key.
|
5
|
+
|
1
6
|
# hydroponics 0.3.2
|
2
7
|
|
3
8
|
* Fixed require statements so other machines can run the gem
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.3
|
data/app/actions/dupe.rb
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
module Hydroponics
|
2
2
|
module Actions
|
3
|
-
|
3
|
+
# Dupe
|
4
|
+
#
|
5
|
+
# Change the total rows of a table to target_count, either by duplicating
|
6
|
+
# the first row or deleting rows from the end.
|
7
|
+
def dupe(table, data)
|
4
8
|
table = table.to_sym
|
5
|
-
|
6
|
-
first_row = @db[table].first
|
7
|
-
first_row.delete(:id)
|
8
|
-
|
9
9
|
current_count = @db[table].count
|
10
|
+
target_count = data['count'] || current_count
|
10
11
|
|
11
12
|
if target_count > current_count
|
13
|
+
first_row = @db[table].first
|
14
|
+
first_row.delete(:id)
|
12
15
|
@db[table].multi_insert([first_row] * (target_count - current_count))
|
13
16
|
elsif current_count > target_count
|
14
17
|
cutoff_id = @db[table].map(:id)[target_count-1]
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'active_support/inflector'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
|
4
|
+
module Hydroponics
|
5
|
+
module Actions
|
6
|
+
# Foreign Dupe
|
7
|
+
#
|
8
|
+
# Just like Dupe, except it pulls valid foreign keys from table foreign_table.
|
9
|
+
#
|
10
|
+
# It starts from the beginning and increments as it goes.
|
11
|
+
def foreign_dupe(table, data)
|
12
|
+
table = table.to_sym
|
13
|
+
data.stringify_keys!
|
14
|
+
foreign_table = data['foreign_table'].to_sym
|
15
|
+
foreign_key_col = data['foreign_key'] || (foreign_table.to_s.singularize + "_id")
|
16
|
+
foreign_key_col = foreign_key_col.to_sym
|
17
|
+
|
18
|
+
current_count = @db[table].count
|
19
|
+
target_count = data['count'] || current_count
|
20
|
+
|
21
|
+
if target_count > current_count
|
22
|
+
foreign_ids = @db[foreign_table].map(:id)
|
23
|
+
first_row = @db[table].first
|
24
|
+
first_row.delete(:id)
|
25
|
+
n = target_count - current_count
|
26
|
+
@db[table].multi_insert( (1..n).collect { |i|
|
27
|
+
first_row.merge( Hash[foreign_key_col, foreign_ids[i % foreign_ids.size]] )
|
28
|
+
} )
|
29
|
+
elsif current_count > target_count
|
30
|
+
cutoff_id = @db[table].map(:id)[target_count-1]
|
31
|
+
@db[table].filter("id > #{cutoff_id}").delete
|
32
|
+
end
|
33
|
+
|
34
|
+
@db[table].count.to_s
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
4
|
+
|
5
|
+
<head>
|
6
|
+
<link href="../vendor/jquery-ui-1.8.5.custom/css/smoothness/jquery-ui-1.8.5.custom.css" media="screen" rel="stylesheet" type="text/css" />
|
7
|
+
<script type="text/javascript" src="../vendor/jquery-ui-1.8.5.custom/js/jquery-1.4.2.min.js"></script>
|
8
|
+
<script type="text/javascript" src="../vendor/jquery-ui-1.8.5.custom/js/jquery-ui-1.8.5.custom.min.js"></script>
|
9
|
+
<script type="text/javascript">
|
10
|
+
$(function(){
|
11
|
+
$("#slider div").slider({
|
12
|
+
slide: function(event, ui) {
|
13
|
+
$("#sliderct").html("<i>" + ui.value + "</i>");
|
14
|
+
$("button").button("enable");
|
15
|
+
},
|
16
|
+
max: 25000,
|
17
|
+
value: <%= db[@table].count %>
|
18
|
+
});
|
19
|
+
|
20
|
+
$("button").button();
|
21
|
+
$("button").button("enable");
|
22
|
+
$("button").click(function(){
|
23
|
+
$("#slider div").slider("disable");
|
24
|
+
$("button").button("disable");
|
25
|
+
$(".loader").show();
|
26
|
+
|
27
|
+
var postData = {
|
28
|
+
count: $("#slider div").slider("value"),
|
29
|
+
foreign_table: "<%= params[:foreign_table] %>"
|
30
|
+
};
|
31
|
+
if($("#foreign_key").val() != "") {
|
32
|
+
postData.foreign_key = $("#foreign_key").val()
|
33
|
+
}
|
34
|
+
|
35
|
+
$.ajax({
|
36
|
+
type: "POST",
|
37
|
+
url: "/foreign_dupe/<%= @table %>",
|
38
|
+
data: JSON.stringify(postData),
|
39
|
+
success: function(data, status, xhr) {
|
40
|
+
$("#sliderct").html("<b>" + data + "</b>");
|
41
|
+
$("#slider div").slider("enable");
|
42
|
+
$(".loader").hide();
|
43
|
+
},
|
44
|
+
processData: false
|
45
|
+
});
|
46
|
+
});
|
47
|
+
});
|
48
|
+
</script>
|
49
|
+
<style type="text/css">
|
50
|
+
.container {width:950px;margin:0 auto;}
|
51
|
+
.dupe h3 {
|
52
|
+
margin: 10px 5px 10px 18px;
|
53
|
+
color: #444;
|
54
|
+
float: left;
|
55
|
+
}
|
56
|
+
.dupe #slider {
|
57
|
+
float: left;
|
58
|
+
width: 252px;
|
59
|
+
margin: 16px 12px;
|
60
|
+
}
|
61
|
+
.dupecontainer {
|
62
|
+
height: 130px;
|
63
|
+
width: 501px;
|
64
|
+
}
|
65
|
+
.dupe {
|
66
|
+
height: 106px;
|
67
|
+
width: 500px;
|
68
|
+
border: 1px #ddd solid;
|
69
|
+
}
|
70
|
+
.dupe #button {
|
71
|
+
float: right;
|
72
|
+
margin: 2px 12px;
|
73
|
+
}
|
74
|
+
.dupe p {
|
75
|
+
padding: 50px 18px;
|
76
|
+
font-size: 12px;
|
77
|
+
}
|
78
|
+
h1, h3, p {
|
79
|
+
font-family: Verdana,Arial,sans-serif
|
80
|
+
}
|
81
|
+
.loader {
|
82
|
+
background-image: url('../ajax-loader.gif');
|
83
|
+
width: 32px;
|
84
|
+
height: 16px;
|
85
|
+
margin-top:16px;
|
86
|
+
float: left;
|
87
|
+
}
|
88
|
+
.dupe input {
|
89
|
+
float: right;
|
90
|
+
margin-top: 12px;
|
91
|
+
}
|
92
|
+
</style>
|
93
|
+
<title>Hydroponics <%= settings.version %></title>
|
94
|
+
</head>
|
95
|
+
|
96
|
+
<body class="container">
|
97
|
+
<div class="header">
|
98
|
+
<h1>Hydroponics</h1>
|
99
|
+
</div>
|
100
|
+
<div class="dupecontainer">
|
101
|
+
<div class="dupe">
|
102
|
+
<h3>Foreign Dupe</h3>
|
103
|
+
<div id='slider'><div></div></div>
|
104
|
+
<div class="loader" style="display:none;"></div>
|
105
|
+
<div id='button'><button>Update</button></div>
|
106
|
+
<input id='foreign_key'></input>
|
107
|
+
<p><%= @table.to_s.gsub("_"," ") %>: <span id='sliderct'><%= db[@table].count %></span></p>
|
108
|
+
</div>
|
109
|
+
</div>
|
110
|
+
</body>
|
111
|
+
</html>
|
data/config/hydro_app.rb
CHANGED
@@ -19,13 +19,17 @@ class HydroApp < Sinatra::Base
|
|
19
19
|
set :public, File.join(File.dirname(__FILE__), "../static")
|
20
20
|
set :version, File.read(File.join(File.dirname(__FILE__), "../VERSION")).chomp
|
21
21
|
|
22
|
-
|
22
|
+
# new actions can be used without any changes to the routes, as long as they follow
|
23
|
+
# the existing format.
|
24
|
+
# => ex: GET /dupe/users; POST /dupe/users {count: 10}
|
25
|
+
# => ex: GET /foreign_dupe/portfolios?foreign_table=users; POST /foreign_dupe/users {count: 100, foreign_table: 'users'}
|
26
|
+
post '/:action/:table' do |action, table|
|
23
27
|
data = JSON.parse(request.body.read)
|
24
|
-
|
28
|
+
send(action.to_sym, table, data)
|
25
29
|
end
|
26
30
|
|
27
|
-
get '
|
31
|
+
get '/:action/:table' do |action, table|
|
28
32
|
@table = table.to_sym
|
29
|
-
erb :"
|
33
|
+
erb :"#{action}/index"
|
30
34
|
end
|
31
35
|
end
|
data/hydroponics.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{hydroponics}
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Tyler Boyd"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-11-03}
|
13
13
|
s.default_executable = %q{hydro}
|
14
14
|
s.description = %q{A user interface to seed or destroy large quantities of data in a Rails app.}
|
15
15
|
s.email = %q{tboyd47@gmail.com}
|
@@ -28,7 +28,9 @@ Gem::Specification.new do |s|
|
|
28
28
|
"Rakefile",
|
29
29
|
"VERSION",
|
30
30
|
"app/actions/dupe.rb",
|
31
|
+
"app/actions/foreigndupe.rb",
|
31
32
|
"app/views/dupe/index.erb",
|
33
|
+
"app/views/foreign_dupe/index.erb",
|
32
34
|
"bin/hydro",
|
33
35
|
"config/hydro_app.rb",
|
34
36
|
"hydroponics.gemspec",
|
data/spec/hydro_app_spec.rb
CHANGED
@@ -31,7 +31,7 @@ describe "HydroApp" do
|
|
31
31
|
|
32
32
|
it "should show the table's count" do
|
33
33
|
get '/dupe/users'
|
34
|
-
last_response.body.include?("
|
34
|
+
last_response.body.include?("<span id='sliderct'>" + @db[:users].count.to_s).should be_true
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
@@ -42,9 +42,25 @@ describe "HydroApp" do
|
|
42
42
|
@db[:users].count.should == 10
|
43
43
|
end
|
44
44
|
|
45
|
-
it "should return the
|
45
|
+
it "should return the final count on success" do
|
46
46
|
post '/dupe/users', {:count => 10}.to_json
|
47
|
-
last_response.body.match(
|
47
|
+
last_response.body.match("10").should be_true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "/foreigndupe/*" do
|
52
|
+
it "should open foreigndupe/index.erb" do
|
53
|
+
get '/foreign_dupe/portfolios'
|
54
|
+
last_response.should be_ok
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "/foreign_dupe/*/*" do
|
59
|
+
it "should copy the first row n times" do
|
60
|
+
@db[:users].multi_insert([{:name => "ABC", :email => "123@example.com"}] * 10)
|
61
|
+
post '/foreign_dupe/portfolios', {:count => 10, :foreign_table => 'users'}.to_json
|
62
|
+
last_response.should be_ok
|
63
|
+
@db[:portfolios].count.should == 10
|
48
64
|
end
|
49
65
|
end
|
50
66
|
end
|
data/spec/hydroponics_spec.rb
CHANGED
@@ -61,27 +61,67 @@ describe "Hydroponics::Actions" do
|
|
61
61
|
|
62
62
|
describe "#dupe" do
|
63
63
|
it "should duplicate the first user until the desired count is reached" do
|
64
|
-
dupe(:users, 10)
|
64
|
+
dupe(:users, {'count' => 10})
|
65
65
|
@db[:users].count.should == 10
|
66
66
|
end
|
67
67
|
|
68
68
|
it "should delete users from the end until the desired count is reached" do
|
69
69
|
@db[:users].multi_insert([{:name => "ABC", :email => "123@example.com"}] * 10)
|
70
70
|
@db[:users].count.should == 11
|
71
|
-
dupe(:users, 2)
|
71
|
+
dupe(:users, {'count' => 2})
|
72
72
|
@db[:users].count.should == 2
|
73
73
|
end
|
74
74
|
|
75
75
|
it "should handle non-consecutive id numbers" do
|
76
76
|
@db[:users].multi_insert([{:id => 6789, :name => "ABC", :email => "123@example.com"}, {:id => 6790, :name => "ABC", :email => "123@example.com"}])
|
77
|
-
dupe(:users, 2)
|
77
|
+
dupe(:users, {'count' => 2})
|
78
78
|
@db[:users].count.should == 2
|
79
79
|
end
|
80
80
|
|
81
81
|
it "should require the table name and count" do
|
82
82
|
lambda { dupe }.should raise_error
|
83
83
|
lambda { dupe(:users) }.should raise_error
|
84
|
-
lambda { dupe(16) }.should raise_error
|
84
|
+
lambda { dupe({'count' => 16}) }.should raise_error
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "#foreigndupe" do
|
89
|
+
it "should copy the first row n times" do
|
90
|
+
@db[:users].multi_insert([{:name => "ABC", :email => "123@example.com"}] * 10)
|
91
|
+
foreign_dupe('portfolios', {:count => 10, :foreign_table => 'users'})
|
92
|
+
@db[:portfolios].count.should == 10
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should add the foreign key" do
|
96
|
+
@db[:users].multi_insert([{:name => "ABC", :email => "123@example.com"}] * 10)
|
97
|
+
foreign_dupe('portfolios', {:count => 10, :foreign_table => 'users'})
|
98
|
+
@db[:portfolios].map(:user_id)[9].should > 0
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should return the table's count" do
|
102
|
+
@db[:users].multi_insert([{:name => "ABC", :email => "123@example.com"}] * 10)
|
103
|
+
foreign_dupe('portfolios', {:count => 10, :foreign_table => 'users'}).should == "10"
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should allow a custom foreign key name" do
|
107
|
+
@db.drop_table :portfolios if @db.table_exists?(:portfolios)
|
108
|
+
@db.create_table :portfolios do
|
109
|
+
primary_key :id
|
110
|
+
Integer :custom_id
|
111
|
+
String :experience
|
112
|
+
String :education
|
113
|
+
end
|
114
|
+
@db[:portfolios].insert(:experience => "None", :education => "None", :custom_id => @db[:users].first[:id])
|
115
|
+
|
116
|
+
foreign_dupe('portfolios', {:count => 10, :foreign_table => 'users', :foreign_key => "custom_id"}).should == "10"
|
117
|
+
@db[:portfolios].map(:custom_id)[9].should > 0
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should start from the beginning of the foreign table if it runs out of foreign keys" do
|
121
|
+
@db[:users].multi_insert([{:name => "ABC", :email => "123@example.com"}] * 9) # so there are 10 total.
|
122
|
+
foreign_dupe('portfolios', {:count => 11, :foreign_table => 'users'})
|
123
|
+
@db[:portfolios].map(:user_id)[1].should == @db[:users].map(:id)[1]
|
124
|
+
@db[:portfolios].map(:user_id)[10].should == @db[:users].map(:id)[0]
|
85
125
|
end
|
86
126
|
end
|
87
127
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -26,10 +26,18 @@ end
|
|
26
26
|
def populate_test_db
|
27
27
|
db = Hydroponics.db
|
28
28
|
db.drop_table :users if db.table_exists?(:users)
|
29
|
+
db.drop_table :portfolios if db.table_exists?(:portfolios)
|
29
30
|
db.create_table :users do
|
30
31
|
primary_key :id
|
31
32
|
String :name
|
32
33
|
String :email
|
33
34
|
end
|
35
|
+
db.create_table :portfolios do
|
36
|
+
primary_key :id
|
37
|
+
Integer :user_id
|
38
|
+
String :experience
|
39
|
+
String :education
|
40
|
+
end
|
34
41
|
db[:users].insert(:name => "Acorn Hrefski", :email => "acorn@example.com")
|
42
|
+
db[:portfolios].insert(:experience => "None", :education => "None", :user_id => db[:users].first[:id])
|
35
43
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hydroponics
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 3
|
10
|
+
version: 0.3.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tyler Boyd
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-11-03 00:00:00 -04:00
|
19
19
|
default_executable: hydro
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -138,7 +138,9 @@ files:
|
|
138
138
|
- Rakefile
|
139
139
|
- VERSION
|
140
140
|
- app/actions/dupe.rb
|
141
|
+
- app/actions/foreigndupe.rb
|
141
142
|
- app/views/dupe/index.erb
|
143
|
+
- app/views/foreign_dupe/index.erb
|
142
144
|
- bin/hydro
|
143
145
|
- config/hydro_app.rb
|
144
146
|
- hydroponics.gemspec
|