ndr_import 11.7.0 → 11.8.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
  SHA256:
3
- metadata.gz: 42a13d9464123749bb78650658d058a47b23f59c75d611c2bebe127a056e705c
4
- data.tar.gz: ba30f77ba569506765a14d514e0b021a9d30a0f097fab18b38dc002ff6c53634
3
+ metadata.gz: c16e2b4fa7494365c5c55d5b8947641a3396cd58bf53ae6914525554cdf565a1
4
+ data.tar.gz: ca00a216b0bf6542e03777c60b26a41b2824c3902da8b3bee2bd12369b3e0197
5
5
  SHA512:
6
- metadata.gz: 94ac6dd14da96864fb812129036ee81a2715fef3b464279e43341434f4a70cf82142a89abbc324d0b9ce6a9a784e89c60422c5a6176073b635b49997977ad4e2
7
- data.tar.gz: 56b8b030cea738fdf43e654cc91251a5eefd7a6ee3b58e5482d4c6a8cc8a1484b48a9a2e04ba84f80599f67725400e93d3aae3533ee617b141069dc18b443886
6
+ metadata.gz: b0fa0f74a4c2a1cf3d036a26aa60e186b56531fb3d4328c68ead64b6d8fc81a046f7eca633f5e9acd149121debae3ecf67f83d52f7a56ad316da46f1b963a9ff
7
+ data.tar.gz: e9f9a6adb560d9d5fce254e9a33a869dfeb57e4121b2ecb8a6b4d501b9b4bc965021805e912eb7dad37f899bf3eeb0340367f1232a595580cfcef6bef1960a32
data/CHANGELOG.md CHANGED
@@ -1,6 +1,19 @@
1
1
  ## [Unreleased]
2
2
  * no unreleased changes
3
3
 
4
+ ## 11.8.0 / 2026-11-03
5
+ ### Added
6
+ * Support Gzip/gz
7
+
8
+ ### Changed
9
+ * Removed deprecated `CSVLibrary`
10
+ * Minimum `rubyzip` version is now 2.4
11
+
12
+ ### Fixed
13
+ * Drop support for Rails 7.1, 7.2
14
+ * Fix bug in VCF metadata
15
+ * Fix bug where table columns are mutated by a regexp column
16
+
4
17
  ## 11.7.0 / 2026-09-24
5
18
  ### Added
6
19
  * Added the ability to define a virtual :filename column
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # NdrImport [![Build Status](https://github.com/NHSDigital/ndr_import/workflows/Test/badge.svg)](https://github.com/NHSDigital/ndr_import/actions?query=workflow%3Atest) [![Gem Version](https://badge.fury.io/rb/ndr_import.svg)](https://rubygems.org/gems/ndr_import) [![Documentation](https://img.shields.io/badge/ndr_import-docs-blue.svg)](https://www.rubydoc.info/gems/ndr_import)
2
2
  This is the NHS Digital (NHSD) National Disease Registers (NDR) Import ETL ruby gem, providing:
3
3
 
4
- 1. file import handlers for *extracting* data from delimited files (csv, pipe, tab, thorn), JSON Lines, .xls(x) spreadsheets, .doc(x) word documents, PDF, PDF AcroForms, XML, 7-Zip, Zip, avro and VCF files.
4
+ 1. file import handlers for *extracting* data from delimited files (csv, pipe, tab, thorn), JSON Lines, .xls(x) spreadsheets, .doc(x) word documents, PDF, PDF AcroForms, XML, 7-Zip, Zip, gzip, avro and VCF files.
5
5
  2. table mappers for *transforming* tabular and non-tabular data into key value pairs grouped by a common "klass".
6
6
 
7
7
  ## Installation
@@ -0,0 +1,13 @@
1
+ require 'csv'
2
+
3
+ # Forward port CSV::Cell, as it is sometimes
4
+ # serialised in YAML. :-(
5
+ class CSV::Cell < String
6
+ def initialize(data = '', is_null = false)
7
+ super(is_null ? '' : data)
8
+ end
9
+
10
+ def data
11
+ to_s
12
+ end
13
+ end
@@ -3,6 +3,7 @@ require_relative 'acro_form'
3
3
  require_relative 'avro'
