sequel-from_csv 0.1.2 → 0.2.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
- SHA1:
3
- metadata.gz: c509d23016e8e8322ca15d6698fc264dd2742455
4
- data.tar.gz: fa28138de74f186e4629d4805b629a06149794df
2
+ SHA256:
3
+ metadata.gz: 3706abc5bcbc730c436d702292e8a7ace38ad3419c73ae9deb82f6b6cc0e3b56
4
+ data.tar.gz: 759e60fa7eec0007d63df5eef240917dad0174ee9b86f5a4ebba5b7d8b8fb09e
5
5
  SHA512:
6
- metadata.gz: 470ee8941735710910d0ae3161b92736de5132f1ec7427b2bb18a7adeb6a6c70f5e35fcd8088aece5bf107028aa3af68d885e8ea5c49bc3d062611adb71b7b76
7
- data.tar.gz: a9d03c786efa839139f7e965cb579145b9beec4c10a828116061271842531ff7417f57de19dae8b03bb20454db1e74a841ef79d18fd9469962663e0aa6f6fa25
6
+ metadata.gz: 8dfbd463ee485c63aba9e405d9b3fed23fa4578bf5ff9109d3521af5162dc531c8c6f3a4ea4a2be6480e2dd7737a43c53c23c9e1e0a667f0f3cf2903cc707574
7
+ data.tar.gz: f148140f6ad0c12deb8ec902e415cf5575f6226d7d617e2c5a2a67454a2b0598295a1a9dc3c82bf43d9b7f020eb853173fefb9eb9a134d18ecd1803efc6576ce
@@ -0,0 +1,2 @@
1
+ require "sequel/extensions/from_csv"
2
+ require "sequel/plugins/from_csv"
@@ -2,7 +2,21 @@ module Sequel
2
2
  module Extensions
3
3
  module FromCsv
4
4
 
5
- # Finds all CSV files in a directory and synchronizes with their respective DB tables
5
+ # Finds all CSV files recursively within a directory and calls #seed_from_csv on their respective models
6
+ #
7
+ # Calling #seed_from_csv with a directory contaning:
8
+ # - artists.csv
9
+ # - artist/has_albums.csv
10
+ #
11
+ # Would be equivalent to calling:
12
+ # Artist.seed_from_csv "artists.csv"
13
+ # Artist::HasAlbum.seed_from_csv "artist/has_albums.csv"
14
+ #
15
+ # *Options:*
16
+ # :delete_missing :: whether to remove rows from the table that were not found in the CSV file
17
+ # :reset_sequence :: whether to update the primary key's sequence to reflect the max primary key value
18
+ #
19
+ # :reset_sequence only works on PostgreSQL tables that auto-increment their primary keys using sequences
6
20
  def seed_from_csv directory, **opts
7
21
 
8
22
  Dir.glob("#{directory}/**/*.csv").each do |filename|
@@ -22,7 +36,6 @@ module Sequel
22
36
  end
23
37
 
24
38
  end
25
-
26
39
  end
27
- Database.register_extension(:from_csv, Extensions::FromCsv)
40
+ Database.register_extension :from_csv, Extensions::FromCsv
28
41
  end
@@ -3,17 +3,48 @@ require 'csv'
3
3
  module Sequel
4
4
  module Plugins
5
5
  module FromCsv
6
+
7
+ class MissingDataException < StandardError; end
8
+ class MissingFieldException < StandardError; end
9
+ class NotYetImplementedException < StandardError; end
10
+
6
11
  module ClassMethods
7
12
 
8
- # Synchronizes a table's data with a CSV file
9
- def seed_from_csv csv_path, delete_missing: false, reset_sequence: true
13
+ # Synchronizes a table's data with a CSV file. Returns self.
14
+ #
15
+ # The table being synchronized must contain exactly one primary key column, and the CSV file used
16
+ # must contain the primary key column as one of its fields.
17
+ #
18
+ # *Options:*
19
+ # :delete_missing :: whether to remove rows from the table that were not found in the CSV file
20
+ # :reset_sequence :: whether to update the primary key's sequence to reflect the max primary key value
21
+ #
22
+ # :reset_sequence only works on PostgreSQL tables that auto-increment their primary keys using sequences
23
+ #
24
+ # *Usage:*
25
+ # class Artist < Sequel::Model
26
+ # plugin :from_csv
27
+ # end
28
+ # Artist.seed_from_csv "seeds/artists.csv", reset_sequence: true
29
+ def seed_from_csv csv_path, delete_missing: false, reset_sequence: false
10
30
 
