ar_loader 0.0.6 → 0.0.8

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.
Files changed (53) hide show
  1. data/LICENSE +9 -9
  2. data/README.markdown +268 -221
  3. data/Rakefile +76 -76
  4. data/lib/VERSION +1 -1
  5. data/lib/ar_loader.rb +87 -66
  6. data/lib/ar_loader/exceptions.rb +2 -0
  7. data/lib/{engine → ar_loader}/file_definitions.rb +353 -353
  8. data/lib/{engine → ar_loader}/mapping_file_definitions.rb +87 -87
  9. data/lib/ar_loader/method_detail.rb +257 -0
  10. data/lib/ar_loader/method_mapper.rb +213 -0
  11. data/lib/helpers/jruby/jexcel_file.rb +187 -0
  12. data/lib/{engine → helpers/jruby}/word.rb +79 -70
  13. data/lib/helpers/spree_helper.rb +85 -0
  14. data/lib/loaders/csv_loader.rb +87 -0
  15. data/lib/loaders/excel_loader.rb +132 -0
  16. data/lib/loaders/loader_base.rb +205 -73
  17. data/lib/loaders/spree/image_loader.rb +45 -41
  18. data/lib/loaders/spree/product_loader.rb +140 -91
  19. data/lib/to_b.rb +24 -24
  20. data/spec/csv_loader_spec.rb +27 -0
  21. data/spec/database.yml +19 -6
  22. data/spec/db/migrate/20110803201325_create_test_bed.rb +78 -0
  23. data/spec/excel_loader_spec.rb +113 -98
  24. data/spec/fixtures/BadAssociationName.xls +0 -0
  25. data/spec/fixtures/DemoNegativeTesting.xls +0 -0
  26. data/spec/fixtures/DemoTestModelAssoc.xls +0 -0
  27. data/spec/fixtures/ProjectsMultiCategories.xls +0 -0
  28. data/spec/fixtures/SimpleProjects.xls +0 -0
  29. data/spec/fixtures/SpreeProducts.xls +0 -0
  30. data/spec/fixtures/SpreeZoneExample.csv +5 -0
  31. data/spec/fixtures/SpreeZoneExample.xls +0 -0
  32. data/spec/loader_spec.rb +116 -0
  33. data/spec/logs/test.log +5000 -0
  34. data/spec/method_mapper_spec.rb +222 -0
  35. data/spec/models.rb +55 -0
  36. data/spec/spec_helper.rb +85 -18
  37. data/spec/spree_loader_spec.rb +223 -157
  38. data/tasks/config/seed_fu_product_template.erb +15 -15
  39. data/tasks/config/tidy_config.txt +12 -12
  40. data/tasks/db_tasks.rake +64 -64
  41. data/tasks/excel_loader.rake +63 -113
  42. data/tasks/file_tasks.rake +36 -37
  43. data/tasks/loader.rake +45 -0
  44. data/tasks/spree/image_load.rake +108 -107
  45. data/tasks/spree/product_loader.rake +49 -107
  46. data/tasks/word_to_seedfu.rake +166 -166
  47. metadata +66 -61
  48. data/lib/engine/jruby/jexcel_file.rb +0 -182
  49. data/lib/engine/jruby/method_mapper_excel.rb +0 -44
  50. data/lib/engine/method_detail.rb +0 -140
  51. data/lib/engine/method_mapper.rb +0 -157
  52. data/lib/engine/method_mapper_csv.rb +0 -28
  53. data/spec/db/migrate/20110803201325_create_testbed.rb +0 -25
