dbf 4.2.4 → 4.3.1

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: 458e14a93544a7b6ade6746332bcf39731780bd9af34aebee260e6abcca9543c
4
- data.tar.gz: b0d645e6728a885db8d7a98c45f7be8aa9383561bae0b088f9b5b2dc6f1e6284
3
+ metadata.gz: 8d40b6c4a0c614eda7638ef810b682b3ee767153b95cc4075d90c1f12937e57c
4
+ data.tar.gz: 6b74646387585dc0d497181d2253324cf92717b217b6642f5a1e307a7413e557
5
5
  SHA512:
6
- metadata.gz: 3c8541239362433b39e376576b46469af9359982b1b8679dd7661e622510cd8be953bfbe0529b9b14b1f8695c172c5376e4f03b38fa4448dde1ea01ab90c2cff
7
- data.tar.gz: 71da6ab478a3c8aa66dc5297df731906bbb34970360639dd9b5ae7fa4bb98c93ff3d043a1e2d70f2e01059178f6e8e3d99f6299cf8a9fe2109bf8e9dec52b332
6
+ metadata.gz: 98414f9a53a66b60f69b419740cb2f28eff4bdd81de67e5b09b9ae274c1f5a2e40c8730546f4719c09078b590837b1da607685833034f96a86ab2bea62637629
7
+ data.tar.gz: 28a3a92617d4d889777d718cd88f43cec0217c6fd64135375699f81047186ddad0d1a345f32e2822d8f29a192fec579bef255efd316c5fb10594740042cd63a3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.3.1
4
+
5
+ - Fix bug (since 4.2.0) that caused column names not to be truncated after null character
6
+
7
+ ## 4.3.0
8
+
9
+ - Drop support for Ruby versions older than 3.0
10
+ - Require CSV gem
11
+
3
12
  ## 4.2.4
4
13
 
5
14
  - Exclude unnecessary files from the gem file list
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2006-2023 Keith Morrison <keithm@infused.org>
1
+ Copyright (c) 2006-2024 Keith Morrison <keithm@infused.org>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -10,23 +10,25 @@
10
10
  DBF is a small, fast Ruby library for reading dBase, xBase, Clipper, and FoxPro database files.
11
11
 
12
12
  * Project page: <https://github.com/infused/dbf>
13
- * API Documentation: <https://dbf.infused.org>
13
+ * API Documentation: <https://rubydoc.info/github/infused/dbf>
14
14
  * Report bugs: <https://github.com/infused/dbf/issues>
15
15
  * Questions: Email <mailto:keithm@infused.org> and put DBF somewhere in the
16
16
  subject line
17
17
  * Change log: <https://github.com/infused/dbf/blob/master/CHANGELOG.md>
18
18
 
