yaml_db 0.3.0 → 0.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: acdb560a3395eccc63e09765a383c21a04989f16
4
- data.tar.gz: d212a746810f53f432a0f0d0470a0786f69afeae
3
+ metadata.gz: 04f954464b2709f0799c94e237e9be6908fae386
4
+ data.tar.gz: 284dcf617e715dc8fac6359d987c96a6ec3968ea
5
5
  SHA512:
6
- metadata.gz: 7b584320742d6e98d03dc8bc5d83a967a6386b938719d2a67343f6d6197203c0a8fe21dffdc51d1cdd5f1f3ff9fb1aeb161ddeeedb0d3b0a954f66258aa5415b
7
- data.tar.gz: 6b9e694bd379f5c198316e366af098f3b7e9c94b9397926cc129911cb66182fa218b4586e72eff418909c1734eac04aada3ccda1d68c902569d87fc0c0b25014
6
+ metadata.gz: 88e48da7a8e781d54fbcfa6f88d08fb8103f5a39450c4d3226d475edd6a4129882b60fdc4af4c88a1321e9be54bb49f5b701a1be0091013518b22e4dda821bd9
7
+ data.tar.gz: e20c244eef8ae1d6b20bb63352910d3238fc251d379b6c023d1f13256f1976b32aa5a4b571baa4c1585b2956ff1c728fa89cdcb8c9fdafbae0b9a515ab98b63d
data/README.md CHANGED
@@ -1,10 +1,12 @@
1
1
  # YamlDb
2
2
 
3
- YamlDb is a database-independent format for dumping and restoring data. It complements the the database-independent schema format found in db/schema.rb. The data is saved into db/data.yml.
3
+ YamlDb is a database-independent format for dumping and restoring data. It complements the database-independent schema format found in db/schema.rb. The data is saved into db/data.yml.
4
4
 
5
5
  This can be used as a replacement for mysqldump or pg_dump, but only for the databases typically used by Rails apps. Users, permissions, schemas, triggers, and other advanced database features are not supported - by design.
6
6
 
7
- Any database that has an ActiveRecord adapter should work. This gem is now Rails 3 only. For Rails 2, clone and checkout the Rails2 branch.
7
+ Any database that has an ActiveRecord adapter should work.
8
+
9
+ This gem supports Rails 3.x, 4.x, and 5.0.
8
10
 
