dbf 5.0.1 → 5.1.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: 4db2b075394f8f3cb60fc36e71a71eb9f8367e7b34b8863481fe6c2ab0a2aeac
4
- data.tar.gz: f3e7ba5bd793d1732d2ae20b23b3a56285fa81228d06db9d38b055049591b76e
3
+ metadata.gz: 7d565a51490240e9f5ed724970a568f12641b595b66e426a3a4a1a6ba0c84003
4
+ data.tar.gz: 12fc66ce2b83c55157532d252b52eb6a343174898a7965a636beb7877aa29c17
5
5
  SHA512:
6
- metadata.gz: b7c5847999bf422df92d90bbdea11bf0d6baa09ace5649cd65814b22cb5192a5ec085e8b25b9a2c56cb889f0f23d0fd0e3e20561c737ae05857afb63db69aea4
7
- data.tar.gz: e1ed01f59b6f13e5bd3a91b327cdcd2060f85f2a608dfaf3e4dae1723f9a97b0ef2221465b0ae14aed1345e99b0c6c8edf9de00259f8a741914d889212ca5dc6
6
+ metadata.gz: c2de237f84ddc71f271a782b537f03d10a8586e939ad08f66b34c9f6bcc38a1b34aa4a2899d3248a1ff2f574bfb9920c19d2f134cae01ac66f0e228acd9a1c13
7
+ data.tar.gz: 5b5b3ee469e5afe32bc54ea4f494b543c675a2b4c61b6e6cf56af68ab2ab989a35644b7795a29e1cd9e4dfe8e4129c1abf85696a4ff7df8fb0444f89c7f80193
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.1.1
4
+
5
+ - Frozen string literals
6
+
7
+ ## 5.1.0
8
+
9
+ - Drop support for Ruby 3.0.x
10
+
3
11
  ## 5.0.1
4
12
 
5
13
  - Raise ArgumentError data is not a string or StringIO object
data/README.md CHANGED
@@ -14,7 +14,7 @@ DBF is a small, fast Ruby library for reading dBase, xBase, Clipper, and FoxPro
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
- * Change log: <https://github.com/infused/dbf/blob/master/CHANGELOG.md>
17
+ * Change log: <https://github.com/infused/dbf/blob/main/CHANGELOG.md>
18
18
 
19
19
  NOTE: Beginning with version 4.3 we have dropped support for Ruby 3.0 and earlier.
20
20
 
data/dbf.gemspec CHANGED
@@ -17,8 +17,8 @@ Gem::Specification.new do |s|
17
17
  s.extra_rdoc_files = ['README.md', 'CHANGELOG.md', 'LICENSE']
18
18
  s.files = Dir['README.md', 'CHANGELOG.md', 'LICENSE', '{bin,lib,spec}/**/*', 'dbf.gemspec']
19
19
  s.require_paths = ['lib']
20
- s.required_rubygems_version = Gem::Requirement.new('>= 1.3.0')
21
- s.required_ruby_version = Gem::Requirement.new('>= 3.0.0')
20
+ s.required_rubygems_version = Gem::Requirement.new('>= 3.2.3')
21
+ s.required_ruby_version = Gem::Requirement.new('>= 3.1.0')
22
22
  s.metadata['rubygems_mfa_required'] = 'true'
23
- s.add_runtime_dependency 'csv'
23
+ s.add_dependency 'csv'
24
24
  end
data/lib/dbf/column.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DBF
2
4
  class Column
3
5
  extend Forwardable
@@ -24,7 +26,7 @@ module DBF
24
26
  M: ColumnType::Memo,
25
27
  B: ColumnType::Double,
26
28
  G: ColumnType::General,
27
- '+'.to_sym => ColumnType::SignedLong2
29
+ :+ => ColumnType::SignedLong2
28
30
  }
29
31
  # rubocop:enable Style/MutableConstant
30
32
  TYPE_CAST_CLASS.default = ColumnType::String
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DBF
2
4
  module ColumnType
3
5
  class Base
@@ -95,7 +97,7 @@ module DBF
95
97
  # @param value [String]
96
98
  def type_cast(value)
97
99
  if encoding && !value.nil?
98
- value.force_encoding(@encoding).encode(Encoding.default_external, undef: :replace, invalid: :replace)
100
+ value.dup.force_encoding(@encoding).encode(Encoding.default_external, undef: :replace, invalid: :replace)
99
101
  else