4
4
  require_relative 'delimited'
5
5
  require_relative 'docx'
6
+ require_relative 'gzip'
6
7
  require_relative 'excel'
7
8
  require_relative 'pdf'
8
9
  require_relative 'seven_zip'
@@ -1,6 +1,6 @@
1
1
  require 'active_support/core_ext/hash'
2
2
  require 'ndr_support/safe_file'
3
- require 'ndr_import/csv_library'
3
+ require 'ndr_import/csv_cell'
4
4
  require_relative 'registry'
5
5
 
6
6
  module NdrImport
@@ -1,5 +1,5 @@
1
1
  require 'ndr_support/safe_file'
2
- require 'ndr_import/csv_library'
2
+ require 'ndr_import/csv_cell'
3
3
  require 'ndr_import/helpers/file/delimited'
4
4
  require_relative 'registry'
5
5
 
@@ -0,0 +1,66 @@
1
+ require 'securerandom'
2
+ require 'zlib'
3
+ require 'ndr_support/safe_file'
4
+ require_relative 'registry'
5
+
6
+ module NdrImport
7
+ # This is one of a collection of file handlers that deal with individual formats of data.
8
+ # They can be instantiated directly or via the factory method Registry.tables
9
+ module File
10
+ # This class is a gzip file handler that returns tables from the decompressed file. It also
11
+ # handles bgzip files (e.g. .vcf.gz), which are a series of gzip members.
12
+ class Gzip < Base
13
+ def initialize(filename, format, options = {})
14
+ super
15
+ @unzip_path = options['unzip_path']
16
+
17
+ validate_unzip_path_is_safe!
18
+ end
19
+
20
+ def files(&block)
21
+ fail 'Not allowed in external environment' if defined?(::Rails) && ::Rails.env.external?
22
+
23
+ return enum_for(:files) unless block
24
+
25
+ destination = unique_destination
26
+ FileUtils.mkdir_p(SafeFile.safepath_to_string(destination))
27
+
28
+ # e.g. sample.vcf.gz is decompressed to sample.vcf
29
+ basename = ::File.basename(SafeFile.safepath_to_string(@filename), '.gz')
30
+ decompressed_filename = destination.join(basename)
31
+ decompress(decompressed_filename)
32
+
33
+ Registry.files(decompressed_filename, @options).each(&block)
34
+ end
35
+
36
+ # Gzip files produce files, never tables.
37
+ def tables
38
+ fail 'Gzip#tables should never be called'
39
+ end
40
+
41
+ private
42
+
43
+ # A new folder to decompress into. The time alone isn't unique: two decompressions in the
44
+ # same millisecond (e.g. consecutive tests, or two imports) would share a folder and collide.
45
+ def unique_destination
46
+ @unzip_path.join("#{Time.current.strftime('%H%M%S%L')}_#{SecureRandom.hex(4)}")
47
+ end
48
+
49
+ # zcat reads every gzip member. GzipReader#read stops after the first, which would silently
50
+ # read only the first block of a bgzip file.
51
+ def decompress(decompressed_filename)
52
+ ::File.open(SafeFile.safepath_to_string(@filename), 'rb') do |input|
53
+ ::File.open(SafeFile.safepath_to_string(decompressed_filename), 'wb') do |output|
54
+ Zlib::GzipReader.zcat(input) { |chunk| output.write(chunk) }
55
+ end
56
+ end
57
+ end
58
+
59
+ def validate_unzip_path_is_safe!
60
+ SafeFile.safepath_to_string(@unzip_path)
61
+ end
62
+ end
63
+
64
+ Registry.register(Gzip, 'gz')
65
+ end
66
+ end
@@ -1,3 +1,4 @@
1
+ require 'securerandom'
1
2
  require 'zip'
2
3
  require 'ndr_support/safe_file'
3
4
  require_relative 'registry'
@@ -21,7 +22,7 @@ module NdrImport
21
22
 
22
23
  return enum_for(:files) unless block
23
24
 
24
- destination = @unzip_path.join(Time.current.strftime('%H%M%S%L'))
25
+ destination = unique_destination
25
26
  FileUtils.mkdir_p(SafeFile.safepath_to_string(destination))
26
27
 