19
- NOTE: Beginning with version 4, we have dropped support for Ruby 2.0, 2.1, 2.2, and 2.3. If you need support for these older Rubies,
19
+ NOTE: Beginning with version 4.3 we have dropped support for Ruby 3.0 and earlier.
20
+
21
+ NOTE: Beginning with version 4 we have dropped support for Ruby 2.0, 2.1, 2.2, and 2.3. If you need support for these older Rubies,
20
22
  please use 3.0.x (<https://github.com/infused.org/dbf/tree/3_stable>)
21
23
 
22
- NOTE: Beginning with version 3, we have dropped support for Ruby 1.8 and 1.9. If you need support for older Rubies,
24
+ NOTE: Beginning with version 3 we have dropped support for Ruby 1.8 and 1.9. If you need support for older Rubies,
23
25
  please use 2.0.x (<https://github.com/infused/dbf/tree/2_stable>)
24
26
 
25
27
  ## Compatibility
26
28
 
27
29
  DBF is tested to work with the following versions of Ruby:
28
30
 
29
- * Ruby 2.4.x, 2.5.x, 2.6.x, 2.7.x, 3.0.x, 3.1.x, and 3.2.x
31
+ * Ruby 3.1.x, 3.2.x, 3.3.x
30
32
 
31
33
  ## Installation
32
34
 
@@ -362,7 +364,7 @@ Data type descriptions
362
364
 
363
365
  ## License
364
366
 
365
- Copyright (c) 2006-2023 Keith Morrison <<keithm@infused.org>>
367
+ Copyright (c) 2006-2024 Keith Morrison <<keithm@infused.org>>
366
368
 
367
369
  Permission is hereby granted, free of charge, to any person
368
370
  obtaining a copy of this software and associated documentation
data/dbf.gemspec CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.files = Dir['README.md', 'CHANGELOG.md', 'LICENSE', '{bin,lib,spec}/**/*', 'dbf.gemspec']
19
19
  s.require_paths = ['lib']
20
20
  s.required_rubygems_version = Gem::Requirement.new('>= 1.3.0')
21
- s.required_ruby_version = Gem::Requirement.new('>= 2.4.0')
21
+ s.required_ruby_version = Gem::Requirement.new('>= 3.0.0')
22
22
  s.metadata['rubygems_mfa_required'] = 'true'
23
+ s.add_runtime_dependency 'csv'
23
24
  end
data/lib/dbf/column.rb CHANGED
@@ -9,8 +9,10 @@ module DBF
9
9
  end
10
10
 
11
11
  attr_reader :table, :name, :type, :length, :decimal
12
+
12
13
  def_delegator :type_cast_class, :type_cast
13
14
 
15
+ # rubocop:disable Style/MutableConstant
14
16
  TYPE_CAST_CLASS = {
15
17
  N: ColumnType::Number,
16
18
  I: ColumnType::SignedLong,
@@ -24,6 +26,7 @@ module DBF
24
26
  G: ColumnType::General,
25
27
  '+'.to_sym => ColumnType::SignedLong2
26
28
  }
29
+ # rubocop:enable Style/MutableConstant
27
30
  TYPE_CAST_CLASS.default = ColumnType::String
28
31
  TYPE_CAST_CLASS.freeze
29
32
 
@@ -58,7 +61,7 @@ module DBF
58
61
  #
59
62
  # @return [Hash]
60
63
  def to_hash
61
- {name: name, type: type, length: length, decimal: decimal}
64
+ {name:, type:, length:, decimal:}
62
65
  end
63
66
 
64
67
  # Underscored name
@@ -68,22 +71,17 @@ module DBF
68
71
  #
69
72
  # @return [String]
70
73
  def underscored_name
71
- @underscored_name ||= begin
72
- name.gsub(/::/, '/')
73
- .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
74
- .gsub(/([a-z\d])([A-Z])/, '\1_\2')
75
- .tr('-', '_')
76
- .downcase
77
- end
74
+ @underscored_name ||= name.gsub(/([a-z\d])([A-Z])/, '\1_\2').tr('-', '_').downcase
75
+
78
76
  end
79
77
 
80
78
  private
81
79
 
82
80
  def clean(value) # :nodoc:
83
- value.strip.gsub("\x00", '').gsub(/[^\x20-\x7E]/, '')
81
+ value.strip.partition("\x00").first.gsub(/[^\x20-\x7E]/, '')
84
82
  end
85
83
 
86
- def encode(value, strip_output = false) # :nodoc:
84
+ def encode(value, strip_output: false) # :nodoc:
87
85
  return value unless value.respond_to?(:encoding)
88
86
 
89
87
  output = @encoding ? encode_string(value) : value
@@ -105,7 +105,7 @@ module DBF
105
105
  end
106
106
 
107
107
  def table_field_hash(name)
108
- {name: name, fields: []}
108
+ {name:, fields: []}
109
109
  end
110
110
  end
111
111
 
data/lib/dbf/header.rb CHANGED
@@ -1,11 +1,6 @@
1
1
  module DBF
2
2
  class Header
3
- attr_reader :version
4
- attr_reader :record_count
5
- attr_reader :header_length
6
- attr_reader :record_length
7
- attr_reader :encoding_key
8
- attr_reader :encoding
3
+ attr_reader :version, :record_count, :header_length, :record_length, :encoding_key, :encoding
9
4
 
10
5
  def initialize(data)
11
6
  @data = data
@@ -13,7 +8,7 @@ module DBF
13
8
  end
14
9
 
15
10
  def unpack_header
16
- @version = @data.unpack('H2').first
11
+ @version = @data.unpack1('H2')
17
12
 
18
13
  case @version
19
14
  when '02'
data/lib/dbf/record.rb CHANGED
@@ -29,7 +29,7 @@ module DBF
29
29
  key = name.to_s
30
30
  if attributes.key?(key)
31
31
  attributes[key]
32
- elsif index = underscored_column_names.index(key)
32
+ elsif (index = underscored_column_names.index(key))
33
33
  attributes[@columns[index].name]
34
34
  end
35
35
  end
@@ -59,7 +59,7 @@ module DBF
59
59
  private
60
60
 
61
61
  def column_names # :nodoc:
62
- @column_names ||= @columns.map { |column| column.name }
62
+ @column_names ||= @columns.map(&:name)
63
63
  end
64
64
 
65
65
  def get_data(column) # :nodoc:
data/lib/dbf/schema.rb CHANGED
@@ -35,9 +35,9 @@ module DBF
35
35
  # @param format [Symbol] format Valid options are :activerecord and :json
36
36
  # @param table_only [Boolean]
37
37
  # @return [String]
38
- def schema(format = :activerecord, table_only = false)
38
+ def schema(format = :activerecord, table_only: false)
39
39
  schema_method_name = schema_name(format)
40
- send(schema_method_name, table_only)
40
+ send(schema_method_name, table_only:)
41
41
  rescue NameError
42
42
  raise ArgumentError, ":#{format} is not a valid schema. Valid schemas are: #{FORMATS.join(', ')}."
43
43
  end
@@ -46,7 +46,7 @@ module DBF
46
46
  "#{format}_schema"
47
47
  end
48
48
 
49
- def activerecord_schema(_table_only = false) # :nodoc:
49
+ def activerecord_schema(*) # :nodoc:
50
50
  s = "ActiveRecord::Schema.define do\n"
51
51
  s << " create_table \"#{name}\" do |t|\n"
52
52
  columns.each do |column|
@@ -56,7 +56,7 @@ module DBF
56
56
  s
57
57
  end
58
58
 
59
- def sequel_schema(table_only = false) # :nodoc:
59
+ def sequel_schema(table_only: false) # :nodoc:
60
60
  s = ''
61
61
  s << "Sequel.migration do\n" unless table_only
62
62
  s << " change do\n " unless table_only
@@ -70,7 +70,7 @@ module DBF
70
70
  s
71
71
  end
72
72
 
73
- def json_schema(_table_only = false) # :nodoc:
73
+ def json_schema(*) # :nodoc:
74
74
  columns.map(&:to_hash).to_json
75
75
  end
76
76
 
@@ -92,9 +92,9 @@ module DBF
92
92
 
93
93
  def schema_data_type(column, format = :activerecord) # :nodoc:
94
94
  case column.type
95
- when *%w[N F I]
95
+ when 'N', 'F', 'I'
96
96
  number_data_type(column)
97
- when *%w[Y D T L M B]
97
+ when 'Y', 'D', 'T', 'L', 'M', 'B'
98
98
  OTHER_DATA_TYPES[column.type]
99
99
  else
100
100
  string_data_format(format, column)
data/lib/dbf/table.rb CHANGED
@@ -86,7 +86,7 @@ module DBF
86
86
  # @return [TrueClass, FalseClass]
87
87
  def close
88
88
  @data.close
89
- @memo && @memo.close
89
+ @memo&.close
90
90
  end
91
91
 
92
92
  # @return [TrueClass, FalseClass]
@@ -255,7 +255,7 @@ module DBF
255
255
 
256
256
  def find_all(options) # :nodoc:
257
257
  select do |record|
258
- next unless record && record.match?(options)
258
+ next unless record&.match?(options)
259
259
 
260
260
  yield record if block_given?
261
261
  record
@@ -263,7 +263,7 @@ module DBF
263
263
  end
264
264
 
265
265
  def find_first(options) # :nodoc:
266
- detect { |record| record && record.match?(options) }
266
+ detect { |record| record&.match?(options) }
267
267
  end
268
268
 
269
269
  def foxpro? # :nodoc:
@@ -278,13 +278,12 @@ module DBF
278
278
  end
279
279
 
280
280
  def memo_class # :nodoc:
281
- @memo_class ||= begin
282
- if foxpro?
283
- Memo::Foxpro
281
+ @memo_class ||= if foxpro?
282
+ Memo::Foxpro
284
283
  else
285
284
  version == '83' ? Memo::Dbase3 : Memo::Dbase4
286
- end
287
285
  end
286
+
288
287
  end
289
288
 
290
289
  def memo_search_path(io) # :nodoc:
data/lib/dbf/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module DBF
2
- VERSION = '4.2.4'.freeze
2
+ VERSION = '4.3.1'.freeze
3
3
  end
@@ -287,12 +287,12 @@ RSpec.describe DBF::Column do
287
287
  describe '#name' do
288
288
  it 'contains only ASCII characters' do
289
289
  column = DBF::Column.new table, "--\x1F-\x68\x65\x6C\x6C\x6F \x00world-\x80--", 'N', 1, 0
290
- expect(column.name).to eq '---hello world---'
290
+ expect(column.name).to eq '---hello '
291
291
  end
292
292
 
293
293
  it 'is truncated at the null character' do
294
294
  column = DBF::Column.new table, "--\x1F-\x68\x65\x6C\x6C\x6F \x00world-\x80\x80--", 'N', 1, 0
295
- expect(column.name).to eq '---hello world---'
295
+ expect(column.name).to eq '---hello '
296
296
  end
297
297
  end
298
298
  end
@@ -3,25 +3,25 @@ require 'spec_helper'
3
3
  RSpec.describe DBF::Record do
4
4
  describe '#to_a' do
5
5
  let(:table) { DBF::Table.new fixture('dbase_83.dbf') }
6
- let(:record_0) { YAML.load_file(fixture('dbase_83_record_0.yml')) }
7
- let(:record_9) { YAML.load_file(fixture('dbase_83_record_9.yml')) }
6
+ let(:record0) { YAML.load_file(fixture('dbase_83_record_0.yml')) }
7
+ let(:record9) { YAML.load_file(fixture('dbase_83_record_9.yml')) }
8
8
 
9
9
  it 'returns an ordered array of attribute values' do
10
10
  record = table.record(0)
11
- expect(record.to_a).to eq record_0
11
+ expect(record.to_a).to eq record0
12
12
 
13
13
  record = table.record(9)
14
- expect(record.to_a).to eq record_9
14
+ expect(record.to_a).to eq record9
15
15
  end
16
16
 
17
17
  describe 'with missing memo file' do
18
18
  describe 'when opening a path' do
19
19
  let(:table) { DBF::Table.new fixture('dbase_83_missing_memo.dbf') }
20
- let(:record_0) { YAML.load_file(fixture('dbase_83_missing_memo_record_0.yml')) }
20
+ let(:record0) { YAML.load_file(fixture('dbase_83_missing_memo_record_0.yml')) }
21
21
 
22
22
  it 'returns nil values for memo fields' do
23
23
  record = table.record(0)
24
- expect(record.to_a).to eq record_0
24
+ expect(record.to_a).to eq record0
25
25
  end
26
26
  end
27
27
  end
@@ -29,11 +29,11 @@ RSpec.describe DBF::Record do
29
29
  describe 'when opening StringIO' do
30
30
  let(:data) { StringIO.new(File.read(fixture('dbase_83_missing_memo.dbf'))) }
31
31
  let(:table) { DBF::Table.new(data) }
32
- let(:record_0) { YAML.load_file(fixture('dbase_83_missing_memo_record_0.yml')) }
32
+ let(:record0) { YAML.load_file(fixture('dbase_83_missing_memo_record_0.yml')) }
33
33
 
34
34
  it 'returns nil values for memo fields' do
35
35
  record = table.record(0)
36
- expect(record.to_a).to eq record_0
36
+ expect(record.to_a).to eq record0
37
37
  end
38
38
  end
39
39
  end
@@ -50,7 +50,7 @@ RSpec.describe DBF::Record do
50
50
 
51
51
  describe 'if other attributes match' do
52
52
  let(:attributes) { {x: 1, y: 2} }
53
- let(:other) { instance_double('DBF::Record', attributes: attributes) }
53
+ let(:other) { instance_double('DBF::Record', attributes:) }
54
54
 
55
55
  before do
56
56
  allow(record).to receive(:attributes).and_return(attributes)
@@ -70,7 +70,6 @@ RSpec.describe DBF::Table do
70
70
 
71
71
  describe 'when data is StringIO' do
72
72
  let(:data) { StringIO.new File.read(dbf_path) }
73
- let(:memo) { StringIO.new File.read(memo_path) }
74
73
  let(:table) { DBF::Table.new data }
75
74
 
76
75
  let(:control_schema) { File.read(fixture('dbase_83_schema_ar.txt')) }
@@ -200,7 +199,7 @@ RSpec.describe DBF::Table do
200
199
  end
201
200
 
202
201
  it 'returns matching records when used with options' do
203
- expect(table.find(:all, 'WEIGHT' => 0.0)).to eq table.select { |r| r['weight'] == 0.0 }
202
+ expect(table.find(:all, 'WEIGHT' => 0.0)).to eq(table.select { |r| r['weight'] == 0.0 })
204
203
  end
205
204
 
206
205
  it 'ANDS multiple search terms' do
@@ -295,7 +294,7 @@ RSpec.describe DBF::Table do
295
294
  it 'is an array of Columns' do
296
295
  expect(columns).to be_an(Array)
297
296
  expect(columns).to_not be_empty
298
- expect(columns).to be_all { |c| c.is_a? DBF::Column }
297
+ expect(columns).to(be_all { |c| c.is_a? DBF::Column })
299
298
  end
300
299
  end
301
300
 
data/spec/spec_helper.rb CHANGED
@@ -2,6 +2,7 @@ begin
2
2
  require 'simplecov'
3
3
  SimpleCov.start
4
4
  rescue LoadError
5
+ # ignore
5
6
  end
6
7
 
7
8
  require 'dbf'
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbf
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.4
4
+ version: 4.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-30 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2024-01-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: csv
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  description: A small fast library for reading dBase, xBase, Clipper and FoxPro database
14
28
  files.
15
29
  email: keithm@infused.org
@@ -104,14 +118,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
104
118
  requirements:
105
119
  - - ">="
106
120
  - !ruby/object:Gem::Version
107
- version: 2.4.0
121
+ version: 3.0.0
108
122
  required_rubygems_version: !ruby/object:Gem::Requirement
109
123
  requirements:
110
124
  - - ">="
111
125
  - !ruby/object:Gem::Version
112
126
  version: 1.3.0
113
127
  requirements: []
114
- rubygems_version: 3.4.13
128
+ rubygems_version: 3.5.3
115
129
  signing_key:
116
130
  specification_version: 4
117
131
  summary: Read xBase files