datashift 0.10.1 → 0.10.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +6 -1
- data/VERSION +1 -1
- data/datashift.gemspec +13 -6
- data/lib/datashift.rb +2 -20
- data/lib/datashift/exceptions.rb +2 -0
- data/lib/datashift/method_detail.rb +15 -29
- data/lib/datashift/method_dictionary.rb +36 -21
- data/lib/datashift/method_mapper.rb +56 -16
- data/lib/datashift/populator.rb +23 -0
- data/lib/datashift/querying.rb +86 -0
- data/lib/generators/csv_generator.rb +1 -4
- data/lib/generators/excel_generator.rb +28 -11
- data/lib/generators/generator_base.rb +12 -0
- data/lib/loaders/csv_loader.rb +9 -3
- data/lib/loaders/excel_loader.rb +14 -6
- data/lib/loaders/loader_base.rb +38 -125
- data/lib/loaders/paperclip/attachment_loader.rb +130 -62
- data/lib/loaders/paperclip/datashift_paperclip.rb +46 -12
- data/lib/loaders/paperclip/image_loading.rb +25 -41
- data/lib/thor/generate.thor +16 -6
- data/lib/thor/paperclip.thor +25 -5
- data/spec/Gemfile +3 -2
- data/spec/MissingAttachmentRecords/DEMO_001_ror_bag.jpeg +0 -0
- data/spec/{fixtures/images/DEMO_002_Powerstation.jpg → MissingAttachmentRecords/DEMO_002_Powerstation.jpeg} +0 -0
- data/spec/MissingAttachmentRecords/DEMO_002_Powerstation.jpg +0 -0
- data/spec/MissingAttachmentRecords/DEMO_003_ror_mug.jpeg +0 -0
- data/spec/MissingAttachmentRecords/DEMO_004_ror_ringer.jpeg +0 -0
- data/spec/excel_generator_spec.rb +28 -0
- data/spec/excel_loader_spec.rb +12 -17
- data/spec/fixtures/config/database.yml +1 -1
- data/spec/fixtures/db/datashift_test_models_db.sqlite +0 -0
- data/spec/fixtures/db/migrate/20121009161700_add_digitals.rb +24 -0
- data/spec/fixtures/images/DEMO_002_Powerstation.jpeg +0 -0
- data/spec/fixtures/models/digital.rb +14 -0
- data/spec/fixtures/models/owner.rb +5 -3
- data/spec/fixtures/test_model_defs.rb +4 -62
- data/spec/loader_spec.rb +42 -50
- data/spec/method_dictionary_spec.rb +3 -10
- data/spec/method_mapper_spec.rb +79 -20
- data/spec/paperclip_loader_spec.rb +95 -0
- data/spec/spec_helper.rb +44 -8
- metadata +236 -224
- data/lib/helpers/rake_utils.rb +0 -42
- data/spec/fixtures/models/test_model_defs.rb +0 -67
data/lib/thor/paperclip.thor
CHANGED
@@ -22,8 +22,12 @@ module Datashift
|
|
22
22
|
|
23
23
|
include DataShift::Logging
|
24
24
|
|
25
|
-
desc "attach", "Attach files from a directory\
|
26
|
-
|
25
|
+
desc "attach", "Attach files from a directory\nThe attachment file names must contain the lookup info within them.
|
26
|
+
The instance of :attach_to_klass can be searched for and the new attachment assigned.
|
27
|
+
Examples
|
28
|
+
Owner has_many pdfs and mp3 files as Digitals .... :attach_to_klass = Owner
|
29
|
+
User has a single image used as an avatar ... :attach_to_klass = User"
|
30
|
+
|
27
31
|
# :dummy => dummy run without actual saving to DB
|
28
32
|
method_option :input, :aliases => '-i', :required => true, :desc => "The input path containing images "
|
29
33
|
|
@@ -31,11 +35,27 @@ module Datashift
|
|
31
35
|
method_option :recursive, :aliases => '-r', :type => :boolean, :desc => "Scan sub directories of input for images"
|
32
36
|
|
33
37
|
method_option :attachment_klass, :required => true, :aliases => '-a', :desc => "Ruby Class name of the Attachment e.g Image, Icon"
|
34
|
-
method_option :attach_to_klass, :required => true, :aliases => '-k', :desc => "
|
35
|
-
|
38
|
+
method_option :attach_to_klass, :required => true, :aliases => '-k', :desc => "A class that has a relationship with the attachment (has_many, has_one, belongs_to)"
|
39
|
+
|
36
40
|
|
37
|
-
method_option :
|
41
|
+
method_option :attach_to_field, :required => true, :aliases => '-f', :desc => "Attachment belongs to field e.g Product.image, Blog.digital"
|
38
42
|
|
43
|
+
method_option :attach_to_find_by_field, :required => true, :aliases => '-l', :desc => "The field to use to find the :attach_to_klass record"
|
44
|
+
|
45
|
+
|
46
|
+
# => :attach_to_find_by_field
|
47
|
+
# For the :attach_to_klass, this is the field used to search for the parent
|
48
|
+
# object to assign the new attachment to.
|
49
|
+
# Examples
|
50
|
+
# Owner has a unique 'name' field ... :attach_to_find_by_field = :name
|
51
|
+
# User has a unique 'login' field ... :attach_to_klass = :login
|
52
|
+
#
|
53
|
+
# => :attach_to_field
|
54
|
+
# Attribute/association to assign attachment to on :attach_to_klass.
|
55
|
+
# Examples
|
56
|
+
# :attach_to_field => digitals : Owner.digitals = attachment
|
57
|
+
# :attach_to_field => avatar : User.avatar = attachment
|
58
|
+
|
39
59
|
method_option :split_file_name_on, :type => :string, :desc => "delimiter to progressivley split filename for lookup", :default => ' '
|
40
60
|
method_option :case_sensitive, :type => :boolean, :desc => "Use case sensitive where clause to find :attach_to_klass"
|
41
61
|
method_option :use_like, :type => :boolean, :desc => "Use :lookup_field LIKE 'string%' instead of :lookup_field = 'string' in where clauses to find :attach_to_klass"
|
data/spec/Gemfile
CHANGED
Binary file
|
File without changes
|
Binary file
|
Binary file
|
Binary file
|
@@ -164,6 +164,34 @@ describe 'Excel Generator' do
|
|
164
164
|
end
|
165
165
|
|
166
166
|
|
167
|
+
it "should enable us to remove standard rails feilds from template .xls file ", :fail => true do
|
168
|
+
|
169
|
+
expect= result_file('project_plus_some_assoc_template_spec.xls')
|
170
|
+
|
171
|
+
gen = ExcelGenerator.new(expect)
|
172
|
+
|
173
|
+
options = {:remove_rails => true}
|
174
|
+
|
175
|
+
gen.generate_with_associations(Project, options)
|
176
|
+
|
177
|
+
File.exists?(expect).should be_true, "Failed to find expected result file #{expect}"
|
178
|
+
|
179
|
+
excel = Excel.new
|
180
|
+
excel.open(expect)
|
181
|
+
|
182
|
+
excel.worksheets.should have(1).items
|
183
|
+
|
184
|
+
excel.worksheet(0).name.should == 'Project'
|
185
|
+
|
186
|
+
headers = excel.worksheets[0].row(0)
|
187
|
+
|
188
|
+
["id", "updated_at", "created_at"].each do |check|
|
189
|
+
headers.should_not include check
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
end
|
194
|
+
|
167
195
|
it "should enable us to autosize columns in the .xls file" do
|
168
196
|
|
169
197
|
expect= result_file('project_autosized_template_spec.xls')
|
data/spec/excel_loader_spec.rb
CHANGED
@@ -14,32 +14,27 @@ include DataShift
|
|
14
14
|
|
15
15
|
describe 'Excel Loader' do
|
16
16
|
|
17
|
-
|
17
|
+
include_context "ActiveRecordTestModelsConnected"
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
db_connect( 'test_file' ) # , test_memory, test_mysql
|
19
|
+
before(:each) do
|
20
|
+
DataShift::MethodDictionary.clear
|
23
21
|
|
24
|
-
|
25
|
-
migrate_up
|
26
|
-
|
27
|
-
db_clear() # todo read up about proper transactional fixtures
|
28
|
-
|
29
|
-
@assoc_klazz = Category
|
22
|
+
@method_mapper = DataShift::MethodMapper.new
|
30
23
|
end
|
31
24
|
|
25
|
+
|
26
|
+
include_context "ClearAndPopulateProject"
|
27
|
+
|
32
28
|
before(:each) do
|
33
29
|
|
34
|
-
Project.delete_all
|
35
|
-
|
36
30
|
%w{category_001 category_002 category_003 category_004 category_005}.each do |cat|
|
37
|
-
|
31
|
+
Category.find_or_create_by_reference(cat)
|
38
32
|
end
|
39
33
|
|
40
|
-
MethodDictionary.
|
41
|
-
|
42
|
-
MethodDictionary.
|
34
|
+
DataShift::MethodDictionary.find_operators( Category )
|
35
|
+
|
36
|
+
DataShift::MethodDictionary.build_method_details( Category )
|
37
|
+
|
43
38
|
end
|
44
39
|
|
45
40
|
it "should be able to create a new excel loader and load object" do
|
Binary file
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Author :: Tom Statter
|
2
|
+
# Date :: Oct 2012
|
3
|
+
# License:: MIT
|
4
|
+
#
|
5
|
+
# Details:: Migration for paperclip specs
|
6
|
+
|
7
|
+
class AddDigitals < ActiveRecord::Migration
|
8
|
+
|
9
|
+
def self.up
|
10
|
+
|
11
|
+
create_table :digitals do |t|
|
12
|
+
t.integer :owner_id
|
13
|
+
t.string :attachment_file_name
|
14
|
+
t.string :attachment_content_type
|
15
|
+
t.integer :attachment_file_size
|
16
|
+
t.timestamps
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.down
|
22
|
+
drop_table :digitals
|
23
|
+
end
|
24
|
+
end
|
Binary file
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# To change this template, choose Tools | Templates
|
2
|
+
# and open the template in the editor.
|
3
|
+
|
4
|
+
require 'paperclip'
|
5
|
+
|
6
|
+
class Digital < ActiveRecord::Base
|
7
|
+
|
8
|
+
include Paperclip::Glue
|
9
|
+
|
10
|
+
attr_accessible :attachment
|
11
|
+
|
12
|
+
has_attached_file :attachment, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :path => ":rails_root/private/digitals/:id/:basename.:extension"
|
13
|
+
|
14
|
+
end
|
@@ -1,67 +1,9 @@
|
|
1
|
-
# A set of models and associations we can use in our specs to test
|
2
|
-
# basic database columns and also relationships
|
3
1
|
|
4
|
-
# See Companion migration spec/db/migrate
|
5
2
|
|
6
|
-
|
3
|
+
# TODO investigate potential gem that might this require_all
|
7
4
|
|
8
|
-
|
9
|
-
|
10
|
-
has_many :milestones
|
11
|
-
|
12
|
-
has_many :loader_releases
|
13
|
-
has_many :versions, :through => :loader_releases
|
14
|
-
|
15
|
-
|
16
|
-
#has_many :release_versions, :through => :loader_releases, :source => :versions
|
17
|
-
|
18
|
-
has_and_belongs_to_many :categories
|
19
|
-
|
20
|
-
attr_accessible :value_as_string, :value_as_boolean, :value_as_double
|
21
|
-
|
22
|
-
def multiply
|
23
|
-
10 * value_as_double
|
24
|
-
end
|
5
|
+
base = File.join(File.dirname(__FILE__), 'models')
|
25
6
|
|
26
|
-
|
27
|
-
|
28
|
-
class Owner < ActiveRecord::Base
|
29
|
-
belongs_to :project
|
30
|
-
end
|
31
|
-
|
32
|
-
class Milestone < ActiveRecord::Base
|
33
|
-
belongs_to :project
|
34
|
-
#validate the name, cost
|
35
|
-
|
36
|
-
delegate :title, :title=, :to => :project
|
37
|
-
end
|
38
|
-
|
39
|
-
# had_and_belongs to join table
|
40
|
-
class Category < ActiveRecord::Base
|
41
|
-
has_and_belongs_to_many :projects
|
42
|
-
end
|
43
|
-
|
44
|
-
|
45
|
-
class Version < ActiveRecord::Base
|
46
|
-
has_many :releases
|
47
|
-
|
48
|
-
has_one :long_and_complex_table_linked_to_version
|
49
|
-
end
|
50
|
-
|
51
|
-
# Join Table with additional columns
|
52
|
-
class LoaderRelease < ActiveRecord::Base
|
53
|
-
|
54
|
-
belongs_to :project
|
55
|
-
belongs_to :version
|
56
|
-
|
57
|
-
#validate the name
|
58
|
-
end
|
59
|
-
|
60
|
-
class Empty < ActiveRecord::Base
|
61
|
-
end
|
62
|
-
|
63
|
-
# Join Table with additional columns
|
64
|
-
class LongAndComplexTableLinkedToVersion < ActiveRecord::Base
|
65
|
-
|
66
|
-
belongs_to :version
|
7
|
+
Dir[ File.join(base, '*.rb') ].each do |file|
|
8
|
+
require File.join(base, File.basename(file, File.extname(file) ))
|
67
9
|
end
|
data/spec/loader_spec.rb
CHANGED
@@ -11,71 +11,66 @@ require 'erb'
|
|
11
11
|
|
12
12
|
describe 'Basic Loader' do
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
# load our test model definitions - Project etc
|
17
|
-
require ifixture_file('test_model_defs')
|
14
|
+
include_context "ActiveRecordTestModelsConnected"
|
18
15
|
|
19
|
-
|
20
|
-
|
21
|
-
migrate_up
|
22
|
-
@klazz = Project
|
23
|
-
end
|
16
|
+
include_context "ClearAndPopulateProject"
|
24
17
|
|
25
|
-
before(:each) do
|
26
|
-
|
27
|
-
MethodDictionary.find_operators( @klazz )
|
18
|
+
before(:each) do
|
19
|
+
@loader = DataShift::LoaderBase.new(Project)
|
28
20
|
end
|
29
21
|
|
30
22
|
it "should be able to create a new loader and load object" do
|
31
|
-
loader
|
32
|
-
|
33
|
-
loader.load_object.
|
34
|
-
loader.load_object.should be_is_a(@klazz)
|
35
|
-
loader.load_object.new_record?.should be_true
|
23
|
+
@loader.load_object.should_not be_nil
|
24
|
+
@loader.load_object.should be_is_a(Project)
|
25
|
+
@loader.load_object.new_record?.should be_true
|
36
26
|
end
|
37
27
|
|
28
|
+
|
38
29
|
it "should process a string field against an assigment method detail" do
|
39
30
|
|
40
|
-
|
31
|
+
column = 'Value As String'
|
32
|
+
row = 'Another Lazy fox '
|
33
|
+
|
34
|
+
@loader.find_and_process(column, row)
|
35
|
+
|
36
|
+
@loader.load_object.errors.should have_exactly(0).items
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should process a string field against an assigment method detail" do
|
41
40
|
|
42
41
|
column = 'Value As String'
|
43
42
|
row = 'Another Lazy fox '
|
44
43
|
|
45
|
-
loader.find_and_process(column, row)
|
44
|
+
@loader.find_and_process(column, row)
|
46
45
|
|
47
|
-
loader.load_object.value_as_string.should == row
|
46
|
+
@loader.load_object.value_as_string.should == row
|
48
47
|
end
|
49
48
|
|
50
49
|
it "should process a text field against an assigment method detail" do
|
51
50
|
|
52
|
-
loader = LoaderBase.new(Project)
|
53
|
-
|
54
51
|
column = :value_as_text
|
55
52
|
row = "Another Lazy fox\nJumped over something and bumped,\nHis head"
|
56
53
|
|
57
|
-
loader.find_and_process(column, row)
|
54
|
+
@loader.find_and_process(column, row)
|
58
55
|
|
59
|
-
loader.load_object.value_as_text.should == row
|
56
|
+
@loader.load_object.value_as_text.should == row
|
60
57
|
|
61
58
|
end
|
62
59
|
|
63
60
|
it "should process a boolean field against an assigment method detail" do
|
64
61
|
|
65
|
-
loader = LoaderBase.new(Project)
|
66
|
-
|
67
62
|
column = :value_as_boolean
|
68
63
|
row = true
|
69
64
|
|
70
|
-
loader.find_and_process(column, row)
|
65
|
+
@loader.find_and_process(column, row)
|
71
66
|
|
72
|
-
loader.load_object.value_as_boolean.should == row
|
67
|
+
@loader.load_object.value_as_boolean.should == row
|
73
68
|
|
74
69
|
row = 'false'
|
75
70
|
|
76
|
-
loader.find_and_process(column, row)
|
71
|
+
@loader.find_and_process(column, row)
|
77
72
|
|
78
|
-
loader.load_object.value_as_boolean.should == false
|
73
|
+
@loader.load_object.value_as_boolean.should == false
|
79
74
|
|
80
75
|
|
81
76
|
end
|
@@ -84,38 +79,35 @@ describe 'Basic Loader' do
|
|
84
79
|
end
|
85
80
|
|
86
81
|
it "should process various date formats against a date assigment operator" do
|
87
|
-
|
88
|
-
loader = LoaderBase.new(Project)
|
89
|
-
|
90
82
|
column = :value_as_datetime
|
91
83
|
|
92
|
-
loader.find_and_process(column, Time.now)
|
93
|
-
loader.load_object.value_as_datetime.should_not be_nil
|
84
|
+
@loader.find_and_process(column, Time.now)
|
85
|
+
@loader.load_object.value_as_datetime.should_not be_nil
|
94
86
|
|
95
|
-
loader.find_and_process(column, "2011-07-23")
|
96
|
-
loader.load_object.value_as_datetime.should_not be_nil
|
87
|
+
@loader.find_and_process(column, "2011-07-23")
|
88
|
+
@loader.load_object.value_as_datetime.should_not be_nil
|
97
89
|
|
98
|
-
loader.find_and_process(column, "Sat Jul 23 09:01:56 +0100 2011")
|
99
|
-
loader.load_object.value_as_datetime.should_not be_nil
|
90
|
+
@loader.find_and_process(column, "Sat Jul 23 09:01:56 +0100 2011")
|
91
|
+
@loader.load_object.value_as_datetime.should_not be_nil
|
100
92
|
|
101
|
-
loader.find_and_process(column, Time.now.to_s(:db))
|
102
|
-
loader.load_object.value_as_datetime.should_not be_nil
|
93
|
+
@loader.find_and_process(column, Time.now.to_s(:db))
|
94
|
+
@loader.load_object.value_as_datetime.should_not be_nil
|
103
95
|
|
104
|
-
loader.find_and_process(column, "Jul 23 2011 23:02:59")
|
105
|
-
loader.load_object.value_as_datetime.should_not be_nil
|
96
|
+
@loader.find_and_process(column, "Jul 23 2011 23:02:59")
|
97
|
+
@loader.load_object.value_as_datetime.should_not be_nil
|
106
98
|
|
107
|
-
if(Guards.jruby?)
|
108
|
-
loader.find_and_process(column, "07/23/2011") # dd/mm/YYYY
|
109
|
-
loader.load_object.value_as_datetime.should_not be_nil
|
99
|
+
if(DataShift::Guards.jruby?)
|
100
|
+
@loader.find_and_process(column, "07/23/2011") # dd/mm/YYYY
|
101
|
+
@loader.load_object.value_as_datetime.should_not be_nil
|
110
102
|
end
|
111
103
|
|
112
104
|
# bad casts - TODO - is this really an error needs raising ?
|
113
|
-
loader.find_and_process(column, "2011 07 23")
|
114
|
-
loader.load_object.value_as_datetime.should be_nil
|
105
|
+
@loader.find_and_process(column, "2011 07 23")
|
106
|
+
@loader.load_object.value_as_datetime.should be_nil
|
115
107
|
|
116
108
|
|
117
|
-
loader.find_and_process(column, "2011-23-07")
|
118
|
-
loader.load_object.value_as_datetime.should be_nil
|
109
|
+
@loader.find_and_process(column, "2011-23-07")
|
110
|
+
@loader.load_object.value_as_datetime.should be_nil
|
119
111
|
|
120
112
|
end
|
121
113
|
|
@@ -7,19 +7,12 @@
|
|
7
7
|
# MethodMapper provides the bridge between 'strings' e.g column headings
|
8
8
|
# and a classes different types of assignment operators
|
9
9
|
#
|
10
|
-
require File.dirname(__FILE__)
|
10
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
11
11
|
|
12
|
-
describe 'Method
|
12
|
+
describe 'Method Dictionary' do
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
# load our test model definitions - Project etc
|
17
|
-
require ifixture_file('test_model_defs')
|
14
|
+
include_context "ActiveRecordTestModelsConnected"
|
18
15
|
|
19
|
-
db_connect( 'test_file' ) # , test_memory, test_mysql
|
20
|
-
|
21
|
-
migrate_up
|
22
|
-
end
|
23
16
|
|
24
17
|
before(:each) do
|
25
18
|
MethodDictionary.clear
|