infused-dbf 1.0.7
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.
- data/History.txt +55 -0
- data/Manifest.txt +31 -0
- data/README.txt +115 -0
- data/Rakefile +37 -0
- data/bin/dbf +40 -0
- data/dbf.gemspec +37 -0
- data/lib/dbf/column.rb +85 -0
- data/lib/dbf/globals.rb +27 -0
- data/lib/dbf/record.rb +99 -0
- data/lib/dbf/table.rb +243 -0
- data/lib/dbf.rb +7 -0
- data/spec/fixtures/dbase_03.dbf +0 -0
- data/spec/fixtures/dbase_30.dbf +0 -0
- data/spec/fixtures/dbase_30.fpt +0 -0
- data/spec/fixtures/dbase_83.dbf +0 -0
- data/spec/fixtures/dbase_83.dbt +0 -0
- data/spec/fixtures/dbase_83_schema.txt +19 -0
- data/spec/fixtures/dbase_8b.dbf +0 -0
- data/spec/fixtures/dbase_8b.dbt +0 -0
- data/spec/fixtures/dbase_f5.dbf +0 -0
- data/spec/fixtures/dbase_f5.fpt +0 -0
- data/spec/functional/dbf_shared.rb +45 -0
- data/spec/functional/format_03_spec.rb +23 -0
- data/spec/functional/format_30_spec.rb +23 -0
- data/spec/functional/format_83_spec.rb +23 -0
- data/spec/functional/format_8b_spec.rb +23 -0
- data/spec/functional/format_f5_spec.rb +23 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/unit/column_spec.rb +124 -0
- data/spec/unit/record_spec.rb +99 -0
- data/spec/unit/table_spec.rb +162 -0
- metadata +103 -0
@@ -0,0 +1,99 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../spec_helper"
|
2
|
+
|
3
|
+
describe DBF::Record do
|
4
|
+
|
5
|
+
def example_record(data = '')
|
6
|
+
DBF::Record.new(mock_table(data))
|
7
|
+
end
|
8
|
+
|
9
|
+
def mock_table(data = '')
|
10
|
+
table = mock('table')
|
11
|
+
table.stub!(:memo_block_size).and_return(8)
|
12
|
+
table.stub!(:memo).and_return(nil)
|
13
|
+
table.stub!(:columns).and_return([])
|
14
|
+
table.stub!(:data)
|
15
|
+
table.stub!(:has_memo_file?).and_return(true)
|
16
|
+
table.data.stub!(:read).and_return(data)
|
17
|
+
table
|
18
|
+
end
|
19
|
+
|
20
|
+
context "when initialized" do
|
21
|
+
it "should typecast number columns with decimals == 0 to Integer" do
|
22
|
+
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
23
|
+
table.column("ID").type.should == "N"
|
24
|
+
table.column("ID").decimal.should == 0
|
25
|
+
table.records.all? {|record| record.attributes['id'].should be_kind_of(Integer)}
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should typecast number columns with decimals > 0 to Float" do
|
29
|
+
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
30
|
+
table.column("ID").type.should == "N"
|
31
|
+
table.column("COST").decimal.should == 2
|
32
|
+
table.records.all? {|record| record.attributes['cost'].should be_kind_of(Float)}
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should typecast memo columns to String" do
|
36
|
+
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
37
|
+
table.column("DESC").type.should == "M"
|
38
|
+
table.records.all? {|record| record.attributes['desc'].should be_kind_of(String)}
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should typecast logical columns to True or False" do
|
42
|
+
table = DBF::Table.new "#{DB_PATH}/dbase_30.dbf"
|
43
|
+
table.column("WEBINCLUDE").type.should == "L"
|
44
|
+
table.records.all? {|record| record.attributes["webinclude"].should satisfy {|v| v == true || v == false}}
|
45
|
+
end
|
46
|
+
|
47
|
+
# it "should typecast datetime columns to DateTime" do
|
48
|
+
# record = example_record("Nl%\000\300Z\252\003")
|
49
|
+
# column = mock('column', :length => 8)
|
50
|
+
#
|
51
|
+
# record.instance_eval {unpack_datetime(column)}.to_s.should == "2002-10-10T17:04:56+00:00"
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# it "should typecast integers to Fixnum" do
|
55
|
+
# record = example_record("\017\020\000\000")
|
56
|
+
# column = mock('column', :length => 4)
|
57
|
+
#
|
58
|
+
# record.instance_eval {unpack_integer(column)}.should == 4111
|
59
|
+
# end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#memo_block_content_size' do
|
63
|
+
it "should equal the difference between the table's memo_block_size and 8" do
|
64
|
+
table = mock_table
|
65
|
+
table.should_receive(:memo_block_size).and_return(128)
|
66
|
+
record = DBF::Record.new(table)
|
67
|
+
|
68
|
+
record.send(:memo_block_content_size).should == 120
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#memo_content_size' do
|
73
|
+
it "should equal 8 plus the difference between memo_size and the table's memo_block_size" do
|
74
|
+
record = example_record
|
75
|
+
record.should_receive(:memo_block_size).and_return(8)
|
76
|
+
|
77
|
+
record.send(:memo_content_size, 1024).should == 1024
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '#read_memo' do
|
82
|
+
it 'should return nil if start_block is less than 1' do
|
83
|
+
table = mock_table
|
84
|
+
record = DBF::Record.new(table)
|
85
|
+
|
86
|
+
record.send(:read_memo, 0).should be_nil
|
87
|
+
record.send(:read_memo, -1).should be_nil
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should return nil if memo file is missing' do
|
91
|
+
table = mock_table
|
92
|
+
table.should_receive(:has_memo_file?).and_return(false)
|
93
|
+
record = DBF::Record.new(table)
|
94
|
+
|
95
|
+
record.send(:read_memo, 5).should be_nil
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../spec_helper"
|
2
|
+
|
3
|
+
describe DBF::Table do
|
4
|
+
|
5
|
+
context "when initialized" do
|
6
|
+
before do
|
7
|
+
@table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should load the data file" do
|
11
|
+
@table.data.should be_kind_of(File)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should locate load the memo file" do
|
15
|
+
@table.has_memo_file?.should be_true
|
16
|
+
@table.instance_eval("@memo").should be_kind_of(File)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should determine the memo file format" do
|
20
|
+
@table.memo_file_format.should == :dbt
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should determine the correct memo block size" do
|
24
|
+
@table.memo_block_size.should == 512
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should determine the number of columns in each record" do
|
28
|
+
@table.columns.size.should == 15
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should determine the number of records in the database" do
|
32
|
+
@table.record_count.should == 67
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should determine the database version" do
|
36
|
+
@table.version.should == "83"
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#find" do
|
42
|
+
describe "with index" do
|
43
|
+
it "should return the correct record" do
|
44
|
+
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
45
|
+
table.find(5).should == table.record(5)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "with :all" do
|
50
|
+
before do
|
51
|
+
@table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return all records if options are empty" do
|
55
|
+
@table.find(:all).should == @table.records
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should return matching records when used with options" do
|
59
|
+
@table.find(:all, "WEIGHT" => 0.0).should == @table.select {|r| r.attributes["weight"] == 0.0}
|
60
|
+
end
|
61
|
+
|
62
|
+
it "with multiple options should search for all search terms as if using AND" do
|
63
|
+
@table.find(:all, "ID" => 30, "IMAGE" => "graphics/00000001/TBC01.jpg").should == []
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should match original column names" do
|
67
|
+
@table.find(:all, "WEIGHT" => 0.0).should_not be_empty
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should match symbolized column names" do
|
71
|
+
@table.find(:all, :WEIGHT => 0.0).should_not be_empty
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should match downcased column names" do
|
75
|
+
@table.find(:all, "weight" => 0.0).should_not be_empty
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should match symbolized downcased column names" do
|
79
|
+
@table.find(:all, :weight => 0.0).should_not be_empty
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "with :first" do
|
84
|
+
before do
|
85
|
+
@table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should return the first record if options are empty" do
|
89
|
+
@table.find(:first).should == @table.records.first
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should return the first matching record when used with options" do
|
93
|
+
@table.find(:first, "CODE" => "C").should == @table.record(5)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "with multiple options should search for all search terms as if using AND" do
|
97
|
+
@table.find(:first, "ID" => 30, "IMAGE" => "graphics/00000001/TBC01.jpg").should be_nil
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "#reload" do
|
103
|
+
# TODO
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "#column" do
|
107
|
+
it "should accept a string or symbol as input" do
|
108
|
+
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
109
|
+
table.column(:IMAGE).should be_kind_of(DBF::Column)
|
110
|
+
table.column("IMAGE").should be_kind_of(DBF::Column)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should return a DBF::Field object when the column_name exists" do
|
114
|
+
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
115
|
+
table.column(:IMAGE).should be_kind_of(DBF::Column)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should return nil when the column_name does not exist" do
|
119
|
+
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
120
|
+
table.column(:NOTANIMAGE).should be_nil
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "#schema" do
|
125
|
+
it "should match the test schema fixture" do
|
126
|
+
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
127
|
+
control_schema = File.read(File.dirname(__FILE__) + '/../fixtures/dbase_83_schema.txt')
|
128
|
+
|
129
|
+
table.schema.should == control_schema
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "#version_description" do
|
134
|
+
it "should return a text description of the database type" do
|
135
|
+
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
136
|
+
table.version_description.should == "dBase III with memo file"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe '#replace_extname' do
|
141
|
+
it 'should replace the extname' do
|
142
|
+
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
143
|
+
table.send(:replace_extname, "dbase_83.dbf", 'fpt').should == 'dbase_83.fpt'
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe '#each' do
|
148
|
+
it 'should enumerate all records' do
|
149
|
+
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
150
|
+
records = []
|
151
|
+
table.each do |record|
|
152
|
+
records << record
|
153
|
+
end
|
154
|
+
|
155
|
+
records.map! { |r| r.attributes }
|
156
|
+
records.should == table.records.map {|r| r.attributes}
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: infused-dbf
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.7
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Keith Morrison
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-01 00:00:00 -08:00
|
13
|
+
default_executable: dbf
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activesupport
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.1.0
|
23
|
+
version:
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
name: hoe
|
26
|
+
version_requirement:
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - ">="
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: 1.8.2
|
32
|
+
version:
|
33
|
+
description: "DBF is a small fast library for reading dBase, xBase, Clipper and FoxPro database files Copyright (c) 2006-2008 Keith Morrison <keithm@infused.org, www.infused.org> * Official project page: http://rubyforge.org/projects/dbf * API Documentation: http://dbf.rubyforge.org/docs * To report bugs: http://www.rubyforge.org/tracker/?group_id=2009 * Questions: Email keithm@infused.org and put DBF somewhere in the subject line"
|
34
|
+
email: keithm@infused.org
|
35
|
+
executables:
|
36
|
+
- dbf
|
37
|
+
extensions: []
|
38
|
+
|
39
|
+
extra_rdoc_files:
|
40
|
+
- History.txt
|
41
|
+
- Manifest.txt
|
42
|
+
- README.txt
|
43
|
+
files:
|
44
|
+
- History.txt
|
45
|
+
- Manifest.txt
|
46
|
+
- README.txt
|
47
|
+
- Rakefile
|
48
|
+
- bin/dbf
|
49
|
+
- dbf.gemspec
|
50
|
+
- lib/dbf.rb
|
51
|
+
- lib/dbf/column.rb
|
52
|
+
- lib/dbf/globals.rb
|
53
|
+
- lib/dbf/record.rb
|
54
|
+
- lib/dbf/table.rb
|
55
|
+
- spec/fixtures/dbase_03.dbf
|
56
|
+
- spec/fixtures/dbase_30.dbf
|
57
|
+
- spec/fixtures/dbase_30.fpt
|
58
|
+
- spec/fixtures/dbase_83.dbf
|
59
|
+
- spec/fixtures/dbase_83.dbt
|
60
|
+
- spec/fixtures/dbase_83_schema.txt
|
61
|
+
- spec/fixtures/dbase_8b.dbf
|
62
|
+
- spec/fixtures/dbase_8b.dbt
|
63
|
+
- spec/fixtures/dbase_f5.dbf
|
64
|
+
- spec/fixtures/dbase_f5.fpt
|
65
|
+
- spec/functional/dbf_shared.rb
|
66
|
+
- spec/functional/format_03_spec.rb
|
67
|
+
- spec/functional/format_30_spec.rb
|
68
|
+
- spec/functional/format_83_spec.rb
|
69
|
+
- spec/functional/format_8b_spec.rb
|
70
|
+
- spec/functional/format_f5_spec.rb
|
71
|
+
- spec/spec_helper.rb
|
72
|
+
- spec/unit/column_spec.rb
|
73
|
+
- spec/unit/record_spec.rb
|
74
|
+
- spec/unit/table_spec.rb
|
75
|
+
has_rdoc: true
|
76
|
+
homepage: http://github.com/infused/dm-dbf/tree/master
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options:
|
79
|
+
- --main
|
80
|
+
- README.txt
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: "0"
|
88
|
+
version:
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: "0"
|
94
|
+
version:
|
95
|
+
requirements: []
|
96
|
+
|
97
|
+
rubyforge_project: dbf
|
98
|
+
rubygems_version: 1.2.0
|
99
|
+
signing_key:
|
100
|
+
specification_version: 2
|
101
|
+
summary: A small fast library for reading dBase, xBase, Clipper and FoxPro database files.
|
102
|
+
test_files: []
|
103
|
+
|