@@ -1,15 +1,15 @@
1
- p = Product.seed( :name ) do |s|
2
- s.name = <%= @name %>
3
- s.available_on = '2009-09-01 09:00:00.0'
4
- s.meta_keywords = ['training', 'training']
5
- s.meta_description = ""
6
- s.description = '<%= @description %>'
7
- s.price = 0.00
8
- s.sku = '<%= @sku %>'
9
-
10
- s.is_physical = false
11
- s.is_private = false
12
-
13
- s.append_association :taxons, Taxon.find_by_name( 'Training' )
14
-
15
- end
1
+ p = Product.seed( :name ) do |s|
2
+ s.name = <%= @name %>
3
+ s.available_on = '2009-09-01 09:00:00.0'
4
+ s.meta_keywords = ['training', 'training']
5
+ s.meta_description = ""
6
+ s.description = '<%= @description %>'
7
+ s.price = 0.00
8
+ s.sku = '<%= @sku %>'
9
+
10
+ s.is_physical = false
11
+ s.is_private = false
12
+
13
+ s.append_association :taxons, Taxon.find_by_name( 'Training' )
14
+
15
+ end
@@ -1,13 +1,13 @@
1
- # Copyright:: (c) Autotelik Media Ltd 2011
2
- # Author :: Tom Statter
3
- # Date :: Aug 2010
4
- #
5
- # License:: Free, OpenSource... MIT ?
6
-
7
- # This is the best effort I've found so far to reduce the amount of MS cruft
8
- # to absolute minimum
9
- # ... but unfortunately these tags will NOT BE REMOVED completely - manual cleanup still required
10
-
11
- # TODO - add another ruby parse layer to strip these out completely
12
-
1
+ # Copyright:: (c) Autotelik Media Ltd 2011
2
+ # Author :: Tom Statter
3
+ # Date :: Aug 2010
4
+ #
5
+ # License:: Free, OpenSource... MIT ?
6
+
7
+ # This is the best effort I've found so far to reduce the amount of MS cruft
8
+ # to absolute minimum
9
+ # ... but unfortunately these tags will NOT BE REMOVED completely - manual cleanup still required
10
+
11
+ # TODO - add another ruby parse layer to strip these out completely
12
+
13
13
  new-empty-tags: o:smarttagtype, st1:placename, st1:place, st1:placetype