27
28
  ::Zip::File.open(SafeFile.safepath_to_string(@filename)) do |zipfile|
@@ -36,6 +37,12 @@ module NdrImport
36
37
 
37
38
  private
38
39
 
40
+ # A new folder to extract into. The time alone isn't unique: two extractions in the same
41
+ # millisecond (e.g. consecutive tests, or two imports) would share a folder and collide.
42
+ def unique_destination
43
+ @unzip_path.join("#{Time.current.strftime('%H%M%S%L')}_#{SecureRandom.hex(4)}")
44
+ end
45
+
39
46
  # Unzip the zip file entry and enumerate over it
40
47
  def unzip_entries(zipfile, destination, &block)
41
48
  zipfile.entries.each do |entry|
@@ -1,5 +1,5 @@
1
1
  require 'ndr_support/safe_file'
2
- require 'ndr_import/csv_library'
2
+ require 'ndr_import/csv_cell'
3
3
 
4
4
  module NdrImport
5
5
  module Helpers
@@ -81,7 +81,7 @@ module NdrImport
81
81
  next if e.message =~ /invalid multibyte character/ # This encoding didn't work
82
82
 
83
83
  raise(e)
84
- rescue CSVLibrary::MalformedCSVError => e
84
+ rescue CSV::MalformedCSVError => e
85
85
  next if e.message =~ /Invalid byte sequence/ # This encoding didn't work
86
86
 
87
87
  raise malformed_csv_error(e, col_sep, row_num + 1, safe_path)
@@ -50,6 +50,7 @@ module NdrImport
50
50
  @row_index = 0
51
51
  @header_valid = false
52
52
  @header_best_guess = nil
53
+ reset_regexp_columns
53
54
  @notifier.try(:started)
54
55
 
55
56
  last_col = last_column_to_transform
@@ -80,13 +81,19 @@ module NdrImport
80
81
  @notifier.try(:processed, @row_index)
81
82
  end
82
83
 
83
- # Update 'column' values expressed as a regular expression
84
+ # Update 'column' values expressed as a regular expression to the header they match in this
85
+ # file. The patterns themselves are kept (see regexp_column_patterns), so the next file is
86
+ # matched afresh.
84
87
  def mutate_regexp_columns(line)
85
- @columns.each_with_index do |column, index|
86
- next unless column['column'].is_a? Regexp
88
+ return if regexp_column_patterns.empty?
87
89
 
88
- column['column'] = line[index] if line[index].match? column['column']
90
+ @columns = @columns.each_with_index.map do |column, index|
91
+ pattern = regexp_column_patterns[index]
92
+ next column unless pattern && line[index].to_s.match?(pattern)
93
+
94
+ column.merge('column' => line[index])
89
95
  end
96
+ @masked_mappings = nil
90
97
  end
91
98
 
92
99
  # This method transforms an incoming line of data by applying each of the klass masked
@@ -120,11 +127,40 @@ module NdrImport
120
127
  value = send(option)
121
128
  coder[option] = value if value
122
129
  end
123
- coder['columns'] = @columns
130
+ coder['columns'] = columns_with_regexp_patterns
124
131
  end
125
132
 
126
133
  private
127
134
 
135
+ # The 'column' values given as regular expressions, by column index, captured before any
136
+ # are replaced with a matched header. Memoised lazily rather than in initialize, so it also
137
+ # works for tables loaded from YAML, which don't call initialize.
138
+ def regexp_column_patterns
139
+ @regexp_column_patterns ||=
140
+ Array(@columns).each_with_index.with_object({}) do |(column, index), patterns|
141
+ patterns[index] = column['column'] if column && column['column'].is_a?(Regexp)
142
+ end
143
+ end
144
+
145
+ # Puts the original regular expressions back, so a new file is matched against them
146
+ def reset_regexp_columns
147
+ return if regexp_column_patterns.empty?
148
+
149
+ @columns = columns_with_regexp_patterns
150
+ @masked_mappings = nil
151
+ end
152
+
153
+ # The columns, with any 'column' values given as regular expressions restored. Unchanged
154
+ # (including nil, for a table with no columns) when there are none.
155
+ def columns_with_regexp_patterns
156
+ return @columns if regexp_column_patterns.empty?
157
+
158
+ Array(@columns).each_with_index.map do |column, index|
159
+ pattern = regexp_column_patterns[index]
160
+ pattern ? column.merge('column' => pattern) : column
161
+ end
162
+ end
163
+
128
164
  # This method uses a buffer to not yield the last <buffer_size> iterations of an enumerable.
