dbf 1.3.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +22 -0
- data/Gemfile +1 -4
- data/Gemfile.lock +83 -6
- data/README.md +20 -21
- data/Rakefile +9 -46
- data/bin/dbf +0 -0
- data/lib/dbf.rb +6 -11
- data/lib/dbf/column.rb +38 -74
- data/lib/dbf/memo.rb +88 -0
- data/lib/dbf/record.rb +29 -104
- data/lib/dbf/table.rb +54 -142
- data/lib/dbf/version.rb +1 -1
- data/spec/{unit → dbf}/column_spec.rb +37 -46
- data/spec/dbf/file_formats_spec.rb +178 -0
- data/spec/dbf/record_spec.rb +45 -0
- data/spec/{unit → dbf}/table_spec.rb +17 -104
- data/spec/spec_helper.rb +2 -4
- metadata +39 -27
- data/spec/functional/dbf_shared.rb +0 -54
- data/spec/functional/format_03_spec.rb +0 -23
- data/spec/functional/format_30_spec.rb +0 -23
- data/spec/functional/format_31_spec.rb +0 -23
- data/spec/functional/format_83_spec.rb +0 -23
- data/spec/functional/format_8b_spec.rb +0 -23
- data/spec/functional/format_f5_spec.rb +0 -23
- data/spec/unit/record_spec.rb +0 -111
data/spec/spec_helper.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
$:.unshift(File.dirname(__FILE__) + '/../lib/')
|
2
2
|
require 'rubygems'
|
3
|
-
require '
|
3
|
+
require 'rspec'
|
4
4
|
require 'dbf'
|
5
5
|
require 'fileutils'
|
6
6
|
|
7
7
|
DB_PATH = File.dirname(__FILE__) + '/fixtures' unless defined?(DB_PATH)
|
8
8
|
|
9
|
-
|
9
|
+
RSpec.configure do |config|
|
10
10
|
|
11
11
|
end
|
12
|
-
|
13
|
-
self.class.send :remove_const, 'Test' if defined? Test
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dbf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 3
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 1
|
7
|
-
-
|
8
|
+
- 5
|
8
9
|
- 0
|
9
|
-
version: 1.
|
10
|
+
version: 1.5.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Keith Morrison
|
@@ -14,7 +15,7 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-11-16 00:00:00 -08:00
|
18
19
|
default_executable: dbf
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
@@ -25,11 +26,12 @@ dependencies:
|
|
25
26
|
requirements:
|
26
27
|
- - "="
|
27
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 5
|
28
30
|
segments:
|
29
31
|
- 3
|
30
32
|
- 0
|
31
|
-
-
|
32
|
-
version: 3.0.
|
33
|
+
- 1
|
34
|
+
version: 3.0.1
|
33
35
|
type: :runtime
|
34
36
|
version_requirements: *id001
|
35
37
|
- !ruby/object:Gem::Dependency
|
@@ -40,6 +42,7 @@ dependencies:
|
|
40
42
|
requirements:
|
41
43
|
- - "="
|
42
44
|
- !ruby/object:Gem::Version
|
45
|
+
hash: 5
|
43
46
|
segments:
|
44
47
|
- 1
|
45
48
|
- 5
|
@@ -53,15 +56,32 @@ dependencies:
|
|
53
56
|
requirement: &id003 !ruby/object:Gem::Requirement
|
54
57
|
none: false
|
55
58
|
requirements:
|
56
|
-
- - "
|
59
|
+
- - "="
|
57
60
|
- !ruby/object:Gem::Version
|
61
|
+
hash: 11
|
58
62
|
segments:
|
63
|
+
- 2
|
59
64
|
- 1
|
60
|
-
- 3
|
61
65
|
- 0
|
62
|
-
version: 1.
|
66
|
+
version: 2.1.0
|
63
67
|
type: :development
|
64
68
|
version_requirements: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: metric_fu
|
71
|
+
prerelease: false
|
72
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - "="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 13
|
78
|
+
segments:
|
79
|
+
- 2
|
80
|
+
- 0
|
81
|
+
- 1
|
82
|
+
version: 2.0.1
|
83
|
+
type: :development
|
84
|
+
version_requirements: *id004
|
65
85
|
description: A small fast library for reading dBase, xBase, Clipper and FoxPro database files.
|
66
86
|
email: keithm@infused.org
|
67
87
|
executables:
|
@@ -82,10 +102,15 @@ files:
|
|
82
102
|
- docs/supported_types.markdown
|
83
103
|
- lib/dbf/attributes.rb
|
84
104
|
- lib/dbf/column.rb
|
105
|
+
- lib/dbf/memo.rb
|
85
106
|
- lib/dbf/record.rb
|
86
107
|
- lib/dbf/table.rb
|
87
108
|
- lib/dbf/version.rb
|
88
109
|
- lib/dbf.rb
|
110
|
+
- spec/dbf/column_spec.rb
|
111
|
+
- spec/dbf/file_formats_spec.rb
|
112
|
+
- spec/dbf/record_spec.rb
|
113
|
+
- spec/dbf/table_spec.rb
|
89
114
|
- spec/fixtures/dbase_03.dbf
|
90
115
|
- spec/fixtures/dbase_30.dbf
|
91
116
|
- spec/fixtures/dbase_30.fpt
|
@@ -97,17 +122,7 @@ files:
|
|
97
122
|
- spec/fixtures/dbase_8b.dbt
|
98
123
|
- spec/fixtures/dbase_f5.dbf
|
99
124
|
- spec/fixtures/dbase_f5.fpt
|
100
|
-
- spec/functional/dbf_shared.rb
|
101
|
-
- spec/functional/format_03_spec.rb
|
102
|
-
- spec/functional/format_30_spec.rb
|
103
|
-
- spec/functional/format_31_spec.rb
|
104
|
-
- spec/functional/format_83_spec.rb
|
105
|
-
- spec/functional/format_8b_spec.rb
|
106
|
-
- spec/functional/format_f5_spec.rb
|
107
125
|
- spec/spec_helper.rb
|
108
|
-
- spec/unit/column_spec.rb
|
109
|
-
- spec/unit/record_spec.rb
|
110
|
-
- spec/unit/table_spec.rb
|
111
126
|
has_rdoc: true
|
112
127
|
homepage: http://github.com/infused/dbf
|
113
128
|
licenses: []
|
@@ -122,6 +137,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
122
137
|
requirements:
|
123
138
|
- - ">="
|
124
139
|
- !ruby/object:Gem::Version
|
140
|
+
hash: 3
|
125
141
|
segments:
|
126
142
|
- 0
|
127
143
|
version: "0"
|
@@ -130,6 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
130
146
|
requirements:
|
131
147
|
- - ">="
|
132
148
|
- !ruby/object:Gem::Version
|
149
|
+
hash: 27
|
133
150
|
segments:
|
134
151
|
- 1
|
135
152
|
- 3
|
@@ -143,12 +160,7 @@ signing_key:
|
|
143
160
|
specification_version: 3
|
144
161
|
summary: Read xBase files
|
145
162
|
test_files:
|
146
|
-
- spec/
|
147
|
-
- spec/
|
148
|
-
- spec/
|
149
|
-
- spec/
|
150
|
-
- spec/functional/format_8b_spec.rb
|
151
|
-
- spec/functional/format_f5_spec.rb
|
152
|
-
- spec/unit/column_spec.rb
|
153
|
-
- spec/unit/record_spec.rb
|
154
|
-
- spec/unit/table_spec.rb
|
163
|
+
- spec/dbf/column_spec.rb
|
164
|
+
- spec/dbf/file_formats_spec.rb
|
165
|
+
- spec/dbf/record_spec.rb
|
166
|
+
- spec/dbf/table_spec.rb
|
@@ -1,54 +0,0 @@
|
|
1
|
-
describe DBF, :shared => true do
|
2
|
-
specify "sum of column lengths should equal record length specified in header" do
|
3
|
-
header_record_length = @table.instance_eval {@record_length}
|
4
|
-
sum_of_column_lengths = @table.columns.inject(1) {|sum, column| sum + column.length}
|
5
|
-
|
6
|
-
header_record_length.should == sum_of_column_lengths
|
7
|
-
end
|
8
|
-
|
9
|
-
specify "records should be instances of DBF::Record" do
|
10
|
-
@table.each do |record|
|
11
|
-
record.should be_an_instance_of(DBF::Record)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
specify "columns should be instances of DBF::Column" do
|
16
|
-
@table.columns.all? {|column| column.should be_an_instance_of(DBF::Column)}
|
17
|
-
end
|
18
|
-
|
19
|
-
specify "column names should not be blank" do
|
20
|
-
@table.columns.all? {|column| column.name.should_not be_empty}
|
21
|
-
end
|
22
|
-
|
23
|
-
specify "column types should be valid" do
|
24
|
-
valid_column_types = %w(C N L D M F B G P Y T I V X @ O + 0)
|
25
|
-
@table.columns.all? {|column| valid_column_types.should include(column.type)}
|
26
|
-
end
|
27
|
-
|
28
|
-
specify "column lengths should be instances of Fixnum" do
|
29
|
-
@table.columns.all? {|column| column.length.should be_an_instance_of(Fixnum)}
|
30
|
-
end
|
31
|
-
|
32
|
-
specify "column lengths should be larger than 0" do
|
33
|
-
@table.columns.all? {|column| column.length.should > 0}
|
34
|
-
end
|
35
|
-
|
36
|
-
specify "column decimals should be instances of Fixnum" do
|
37
|
-
@table.columns.all? {|column| column.decimal.should be_an_instance_of(Fixnum)}
|
38
|
-
end
|
39
|
-
|
40
|
-
specify "column read accessors should return the attribute after typecast" do
|
41
|
-
@table.columns do |column|
|
42
|
-
record = @table.records.first
|
43
|
-
record.send(column.name).should == record[column.name]
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
specify "column attributes should be accessible in underscored form" do
|
48
|
-
@table.columns do |column|
|
49
|
-
record = @table.records.first
|
50
|
-
record.send(column_name).should == record.send(column_name.underscore)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "../spec_helper"))
|
2
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "dbf_shared"))
|
3
|
-
|
4
|
-
describe DBF, "of type 03 (dBase III without memo file)" do
|
5
|
-
before do
|
6
|
-
@table = DBF::Table.new "#{DB_PATH}/dbase_03.dbf"
|
7
|
-
end
|
8
|
-
|
9
|
-
it_should_behave_like "DBF"
|
10
|
-
|
11
|
-
it "should report the correct version number" do
|
12
|
-
@table.version.should == "03"
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should have a memo file" do
|
16
|
-
@table.should_not have_memo_file
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should have a nil memo_file_format" do
|
20
|
-
@table.memo_file_format.should be_nil
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "../spec_helper"))
|
2
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "dbf_shared"))
|
3
|
-
|
4
|
-
describe DBF, "of type 30 (Visual FoxPro)" do
|
5
|
-
before do
|
6
|
-
@table = DBF::Table.new "#{DB_PATH}/dbase_30.dbf"
|
7
|
-
end
|
8
|
-
|
9
|
-
it_should_behave_like "DBF"
|
10
|
-
|
11
|
-
it "should report the correct version number" do
|
12
|
-
@table.version.should == "30"
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should have a memo file" do
|
16
|
-
@table.should have_memo_file
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should report the correct memo type" do
|
20
|
-
@table.memo_file_format.should == :fpt
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "../spec_helper"))
|
2
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "dbf_shared"))
|
3
|
-
|
4
|
-
describe DBF, "of type 31 (Visual FoxPro with AutoIncrement field)" do
|
5
|
-
before do
|
6
|
-
@table = DBF::Table.new "#{DB_PATH}/dbase_31.dbf"
|
7
|
-
end
|
8
|
-
|
9
|
-
it_should_behave_like "DBF"
|
10
|
-
|
11
|
-
it "should have a dBase version of 31" do
|
12
|
-
@table.version.should == "31"
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should have a memo file" do
|
16
|
-
@table.should_not have_memo_file
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should have a nil memo_file_format" do
|
20
|
-
@table.memo_file_format.should be_nil
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "../spec_helper"))
|
2
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "dbf_shared"))
|
3
|
-
|
4
|
-
describe DBF, "of type 83 (dBase III with memo file)" do
|
5
|
-
before do
|
6
|
-
@table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
7
|
-
end
|
8
|
-
|
9
|
-
it_should_behave_like "DBF"
|
10
|
-
|
11
|
-
it "should report the correct version number" do
|
12
|
-
@table.version.should == "83"
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should have a memo file" do
|
16
|
-
@table.should have_memo_file
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should report the correct memo type" do
|
20
|
-
@table.memo_file_format.should == :dbt
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "../spec_helper"))
|
2
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "dbf_shared"))
|
3
|
-
|
4
|
-
describe DBF, "of type 8b (dBase IV with memo file)" do
|
5
|
-
before do
|
6
|
-
@table = DBF::Table.new "#{DB_PATH}/dbase_8b.dbf"
|
7
|
-
end
|
8
|
-
|
9
|
-
it_should_behave_like "DBF"
|
10
|
-
|
11
|
-
it "should report the correct version number" do
|
12
|
-
@table.version.should == "8b"
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should have a memo file" do
|
16
|
-
@table.should have_memo_file
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should report the correct memo type" do
|
20
|
-
@table.memo_file_format.should == :dbt
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "../spec_helper"))
|
2
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "dbf_shared"))
|
3
|
-
|
4
|
-
describe DBF, "of type f5 (FoxPro with memo file)" do
|
5
|
-
before do
|
6
|
-
@table = DBF::Table.new "#{DB_PATH}/dbase_f5.dbf"
|
7
|
-
end
|
8
|
-
|
9
|
-
it_should_behave_like "DBF"
|
10
|
-
|
11
|
-
it "should report the correct version number" do
|
12
|
-
@table.version.should == "f5"
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should have a memo file" do
|
16
|
-
@table.should have_memo_file
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should report the correct memo type" do
|
20
|
-
@table.memo_file_format.should == :fpt
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
data/spec/unit/record_spec.rb
DELETED
@@ -1,111 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "../spec_helper"))
|
2
|
-
|
3
|
-
describe DBF::Record do
|
4
|
-
|
5
|
-
def example_record(data = '')
|
6
|
-
table = mock_table(data)
|
7
|
-
DBF::Record.new(table)
|
8
|
-
end
|
9
|
-
|
10
|
-
def mock_table(data = '')
|
11
|
-
@column1 = DBF::Column.new 'ColumnName', 'N', 1, 0
|
12
|
-
|
13
|
-
table = mock('table')
|
14
|
-
table.stub!(:memo_block_size).and_return(8)
|
15
|
-
table.stub!(:memo).and_return(nil)
|
16
|
-
table.stub!(:columns).and_return([@column1])
|
17
|
-
table.stub!(:data).and_return(data)
|
18
|
-
table.stub!(:has_memo_file?).and_return(true)
|
19
|
-
table.data.stub!(:read).and_return(data)
|
20
|
-
table
|
21
|
-
end
|
22
|
-
|
23
|
-
describe '#memo_block_content_size' do
|
24
|
-
it "should equal the difference between the table's memo_block_size and 8" do
|
25
|
-
table = mock_table
|
26
|
-
table.should_receive(:memo_block_size).and_return(128)
|
27
|
-
record = DBF::Record.new(table)
|
28
|
-
|
29
|
-
record.send(:memo_block_content_size).should == 120
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe '#memo_content_size' do
|
34
|
-
it "should equal 8 plus the difference between memo_size and the table's memo_block_size" do
|
35
|
-
record = example_record
|
36
|
-
record.should_receive(:memo_block_size).and_return(8)
|
37
|
-
|
38
|
-
record.send(:memo_content_size, 1024).should == 1024
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe '#read_memo' do
|
43
|
-
before do
|
44
|
-
@table = mock_table
|
45
|
-
@record = DBF::Record.new(@table)
|
46
|
-
end
|
47
|
-
|
48
|
-
context 'with start_block of 0' do
|
49
|
-
specify { @record.send(:read_memo, 0).should be_nil }
|
50
|
-
end
|
51
|
-
|
52
|
-
context 'with start_block less than 0' do
|
53
|
-
specify { @record.send(:read_memo, -1).should be_nil }
|
54
|
-
end
|
55
|
-
|
56
|
-
context 'with valid start_block' do
|
57
|
-
before do
|
58
|
-
@table.stub!(:memo_file_format).and_return(:fpt)
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'should build the fpt memo' do
|
62
|
-
@record.should_receive(:build_fpt_memo)
|
63
|
-
@record.send(:read_memo, 1)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
context 'with no memo file' do
|
68
|
-
specify do
|
69
|
-
@table.should_receive(:has_memo_file?).and_return(false)
|
70
|
-
@record.send(:read_memo, 5).should be_nil
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
describe '#to_a' do
|
76
|
-
it 'should return an ordered array of attribute values' do
|
77
|
-
table = DBF::Table.new "#{DB_PATH}/dbase_8b.dbf"
|
78
|
-
record = table.record(9)
|
79
|
-
record.to_a.should == ["Ten records stored in this database", 10.0, nil, false, 0.1, nil]
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
describe '#==' do
|
84
|
-
before do
|
85
|
-
@record = example_record
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'should be false if other does not have attributes' do
|
89
|
-
other = mock('object')
|
90
|
-
(@record == other).should be_false
|
91
|
-
end
|
92
|
-
|
93
|
-
it 'should be true if other attributes match' do
|
94
|
-
attributes = {:x => 1, :y => 2}
|
95
|
-
@record.stub!(:attributes).and_return(attributes)
|
96
|
-
other = mock('object', :attributes => attributes)
|
97
|
-
(@record == other).should be_true
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
describe 'unpack_data' do
|
102
|
-
before do
|
103
|
-
@record = example_record('abc')
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'should unpack the data' do
|
107
|
-
@record.send(:unpack_data, 3).should == 'abc'
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
end
|