11
31
  # Read the source CSV file
12
- data = CSV.table csv_path
32
+ data = CSV.table csv_path, converters: :date_time
33
+
34
+ # Guard against CSV files that have headers but not data (to handle a quirk in Ruby's CSV parser)
35
+ if data.headers.empty?
36
+ raise MissingDataException, "CSV file #{csv_path} did not contain any data rows"
37
+ end
38
+
39
+ # Check that all primary key columns are present
40
+ pk = self.primary_key
41
+ if Array === pk
42
+ raise NotYetImplementedException, "Sequel::Plugins::FromCsv does not yet support composite primary keys."
43
+ end
13
44
 
14
45
  # Ensure the ID column exists
15
- unless data.first[:id]
16
- raise "CSV file #{csv_path} must contain an id column"
46
+ unless data.headers.include? pk
47
+ raise MissingFieldException, "CSV file #{csv_path} must contain a column named '#{pk}'"
17
48
  end
18
49
 
19
50
  self.db.transaction do
@@ -21,12 +52,12 @@ module Sequel
21
52
  # UPSERT
22
53
  data.each do |row|
23
54
  row = row.to_h # Convert CSV::Row to Hash
24
- self.dataset.insert_conflict(target: :id, update: row).insert row
55
+ self.dataset.insert_conflict(target: pk, update: row).insert row
25
56
  end
26
57
 
27
58
  # DELETE old rows
28
59
  if delete_missing
29
- self.exclude("id IN ?", data.map{|row| row[:id]}).delete
60
+ self.exclude(pk => data.map{|row| row[pk]}).delete
30
61
  end
31
62
 
32
63
  # Update the table's sequence
@@ -35,7 +66,7 @@ module Sequel
35
66
  when :postgres
36
67
  self.db.run <<~SQL
37
68
  SELECT
38
- setval(pg_get_serial_sequence('#{self.simple_table}', 'id'), coalesce(max(id), 1), true)
69
+ setval(pg_get_serial_sequence('#{self.simple_table}', '#{pk}'), greatest(max(#{pk}), 1), true)
39
70
  FROM
40
71
  #{self.simple_table}
41
72
  SQL
@@ -44,9 +75,13 @@ module Sequel
44
75
 
45
76
  end
46
77
 
78
+ # Should return itself
79
+ self
80
+
47
81
  end
48
82
 
49
83
  end
84
+
50
85
  end
51
86
  end
52
87
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel-from_csv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenaniah Cerny
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-22 00:00:00.000000000 Z
11
+ date: 2018-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -38,6 +38,76 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pg
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: appraisal
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest-hooks
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: minitest-reporters
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
41
111
  - !ruby/object:Gem::Dependency
42
112
  name: bundler
43
113
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +136,20 @@ dependencies:
66
136
  - - ">="
67
137
  - !ruby/object:Gem::Version
68
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: pry
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
69
153
  description:
70
154
  email:
71
155
  - kenaniah@gmail.com
@@ -73,6 +157,7 @@ executables: []
73
157
  extensions: []
74
158
  extra_rdoc_files: []
75
159
  files:
160
+ - lib/sequel-from_csv.rb
76
161
  - lib/sequel/extensions/from_csv.rb
77
162
  - lib/sequel/plugins/from_csv.rb
78
163
  homepage: https://github.com/kenaniah/sequel-from_csv
@@ -86,7 +171,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
86
171
  requirements:
87
172
  - - ">="
88
173
  - !ruby/object:Gem::Version
89
- version: '0'
174
+ version: 2.3.0
90
175
  required_rubygems_version: !ruby/object:Gem::Requirement
91
176
  requirements:
92
177
  - - ">="
@@ -94,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
179
  version: '0'
95
180
  requirements: []
96
181
  rubyforge_project:
97
- rubygems_version: 2.6.8
182
+ rubygems_version: 2.7.6
98
183
  signing_key:
99
184
  specification_version: 4
100
185
  summary: A simple way to seed and synchronize table data using CSV files