129
165
  # We use it to skip footer lines (without having to convert the enumerable to an array).
130
166
  def skip_footer_lines(lines, buffer_size)
@@ -5,10 +5,14 @@ module NdrImport
5
5
  # Syntatic sugar to ensure `header_lines` and `footer_lines` are 1 and 0 respectively.
6
6
  # All other Table logic is inherited from `NdrImport::Table`
7
7
  class Table < ::NdrImport::Table
8
+ VCF_OPTIONS = %w[vcf_file_metadata].freeze
9
+
8
10
  def self.all_valid_options
9
- super - %w[delimiter header_lines footer_lines] + %w[vcf_file_metadata]
11
+ super - %w[delimiter header_lines footer_lines] + VCF_OPTIONS
10
12
  end
11
13
 
14
+ attr_reader(*VCF_OPTIONS)
15
+
12
16
  def header_lines
13
17
  1
14
18
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  # This stores the current version of the NdrImport gem
3
3
  module NdrImport
4
- VERSION = '11.7.0'
4
+ VERSION = '11.8.0'
5
5
  end
data/lib/ndr_import.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'ndr_import/version'
2
- require 'ndr_import/csv_library'
2
+ require 'ndr_import/csv_cell'
3
3
  require 'ndr_import/mapping_error'
4
4
  require 'ndr_import/missing_field_error'
5
5
  require 'ndr_import/mapper'
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ndr_import
3
3
  version: !ruby/object:Gem::Version
4
- version: 11.7.0
4
+ version: 11.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - NCRS Development Team
8
+ autorequire:
8
9
  bindir: exe
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-11-04 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: activemodel
@@ -29,7 +30,7 @@ dependencies:
29
30
  requirements:
30
31
  - - ">="
31
32
  - !ruby/object:Gem::Version
32
- version: '7.1'
33
+ version: '8.0'
33
34
  - - "<"
34
35
  - !ruby/object:Gem::Version
35
36
  version: '8.2'
@@ -39,7 +40,7 @@ dependencies:
39
40
  requirements:
40
41
  - - ">="
41
42
  - !ruby/object:Gem::Version
42
- version: '7.1'
43
+ version: '8.0'
43
44
  - - "<"
44
45
  - !ruby/object:Gem::Version
45
46
  version: '8.2'
@@ -89,7 +90,7 @@ dependencies:
89
90
  requirements:
90
91
  - - ">="
91
92
  - !ruby/object:Gem::Version
92
- version: '2.0'
93
+ version: '2.4'
93
94
  - - "<"
94
95
  - !ruby/object:Gem::Version
95
96
  version: '4'
@@ -99,7 +100,7 @@ dependencies:
99
100
  requirements:
100
101
  - - ">="
101
102
  - !ruby/object:Gem::Version
102
- version: '2.0'
103
+ version: '2.4'
103
104
  - - "<"
104
105
  - !ruby/object:Gem::Version
105
106
  version: '4'
@@ -107,16 +108,22 @@ dependencies:
107
108
  name: avro
108
109
  requirement: !ruby/object:Gem::Requirement
109
110
  requirements:
110
- - - "~>"
111
+ - - ">="
111
112
  - !ruby/object:Gem::Version
112
113
  version: 1.11.0
114
+ - - "<"
115
+ - !ruby/object:Gem::Version
116
+ version: '1.13'
113
117
  type: :runtime
114
118
  prerelease: false
115
119
  version_requirements: !ruby/object:Gem::Requirement
116
120
  requirements:
117
- - - "~>"
121
+ - - ">="
118
122
  - !ruby/object:Gem::Version
119
123
  version: 1.11.0
124
+ - - "<"
125
+ - !ruby/object:Gem::Version
126
+ version: '1.13'
120
127
  - !ruby/object:Gem::Dependency
121
128
  name: bio-vcf
122
129
  requirement: !ruby/object:Gem::Requirement