9
11
  [![Build Status](https://travis-ci.org/yamldb/yaml_db.svg?branch=master)](https://travis-ci.org/yamldb/yaml_db)
10
12
 
@@ -42,6 +44,4 @@ One common use would be to switch your data from one database backend to another
42
44
 
43
45
  ## Credits
44
46
 
45
- Created by Orion Henry and Adam Wiggins. Major updates by Ricardo Chimal, Jr.
46
-
47
- Patches contributed by Michael Irwin, Tom Locke, and Tim Galeckas.
47
+ Created by Orion Henry and Adam Wiggins. Major updates by Ricardo Chimal Jr. and Nate Kidwell.
@@ -6,40 +6,24 @@ namespace :db do
6
6
  task(:load => [ "db:schema:load", "db:data:load" ])
7
7
 
8
8
  namespace :data do
9
- def db_dump_data_file (extension = "yml")
10
- "#{dump_dir}/data.#{extension}"
11
- end
12
-
13
- def dump_dir(dir = "")
14
- "#{Rails.root}/db#{dir}"
15
- end
16
-
17
9
  desc "Dump contents of database to db/data.extension (defaults to yaml)"
18
10
  task :dump => :environment do
19
- format_class = ENV['class'] || "YamlDb::Helper"
20
- helper = format_class.constantize
21
- SerializationHelper::Base.new(helper).dump db_dump_data_file helper.extension
11
+ YamlDb::RakeTasks.data_dump_task
22
12
  end
23
13
 
24
14
  desc "Dump contents of database to curr_dir_name/tablename.extension (defaults to yaml)"
25
15
  task :dump_dir => :environment do
26
- format_class = ENV['class'] || "YamlDb::Helper"
27
- dir = ENV['dir'] || "#{Time.now.to_s.gsub(/ /, '_')}"
28
- SerializationHelper::Base.new(format_class.constantize).dump_to_dir dump_dir("/#{dir}")
16
+ YamlDb::RakeTasks.data_dump_dir_task
29
17
  end
30
18
 
31
19
  desc "Load contents of db/data.extension (defaults to yaml) into database"
32
20
  task :load => :environment do
33
- format_class = ENV['class'] || "YamlDb::Helper"
34
- helper = format_class.constantize
35
- SerializationHelper::Base.new(helper).load(db_dump_data_file helper.extension)
21
+ YamlDb::RakeTasks.data_load_task
36
22
  end
37
23
 
38
24
  desc "Load contents of db/data_dir into database"
39
25
  task :load_dir => :environment do
40
- dir = ENV['dir'] || "base"
41
- format_class = ENV['class'] || "YamlDb::Helper"
42
- SerializationHelper::Base.new(format_class.constantize).load_from_dir dump_dir("/#{dir}")
26
+ YamlDb::RakeTasks.data_load_dir_task
43
27
  end
44
28
  end
45
29
  end
@@ -1,19 +1,20 @@
1
1
  require 'rubygems'
2
2
  require 'yaml'
3
3
  require 'active_record'
4
- require 'serialization_helper'
5
4
  require 'active_support/core_ext/kernel/reporting'
6
5
  require 'rails/railtie'
6
+ require 'yaml_db/rake_tasks'
7
7
  require 'yaml_db/version'
8
+ require 'yaml_db/serialization_helper'
8
9
 
9
10
  module YamlDb
10
11
  module Helper
11
12
  def self.loader
12
- YamlDb::Load
13
+ Load
13
14
  end
14
15
 
15
16
  def self.dumper
16
- YamlDb::Dump
17
+ Dump
17
18
  end
18
19
 
19
20
  def self.extension
@@ -46,7 +47,7 @@ module YamlDb
46
47
 
47
48
  each_table_page(table) do |records|
48
49
  rows = SerializationHelper::Utils.unhash_records(records.to_a, column_names)
49
- io.write(YamlDb::Utils.chunk_records(rows))
50
+ io.write(Utils.chunk_records(rows))
50
51
  end
51
52
  end
52
53
 
@@ -0,0 +1,77 @@
1
+ module YamlDb
2
+ module CsvDb
3
+ module Helper
4
+ def self.loader
5
+ Load
6
+ end
7
+
8
+ def self.dumper
9
+ Dump
10
+ end
11
+
12
+ def self.extension
13
+ "csv"
14
+ end
15
+ end
16
+
17
+ class Load < SerializationHelper::Load
18
+ def self.load_documents(io, truncate = true)
19
+ tables = {}
20
+ curr_table = nil
21
+ io.each do |line|
22
+ if /BEGIN_CSV_TABLE_DECLARATION(.+)END_CSV_TABLE_DECLARATION/ =~ line
23
+ curr_table = $1
24
+ tables[curr_table] = {}
25
+ else
26
+ if tables[curr_table]["columns"]
27
+ tables[curr_table]["records"] << FasterCSV.parse(line)[0]
28
+ else
29
+ tables[curr_table]["columns"] = FasterCSV.parse(line)[0]
30
+ tables[curr_table]["records"] = []
31
+ end
32
+ end
33
+ end
34
+
35
+ tables.each_pair do |table_name, contents|
36
+ load_table(table_name, contents, truncate)
37
+ end
38
+ end
39
+ end
40
+
41
+ class Dump < SerializationHelper::Dump
42
+
43
+ def self.before_table(io,table)
44
+ io.write "BEGIN_CSV_TABLE_DECLARATION#{table}END_CSV_TABLE_DECLARATION\n"
45
+ end
46
+
47
+ def self.dump(io)
48
+ tables.each do |table|
49
+ before_table(io, table)
50
+ dump_table(io, table)
51
+ after_table(io, table)
52
+ end
53
+ end
54
+
55
+ def self.after_table(io,table)
56
+ io.write ""
57
+ end
58
+
59
+ def self.dump_table_columns(io, table)
60
+ io.write(table_column_names(table).to_csv)
61
+ end
62
+
63
+ def self.dump_table_records(io, table)
64
+
65
+ column_names = table_column_names(table)
66
+
67
+ each_table_page(table) do |records|
68
+ rows = SerializationHelper::Utils.unhash_records(records, column_names)
69
+ records.each do |record|
70
+ io.write(record.to_csv)
71
+ end
72
+ end
73
+ end
74
+
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,36 @@
1
+ module YamlDb
2
+ module RakeTasks
3
+ def self.data_dump_task
4
+ SerializationHelper::Base.new(helper).dump(db_dump_data_file(helper.extension))
5
+ end
6
+
7
+ def self.data_dump_dir_task
8
+ dir = ENV['dir'] || "#{Time.now.strftime('%F_%T')}"
9
+ SerializationHelper::Base.new(helper).dump_to_dir(dump_dir("/#{dir}"))
10
+ end
11
+
12
+ def self.data_load_task
13
+ SerializationHelper::Base.new(helper).load(db_dump_data_file(helper.extension))
14
+ end
15
+
16
+ def self.data_load_dir_task
17
+ dir = ENV['dir'] || 'base'
18
+ SerializationHelper::Base.new(helper).load_from_dir(dump_dir("/#{dir}"))
19
+ end
20
+
21
+ private
22
+
23
+ def self.db_dump_data_file(extension = 'yml')
24
+ "#{dump_dir}/data.#{extension}"
25
+ end
26
+
27
+ def self.dump_dir(dir = '')
28
+ "#{Rails.root}/db#{dir}"
29
+ end
30
+
31
+ def self.helper
32
+ format_class = ENV['class'] || 'YamlDb::Helper'
33
+ format_class.constantize
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,201 @@
1
+ module YamlDb
2
+ module SerializationHelper
3
+
4
+ class Base
5
+ attr_reader :extension
6
+
7
+ def initialize(helper)
8
+ @dumper = helper.dumper
9
+ @loader = helper.loader
10
+ @extension = helper.extension
11
+ end
12
+
13
+ def dump(filename)
14
+ disable_logger
15
+ File.open(filename, "w") do |file|
16
+ @dumper.dump(file)
17
+ end
18
+ reenable_logger
19
+ end
20
+
21
+ def dump_to_dir(dirname)
22
+ Dir.mkdir(dirname)
23
+ tables = @dumper.tables
24
+ tables.each do |table|
25
+ File.open("#{dirname}/#{table}.#{@extension}", "w") do |io|
26
+ @dumper.before_table(io, table)
27
+ @dumper.dump_table io, table
28
+ @dumper.after_table(io, table)
29
+ end
30
+ end
31
+ end
32
+
33
+ def load(filename, truncate = true)
34
+ disable_logger
35
+ @loader.load(File.new(filename, "r"), truncate)
36
+ reenable_logger
37
+ end
38
+
39
+ def load_from_dir(dirname, truncate = true)
40
+ Dir.entries(dirname).each do |filename|
41
+ if filename =~ /^[.]/
42
+ next
43
+ end
44
+ @loader.load(File.new("#{dirname}/#{filename}", "r"), truncate)
45
+ end
46
+ end
47
+
48
+ def disable_logger
49
+ @@old_logger = ActiveRecord::Base.logger
50
+ ActiveRecord::Base.logger = nil
51
+ end
52
+
53
+ def reenable_logger
54
+ ActiveRecord::Base.logger = @@old_logger
55
+ end
56
+ end
57
+
58
+ class Load
59
+ def self.load(io, truncate = true)
60
+ ActiveRecord::Base.connection.transaction do
61
+ load_documents(io, truncate)
62
+ end
63
+ end
64
+
65
+ def self.truncate_table(table)
66
+ begin
67
+ ActiveRecord::Base.connection.execute("TRUNCATE #{Utils.quote_table(table)}")
68
+ rescue Exception
69
+ ActiveRecord::Base.connection.execute("DELETE FROM #{Utils.quote_table(table)}")
70
+ end
71
+ end
72
+
73
+ def self.load_table(table, data, truncate = true)
74
+ column_names = data['columns']
75
+ if truncate
76
+ truncate_table(table)
77
+ end
78
+ load_records(table, column_names, data['records'])
79
+ reset_pk_sequence!(table)
80
+ end
81
+
82
+ def self.load_records(table, column_names, records)
83
+ if column_names.nil?
84
+ return
85
+ end
86
+ columns = column_names.map{|cn| ActiveRecord::Base.connection.columns(table).detect{|c| c.name == cn}}
87
+ quoted_column_names = column_names.map { |column| ActiveRecord::Base.connection.quote_column_name(column) }.join(',')
88
+ quoted_table_name = Utils.quote_table(table)
89
+ records.each do |record|
90
+ quoted_values = record.zip(columns).map{|c| ActiveRecord::Base.connection.quote(c.first, c.last)}.join(',')
91
+ ActiveRecord::Base.connection.execute("INSERT INTO #{quoted_table_name} (#{quoted_column_names}) VALUES (#{quoted_values})")
92
+ end
93
+ end
94
+
95
+ def self.reset_pk_sequence!(table_name)
96
+ if ActiveRecord::Base.connection.respond_to?(:reset_pk_sequence!)
97
+ ActiveRecord::Base.connection.reset_pk_sequence!(table_name)
98
+ end
99
+ end
100
+
101
+ end
102
+
103
+ module Utils
104
+
105
+ def self.unhash(hash, keys)
106
+ keys.map { |key| hash[key] }
107
+ end
108
+
109
+ def self.unhash_records(records, keys)
110
+ records.each_with_index do |record, index|
111
+ records[index] = unhash(record, keys)
112
+ end
113
+
114
+ records
115
+ end
116
+
117
+ def self.convert_booleans(records, columns)
118
+ records.each do |record|
119
+ columns.each do |column|
120
+ next if is_boolean(record[column])
121
+ record[column] = convert_boolean(record[column])
122
+ end
123
+ end
124
+ records
125
+ end
126
+
127
+ def self.convert_boolean(value)
128
+ ['t', '1', true, 1].include?(value)
129
+ end
130
+
131
+ def self.boolean_columns(table)
132
+ columns = ActiveRecord::Base.connection.columns(table).reject { |c| silence_warnings { c.type != :boolean } }
133
+ columns.map { |c| c.name }
134
+ end
135
+
136
+ def self.is_boolean(value)
137
+ value.kind_of?(TrueClass) or value.kind_of?(FalseClass)
138
+ end
139
+
140
+ def self.quote_table(table)
141
+ ActiveRecord::Base.connection.quote_table_name(table)
142
+ end
143
+
144
+ end
145
+
146
+ class Dump
147
+ def self.before_table(io, table)
148
+
149
+ end
150
+
151
+ def self.dump(io)
152
+ tables.each do |table|
153
+ before_table(io, table)
154
+ dump_table(io, table)
155
+ after_table(io, table)
156
+ end
157
+ end
158
+
159
+ def self.after_table(io, table)
160
+
161
+ end
162
+
163
+ def self.tables
164
+ ActiveRecord::Base.connection.tables.reject { |table| ['schema_info', 'schema_migrations'].include?(table) }
165
+ end
166
+
167
+ def self.dump_table(io, table)
168
+ return if table_record_count(table).zero?
169
+
170
+ dump_table_columns(io, table)
171
+ dump_table_records(io, table)
172
+ end
173
+
174
+ def self.table_column_names(table)
175
+ ActiveRecord::Base.connection.columns(table).map { |c| c.name }
176
+ end
177
+
178
+
179
+ def self.each_table_page(table, records_per_page=1000)
180
+ total_count = table_record_count(table)
181
+ pages = (total_count.to_f / records_per_page).ceil - 1
182
+ id = table_column_names(table).first
183
+ boolean_columns = Utils.boolean_columns(table)
184
+ quoted_table_name = Utils.quote_table(table)
185
+
186
+ (0..pages).to_a.each do |page|
187
+ query = Arel::Table.new(table).order(id).skip(records_per_page*page).take(records_per_page).project(Arel.sql('*'))
188
+ records = ActiveRecord::Base.connection.select_all(query.to_sql)
189
+ records = Utils.convert_booleans(records, boolean_columns)
190
+ yield records
191
+ end
192
+ end
193
+
194
+ def self.table_record_count(table)
195
+ ActiveRecord::Base.connection.select_one("SELECT COUNT(*) FROM #{Utils.quote_table(table)}").values.first.to_i
196
+ end
197
+
198
+ end
199
+
200
+ end
201
+ end
@@ -1,3 +1,3 @@
1
1
  module YamlDb
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yaml_db
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Wiggins
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-11-02 00:00:00.000000000 Z
12
+ date: 2016-07-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -20,7 +20,7 @@ dependencies:
20
20
  version: '3.0'
21
21
  - - "<"
22
22
  - !ruby/object:Gem::Version
23
- version: '4.3'
23
+ version: '5.1'
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
@@ -30,7 +30,7 @@ dependencies:
30
30
  version: '3.0'
31
31
  - - "<"
32
32
  - !ruby/object:Gem::Version
33
- version: '4.3'
33
+ version: '5.1'
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: rake
36
36
  requirement: !ruby/object:Gem::Requirement
@@ -89,7 +89,7 @@ dependencies:
89
89
  version: '1.3'
90
90
  description: |2
91
91
 
92
- YamlDb is a database-independent format for dumping and restoring data. It complements the the database-independent schema format found in db/schema.rb. The data is saved into db/data.yml.
92
+ YamlDb is a database-independent format for dumping and restoring data. It complements the database-independent schema format found in db/schema.rb. The data is saved into db/data.yml.
93
93
  This can be used as a replacement for mysqldump or pg_dump, but only for the databases typically used by Rails apps. Users, permissions, schemas, triggers, and other advanced database features are not supported - by design.
94
94
  Any database that has an ActiveRecord adapter should work.
95
95
  email:
@@ -99,11 +99,11 @@ extra_rdoc_files:
99
99
  - README.md
100
100
  files:
101
101
  - README.md
102
- - init.rb
103
- - lib/csv_db.rb
104
- - lib/serialization_helper.rb
105
102
  - lib/tasks/yaml_db_tasks.rake
106
103
  - lib/yaml_db.rb
104
+ - lib/yaml_db/csv_db.rb
105
+ - lib/yaml_db/rake_tasks.rb
106
+ - lib/yaml_db/serialization_helper.rb
107
107
  - lib/yaml_db/version.rb
108
108
  homepage: https://github.com/yamldb/yaml_db
109
109
  licenses:
@@ -125,8 +125,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
125
  version: '0'
126
126
  requirements: []
127
127
  rubyforge_project:
128
- rubygems_version: 2.4.2
128
+ rubygems_version: 2.5.2
129
129
  signing_key:
130
130
  specification_version: 4
131
131
  summary: yaml_db allows export/import of database into/from yaml files
132
132
  test_files: []
133
+ has_rdoc:
data/init.rb DELETED
@@ -1 +0,0 @@
1
- require 'yaml_db'
@@ -1,78 +0,0 @@
1
- #require 'FasterCSV'
2
- module CsvDb
3
- module Helper
4
- def self.loader
5
- Load
6
- end
7
-
8
- def self.dumper
9
- Dump
10
- end
11
-
12
- def self.extension
13
- "csv"
14
- end
15
- end
16
-
17
- class Load < SerializationHelper::Load
18
- def self.load_documents(io, truncate = true)
19
- tables = {}
20
- curr_table = nil
21
- io.each do |line|
22
- if /BEGIN_CSV_TABLE_DECLARATION(.+)END_CSV_TABLE_DECLARATION/ =~ line
23
- curr_table = $1
24
- tables[curr_table] = {}
25
- else
26
- if tables[curr_table]["columns"]
27
- tables[curr_table]["records"] << FasterCSV.parse(line)[0]
28
- else
29
- tables[curr_table]["columns"] = FasterCSV.parse(line)[0]
30
- tables[curr_table]["records"] = []
31
- end
32
- end
33
- end
34
-
35
- tables.each_pair do |table_name, contents|
36
- load_table(table_name, contents, truncate)
37
- end
38
- end
39
- end
40
-
41
- class Dump < SerializationHelper::Dump
42
-
43
- def self.before_table(io,table)
44
- io.write "BEGIN_CSV_TABLE_DECLARATION#{table}END_CSV_TABLE_DECLARATION\n"
45
- end
46
-
47
- def self.dump(io)
48
- tables.each do |table|
49
- before_table(io, table)
50
- dump_table(io, table)
51
- after_table(io, table)
52
- end
53
- end
54
-
55
- def self.after_table(io,table)
56
- io.write ""
57
- end
58
-
59
- def self.dump_table_columns(io, table)
60
- io.write(table_column_names(table).to_csv)
61
- end
62
-
63
- def self.dump_table_records(io, table)
64
-
65
- column_names = table_column_names(table)
66
-
67
- each_table_page(table) do |records|
68
- rows = SerializationHelper::Utils.unhash_records(records, column_names)
69
- records.each do |record|
70
- io.write(record.to_csv)
71
- end
72
- end
73
- end
74
-
75
- end
76
-
77
-
78
- end
@@ -1,196 +0,0 @@
1
- module SerializationHelper
2
-
3
- class Base
4
- attr_reader :extension
5
-
6
- def initialize(helper)
7
- @dumper = helper.dumper
8
- @loader = helper.loader
9
- @extension = helper.extension
10
- end
11
-
12
- def dump(filename)
13
- disable_logger
14
- @dumper.dump(File.new(filename, "w"))
15
- reenable_logger
16
- end
17
-
18
- def dump_to_dir(dirname)
19
- Dir.mkdir(dirname)
20
- tables = @dumper.tables
21
- tables.each do |table|
22
- io = File.new "#{dirname}/#{table}.#{@extension}", "w"
23
- @dumper.before_table(io, table)
24
- @dumper.dump_table io, table
25
- @dumper.after_table(io, table)
26
- end
27
- end
28
-
29
- def load(filename, truncate = true)
30
- disable_logger
31
- @loader.load(File.new(filename, "r"), truncate)
32
- reenable_logger
33
- end
34
-
35
- def load_from_dir(dirname, truncate = true)
36
- Dir.entries(dirname).each do |filename|
37
- if filename =~ /^[.]/
38
- next
39
- end
40
- @loader.load(File.new("#{dirname}/#{filename}", "r"), truncate)
41
- end
42
- end
43
-
44
- def disable_logger
45
- @@old_logger = ActiveRecord::Base.logger
46
- ActiveRecord::Base.logger = nil
47
- end
48
-
49
- def reenable_logger
50
- ActiveRecord::Base.logger = @@old_logger
51
- end
52
- end
53
-
54
- class Load
55
- def self.load(io, truncate = true)
56
- ActiveRecord::Base.connection.transaction do
57
- load_documents(io, truncate)
58
- end
59
- end
60
-
61
- def self.truncate_table(table)
62
- begin
63
- ActiveRecord::Base.connection.execute("TRUNCATE #{SerializationHelper::Utils.quote_table(table)}")
64
- rescue Exception
65
- ActiveRecord::Base.connection.execute("DELETE FROM #{SerializationHelper::Utils.quote_table(table)}")
66
- end
67
- end
68
-
69
- def self.load_table(table, data, truncate = true)
70
- column_names = data['columns']
71
- if truncate
72
- truncate_table(table)
73
- end
74
- load_records(table, column_names, data['records'])
75
- reset_pk_sequence!(table)
76
- end
77
-
78
- def self.load_records(table, column_names, records)
79
- if column_names.nil?
80
- return
81
- end
82
- columns = column_names.map{|cn| ActiveRecord::Base.connection.columns(table).detect{|c| c.name == cn}}
83
- quoted_column_names = column_names.map { |column| ActiveRecord::Base.connection.quote_column_name(column) }.join(',')
84
- quoted_table_name = SerializationHelper::Utils.quote_table(table)
85
- records.each do |record|
86
- quoted_values = record.zip(columns).map{|c| ActiveRecord::Base.connection.quote(c.first, c.last)}.join(',')
87
- ActiveRecord::Base.connection.execute("INSERT INTO #{quoted_table_name} (#{quoted_column_names}) VALUES (#{quoted_values})")
88
- end
89
- end
90
-
91
- def self.reset_pk_sequence!(table_name)
92
- if ActiveRecord::Base.connection.respond_to?(:reset_pk_sequence!)
93
- ActiveRecord::Base.connection.reset_pk_sequence!(table_name)
94
- end
95
- end
96
-
97
- end
98
-
99
- module Utils
100
-
101
- def self.unhash(hash, keys)
102
- keys.map { |key| hash[key] }
103
- end
104
-
105
- def self.unhash_records(records, keys)
106
- records.each_with_index do |record, index|
107
- records[index] = unhash(record, keys)
108
- end
109
-
110
- records
111
- end
112
-
113
- def self.convert_booleans(records, columns)
114
- records.each do |record|
115
- columns.each do |column|
116
- next if is_boolean(record[column])
117
- record[column] = convert_boolean(record[column])
118
- end
119
- end
120
- records
121
- end
122
-
123
- def self.convert_boolean(value)
124
- ['t', '1', true, 1].include?(value)
125
- end
126
-
127
- def self.boolean_columns(table)
128
- columns = ActiveRecord::Base.connection.columns(table).reject { |c| silence_warnings { c.type != :boolean } }
129
- columns.map { |c| c.name }
130
- end
131
-
132
- def self.is_boolean(value)
133
- value.kind_of?(TrueClass) or value.kind_of?(FalseClass)
134
- end
135
-
136
- def self.quote_table(table)
137
- ActiveRecord::Base.connection.quote_table_name(table)
138
- end
139
-
140
- end
141
-
142
- class Dump
143
- def self.before_table(io, table)
144
-
145
- end
146
-
147
- def self.dump(io)
148
- tables.each do |table|
149
- before_table(io, table)
150
- dump_table(io, table)
151
- after_table(io, table)
152
- end
153
- end
154
-
155
- def self.after_table(io, table)
156
-
157
- end
158
-
159
- def self.tables
160
- ActiveRecord::Base.connection.tables.reject { |table| ['schema_info', 'schema_migrations'].include?(table) }
161
- end
162
-
163
- def self.dump_table(io, table)
164
- return if table_record_count(table).zero?
165
-
166
- dump_table_columns(io, table)
167
- dump_table_records(io, table)
168
- end
169
-
170
- def self.table_column_names(table)
171
- ActiveRecord::Base.connection.columns(table).map { |c| c.name }
172
- end
173
-
174
-
175
- def self.each_table_page(table, records_per_page=1000)
176
- total_count = table_record_count(table)
177
- pages = (total_count.to_f / records_per_page).ceil - 1
178
- id = table_column_names(table).first
179
- boolean_columns = SerializationHelper::Utils.boolean_columns(table)
180
- quoted_table_name = SerializationHelper::Utils.quote_table(table)
181
-
182
- (0..pages).to_a.each do |page|
183
- query = Arel::Table.new(table, ActiveRecord::Base).order(id).skip(records_per_page*page).take(records_per_page).project(Arel.sql('*'))
184
- records = ActiveRecord::Base.connection.select_all(query.to_sql)
185
- records = SerializationHelper::Utils.convert_booleans(records, boolean_columns)
186
- yield records
187
- end
188
- end
189
-
190
- def self.table_record_count(table)
191
- ActiveRecord::Base.connection.select_one("SELECT COUNT(*) FROM #{SerializationHelper::Utils.quote_table(table)}").values.first.to_i
192
- end
193
-
194
- end
195
-
196
- end