100
102
  value
101
103
  end
@@ -105,7 +107,7 @@ module DBF
105
107
  class General < Base
106
108
  # @param value [String]
107
109
  def type_cast(value)
108
- value
110
+ value&.dup&.force_encoding(Encoding::ASCII_8BIT)
109
111
  end
110
112
  end
111
113
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DBF
2
4
  # DBF::Database::Foxpro is the primary interface to a Visual Foxpro database
3
5
  # container (.dbc file). When using this database container, long fieldnames
@@ -85,9 +87,7 @@ module DBF
85
87
  end
86
88
  end
87
89
 
88
- Hash[
89
- data.values.map { |v| [v[:name], v[:fields]] }
90
- ]
90
+ data.values.to_h { |v| [v[:name], v[:fields]] }
91
91
  end
92
92
 
93
93
  def process_table(record, data)
data/lib/dbf/encodings.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DBF
2
4
  ENCODINGS = {
3
5
  '01' => 'cp437', # U.S. MS-DOS
data/lib/dbf/header.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DBF
2
4
  class Header
3
5
  attr_reader :version, :record_count, :header_length, :record_length, :encoding_key, :encoding
data/lib/dbf/memo/base.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DBF
2
4
  module Memo
3
5
  class Base
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DBF
2
4
  module Memo
3
5
  class Dbase3 < Base
4
6
  def build_memo(start_block) # :nodoc:
5
7
  @data.seek offset(start_block)
6
- memo_string = ''
8
+ memo_string = +''
7
9
  loop do
8
10
  block = @data.read(BLOCK_SIZE).gsub(/(\000|\032)/, '')
9
11
  memo_string << block
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DBF
2
4
  module Memo
3
5
  class Dbase4 < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DBF
2
4
  module Memo
3
5
  class Foxpro < Base
data/lib/dbf/record.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DBF
2
4
  # An instance of DBF::Record represents a row in the DBF file
3
5
  class Record
@@ -38,7 +40,7 @@ module DBF
38
40
  #
39
41
  # @return [Hash]
40
42
  def attributes
41
- @attributes ||= Hash[column_names.zip(to_a)]
43
+ @attributes ||= column_names.zip(to_a).to_h
42
44
  end
43
45
 
44
46
  # Do all search parameters match?
data/lib/dbf/schema.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DBF
2
4
  # The Schema module is mixin for the Table class
3
5
  module Schema
@@ -47,7 +49,7 @@ module DBF
47
49
  end
48
50
 
49
51
  def activerecord_schema(*) # :nodoc:
50
- s = "ActiveRecord::Schema.define do\n"
52
+ s = +"ActiveRecord::Schema.define do\n"
51
53
  s << " create_table \"#{name}\" do |t|\n"
52
54
  columns.each do |column|
53
55
  s << " t.column #{activerecord_schema_definition(column)}"
@@ -57,7 +59,7 @@ module DBF
57
59
  end
58
60
 
59
61
  def sequel_schema(table_only: false) # :nodoc:
60
- s = ''
62
+ s = +''
61
63
  s << "Sequel.migration do\n" unless table_only
62
64
  s << " change do\n " unless table_only
63
65
  s << " create_table(:#{name}) do\n"
data/lib/dbf/table.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DBF
2
4
  class FileNotFoundError < StandardError
3
5
  end
@@ -295,10 +297,9 @@ module DBF
295
297
  def memo_class # :nodoc:
296
298
  @memo_class ||= if foxpro?
297
299
  Memo::Foxpro
298
- else
299
- version == '83' ? Memo::Dbase3 : Memo::Dbase4
300
+ else
301
+ version == '83' ? Memo::Dbase3 : Memo::Dbase4
300
302
  end
301
-
302
303
  end
303
304
 
304
305
  def memo_search_path(io) # :nodoc:
data/lib/dbf/version.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DBF
2
- VERSION = '5.0.1'.freeze
4
+ VERSION = '5.1.1'.freeze
3
5
  end
data/lib/dbf.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'csv'
2
4
  require 'date'
3
5
  require 'forwardable'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # encoding: ascii-8bit
2
3
 
3
4
  require 'spec_helper'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe DBF::Database::Foxpro do
@@ -1,47 +1,49 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- RSpec.describe 'default encoding' do
6
- let(:dbf_path) { fixture('dbase_03_cyrillic.dbf') }
7
- let(:table) { DBF::Table.new dbf_path }
8
-
9
- it 'defaults to UTF-8 encoding' do
10
- expect(table.encoding).to eq Encoding::UTF_8
11
- end
12
-
13
- it 'uses the table encoding for column encoding' do
14
- column = table.columns.first
15
- expect(column.encoding).to eq table.encoding
16
- end
17
-
18
- it 'encodes column names' do
19
- expect(table.column_names).to eq ['ШАР', 'ПЛОЩА']
20
- end
21
-
22
- it 'encodes record values' do
23
- expect(table.record(0).attributes['ШАР']).to eq 'Номер'
24
- end
25
- end
26
-
27
- RSpec.describe 'embedded encoding' do
28
- let(:dbf_path) { fixture('cp1251.dbf') }
29
- let(:table) { DBF::Table.new dbf_path }
30
-
31
- it 'defaults to UTF-8 encoding' do
32
- expect(table.encoding).to eq 'cp1251'
33
- end
34
-
35
- it 'uses the table encoding for column encoding' do
36
- column = table.columns.first
37
- expect(column.encoding).to eq table.encoding
38
- end
39
-
40
- it 'encodes column names' do
41
- expect(table.column_names).to eq ['RN', 'NAME']
42
- end
43
-
44
- it 'encodes record values' do
45
- expect(table.record(0).attributes['NAME']).to eq 'амбулаторно-поликлиническое'
5
+ RSpec.describe 'DBF::Table' do
6
+ context 'with default encoding' do
7
+ let(:dbf_path) { fixture('dbase_03_cyrillic.dbf') }
8
+ let(:table) { DBF::Table.new dbf_path }
9
+
10
+ it 'defaults to UTF-8 encoding' do
11
+ expect(table.encoding).to eq Encoding::UTF_8
12
+ end
13
+
14
+ it 'uses the table encoding for column encoding' do
15
+ column = table.columns.first
16
+ expect(column.encoding).to eq table.encoding
17
+ end
18
+
19
+ it 'encodes column names' do
20
+ expect(table.column_names).to eq %w[ШАР ПЛОЩА]
21
+ end
22
+
23
+ it 'encodes record values' do
24
+ expect(table.record(0).attributes['ШАР']).to eq 'Номер'
25
+ end
26
+ end
27
+
28
+ context 'with embedded encoding' do
29
+ let(:dbf_path) { fixture('cp1251.dbf') }
30
+ let(:table) { DBF::Table.new dbf_path }
31
+
32
+ it 'defaults to UTF-8 encoding' do
33
+ expect(table.encoding).to eq 'cp1251'
34
+ end
35
+
36
+ it 'uses the table encoding for column encoding' do
37
+ column = table.columns.first
38
+ expect(column.encoding).to eq table.encoding
39
+ end
40
+
41
+ it 'encodes column names' do
42
+ expect(table.column_names).to eq %w[RN NAME]
43
+ end
44
+
45
+ it 'encodes record values' do
46
+ expect(table.record(0).attributes['NAME']).to eq 'амбулаторно-поликлиническое'
47
+ end
46
48
  end
47
49
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.shared_examples_for 'DBF' do
@@ -9,7 +11,7 @@ RSpec.shared_examples_for 'DBF' do
9
11
  end
10
12
 
11
13
  specify 'records should be instances of DBF::Record' do
12
- expect(table).to all be_kind_of(DBF::Record)
14
+ expect(table).to all be_a(DBF::Record)
13
15
  end
14
16
 
15
17
  specify 'record count should be the same as reported in the header' do
@@ -31,7 +33,7 @@ RSpec.shared_examples_for 'DBF' do
31
33
 
32
34
  specify 'column lengths should be instances of Integer' do
33
35
  table.columns.each do |column|
34
- expect(column.length).to be_kind_of(Integer)
36
+ expect(column.length).to be_a(Integer)
35
37
  end
36
38
  end
37
39
 
@@ -43,7 +45,7 @@ RSpec.shared_examples_for 'DBF' do
43
45
 
44
46
  specify 'column decimals should be instances of Integer' do
45
47
  table.columns.each do |column|
46
- expect(column.decimal).to be_kind_of(Integer)
48
+ expect(column.decimal).to be_a(Integer)
47
49
  end
48
50
  end
49
51
  end
@@ -1,27 +1,26 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe DBF::Record do
4
6
  describe '#to_a' do
5
7
  let(:table) { DBF::Table.new fixture('dbase_83.dbf') }
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 record0
11
+ expect(record.to_a).to eq YAML.load_file(fixture('dbase_83_record_0.yml'))
12
12
 
13
13
  record = table.record(9)
14
- expect(record.to_a).to eq record9
14
+ expect(record.to_a).to eq YAML.load_file(fixture('dbase_83_record_9.yml'))
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(:record0) { YAML.load_file(fixture('dbase_83_missing_memo_record_0.yml')) }
21
20
 
22
21
  it 'returns nil values for memo fields' do
23
22
  record = table.record(0)
24
- expect(record.to_a).to eq record0
23
+ expect(record.to_a).to eq YAML.load_file(fixture('dbase_83_missing_memo_record_0.yml'))
25
24
  end
26
25
  end
27
26
  end
@@ -29,11 +28,10 @@ RSpec.describe DBF::Record do
29
28
  describe 'when opening StringIO' do
30
29
  let(:data) { StringIO.new(File.read(fixture('dbase_83_missing_memo.dbf'))) }
31
30
  let(:table) { DBF::Table.new(data) }
32
- let(:record0) { YAML.load_file(fixture('dbase_83_missing_memo_record_0.yml')) }
33
31
 
34
32
  it 'returns nil values for memo fields' do
35
33
  record = table.record(0)
36
- expect(record.to_a).to eq record0
34
+ expect(record.to_a).to eq YAML.load_file(fixture('dbase_83_missing_memo_record_0.yml'))
37
35
  end
38
36
  end
39
37
  end
@@ -44,13 +42,13 @@ RSpec.describe DBF::Record do
44
42
 
45
43
  describe 'when other does not have attributes' do
46
44
  it 'returns false' do
47
- expect((record == instance_double('DBF::Record'))).to be_falsey
45
+ expect(record == instance_double(DBF::Record)).to be_falsey
48
46
  end
49
47
  end
50
48
 
51
49
  describe 'if other attributes match' do
52
50
  let(:attributes) { {x: 1, y: 2} }
53
- let(:other) { instance_double('DBF::Record', attributes: attributes) }
51
+ let(:other) { instance_double(DBF::Record, attributes: attributes) }
54
52
 
55
53
  before do
56
54
  allow(record).to receive(:attributes).and_return(attributes)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe DBF::Table do
@@ -142,7 +144,7 @@ RSpec.describe DBF::Table do
142
144
  before { table.to_csv('test.csv') }
143
145
 
144
146
  it 'creates a custom csv file' do
145
- expect(File).to be_exist('test.csv')
147
+ expect(File).to exist('test.csv')
146
148
  end
147
149
  end
148
150
  end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  begin
2
4
  require 'simplecov'
3
5
  SimpleCov.start
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbf
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.1
4
+ version: 5.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Morrison
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-04-25 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: csv
@@ -31,9 +30,9 @@ executables:
31
30
  - dbf
32
31
  extensions: []
33
32
  extra_rdoc_files:
34
- - README.md
35
33
  - CHANGELOG.md
36
34
  - LICENSE
35
+ - README.md
37
36
  files:
38
37
  - CHANGELOG.md
39
38
  - LICENSE
@@ -112,7 +111,6 @@ licenses:
112
111
  - MIT
113
112
  metadata:
114
113
  rubygems_mfa_required: 'true'
115
- post_install_message:
116
114
  rdoc_options:
117
115
  - "--charset=UTF-8"
118
116
  require_paths:
@@ -121,15 +119,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
121
119
  requirements:
122
120
  - - ">="
123
121
  - !ruby/object:Gem::Version
124
- version: 3.0.0
122
+ version: 3.1.0
125
123
  required_rubygems_version: !ruby/object:Gem::Requirement
126
124
  requirements:
127
125
  - - ">="
128
126
  - !ruby/object:Gem::Version
129
- version: 1.3.0
127
+ version: 3.2.3
130
128
  requirements: []
131
- rubygems_version: 3.5.8
132
- signing_key:
129
+ rubygems_version: 3.6.7
133
130
  specification_version: 4
134
131
  summary: Read xBase files
135
132
  test_files: []