datashift 0.10.1 → 0.10.2
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/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
|