datashift 0.10.1 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/Rakefile +6 -1
  2. data/VERSION +1 -1
  3. data/datashift.gemspec +13 -6
  4. data/lib/datashift.rb +2 -20
  5. data/lib/datashift/exceptions.rb +2 -0
  6. data/lib/datashift/method_detail.rb +15 -29
  7. data/lib/datashift/method_dictionary.rb +36 -21
  8. data/lib/datashift/method_mapper.rb +56 -16
  9. data/lib/datashift/populator.rb +23 -0
  10. data/lib/datashift/querying.rb +86 -0
  11. data/lib/generators/csv_generator.rb +1 -4
  12. data/lib/generators/excel_generator.rb +28 -11
  13. data/lib/generators/generator_base.rb +12 -0
  14. data/lib/loaders/csv_loader.rb +9 -3
  15. data/lib/loaders/excel_loader.rb +14 -6
  16. data/lib/loaders/loader_base.rb +38 -125
  17. data/lib/loaders/paperclip/attachment_loader.rb +130 -62
  18. data/lib/loaders/paperclip/datashift_paperclip.rb +46 -12
  19. data/lib/loaders/paperclip/image_loading.rb +25 -41
  20. data/lib/thor/generate.thor +16 -6
  21. data/lib/thor/paperclip.thor +25 -5
  22. data/spec/Gemfile +3 -2
  23. data/spec/MissingAttachmentRecords/DEMO_001_ror_bag.jpeg +0 -0
  24. data/spec/{fixtures/images/DEMO_002_Powerstation.jpg → MissingAttachmentRecords/DEMO_002_Powerstation.jpeg} +0 -0
  25. data/spec/MissingAttachmentRecords/DEMO_002_Powerstation.jpg +0 -0
  26. data/spec/MissingAttachmentRecords/DEMO_003_ror_mug.jpeg +0 -0
  27. data/spec/MissingAttachmentRecords/DEMO_004_ror_ringer.jpeg +0 -0
  28. data/spec/excel_generator_spec.rb +28 -0
  29. data/spec/excel_loader_spec.rb +12 -17
  30. data/spec/fixtures/config/database.yml +1 -1
  31. data/spec/fixtures/db/datashift_test_models_db.sqlite +0 -0
  32. data/spec/fixtures/db/migrate/20121009161700_add_digitals.rb +24 -0
  33. data/spec/fixtures/images/DEMO_002_Powerstation.jpeg +0 -0
  34. data/spec/fixtures/models/digital.rb +14 -0
  35. data/spec/fixtures/models/owner.rb +5 -3
  36. data/spec/fixtures/test_model_defs.rb +4 -62
  37. data/spec/loader_spec.rb +42 -50
  38. data/spec/method_dictionary_spec.rb +3 -10
  39. data/spec/method_mapper_spec.rb +79 -20
  40. data/spec/paperclip_loader_spec.rb +95 -0
  41. data/spec/spec_helper.rb +44 -8
  42. metadata +236 -224
  43. data/lib/helpers/rake_utils.rb +0 -42
  44. data/spec/fixtures/models/test_model_defs.rb +0 -67
@@ -22,8 +22,12 @@ module Datashift
22
22
 
23
23
  include DataShift::Logging
24
24
 
25
- desc "attach", "Attach files from a directory\nwhere file names contain somewhere the lookup info"
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 => "Ruby Class name attachment belongs to e.g Product, Blog"
35
- method_option :attach_to_klass_field, :required => true, :aliases => '-f', :desc => "Attachment belongs to field e.g Product.image, Blog.digital"
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 :attach_to_lookup_field, :required => true, :aliases => '-l', :desc => "The field to use to find the :attach_to_klass record"
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
@@ -18,7 +18,8 @@ end
18
18
 
19
19
  # DEFINE WHICH VERSIONS WE WANT TO TEST WITH
20
20
 
21
- gem 'spreadsheet'
22
-
23
21
  gem 'rails', '3.2.8'
24
22
 
23
+ gem 'spreadsheet'
24
+ gem 'paperclip'
25
+
@@ -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')
@@ -14,32 +14,27 @@ include DataShift
14
14
 
15
15
  describe 'Excel Loader' do
16
16
 
17
- before(:all) do
17
+ include_context "ActiveRecordTestModelsConnected"
18
18
 
19
- # load our test model definitions - Project etc
20
- require ifixture_file('test_model_defs')
21
-
22
- db_connect( 'test_file' ) # , test_memory, test_mysql
19
+ before(:each) do
20
+ DataShift::MethodDictionary.clear
23
21
 
24
- # handle migration changes or reset of test DB
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
- @assoc_klazz.find_or_create_by_reference(cat)
31
+ Category.find_or_create_by_reference(cat)
38
32
  end
39
33
 
40
- MethodDictionary.clear
41
- MethodDictionary.find_operators( Project )
42
- MethodDictionary.find_operators( @assoc_klazz )
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
@@ -2,7 +2,7 @@
2
2
  # These entires can be used in call to db_connect ( see spec_helper )
3
3
 
4
4
  <% adapter = 'sqlite3' %>
5
- <% adapter = 'jdbcsqlite3' if(Guards::jruby? ) %>
5
+ <% adapter = 'jdbcsqlite3' if(DataShift::Guards::jruby? ) %>
6
6
 
7
7
  test_mysql:
8
8
  adapter: jdbcmysql
@@ -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
@@ -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,5 +1,7 @@
1
-
2
-
3
1
  class Owner < ActiveRecord::Base
4
- belongs_to :project
2
+
3
+ belongs_to :project, :dependent => :destroy
4
+
5
+ has_many :digitals, :dependent => :destroy
6
+
5
7
  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
- class Project < ActiveRecord::Base
3
+ # TODO investigate potential gem that might this require_all
7
4
 
8
- has_one :owner
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
- end
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
- before(:all) do
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
- @klazz = Project
23
- end
16
+ include_context "ClearAndPopulateProject"
24
17
 
25
- before(:each) do
26
- MethodDictionary.clear
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 = LoaderBase.new( @klazz )
32
-
33
- loader.load_object.should_not be_nil
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
- loader = LoaderBase.new(Project)
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__) + '/spec_helper'
10
+ require File.join(File.dirname(__FILE__), 'spec_helper')
11
11
 
12
- describe 'Method Mapping' do
12
+ describe 'Method Dictionary' do
13
13
 
14
- before(:all) do
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