data/tasks/db_tasks.rake CHANGED
@@ -1,65 +1,65 @@
1
- # Author :: Tom Statter
2
- # Date :: Mar 2011
3
- #
4
- # License:: The MIT License (Free and OpenSource)
5
- #
6
- # About:: Additional Rake tasks useful when testing seeding DB via ARLoader
7
- #
8
- namespace :autotelik do
9
-
10
- namespace :db do
11
-
12
- SYSTEM_TABLE_EXCLUSION_LIST = ['schema_migrations']
13
-
14
- desc "Purge the current database"
15
- task :purge, :exclude_system_tables, :needs => [:environment] do |t, args|
16
- require 'highline/import'
17
-
18
- if(RAILS_ENV == 'production')
19
- agree("WARNING: In Production database, REALLY PURGE ? [y]:")
20
- end
21
-
22
- config = ActiveRecord::Base.configurations[RAILS_ENV || 'development']
23
- case config['adapter']
24
- when "mysql", "jdbcmysql"
25
- ActiveRecord::Base.establish_connection(config)
26
- ActiveRecord::Base.connection.tables.each do |table|
27
- next if(args[:exclude_system_tables] && SYSTEM_TABLE_EXCLUSION_LIST.include?(table) )
28
- puts "purging table: #{table}"
29
- ActiveRecord::Base.connection.execute("TRUNCATE #{table}")
30
- end
31
- when "sqlite","sqlite3"
32
- dbfile = config["database"] || config["dbfile"]
33
- File.delete(dbfile) if File.exist?(dbfile)
34
- when "sqlserver"
35
- dropfkscript = "#{config["host"]}.#{config["database"]}.DP1".gsub(/\\/,'-')
36
- `osql -E -S #{config["host"]} -d #{config["database"]} -i db\\#{dropfkscript}`
37
- `osql -E -S #{config["host"]} -d #{config["database"]} -i db\\#{RAILS_ENV}_structure.sql`
38
- when "oci", "oracle"
39
- ActiveRecord::Base.establish_connection(config)
40
- ActiveRecord::Base.connection.structure_drop.split(";\n\n").each do |ddl|
41
- ActiveRecord::Base.connection.execute(ddl)
42
- end
43
- when "firebird"
44
- ActiveRecord::Base.establish_connection(config)
45
- ActiveRecord::Base.connection.recreate_database!
46
- else
47
- raise "Task not supported by '#{config["adapter"]}'"
48
- end
49
- end
50
-
51
- desc "Clear database and optional directories such as assets, then run db:seed"
52
- task :seed_again, :assets, :needs => [:environment] do |t, args|
53
-
54
- Rake::Task['autotelik:db:purge'].invoke( true ) # i.e ENV['exclude_system_tables'] = true
55
-
56
- if(args[:assets])
57
- assets = "#{Rails.root}/public/assets"
58
- FileUtils::rm_rf(assets) if(File.exists?(assets))
59
- end
60
-
61
- Rake::Task['db:seed'].invoke
62
- end
63
-
64
- end # db
1
+ # Author :: Tom Statter
2
+ # Date :: Mar 2011
3
+ #
4
+ # License:: The MIT License (Free and OpenSource)
5
+ #
6
+ # About:: Additional Rake tasks useful when testing seeding DB via ARLoader
7
+ #
8
+ namespace :autotelik do
9
+
10
+ namespace :db do
11
+
12
+ SYSTEM_TABLE_EXCLUSION_LIST = ['schema_migrations']
13
+
14
+ desc "Purge the current database"
15
+ task :purge, :exclude_system_tables, :needs => [:environment] do |t, args|
16
+ require 'highline/import'
17
+
18
+ if(RAILS_ENV == 'production')
19
+ agree("WARNING: In Production database, REALLY PURGE ? [y]:")
20
+ end
21
+
22
+ config = ActiveRecord::Base.configurations[RAILS_ENV || 'development']
23
+ case config['adapter']
24
+ when "mysql", "jdbcmysql"
25
+ ActiveRecord::Base.establish_connection(config)
26
+ ActiveRecord::Base.connection.tables.each do |table|
27
+ next if(args[:exclude_system_tables] && SYSTEM_TABLE_EXCLUSION_LIST.include?(table) )
28
+ puts "purging table: #{table}"
29
+ ActiveRecord::Base.connection.execute("TRUNCATE #{table}")
30
+ end
31
+ when "sqlite","sqlite3"
32
+ dbfile = config["database"] || config["dbfile"]
33
+ File.delete(dbfile) if File.exist?(dbfile)
34
+ when "sqlserver"
35
+ dropfkscript = "#{config["host"]}.#{config["database"]}.DP1".gsub(/\\/,'-')
36
+ `osql -E -S #{config["host"]} -d #{config["database"]} -i db\\#{dropfkscript}`
37
+ `osql -E -S #{config["host"]} -d #{config["database"]} -i db\\#{RAILS_ENV}_structure.sql`
38
+ when "oci", "oracle"
39
+ ActiveRecord::Base.establish_connection(config)
40
+ ActiveRecord::Base.connection.structure_drop.split(";\n\n").each do |ddl|
41
+ ActiveRecord::Base.connection.execute(ddl)
42
+ end
43
+ when "firebird"
44
+ ActiveRecord::Base.establish_connection(config)
45
+ ActiveRecord::Base.connection.recreate_database!
46
+ else
47
+ raise "Task not supported by '#{config["adapter"]}'"
48
+ end
49
+ end
50
+
51
+ desc "Clear database and optional directories such as assets, then run db:seed"
52
+ task :seed_again, :assets, :needs => [:environment] do |t, args|
53
+
54
+ Rake::Task['autotelik:db:purge'].invoke( true ) # i.e ENV['exclude_system_tables'] = true
55
+
56
+ if(args[:assets])
57
+ assets = "#{Rails.root}/public/assets"
58
+ FileUtils::rm_rf(assets) if(File.exists?(assets))
59
+ end
60
+
61
+ Rake::Task['db:seed'].invoke
62
+ end
63
+
64
+ end # db
65
65
  end # autotelik
