squealer 2.1.1 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +5 -5
- data/LICENSE +20 -0
- data/README.md +36 -12
- data/Rakefile +10 -1
- data/VERSION +1 -1
- data/bin/skewer +5 -9
- data/lib/example_squeal.rb +10 -3
- data/lib/squealer/database.rb +22 -4
- data/lib/squealer/hash.rb +1 -0
- data/lib/squealer/object.rb +2 -2
- data/lib/squealer/target.rb +32 -33
- data/lib/squealer.rb +0 -1
- data/spec/integration/export_a_record_spec.rb +148 -0
- data/spec/spec_helper.rb +34 -54
- data/spec/spec_helper_dbms_mysql.rb +56 -0
- data/spec/spec_helper_dbms_postgres.rb +55 -0
- data/spec/squealer/database_spec.rb +41 -11
- data/spec/squealer/object_spec.rb +4 -4
- data/spec/squealer/target_spec.rb +77 -108
- data/squealer.gemspec +31 -12
- metadata +109 -25
- data/lib/.example_squeal.rb.swp +0 -0
- data/lib/squealer/time.rb +0 -5
- data/spec/squealer/time_spec.rb +0 -10
data/spec/spec_helper.rb
CHANGED
@@ -6,37 +6,31 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
6
6
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
7
|
|
8
8
|
require 'squealer'
|
9
|
+
require "spec_helper_dbms_#{ENV['EXPORT_DBMS']||'mysql'}"
|
9
10
|
|
10
11
|
Spec::Runner.configure do |config|
|
11
12
|
config.before(:suite) do
|
12
13
|
$db_name = "test_export_#{object_id}"
|
13
|
-
|
14
|
+
create_export_db($db_name)
|
15
|
+
create_import_db($db_name)
|
14
16
|
end
|
15
17
|
|
16
18
|
config.after(:suite) do
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
def create_test_db(name)
|
21
|
-
@my = Mysql.connect('localhost', 'root')
|
22
|
-
@my.query("DROP DATABASE IF EXISTS #{name}")
|
23
|
-
@my.query("CREATE DATABASE #{name}")
|
24
|
-
@my.query("USE #{name}")
|
25
|
-
@my.query("SET sql_mode='ANSI_QUOTES'")
|
26
|
-
|
27
|
-
create_export_tables
|
19
|
+
Squealer::Database.instance.send(:dispose_all_connections)
|
20
|
+
drop_export_test_db($db_name)
|
28
21
|
|
29
|
-
Squealer::Database.instance.import_from('localhost', 27017, $db_name)
|
30
|
-
@mongo = Squealer::Database.instance.import.send(:instance_variable_get, '@dbc')
|
31
22
|
drop_mongo
|
32
|
-
seed_import
|
33
23
|
end
|
34
24
|
|
35
|
-
|
36
|
-
@
|
37
|
-
|
25
|
+
config.after(:each) do
|
26
|
+
@export_dbc.dispose if @export_dbc
|
27
|
+
end
|
38
28
|
|
29
|
+
def create_import_db(name)
|
30
|
+
Squealer::Database.instance.import_from('localhost', 27017, name)
|
31
|
+
@mongo = Squealer::Database.instance.import.instance_variable_get('@dbc')
|
39
32
|
drop_mongo
|
33
|
+
seed_import
|
40
34
|
end
|
41
35
|
|
42
36
|
def drop_mongo
|
@@ -51,24 +45,24 @@ Spec::Runner.configure do |config|
|
|
51
45
|
{ :name => 'Josh Graham', :dob => as_time(Date.parse('01-Jan-1971')), :gender => 'M',
|
52
46
|
:organization_id => hashrocket,
|
53
47
|
:activities => [
|
54
|
-
{ :name => 'Develop squealer', :due_date => as_time(Date.today + 1) },
|
55
|
-
{ :name => 'Organize speakerconf.com', :due_date => as_time(Date.today + 30) },
|
56
|
-
{ :name => 'Hashrocket party', :due_date => as_time(Date.today + 7) }
|
48
|
+
{ :_id => id, :name => 'Develop squealer', :due_date => as_time(Date.today + 1) },
|
49
|
+
{ :_id => id, :name => 'Organize speakerconf.com', :due_date => as_time(Date.today + 30) },
|
50
|
+
{ :_id => id, :name => 'Hashrocket party', :due_date => as_time(Date.today + 7) }
|
57
51
|
]
|
58
52
|
},
|
59
53
|
{ :name => 'Bernerd Schaefer', :dob => as_time(Date.parse('31-Dec-1985')), :gender => 'M',
|
60
54
|
:organization_id => hashrocket,
|
61
55
|
:activities => [
|
62
|
-
{ :name => 'Retype all of the code Josh wrote in squealer', :due_date => as_time(Date.today + 2) },
|
63
|
-
{ :name => 'Listen to rare Thelonius Monk EP', :due_date => as_time(Date.today) },
|
64
|
-
{ :name => 'Practice karaoke', :due_date => as_time(Date.today + 7) }
|
56
|
+
{ :_id => id, :name => 'Retype all of the code Josh wrote in squealer', :due_date => as_time(Date.today + 2) },
|
57
|
+
{ :_id => id, :name => 'Listen to rare Thelonius Monk EP', :due_date => as_time(Date.today) },
|
58
|
+
{ :_id => id, :name => 'Practice karaoke', :due_date => as_time(Date.today + 7) }
|
65
59
|
]
|
66
60
|
},
|
67
61
|
{ :name => 'Your momma', :dob => as_time(Date.parse('15-Jun-1955')), :gender => 'F',
|
68
62
|
:organization_id => zorganization,
|
69
63
|
:activities => [
|
70
|
-
{ :name => 'Cook me some pie', :due_date => as_time(Date.today) },
|
71
|
-
{ :name => 'Make me a sammich', :due_date => as_time(Date.today) }
|
64
|
+
{ :_id => id, :name => 'Cook me some pie', :due_date => as_time(Date.today) },
|
65
|
+
{ :_id => id, :name => 'Make me a sammich', :due_date => as_time(Date.today) }
|
72
66
|
]
|
73
67
|
}
|
74
68
|
]
|
@@ -76,37 +70,23 @@ Spec::Runner.configure do |config|
|
|
76
70
|
users.each { |user| @mongo.collection('users').save user }
|
77
71
|
end
|
78
72
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
"gender" CHAR(1) NULL ,
|
85
|
-
"dob" DATE NULL ,
|
86
|
-
PRIMARY KEY ("id") )
|
87
|
-
COMMAND
|
88
|
-
@my.query(command)
|
89
|
-
|
90
|
-
command = <<-COMMAND.gsub(/\n\s*/, " ")
|
91
|
-
CREATE TABLE "activity" (
|
92
|
-
"id" INT NOT NULL AUTO_INCREMENT ,
|
93
|
-
"user_id" INT NULL ,
|
94
|
-
"name" VARCHAR(255) NULL ,
|
95
|
-
"due_date" DATE NULL ,
|
96
|
-
PRIMARY KEY ("id") )
|
97
|
-
COMMAND
|
98
|
-
@my.query(command)
|
99
|
-
|
100
|
-
command = <<-COMMAND.gsub(/\n\s*/, " ")
|
101
|
-
CREATE TABLE "organizations" (
|
102
|
-
"id" INT NOT NULL AUTO_INCREMENT ,
|
103
|
-
"disabed_date" DATE NULL ,
|
104
|
-
PRIMARY KEY ("id") )
|
105
|
-
COMMAND
|
106
|
-
@my.query(command)
|
73
|
+
|
74
|
+
def truncate_export_tables
|
75
|
+
non_query('TRUNCATE TABLE "user"')
|
76
|
+
non_query('TRUNCATE TABLE "activity"')
|
77
|
+
non_query('TRUNCATE TABLE "organization"')
|
107
78
|
end
|
108
79
|
|
109
80
|
def as_time(date)
|
110
81
|
Time.parse(date.to_s)
|
111
82
|
end
|
83
|
+
|
84
|
+
def non_query(text)
|
85
|
+
export_dbc.create_command(text).execute_non_query
|
86
|
+
end
|
87
|
+
|
88
|
+
def id
|
89
|
+
require 'digest/sha1'
|
90
|
+
(Digest::SHA1.hexdigest rand.to_s)[0,24]
|
91
|
+
end
|
112
92
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
def create_export_db(name)
|
2
|
+
$db_adapter = 'mysql'
|
3
|
+
dbc = DataObjects::Connection.new("mysql://root@localhost/mysql")
|
4
|
+
dbc.create_command("DROP DATABASE IF EXISTS #{name}").execute_non_query
|
5
|
+
dbc.create_command("CREATE DATABASE #{name}").execute_non_query
|
6
|
+
dbc.create_command("SET sql_mode='ANSI_QUOTES'").execute_non_query
|
7
|
+
create_export_tables
|
8
|
+
dbc.dispose
|
9
|
+
end
|
10
|
+
|
11
|
+
def drop_export_test_db(name)
|
12
|
+
@export_dbc.dispose if @export_dbc
|
13
|
+
dbc = DataObjects::Connection.new("mysql://root@localhost/mysql")
|
14
|
+
dbc.create_command("DROP DATABASE IF EXISTS #{name}").execute_non_query
|
15
|
+
dbc.dispose
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_export_tables
|
19
|
+
command = <<-COMMAND.gsub(/\n\s*/, " ")
|
20
|
+
CREATE TABLE "user" (
|
21
|
+
"id" CHAR(24) NOT NULL ,
|
22
|
+
"organization_id" CHAR(24) NOT NULL ,
|
23
|
+
"name" VARCHAR(255) NULL ,
|
24
|
+
"gender" CHAR(1) NULL ,
|
25
|
+
"dob" DATETIME NULL ,
|
26
|
+
"foreign" BOOLEAN NULL ,
|
27
|
+
"dull" BOOLEAN NULL ,
|
28
|
+
"symbolic" VARCHAR(255) NULL ,
|
29
|
+
"interests" TEXT NULL ,
|
30
|
+
PRIMARY KEY ("id") )
|
31
|
+
COMMAND
|
32
|
+
non_query(command)
|
33
|
+
|
34
|
+
command = <<-COMMAND.gsub(/\n\s*/, " ")
|
35
|
+
CREATE TABLE "activity" (
|
36
|
+
"id" CHAR(24) NOT NULL ,
|
37
|
+
"user_id" CHAR(24) NULL ,
|
38
|
+
"name" VARCHAR(255) NULL ,
|
39
|
+
"due_date" DATETIME NULL ,
|
40
|
+
PRIMARY KEY ("id") )
|
41
|
+
COMMAND
|
42
|
+
non_query(command)
|
43
|
+
|
44
|
+
command = <<-COMMAND.gsub(/\n\s*/, " ")
|
45
|
+
CREATE TABLE "organization" (
|
46
|
+
"id" CHAR(24) NOT NULL ,
|
47
|
+
"disabled_date" DATETIME NULL ,
|
48
|
+
PRIMARY KEY ("id") )
|
49
|
+
COMMAND
|
50
|
+
non_query(command)
|
51
|
+
end
|
52
|
+
|
53
|
+
def export_dbc
|
54
|
+
$db_user ||= 'root'
|
55
|
+
@export_dbc ||= DataObjects::Connection.new("mysql://root@localhost/#{$db_name}")
|
56
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
def create_export_db(name)
|
2
|
+
$db_adapter = 'postgres'
|
3
|
+
dbc = DataObjects::Connection.new("postgres://localhost/postgres")
|
4
|
+
dbc.create_command("DROP DATABASE IF EXISTS #{name}").execute_non_query
|
5
|
+
dbc.create_command("CREATE DATABASE #{name}").execute_non_query
|
6
|
+
create_export_tables
|
7
|
+
dbc.dispose
|
8
|
+
end
|
9
|
+
|
10
|
+
def drop_export_test_db(name)
|
11
|
+
@export_dbc.dispose if @export_dbc
|
12
|
+
dbc = DataObjects::Connection.new("postgres://localhost/postgres")
|
13
|
+
dbc.create_command("DROP DATABASE IF EXISTS #{name}").execute_non_query
|
14
|
+
dbc.dispose
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_export_tables
|
18
|
+
command = <<-COMMAND.gsub(/\n\s*/, " ")
|
19
|
+
CREATE TABLE "user" (
|
20
|
+
"id" CHAR(24) NOT NULL ,
|
21
|
+
"organization_id" CHAR(24) NOT NULL ,
|
22
|
+
"name" VARCHAR(255) NULL ,
|
23
|
+
"gender" CHAR(1) NULL ,
|
24
|
+
"dob" TIMESTAMP NULL ,
|
25
|
+
"foreign" BOOLEAN NULL ,
|
26
|
+
"dull" BOOLEAN NULL ,
|
27
|
+
"symbolic" VARCHAR(255) NULL ,
|
28
|
+
"interests" TEXT NULL ,
|
29
|
+
PRIMARY KEY ("id") )
|
30
|
+
COMMAND
|
31
|
+
non_query(command)
|
32
|
+
|
33
|
+
command = <<-COMMAND.gsub(/\n\s*/, " ")
|
34
|
+
CREATE TABLE "activity" (
|
35
|
+
"id" CHAR(24) NOT NULL ,
|
36
|
+
"user_id" CHAR(24) NULL ,
|
37
|
+
"name" VARCHAR(255) NULL ,
|
38
|
+
"due_date" TIMESTAMP NULL ,
|
39
|
+
PRIMARY KEY ("id") )
|
40
|
+
COMMAND
|
41
|
+
non_query(command)
|
42
|
+
|
43
|
+
command = <<-COMMAND.gsub(/\n\s*/, " ")
|
44
|
+
CREATE TABLE "organization" (
|
45
|
+
"id" CHAR(24) NOT NULL ,
|
46
|
+
"disabled_date" TIMESTAMP NULL ,
|
47
|
+
PRIMARY KEY ("id") )
|
48
|
+
COMMAND
|
49
|
+
non_query(command)
|
50
|
+
end
|
51
|
+
|
52
|
+
def export_dbc
|
53
|
+
$db_user ||= ''
|
54
|
+
@export_dbc ||= DataObjects::Connection.new("postgres://localhost/#{$db_name}")
|
55
|
+
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'mysql'
|
3
2
|
require 'mongo'
|
4
3
|
|
5
4
|
describe Squealer::Database do
|
@@ -105,14 +104,25 @@ describe Squealer::Database do
|
|
105
104
|
end
|
106
105
|
|
107
106
|
context "real squeal" do
|
108
|
-
before { pending "interactive_view" }
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
107
|
+
# before { pending "interactive_view" }
|
108
|
+
it "exports that stuff to SQL" do
|
109
|
+
databases.export_to($db_adapter, 'localhost', $db_user, '', $db_name)
|
110
|
+
databases.import.source("users").each do |user|
|
111
|
+
target(:user) do |target|
|
112
|
+
target.instance_variable_get('@row_id').should == user['_id'].to_s
|
113
|
+
assign(:organization_id)
|
114
|
+
assign(:name)
|
115
|
+
|
116
|
+
#TODO: Update README to highlight that all embedded docs should have an _id
|
117
|
+
# as all Ruby mappers for MongoDB make one. (according to Durran)
|
118
|
+
user.activities.each do |activity|
|
119
|
+
target(:activity) do |target|
|
120
|
+
assign(:user_id)
|
121
|
+
assign(:name)
|
122
|
+
assign(:due_date)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
116
126
|
end
|
117
127
|
end
|
118
128
|
end
|
@@ -125,8 +135,28 @@ describe Squealer::Database do
|
|
125
135
|
let(:databases) { Squealer::Database.instance }
|
126
136
|
|
127
137
|
it "takes an export database" do
|
128
|
-
databases.export_to('localhost',
|
129
|
-
databases.
|
138
|
+
databases.export_to($db_adapter, 'localhost', $db_user, '', $db_name)
|
139
|
+
databases.instance_variable_get('@export_do').should_not be_nil
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "upsertable?" do
|
144
|
+
subject { Squealer::Database.instance }
|
145
|
+
|
146
|
+
context "mysql connection" do
|
147
|
+
before do
|
148
|
+
subject.export_to('mysql', 'localhost', 'root', '', 'mysql')
|
149
|
+
end
|
150
|
+
|
151
|
+
it { should be_upsertable }
|
152
|
+
end
|
153
|
+
|
154
|
+
context "postgres connection" do
|
155
|
+
before do
|
156
|
+
subject.export_to('postgres', 'localhost', '', '', 'postgres')
|
157
|
+
end
|
158
|
+
|
159
|
+
it { should_not be_upsertable }
|
130
160
|
end
|
131
161
|
end
|
132
162
|
|
@@ -112,11 +112,11 @@ describe Object do
|
|
112
112
|
end
|
113
113
|
|
114
114
|
def mock_mysql
|
115
|
-
my = mock(
|
116
|
-
|
115
|
+
my = mock(DataObjects::Connection)
|
116
|
+
comm = mock(DataObjects::Command)
|
117
117
|
Squealer::Database.instance.should_receive(:export).at_least(:once).and_return(my)
|
118
|
-
my.should_receive(:
|
119
|
-
|
118
|
+
my.should_receive(:create_command).at_least(:once).and_return(comm)
|
119
|
+
comm.should_receive(:execute_non_query).at_least(:once)
|
120
120
|
end
|
121
121
|
|
122
122
|
end
|