@@ -284,21 +291,21 @@ dependencies:
284
291
  - !ruby/object:Gem::Version
285
292
  version: '0'
286
293
  - !ruby/object:Gem::Dependency
287
- name: rake
294
+ name: guard
288
295
  requirement: !ruby/object:Gem::Requirement
289
296
  requirements:
290
297
  - - ">="
291
298
  - !ruby/object:Gem::Version
292
- version: 12.3.3
299
+ version: '0'
293
300
  type: :development
294
301
  prerelease: false
295
302
  version_requirements: !ruby/object:Gem::Requirement
296
303
  requirements:
297
304
  - - ">="
298
305
  - !ruby/object:Gem::Version
299
- version: 12.3.3
306
+ version: '0'
300
307
  - !ruby/object:Gem::Dependency
301
- name: minitest
308
+ name: guard-rubocop
302
309
  requirement: !ruby/object:Gem::Requirement
303
310
  requirements:
304
311
  - - ">="
@@ -312,7 +319,7 @@ dependencies:
312
319
  - !ruby/object:Gem::Version
313
320
  version: '0'
314
321
  - !ruby/object:Gem::Dependency
315
- name: mocha
322
+ name: guard-test
316
323
  requirement: !ruby/object:Gem::Requirement
317
324
  requirements:
318
325
  - - ">="
@@ -326,21 +333,21 @@ dependencies:
326
333
  - !ruby/object:Gem::Version
327
334
  version: '0'
328
335
  - !ruby/object:Gem::Dependency
329
- name: ndr_dev_support
336
+ name: minitest
330
337
  requirement: !ruby/object:Gem::Requirement
331
338
  requirements:
332
339
  - - ">="
333
340
  - !ruby/object:Gem::Version
334
- version: 3.1.3
341
+ version: '0'
335
342
  type: :development
336
343
  prerelease: false
337
344
  version_requirements: !ruby/object:Gem::Requirement
338
345
  requirements:
339
346
  - - ">="
340
347
  - !ruby/object:Gem::Version
341
- version: 3.1.3
348
+ version: '0'
342
349
  - !ruby/object:Gem::Dependency
343
- name: guard
350
+ name: mocha
344
351
  requirement: !ruby/object:Gem::Requirement
345
352
  requirements:
346
353
  - - ">="
@@ -354,35 +361,35 @@ dependencies:
354
361
  - !ruby/object:Gem::Version
355
362
  version: '0'
356
363
  - !ruby/object:Gem::Dependency
357
- name: guard-rubocop
364
+ name: ndr_dev_support
358
365
  requirement: !ruby/object:Gem::Requirement
359
366
  requirements:
360
367
  - - ">="
361
368
  - !ruby/object:Gem::Version
362
- version: '0'
369
+ version: 3.1.3
363
370
  type: :development
364
371
  prerelease: false
365
372
  version_requirements: !ruby/object:Gem::Requirement
366
373
  requirements:
367
374
  - - ">="
368
375
  - !ruby/object:Gem::Version
369
- version: '0'
376
+ version: 3.1.3
370
377
  - !ruby/object:Gem::Dependency
371
- name: guard-test
378
+ name: rake
372
379
  requirement: !ruby/object:Gem::Requirement
373
380
  requirements:
374
381
  - - ">="
375
382
  - !ruby/object:Gem::Version
376
- version: '0'
383
+ version: 12.3.3
377
384
  type: :development
378
385
  prerelease: false
379
386
  version_requirements: !ruby/object:Gem::Requirement
380
387
  requirements:
381
388
  - - ">="
382
389
  - !ruby/object:Gem::Version
383
- version: '0'
390
+ version: 12.3.3
384
391
  - !ruby/object:Gem::Dependency
385
- name: terminal-notifier-guard
392
+ name: simplecov
386
393
  requirement: !ruby/object:Gem::Requirement
387
394
  requirements:
388
395
  - - ">="
@@ -396,7 +403,7 @@ dependencies:
396
403
  - !ruby/object:Gem::Version
397
404
  version: '0'
398
405
  - !ruby/object:Gem::Dependency
399
- name: simplecov
406
+ name: terminal-notifier-guard
400
407
  requirement: !ruby/object:Gem::Requirement
401
408
  requirements:
