ferry 0.1.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,117 @@
1
+ require_relative 'utilities'
2
+
3
+ module Ferry
4
+ class Exporter < Utilities
5
+ def to_csv(environment, model)
6
+ db_type = db_connect(environment)
7
+ FileUtils.mkdir "db" unless Dir["db"].present? #to help with tests
8
+ FileUtils.mkdir "db/csv" unless Dir["db/csv"].present?
9
+ homedir = "db/csv/#{environment}"
10
+ FileUtils.mkdir homedir unless Dir[homedir].present?
11
+ table = ActiveRecord::Base.connection.execute("SELECT * FROM #{model};")
12
+ CSV.open("#{homedir}/#{model}.csv", "w") do |csv|
13
+ case db_type
14
+ when 'sqlite3'
15
+ csv_bar = ProgressBar.new("to_csv", table.length)
16
+ keys = table[0].keys.first(table[0].length / 2)
17
+ csv << keys
18
+ table.each do |row|
19
+ csv << row.values_at(*keys)
20
+ csv_bar.inc
21
+ end
22
+ when 'postgresql'
23
+ csv_bar = ProgressBar.new("to_csv", table.num_tuples)
24
+ keys = table[0].keys
25
+ csv << keys
26
+ table.each do |row|
27
+ csv << row.values_at(*keys)
28
+ csv_bar.inc
29
+ end
30
+ when 'mysql2'
31
+ csv_bar = ProgressBar.new("to_csv", table.count)
32
+ db_config = YAML::load(IO.read("config/database.yml"))
33
+ columns = ActiveRecord::Base.connection.execute("SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA`= '#{db_config[environment]['database']}' AND `TABLE_NAME`='#{model}';")
34
+ col_names=[]
35
+ columns.each do |col|
36
+ col_names.append(col[0])
37
+ end
38
+ csv << col_names
39
+ table.each do |row|
40
+ csv << row
41
+ csv_bar.inc
42
+ end
43
+ else
44
+ puts "error in db type"
45
+ return false
46
+ end
47
+ end
48
+ puts ""
49
+ puts "exported to db/csv/#{environment}"
50
+ end
51
+
52
+ def to_yaml(environment, model)
53
+ db_type = db_connect(environment)
54
+ FileUtils.mkdir "db" unless Dir["db"].present? #to help with tests
55
+ FileUtils.mkdir "db/yaml" unless Dir["db/yaml"].present?
56
+ homedir = "db/yaml/#{environment}"
57
+ FileUtils.mkdir homedir unless Dir[homedir].present?
58
+ table = ActiveRecord::Base.connection.execute("SELECT * FROM #{model};")
59
+ db_object = {}
60
+ db_output = {}
61
+ case db_type
62
+ when 'sqlite3'
63
+ yaml_bar = ProgressBar.new("to_csv", table.length)
64
+ keys = table[0].keys.first(table[0].length / 2)
65
+ db_object["columns"] = keys
66
+ model_arr=[]
67
+ table.each do |row|
68
+ model_arr << row.values_at(*keys)
69
+ yaml_bar.inc
70
+ end
71
+ db_object["records"] = model_arr
72
+ db_output[model] = db_object
73
+ File.open("#{homedir}/#{model}.yml",'a') do |file|
74
+ YAML::dump(db_output, file)
75
+ end
76
+ when 'postgresql'
77
+ yaml_bar = ProgressBar.new("to_csv", table.num_tuples)
78
+ keys = table[0].keys
79
+ db_object["columns"] = keys
80
+ model_arr=[]
81
+ table.each do |row|
82
+ model_arr << row.values_at(*keys)
83
+ yaml_bar.inc
84
+ end
85
+ db_object["records"] = model_arr
86
+ db_output[model] = db_object
87
+ File.open("#{homedir}/#{model}.yml",'a') do |file|
88
+ YAML::dump(db_output, file)
89
+ end
90
+ when 'mysql2'
91
+ yaml_bar = ProgressBar.new("to_csv", table.count)
92
+ db_config = YAML::load(IO.read("config/database.yml"))
93
+ columns = ActiveRecord::Base.connection.execute("SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA`= '#{db_config[environment]['database']}' AND `TABLE_NAME`='#{model}';")
94
+ col_names=[]
95
+ columns.each do |col|
96
+ col_names.append(col[0])
97
+ end
98
+ db_object["columns"] = col_names
99
+ model_arr=[]
100
+ table.each do |row|
101
+ model_arr << row
102
+ yaml_bar.inc
103
+ end
104
+ db_object["records"] = model_arr
105
+ db_output[model] = db_object
106
+ File.open("#{homedir}/#{model}.yml",'a') do |file|
107
+ YAML::dump(db_output, file)
108
+ end
109
+ else
110
+ puts "error in db type"
111
+ return false
112
+ end
113
+ puts ""
114
+ puts "exported to db/yaml/#{environment}"
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,57 @@
1
+ require_relative 'utilities'
2
+
3
+ module Ferry
4
+ class Importer < Utilities
5
+ def row_sql_format(hash, columns, adapter)
6
+ values = hash.values_at(*columns)
7
+ values.map! do |value|
8
+ if(adapter=="mysql2" && (value=='t' || value =='f'))
9
+ value=='t' ? value=1 : value=0 #attempt to convert 't' and 'f' to int in mysql
10
+ end
11
+ value = ActiveRecord::Base::sanitize(value)
12
+ end
13
+ "(#{values.join(",")})"
14
+ end
15
+
16
+ def insert_sql(model, columns, values)
17
+ col_names_sql = "(#{columns.join(",")})"
18
+ model_sql = model.downcase
19
+ sql_insert_beg = "INSERT INTO #{model_sql} #{col_names_sql} VALUES "
20
+ ActiveRecord::Base.connection.begin_db_transaction
21
+ values.each_slice(1000) do |records|
22
+ sql_statement = sql_insert_beg + records.join(",") + ";"
23
+ ActiveRecord::Base.connection.execute(sql_statement)
24
+ end
25
+ ActiveRecord::Base.connection.commit_db_transaction
26
+ end
27
+
28
+ def import(environment, model, filename)
29
+ db_connect(environment)
30
+ adapter = YAML::load(IO.read("config/database.yml"))[environment]["adapter"]
31
+ if(File.extname(filename) != ".csv")
32
+ puts "Import aborted -- only csv import is supported"
33
+ return false
34
+ end
35
+ lines = CSV.read(filename)#encoding option here? might break given db's limits
36
+ if(lines.nil?)
37
+ puts "Import aborted -- file not found"
38
+ return false
39
+ end
40
+ import_bar = ProgressBar.new("import", lines.length-1)
41
+ col_names = lines.shift
42
+ records = []
43
+ lines.each do |line|
44
+ record = Hash[col_names.zip line]
45
+ records << record
46
+ end
47
+ values = []
48
+ records.map do |record|
49
+ values << row_sql_format(record, col_names, adapter)
50
+ import_bar.inc
51
+ end
52
+ insert_sql(model, col_names, values)
53
+ puts ""
54
+ puts "csv imported to #{model} table"
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,21 @@
1
+ require_relative 'utilities'
2
+
3
+ module Ferry
4
+ class Switcher < Utilities
5
+ def to_new_db_type(which_db_env, switch_to_db_type)
6
+ info = YAML::load(IO.read("config/database.yml"))
7
+ current_db_type = info[which_db_env]["adapter"]
8
+ puts "switching the #{which_db_env} database's adapter"
9
+ puts "current_db_type: #{current_db_type}"
10
+ puts "to_new_db_type: #{switch_to_db_type}"
11
+ if ['sqlite', 'postgresql', 'mysql'].include?(switch_to_db_type)
12
+ info[which_db_env]["adapter"] = switch_to_db_type
13
+ puts "switching #{which_db_env} env to #{switch_to_db_type} ... "
14
+ File.open("config/database.yml", "w") {|f| f.write info.to_yaml}
15
+ puts "switched #{which_db_env} env to #{switch_to_db_type}"
16
+ else
17
+ puts "#{switch_to_db_type} is currently unsupported"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,42 @@
1
+ module Ferry
2
+ class Utilities
3
+ def db_connect(environment)
4
+ db_config = YAML::load(IO.read("config/database.yml"))
5
+ db_type = db_config[environment]["adapter"]
6
+
7
+ if ['sqlite3', 'postgresql', 'mysql2'].include?(db_type)
8
+ ActiveRecord::Base.establish_connection(adapter: db_type, database: db_config[environment]['database'])
9
+ puts "operating with "+db_type
10
+ return db_type
11
+ else
12
+ puts "Unsupported db type or no database associated with this application."
13
+ return false
14
+ end
15
+ end
16
+
17
+ def continue?(prompt = "Are you sure", default = false)
18
+ a = ''
19
+ s = default ? '[Y/n]' : '[y/N]'
20
+ d = default ? 'y' : 'n'
21
+ until %w[y n].include? a
22
+ a = ask("#{prompt} #{s} ") { |q| q.limit = 1; q.case = :downcase }
23
+ a = d if a.length == 0
24
+ end
25
+ a == 'y'
26
+ end
27
+
28
+ def init
29
+ if !File.exist?("lib/tasks/ferry.rake")
30
+ File.open("lib/tasks/ferry.rake", 'w') {|f| f.write("# this is your ferry init file
31
+ # in this file you can write rake tasks that are easily tailored to more case-by-case user implementations
32
+
33
+ namespace :ferry do
34
+ # your code here!
35
+ end")}
36
+ puts "/lib/tasks/ferry.rake created!"
37
+ else
38
+ puts "/lib/tasks/ferry.rake already exists - but you knew that already ... didn't you?"
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,3 +1,3 @@
1
1
  module Ferry
2
- VERSION = "0.1.3"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -0,0 +1,20 @@
1
+ default: &default
2
+ username: root
3
+ password:
4
+ encoding: utf8
5
+ host: localhost
6
+ database: ferry_test
7
+
8
+ mysql2: &mysql2
9
+ <<: *default
10
+ adapter: mysql2
11
+
12
+ postgresql: &postgresql
13
+ <<: *default
14
+ username: postgres
15
+ adapter: postgresql
16
+ min_messages: warning
17
+
18
+ sqlite3: &sqlite3
19
+ adapter: sqlite3
20
+ database: test.db
@@ -0,0 +1,20 @@
1
+ require 'sets/category_context'
2
+ require 'sets/product_context'
3
+ require 'sets/cart_context'
4
+ require 'sets/order_context'
5
+
6
+ module Contexts
7
+ def self.setup
8
+ create_categories
9
+ create_products
10
+ create_carts
11
+ create_orders
12
+ end
13
+
14
+ def self.teardown
15
+ delete_orders
16
+ delete_carts
17
+ delete_products
18
+ delete_categories
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ # please note that running rspec spec/ferry_spec.rb will assumes you have ...
2
+ # a pg and mysql db named ferry_test on your local machine
3
+ require 'spec_helper'
4
+ require 'tests/exporter_tests'
5
+ require 'tests/importer_tests'
@@ -0,0 +1,10 @@
1
+ class Cart < ActiveRecord::Base
2
+
3
+ has_many :orders
4
+
5
+
6
+ validates_presence_of :email
7
+ validates_uniqueness_of :email
8
+
9
+
10
+ end
@@ -0,0 +1,7 @@
1
+ class Category < ActiveRecord::Base
2
+
3
+ has_many :products
4
+
5
+ validates_presence_of :name
6
+
7
+ end
@@ -0,0 +1,7 @@
1
+ class Order < ActiveRecord::Base
2
+
3
+ belongs_to :cart
4
+ belongs_to :product
5
+
6
+
7
+ end
@@ -0,0 +1,9 @@
1
+ class Product < ActiveRecord::Base
2
+
3
+ has_many :orders
4
+ belongs_to :category
5
+
6
+
7
+ validates_presence_of :name
8
+
9
+ end
@@ -0,0 +1,57 @@
1
+ def create_carts
2
+ @cart1 = FactoryGirl.create(:cart, email: "abby@example.com")
3
+ @cart2 = FactoryGirl.create(:cart, email: "bob@example.com")
4
+ @cart3 = FactoryGirl.create(:cart, email: "chris@example.com")
5
+ @cart4 = FactoryGirl.create(:cart, email: "david@example.com")
6
+ @cart5 = FactoryGirl.create(:cart, email: "eric@example.com")
7
+ @cart6 = FactoryGirl.create(:cart, email: "frank@example.com")
8
+ @cart7 = FactoryGirl.create(:cart, email: "greg@example.com")
9
+ @cart8 = FactoryGirl.create(:cart, email: "henry@example.com")
10
+ @cart9 = FactoryGirl.create(:cart, email: "ian@example.com")
11
+ @cart10 = FactoryGirl.create(:cart, email: "joe@example.com")
12
+ @cart11 = FactoryGirl.create(:cart, email: "kevin@example.com")
13
+ @cart12 = FactoryGirl.create(:cart, email: "logan@example.com")
14
+ @cart13 = FactoryGirl.create(:cart, email: "max@example.com")
15
+ @cart14 = FactoryGirl.create(:cart, email: "nancy@example.com")
16
+ @cart15 = FactoryGirl.create(:cart, email: "oliver@example.com")
17
+ @cart16 = FactoryGirl.create(:cart, email: "pamela@example.com")
18
+ @cart17 = FactoryGirl.create(:cart, email: "quinn@example.com")
19
+ @cart18 = FactoryGirl.create(:cart, email: "ryan@example.com")
20
+ @cart19 = FactoryGirl.create(:cart, email: "steve@example.com")
21
+ @cart20 = FactoryGirl.create(:cart, email: "ted@example.com")
22
+ @cart21 = FactoryGirl.create(:cart, email: "uma@example.com")
23
+ @cart22 = FactoryGirl.create(:cart, email: "victor@example.com")
24
+ @cart23 = FactoryGirl.create(:cart, email: "walter@example.com")
25
+ @cart24 = FactoryGirl.create(:cart, email: "xavier@example.com")
26
+ @cart25 = FactoryGirl.create(:cart, email: "yolo@example.com")
27
+ @cart26 = FactoryGirl.create(:cart, email: "zach@example.com")
28
+ end
29
+
30
+ def delete_carts
31
+ @cart1.delete
32
+ @cart2.delete
33
+ @cart3.delete
34
+ @cart4.delete
35
+ @cart5.delete
36
+ @cart6.delete
37
+ @cart7.delete
38
+ @cart8.delete
39
+ @cart9.delete
40
+ @cart10.delete
41
+ @cart11.delete
42
+ @cart12.delete
43
+ @cart13.delete
44
+ @cart14.delete
45
+ @cart15.delete
46
+ @cart16.delete
47
+ @cart17.delete
48
+ @cart18.delete
49
+ @cart19.delete
50
+ @cart20.delete
51
+ @cart21.delete
52
+ @cart22.delete
53
+ @cart23.delete
54
+ @cart24.delete
55
+ @cart25.delete
56
+ @cart26.delete
57
+ end
@@ -0,0 +1,18 @@
1
+ def create_categories
2
+ # assumes create_curriculums prior
3
+ @food = FactoryGirl.create(:category)
4
+ @cleaning = FactoryGirl.create(:category, name: "Cleaning Supplies", description: "Household cleaning products.")
5
+ @antiques = FactoryGirl.create(:category, name: "Antiques", active: false, description:"No longer carried.")
6
+ @toilet = FactoryGirl.create(:category, name: "Toiletries", description: "Things for the bathroom.")
7
+ @toys = FactoryGirl.create(:category, name: "Toys", description: "Anything that is meant to be played with.")
8
+ @furniture = FactoryGirl.create(:category, name: "Furniture", float_score: 42.12097593749, description: "Furniture.")
9
+ end
10
+
11
+ def delete_categories
12
+ @food.delete
13
+ @cleaning.delete
14
+ @antiques.delete
15
+ @toilet.delete
16
+ @toys.delete
17
+ @furniture.delete
18
+ end
@@ -0,0 +1,56 @@
1
+ def create_orders
2
+ # assumes create_products and create_carts prior
3
+ @order1 = FactoryGirl.create(:order, product: @toy1, cart: @cart1, quantity: 1, date: Date.new(2014, 1, 23))
4
+ @order2 = FactoryGirl.create(:order, product: @toy2, cart: @cart2, quantity: 22, date: Date.new(2014, 4, 5))
5
+ @order3 = FactoryGirl.create(:order, product: @toy3, cart: @cart3, quantity: 1, date: Date.new(2014, 6, 7))
6
+ @order4 = FactoryGirl.create(:order, product: @food1, cart: @cart3, quantity: 123, date: Date.new(2014, 8, 9))
7
+ @order5 = FactoryGirl.create(:order, product: @food2, cart: @cart7, quantity: 1, date: Date.new(2014, 10, 11))
8
+ @order6 = FactoryGirl.create(:order, product: @food3, cart: @cart6, quantity: 41, date: Date.new(2014, 12, 13))
9
+ @order7 = FactoryGirl.create(:order, product: @food4, cart: @cart8, quantity: 1, date: Date.new(2014, 1, 4))
10
+ @order8 = FactoryGirl.create(:order, product: @antique1, cart: @cart1, quantity: 501, date: Date.new(2015, 1, 6))
11
+ @order9 = FactoryGirl.create(:order, product: @antique2, cart: @cart9, quantity: 1, date: Date.new(2014, 7, 8))
12
+ @order10 = FactoryGirl.create(:order, product: @furniture1, cart: @cart3, quantity: 100, date: Date.new(2014, 10, 1))
13
+ @order11 = FactoryGirl.create(:order, product: @furniture2, cart: @cart11, quantity: 1, date: Date.new(2002, 3, 2))
14
+ @order12 = FactoryGirl.create(:order, product: @furniture3, cart: @cart12, quantity: 10, date: Date.new(2012, 1, 4))
15
+ @order13 = FactoryGirl.create(:order, product: @furnite4, cart: @cart14, quantity: 314, date: Date.new(2008, 5, 5))
16
+ @order14 = FactoryGirl.create(:order, product: @cleaning2, cart: @cart10, quantity: 22, date: Date.new(2012, 1, 1))
17
+ @order15 = FactoryGirl.create(:order, product: @cleaning3, cart: @cart11, quantity: 64, date: Date.new(2011, 2, 14))
18
+ @order16 = FactoryGirl.create(:order, product: @cleaning4, cart: @cart9, quantity: 42, date: Date.new(2013, 3, 14))
19
+ @order17 = FactoryGirl.create(:order, product: @toy3, cart: @cart21, quantity: 1, date: Date.new(2014, 4, 15))
20
+ @order18 = FactoryGirl.create(:order, product: @food1, cart: @cart22, quantity: 42, date: Date.new(2011, 4, 20))
21
+ @order19 = FactoryGirl.create(:order, product: @food1, cart: @cart23, quantity: 1, date: Date.new(2006, 5, 5))
22
+ @order20 = FactoryGirl.create(:order, product: @food1, cart: @cart24, quantity: 69, date: Date.new(2007, 6, 28))
23
+ @order21 = FactoryGirl.create(:order, product: @food2, cart: @cart25, quantity: 808, date: Date.new(2014, 7, 4))
24
+ @order22 = FactoryGirl.create(:order, product: @food3, cart: @cart25, quantity: 407, date: Date.new(2014, 8, 2))
25
+ @order23 = FactoryGirl.create(:order, product: @food2, cart: @cart21, quantity: 77, date: Date.new(2014, 9, 11))
26
+ @order24 = FactoryGirl.create(:order, product: @toy1, cart: @cart25, quantity: 49, date: Date.new(2014, 10, 31))
27
+ @order25 = FactoryGirl.create(:order, product: @toy1, cart: @cart26, quantity: 666, date: Date.new(2014, 12, 25))
28
+ end
29
+
30
+ def delete_orders
31
+ @order1.delete
32
+ @order2.delete
33
+ @order3.delete
34
+ @order4.delete
35
+ @order5.delete
36
+ @order6.delete
37
+ @order7.delete
38
+ @order8.delete
39
+ @order9.delete
40
+ @order10.delete
41
+ @order11.delete
42
+ @order12.delete
43
+ @order13.delete
44
+ @order14.delete
45
+ @order15.delete
46
+ @order16.delete
47
+ @order17.delete
48
+ @order18.delete
49
+ @order19.delete
50
+ @order20.delete
51
+ @order21.delete
52
+ @order22.delete
53
+ @order23.delete
54
+ @order24.delete
55
+ @order25.delete
56
+ end