sequel-from_csv 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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