402
409
  - - ">="
@@ -430,7 +437,7 @@ files:
430
437
  - lib/ndr_import.rb
431
438
  - lib/ndr_import/acroform_reader.rb
432
439
  - lib/ndr_import/avro/table.rb
433
- - lib/ndr_import/csv_library.rb
440
+ - lib/ndr_import/csv_cell.rb
434
441
  - lib/ndr_import/file/acro_form.rb
435
442
  - lib/ndr_import/file/all.rb
436
443
  - lib/ndr_import/file/avro.rb
@@ -438,6 +445,7 @@ files:
438
445
  - lib/ndr_import/file/delimited.rb
439
446
  - lib/ndr_import/file/docx.rb
440
447
  - lib/ndr_import/file/excel.rb
448
+ - lib/ndr_import/file/gzip.rb
441
449
  - lib/ndr_import/file/json_lines.rb
442
450
  - lib/ndr_import/file/office_file_helper.rb
443
451
  - lib/ndr_import/file/pdf.rb
@@ -482,6 +490,7 @@ homepage: https://github.com/NHSDigital/ndr_import
482
490
  licenses:
483
491
  - MIT
484
492
  metadata: {}
493
+ post_install_message:
485
494
  rdoc_options: []
486
495
  require_paths:
487
496
  - lib
@@ -496,7 +505,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
496
505
  - !ruby/object:Gem::Version
497
506
  version: '0'
498
507
  requirements: []
499
- rubygems_version: 3.6.9
508
+ rubygems_version: 3.5.22
509
+ signing_key:
500
510
  specification_version: 4
501
511
  summary: NDR Import
502
512
  test_files: []
@@ -1,74 +0,0 @@
1
- # This file allows us to choose the CSV library we want to use.
2
-
3
- require 'csv'
4
- require 'active_support/deprecation'
5
-
6
- # Using relevant core CSV library.
7
- class CSVLibrary < CSV; end
8
-
9
- class << CSVLibrary
10
- # Is the library we're using FasterCSV?
11
- def fastercsv?
12
- deprecate('if you desparately want fastercsv, please use it explicitly')
13
- not self.const_defined?(:Reader)
14
- end
15
-
16
- # Ensure that we can pass "mode" straight through the underlying IO object
17
- #
18
- # Note: this could likely be refactored now, as upstream support for something
19
- # very similar was added:
20
- #
21
- # https://github.com/ruby/csv/commit/b4edaf2cf1aa36f5c6264c07514b66739b87ceee
22
- #
23
- def foreach(path, **options, &block)
24
- deprecate('CSV#foreach exists, with an optional `mode` argument')
25
- return to_enum(__method__, path, **options) unless block
26
- open(path, options.delete(:mode) || 'r', **options) do |csv|
27
- csv.each(&block)
28
- end
29
- end
30
-
31
- def write_csv_to_string(data)
32
- deprecate('write_csv_to_string -> generate')
33
- self.generate do |csv|
34
- data.each { |line| csv << line }
35
- end
36
- end
37
-
38
- def write_csv_to_file(data, filepath, mode = 'w')
39
- deprecate('write_csv_to_file -> open')
40
- self.open(filepath, mode) do |csv|
41
- data.each { |line| csv << line }
42
- end
43
- end
44
-
45
- def read_csv_from_file(filepath)
46
- deprecate('read_csv_from_file -> read')
47
- self.read(filepath)
48
- end
49
-
50
- private
51
-
52
- def deprecator
53
- @deprecator ||= ActiveSupport::Deprecation.new(NdrImport::VERSION, 'NdrImport')
54
- end
55
-
56
- def deprecate(additional_message = nil)
57
- deprecator.warn(<<~MESSAGE)
58
- CSVLibrary is deprecated, and will be removed in a future version of ndr_import.
59
- Please use standard functionality provided by Ruby's CSV library (#{additional_message}).
60
- MESSAGE
61
- end
62
- end
63
-
64
- # Forward port CSV::Cell, as it is sometimes
65
- # serialised in YAML. :-(
66
- class CSV::Cell < String
67
- def initialize(data = '', is_null = false)
68
- super(is_null ? '' : data)
69
- end
70
-
71
- def data
72
- to_s
73
- end
74
- end