@@ -1,114 +1,64 @@
1
- # Copyright:: (c) Autotelik Media Ltd 2011
2
- # Author :: Tom Statter
3
- # Date :: Feb 2011
4
- # License:: TBD. Free, Open Source. MIT ?
5
- #
6
- # REQUIRES: JRuby
7
- #
8
- # Usage::
9
- # => jruby -S rake autotelik:excel_load model=<active record class> input=<file.xls>
10
- # => jruby -S rake autotelik:excel_load model=<active record class> input=C:\MyProducts.xlsverbose=true
11
- #
12
- namespace :autotelik do
13
-
14
- desc "Populate a model's table in db with data from .xls (Excel) file"
15
- task :excel_load, :model, :loader, :input, :verbose, :needs => :environment do |t, args|
16
-
17
- raise "USAGE: jruby -S rake excel_load input=excel_file.xls" unless args[:input]
18
- raise "ERROR: Cannot process without AR Model - please supply model=<Class>" unless args[:model]
19
- raise "ERROR: Could not find file #{args[:input]}" unless File.exists?(args[:input])
20
-
21
- begin
22
- klass = Kernel.const_get(args[:model])
23
- rescue NameError
24
- raise "ERROR: No such AR Model found - please check model=<Class>"
25
- end
26
-
27
- begin
28
- require "#{args[:model]}_loader"
29
-
30
- loader_klass = Kernel.const_get("#{args[:model]}Loader")
31
-
32
- loader = loader_klass.new(klass)
33
- rescue
34
- puts "INFO: No specific #{args[:model]}Loader found using generic loader"
35
- loader = LoaderBase.new(klass)
36
- end
37
-
38
- require 'method_mapper_excel'
39
-
40
- @method_mapper = MethodMapperExcel.new(args[:input], klass)
41
-
42
- @excel = @method_mapper.excel
43
-
44
- if(args[:verbose])
45
- puts "Loading from Excel file: #{args[:input]}"
46
- puts "Processing #{@excel.num_rows} rows"
47
- end
48
-
49
- # Process spreadsheet and create model instances
50
-
51
- klass.transaction do
52
- @loaded_objects = []
53
-
54
- (1..@excel.num_rows).collect do |row|
55
-
56
- data_row = @excel.sheet.getRow(row)
57
- break if data_row.nil?
58
-
59
- @assoc_classes = {}
60
-
61
- # TODO - Smart sorting of column processing order ....
62
- # Does not currently ensure mandatory columns (for valid?) processed first but model needs saving
63
- # before associations can be processed so user should ensure mandatory columns are prior to associations
64
-
65
- contains_data = false
66
-
67
- # Iterate over the columns method_mapper found in Excel,
68
- # pulling data out of associated column
69
- @method_mapper.methods.each_with_index do |method_map, col|
70
-
71
- value = @excel.value(data_row, col)
72
-
73
- # Excel num_rows seems to return all 'visible' rows so,
74
- # we have to manually detect when actual data ends, this isn't very smart but
75
- # currently got no better idea than ending once we hit the first completely empty row
76
-
77
- contains_data = true if(value.to_s.empty?)
78
-
79
- puts "VALUE #{value.class}"
80
- puts "VALUE #{value} #{value.inspect}"
81
-
82
- loader.process(method_map, @excel.value(data_row, col))
83
-
84
- begin
85
- loader.load_object.save if( loader.load_object.valid? && loader.load_object.new_record? )
86
- rescue
87
- raise "Error processing row"
88
- end
89
- end
90
-
91
- break unless contains_data
92
-
93
- loaded_object = loader.load_object
94
-
95
- # TODO - handle when it's not valid ?
96
- # Process rest and dump out an exception list of Products
97
- #unless(product.valid?)
98
- #end
99
-
100
- puts "SAVING ROW #{row} : #{loaded_object.inspect}" if args[:verbose]
101
-
102
- unless(loaded_object.save)
103
- puts loaded_object.errors.inspect
104
- puts loaded_object.errors.full_messages.inspect
105
- raise "Error Saving : #{loaded_object.inspect}"
106
- else
107
- @loaded_objects << loaded_object
108
- end
109
- end
110
- end # TRANSACTION
111
-
112
- end
113
-
1
+ # Copyright:: (c) Autotelik Media Ltd 2011
2
+ # Author :: Tom Statter
3
+ # Date :: Feb 2011
4
+ # License:: TBD. Free, Open Source. MIT ?
5
+ #
6
+ # REQUIRES: JRuby
7
+ #
8
+ # Usage::
9
+ #
10
+ # In Rakefile:
11
+ #
12
+ # require 'ar_loader'
13
+ #
14
+ # ArLoader::load_tasks
15
+ #
16
+ # Cmd Line:
17
+ #
18
+ # => jruby -S rake ar_loader:excel model=<active record class> input=<file.xls>
19
+ # => jruby -S rake ar_loader:excel model=<active record class> input=C:\MyProducts.xlsverbose=true
20
+ #
21
+ require 'ar_loader'
22
+ require 'excel_loader'
23
+
24
+ namespace :ar_loader do
25
+
26
+ desc "Populate a model's table in db with data from .xls (Excel) file"
27
+
28
+ task :excel, [:model, :loader, :input, :verbose] => [:environment] do |t, args|
29
+
30
+ # in familiar ruby style args seems to have been become empty using this new style for rake 0.9.2
31
+ # whatever format i try, on both Win and OSX .. so had to revert back to ENV
32
+ model = ENV['model']
33
+ input = ENV['input']
34
+
35
+ raise "USAGE: jruby -S rake ar_loader:excel input=excel_file.xls model=<Class>" unless(input)
36
+ raise "ERROR: Cannot process without AR Model - please supply model=<Class>" unless(model)
37
+ raise "ERROR: Could not find file #{args[:input]}" unless File.exists?(input)
38
+
39
+ begin
40
+ klass = Kernel.const_get(model)
41
+ rescue NameError
42
+ raise "ERROR: No such AR Model found - check valid model supplied via model=<Class>"
43
+ end
44
+
45
+ if(ENV['loader'])
46
+ begin
47
+ loader_klass = Kernel.const_get(ENV['loader'])
48
+
49
+ loader = loader_klass.new(klass)
50
+
51
+ puts "INFO: Using loader : #{loader.class}"
52
+ rescue
53
+ puts "INFO: No specific #{model}Loader found - using generic ExcelLoader"
54
+ loader = ARLoader::ExcelLoader.new(klass)
55
+ end
56
+ else
57
+ puts "INFO: No Loader specified - using generic ExcelLoader"
58
+ loader = ARLoader::ExcelLoader.new(klass)
59
+ end
60
+
61
+ loader.load(input)
62
+ end
63
+
114
64
  end
