infused-dbf 1.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|