@@ -1,38 +1,37 @@
1
- # Copyright:: (c) Autotelik Media Ltd 2011
2
- # Author :: Tom Statter
3
- # Date :: Feb 2011
4
- # License:: MIT. Free, Open Source.
5
- #
6
- # Usage:: rake autotelik:file_rename input=/blah image_load input=path_to_images
7
- #
8
-
9
- namespace :autotelik do
10
-
11
- desc "copy or mv a folder of files, consistently renaming in the process"
12
- task :file_rename, :input, :offset, :prefix, :width, :commit, :mv do |t, args|
13
- raise "USAGE: rake file_rename input='C:\blah' [offset=n prefix='str' width=n]" unless args[:input] && File.exists?(args[:input])
14
- width = args[:width] || 2
15
-
16
- action = args[:mv] ? 'mv' : 'cp'
17
-
18
- cache = args[:input]
19
-
20
- if(File.exists?(cache) )
21
- puts "Renaming files from #{cache}"
22
- Dir.glob(File.join(cache, "*")) do |name|
23
- path, base_name = File.split(name)
24
- id = base_name.slice!(/\w+/)
25
-
26
- id = id.to_i + args[:offset].to_i if(args[:offset])
27
- id = "%0#{width}d" % id.to_i if(args[:width])
28
- id = args[:prefix] + id.to_s if(args[:prefix])
29
-
30
- destination = File.join(path, "#{id}#{base_name}")
31
- puts "ACTION: #{action} #{name} #{destination}"
32
-
33
- File.send( action, name, destination) if args[:commit]
34
- end
35
- end
36
- end
37
-
1
+ # Copyright:: (c) Autotelik Media Ltd 2011
2
+ # Author :: Tom Statter
3
+ # Date :: Feb 2011
4
+ # License:: MIT
5
+ #
6
+ # Usage:: rake ar_loader:file_rename input=/blah image_load input=path_to_images
7
+ #
8
+ namespace :ar_loader do
9
+
10
+ desc "copy or mv a folder of files, consistently renaming in the process"
11
+ task :file_rename, :input, :offset, :prefix, :width, :commit, :mv do |t, args|
12
+ raise "USAGE: rake file_rename input='C:\blah' [offset=n prefix='str' width=n]" unless args[:input] && File.exists?(args[:input])
13
+ width = args[:width] || 2
14
+
15
+ action = args[:mv] ? 'mv' : 'cp'
16
+
17
+ cache = args[:input]
18
+
19
+ if(File.exists?(cache) )
20
+ puts "Renaming files from #{cache}"
21
+ Dir.glob(File.join(cache, "*")) do |name|
22
+ path, base_name = File.split(name)
23
+ id = base_name.slice!(/\w+/)
24
+
25
+ id = id.to_i + args[:offset].to_i if(args[:offset])
26
+ id = "%0#{width}d" % id.to_i if(args[:width])
27
+ id = args[:prefix] + id.to_s if(args[:prefix])
28
+
29
+ destination = File.join(path, "#{id}#{base_name}")
30
+ puts "ACTION: #{action} #{name} #{destination}"
31
+
32
+ File.send( action, name, destination) if args[:commit]
33
+ end
34
+ end
35
+ end
36
+
38
37
  end
data/tasks/loader.rake ADDED
@@ -0,0 +1,45 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2011
2
+ # Author :: Tom Statter
3
+ # Date :: Aug 2011
4
+ # License:: MIT
5
+ #
6
+ # Usage::
7
+ #
8
+ # In Rakefile:
9
+ #
10
+ # require 'ar_loader'
11
+ #
12
+ # ArLoader::load_tasks
13
+ #
14
+ # Cmd Line:
15
+ #
16
+ # => jruby -S rake ar_loader:csv model=<active record class> input=<file.csv>
17
+ #
18
+ namespace :ar_loader do
19
+
20
+ desc "Populate a model's table in db with data from CSV file"
21
+ task :csv, [:model, :loader, :input, :verbose] => [:environment] do |t, args|
22
+
23
+ # in familiar ruby style args seems to have been become empty with rake 0.9.2 whatever i try
24
+ # so had to revert back to ENV
25
+ model = ENV['model']
26
+ input = ENV['input']
27
+
28
+ raise "USAGE: jruby -S rake ar_loader:excel input=excel_file.xls model=<Class>" unless(input)
29
+ raise "ERROR: Cannot process without AR Model - please supply model=<Class>" unless(model)
30
+ raise "ERROR: Could not find file #{args[:input]}" unless File.exists?(input)
31
+
32
+ begin
33
+ klass = Kernel.const_get(model)
34
+ rescue NameError
35
+ raise "ERROR: No such AR Model found - check valid model supplied via model=<Class>"
36
+ end
37
+
38
+ puts "INFO: Using CSV loader"
39
+
40
+ loader = CsvLoader.new(klass)
41
+
42
+ loader.load(input)
43
+ end
44
+
45
+ end