dbf 1.2.9 → 1.3.0
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/CHANGELOG.md +126 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +14 -0
- data/{README.markdown → README.md} +17 -20
- data/Rakefile +57 -29
- data/lib/dbf.rb +9 -4
- data/lib/dbf/attributes.rb +6 -0
- data/lib/dbf/column.rb +6 -2
- data/lib/dbf/record.rb +20 -17
- data/lib/dbf/table.rb +32 -24
- data/lib/dbf/version.rb +3 -0
- data/spec/unit/column_spec.rb +30 -33
- data/spec/unit/record_spec.rb +8 -8
- metadata +39 -29
- data/.autotest +0 -15
- data/.gitignore +0 -1
- data/History.txt +0 -118
- data/VERSION.yml +0 -5
- data/dbf.gemspec +0 -94
- data/lib/dbf/globals.rb +0 -22
data/CHANGELOG.md
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
## 1.2.9
|
2
|
+
|
3
|
+
- Retain trailing whitespace in memos
|
4
|
+
|
5
|
+
## 1.2.8
|
6
|
+
|
7
|
+
- Handle missing zeros in date values [#11]
|
8
|
+
|
9
|
+
## 1.2.7
|
10
|
+
|
11
|
+
- MIT License
|
12
|
+
|
13
|
+
## 1.2.6
|
14
|
+
|
15
|
+
- Support for Ruby 1.9.2
|
16
|
+
|
17
|
+
## 1.2.5
|
18
|
+
|
19
|
+
- Remove ruby warning switch
|
20
|
+
- Requires activesupport version 2.3.5
|
21
|
+
|
22
|
+
## 1.2.4
|
23
|
+
|
24
|
+
- Add csv output option to dbf command-line utility
|
25
|
+
- Read Visual FoxPro memos
|
26
|
+
|
27
|
+
## 1.2.3
|
28
|
+
|
29
|
+
- Small performance gain when unpacking values from the dbf file
|
30
|
+
- Correctly handle FoxPro's integer data type
|
31
|
+
|
32
|
+
## 1.2.2
|
33
|
+
|
34
|
+
- Handle invalid date fields
|
35
|
+
|
36
|
+
## 1.2.1
|
37
|
+
|
38
|
+
- Add support for F field type (Float)
|
39
|
+
|
40
|
+
## 1.2.0
|
41
|
+
|
42
|
+
- Add Table#to_a
|
43
|
+
|
44
|
+
## 1.1.1
|
45
|
+
|
46
|
+
- Return invalid DateTime columns as nil
|
47
|
+
|
48
|
+
## 1.1.0
|
49
|
+
|
50
|
+
- Add support for large table that will not fit into memory
|
51
|
+
|
52
|
+
## 1.0.13
|
53
|
+
|
54
|
+
- Allow passing an array of ids to find
|
55
|
+
|
56
|
+
## 1.0.11
|
57
|
+
|
58
|
+
- Attributes are now accessible by original or underscored name
|
59
|
+
|
60
|
+
## 1.0.9
|
61
|
+
|
62
|
+
- Fix incorrect integer column values (only affecting some dbf files)
|
63
|
+
- Add CSV export
|
64
|
+
|
65
|
+
## 1.0.8
|
66
|
+
|
67
|
+
- Truncate column names on NULL
|
68
|
+
- Fix schema dump for date and datetime columns
|
69
|
+
- Replace internal helpers with ActiveSupport
|
70
|
+
- Always underscore attribute names
|
71
|
+
|
72
|
+
## 1.0.7
|
73
|
+
|
74
|
+
- Remove support for original column names. All columns names are now downcased/underscored.
|
75
|
+
|
76
|
+
## 1.0.6
|
77
|
+
|
78
|
+
- DBF::Table now includes the Enumerable module
|
79
|
+
- Return nil for memo values if the memo file is missing
|
80
|
+
- Finder conditions now support the original and downcased/underscored column names
|
81
|
+
|
82
|
+
## 1.0.5
|
83
|
+
|
84
|
+
- Strip non-ascii characters from column names
|
85
|
+
|
86
|
+
## 1.0.4
|
87
|
+
|
88
|
+
- Underscore column names when dumping schemas (FieldId becomes field_id)
|
89
|
+
|
90
|
+
## 1.0.3
|
91
|
+
|
92
|
+
- Add support for Visual Foxpro Integer and Datetime columns
|
93
|
+
|
94
|
+
## 1.0.2
|
95
|
+
|
96
|
+
- Compatibility fix for Visual Foxpro memo files (ignore negative memo index values)
|
97
|
+
|
98
|
+
## 1.0.1
|
99
|
+
|
100
|
+
- Fixes error when using the command-line interface [#11984]
|
101
|
+
|
102
|
+
## 1.0.0
|
103
|
+
|
104
|
+
- Renamed classes and refactored code in preparation for adding the
|
105
|
+
ability to save records and create/compact databases.
|
106
|
+
- The Reader class has been renamed to Table
|
107
|
+
- Attributes are no longer accessed directly from the record. Use record.attribute['column_name']
|
108
|
+
instead, or use the new attribute accessors detailed under Basic Usage.
|
109
|
+
|
110
|
+
## 0.5.4
|
111
|
+
|
112
|
+
- Ignore deleted records in both memory modes
|
113
|
+
|
114
|
+
## 0.5.3
|
115
|
+
|
116
|
+
- Added a standalone dbf utility (try dbf -h for help)
|
117
|
+
|
118
|
+
## 0.5.0 / 2007-05-25
|
119
|
+
|
120
|
+
- New find method
|
121
|
+
- Full compatibility with the two flavors of memo file
|
122
|
+
- Two modes of operation:
|
123
|
+
- In memory (default): All records are loaded into memory on the first
|
124
|
+
request. Records are retrieved from memory for all subsequent requests.
|
125
|
+
- File I/O: All records are retrieved from disk on every request
|
126
|
+
- Improved documentation and more usage examples
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -11,7 +11,7 @@ database files
|
|
11
11
|
|
12
12
|
## Compatibility
|
13
13
|
|
14
|
-
DBF is tested to work with Ruby 1.8.6, 1.8.7, 1.9.1 and 1.9.2
|
14
|
+
DBF is tested to work with Ruby 1.8.6, 1.8.7, 1.9.1 and 1.9.2
|
15
15
|
|
16
16
|
## Installation
|
17
17
|
|
@@ -38,21 +38,21 @@ Load a single record using <tt>record</tt> or <tt>find</tt>
|
|
38
38
|
table.find(6)
|
39
39
|
|
40
40
|
Attributes can also be accessed through the attributes hash in original or
|
41
|
-
underscored form or as an accessor method using the underscored name.
|
42
|
-
|
43
|
-
|
41
|
+
underscored form or as an accessor method using the underscored name. (Note
|
42
|
+
that record() will return nil if the requested record has been deleted and not
|
43
|
+
yet pruned from the database)
|
44
44
|
|
45
45
|
table.record(4).attributes["PhoneBook"]
|
46
46
|
table.record(4).attributes["phone_book"]
|
47
47
|
table.record(4).phone_book
|
48
48
|
|
49
|
-
Search for records using a simple hash format.
|
50
|
-
ANDed. Use the block form
|
51
|
-
|
49
|
+
Search for records using a simple hash format. Multiple search criteria are
|
50
|
+
ANDed. Use the block form if the resulting recordset could be large, otherwise
|
51
|
+
all records will be loaded into memory.
|
52
52
|
|
53
53
|
# find all records with first_name equal to Keith
|
54
54
|
table.find(:all, :first_name => 'Keith') do |record|
|
55
|
-
# the record will be nil if deleted
|
55
|
+
# the record will be nil if deleted, but not yet pruned from the database
|
56
56
|
if record
|
57
57
|
puts record.last_name
|
58
58
|
end
|
@@ -100,26 +100,23 @@ A small command-line utility called dbf is installed along with the gem.
|
|
100
100
|
|
101
101
|
The basic dBase data types are generally supported well. Support for the
|
102
102
|
advanced data types in dbase V and FoxPro are still experimental or not
|
103
|
-
supported. If you have
|
104
|
-
|
105
|
-
|
103
|
+
supported. If you have insight into how any of unsupported data types are
|
104
|
+
implemented, please give me a shout. FoxBase/dBase II files are not supported
|
105
|
+
at this time.
|
106
106
|
|
107
|
-
See
|
108
|
-
|
107
|
+
See
|
108
|
+
[docs/supported_types.markdown](http://github.com/infused/dbf/blob/master/docs/supported_types.markdown)
|
109
|
+
for a full list of supported column types.
|
109
110
|
|
110
111
|
## Limitations
|
111
112
|
|
112
113
|
* DBF is read-only
|
113
|
-
*
|
114
|
-
* No
|
115
|
-
in the dBase file
|
114
|
+
* Index files are not utilized
|
115
|
+
* No character set conversions from the code page defined in the dBase file
|
116
116
|
|
117
117
|
## License
|
118
118
|
|
119
|
-
(
|
120
|
-
|
121
|
-
Copyright (c) 2006-2010 Keith Morrison <mailto:keithm@infused.org>,
|
122
|
-
<http://www.infused.org>.
|
119
|
+
Copyright (c) 2006-2010 Keith Morrison <keithm@infused.org>
|
123
120
|
|
124
121
|
Permission is hereby granted, free of charge, to any person
|
125
122
|
obtaining a copy of this software and associated documentation
|
data/Rakefile
CHANGED
@@ -1,40 +1,68 @@
|
|
1
|
-
|
2
|
-
$: << File.join(PROJECT_ROOT, 'lib')
|
1
|
+
# encoding: utf-8
|
3
2
|
|
4
3
|
require 'rubygems'
|
5
|
-
require '
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
s.platform = Gem::Platform::RUBY
|
13
|
-
s.authors = ['Keith Morrison']
|
14
|
-
s.email = 'keithm@infused.org'
|
15
|
-
s.add_dependency('activesupport', ['>= 2.3.5'])
|
16
|
-
s.add_dependency('fastercsv', ['>= 1.4.0'])
|
17
|
-
s.homepage = 'http://github.com/infused/dbf'
|
4
|
+
require 'rubygems/specification'
|
5
|
+
|
6
|
+
def gemspec
|
7
|
+
@gemspec ||= begin
|
8
|
+
file = File.expand_path('../dbf.gemspec', __FILE__)
|
9
|
+
eval(File.read(file), binding, file)
|
10
|
+
end
|
18
11
|
end
|
19
12
|
|
20
|
-
|
13
|
+
begin
|
14
|
+
require 'rake/gempackagetask'
|
15
|
+
rescue LoadError
|
16
|
+
task(:gem) { $stderr.puts '`gem install rake` to package gems' }
|
17
|
+
else
|
18
|
+
Rake::GemPackageTask.new(gemspec) do |pkg|
|
19
|
+
pkg.gem_spec = gemspec
|
20
|
+
end
|
21
|
+
task :gem => :gemspec
|
22
|
+
end
|
21
23
|
|
22
|
-
|
24
|
+
begin
|
25
|
+
require 'spec/rake/spectask'
|
26
|
+
rescue LoadError
|
27
|
+
raise 'Run `gem install rspec` to be able to run specs'
|
28
|
+
else
|
29
|
+
task :clear_tmp do
|
30
|
+
FileUtils.rm_rf(File.expand_path("../tmp", __FILE__))
|
31
|
+
end
|
23
32
|
|
24
|
-
desc "Run specs"
|
25
|
-
Spec::Rake::SpecTask.new
|
26
|
-
|
33
|
+
desc "Run specs"
|
34
|
+
Spec::Rake::SpecTask.new do |t|
|
35
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
36
|
+
t.spec_opts = %w(-fs --color)
|
37
|
+
t.warning = true
|
38
|
+
end
|
39
|
+
task :spec
|
27
40
|
end
|
28
41
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
42
|
+
require 'rake'
|
43
|
+
require 'rake/rdoctask'
|
44
|
+
Rake::RDocTask.new { |rdoc|
|
45
|
+
rdoc.rdoc_dir = 'doc'
|
46
|
+
rdoc.title = "DBF - A small fast library for reading dBase, xBase, Clipper and FoxPro database files."
|
47
|
+
rdoc.options << '--line-numbers'
|
48
|
+
rdoc.template = "#{ENV['template']}.rb" if ENV['template']
|
49
|
+
rdoc.rdoc_files.include('README.md', 'docs/supported_types.markdown', 'lib/**/*.rb')
|
50
|
+
}
|
51
|
+
|
52
|
+
desc "install the gem locally"
|
53
|
+
task :install => :package do
|
54
|
+
sh %{gem install pkg/#{gemspec.name}-#{gemspec.version}}
|
34
55
|
end
|
35
56
|
|
36
|
-
desc "
|
37
|
-
|
38
|
-
|
39
|
-
t.spec_files = FileList['spec/**/*spec.rb']
|
57
|
+
desc "validate the gemspec"
|
58
|
+
task :gemspec do
|
59
|
+
gemspec.validate
|
40
60
|
end
|
61
|
+
|
62
|
+
task :package => :gemspec
|
63
|
+
task :default => :spec
|
64
|
+
|
65
|
+
desc "Open an irb session preloaded with this library"
|
66
|
+
task :console do
|
67
|
+
sh "irb -rubygems -I lib -r dbf.rb"
|
68
|
+
end
|
data/lib/dbf.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
require 'date'
|
2
|
-
gem 'activesupport', '
|
3
|
-
require 'active_support'
|
4
|
-
require 'active_support/core_ext'
|
2
|
+
gem 'activesupport', '=3.0.0'
|
3
|
+
require 'active_support/core_ext/object'
|
4
|
+
require 'active_support/core_ext/date/conversions'
|
5
|
+
require 'active_support/core_ext/time/conversions'
|
6
|
+
require 'active_support/core_ext/date_time/conversions'
|
7
|
+
require 'active_support/core_ext/string/conversions'
|
8
|
+
require 'active_support/core_ext/module/delegation'
|
9
|
+
require 'active_support/core_ext/string/inflections'
|
5
10
|
|
6
11
|
if RUBY_VERSION > '1.9'
|
7
12
|
require 'csv'
|
@@ -15,7 +20,7 @@ else
|
|
15
20
|
require 'fastercsv'
|
16
21
|
end
|
17
22
|
|
18
|
-
require 'dbf/
|
23
|
+
require 'dbf/attributes'
|
19
24
|
require 'dbf/record'
|
20
25
|
require 'dbf/column'
|
21
26
|
require 'dbf/table'
|
data/lib/dbf/column.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module DBF
|
2
|
-
class ColumnLengthError <
|
3
|
-
class ColumnNameError <
|
2
|
+
class ColumnLengthError < StandardError; end
|
3
|
+
class ColumnNameError < StandardError; end
|
4
4
|
|
5
5
|
# DBF::Column stores all the information about a column including its name,
|
6
6
|
# type, length and number of decimal places (if any)
|
@@ -143,6 +143,10 @@ module DBF
|
|
143
143
|
|
144
144
|
s.gsub(/[^\x20-\x7E]/,"")
|
145
145
|
end
|
146
|
+
|
147
|
+
def memo?
|
148
|
+
type == 'M'
|
149
|
+
end
|
146
150
|
end
|
147
151
|
|
148
152
|
end
|
data/lib/dbf/record.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
module DBF
|
2
|
-
|
3
2
|
# An instance of DBF::Record represents a row in the DBF file
|
4
3
|
class Record
|
4
|
+
BLOCK_HEADER_SIZE = 8
|
5
|
+
|
6
|
+
attr_reader :table
|
5
7
|
attr_reader :attributes
|
6
8
|
attr_reader :memo_block_size
|
7
9
|
|
8
|
-
delegate :columns, :to =>
|
10
|
+
delegate :columns, :to => :table
|
9
11
|
|
10
12
|
# Initialize a new DBF::Record
|
11
13
|
#
|
@@ -32,14 +34,21 @@ module DBF
|
|
32
34
|
columns.map { |column| @attributes[column.name.underscore] }
|
33
35
|
end
|
34
36
|
|
37
|
+
# Do all search parameters match?
|
38
|
+
#
|
39
|
+
# @param [Hash] options
|
40
|
+
# @return [Boolean]
|
41
|
+
def match?(options)
|
42
|
+
options.all? {|key, value| attributes[key.to_s.underscore] == value}
|
43
|
+
end
|
44
|
+
|
35
45
|
private
|
36
46
|
|
37
47
|
# Defined attribute accessor methods
|
38
48
|
def define_accessors
|
39
49
|
columns.each do |column|
|
40
|
-
|
41
|
-
|
42
|
-
self.class.send :define_method, underscored_column_name do
|
50
|
+
unless self.class.method_defined?(column.name.underscore)
|
51
|
+
self.class.send :define_method, column.name.underscore do
|
43
52
|
@attributes[column.name.underscore]
|
44
53
|
end
|
45
54
|
end
|
@@ -48,16 +57,11 @@ module DBF
|
|
48
57
|
|
49
58
|
# Initialize values for a row
|
50
59
|
def initialize_values
|
51
|
-
@attributes = columns.inject(
|
52
|
-
if column.
|
53
|
-
|
54
|
-
hash[column.name] = memo
|
55
|
-
hash[column.name.underscore] = memo
|
60
|
+
@attributes = columns.inject(Attributes.new) do |hash, column|
|
61
|
+
if column.memo?
|
62
|
+
hash[column.name] = read_memo(get_starting_block(column))
|
56
63
|
else
|
57
|
-
|
58
|
-
type_cast_value = column.type_cast(value)
|
59
|
-
hash[column.name] = type_cast_value
|
60
|
-
hash[column.name.underscore] = type_cast_value
|
64
|
+
hash[column.name] = column.type_cast(unpack_data(column.length))
|
61
65
|
end
|
62
66
|
hash
|
63
67
|
end
|
@@ -86,8 +90,7 @@ module DBF
|
|
86
90
|
# @param [Fixnum] start_block
|
87
91
|
def read_memo(start_block)
|
88
92
|
return nil if !@table.has_memo_file? || start_block < 1
|
89
|
-
|
90
|
-
@table.memo_file_format == :fpt ? build_fpt_memo(start_block) : build_dbt_memo(start_block)
|
93
|
+
send "build_#{@table.memo_file_format}_memo", start_block
|
91
94
|
end
|
92
95
|
|
93
96
|
# Reconstructs a memo from an FPT memo file
|
@@ -98,7 +101,7 @@ module DBF
|
|
98
101
|
@memo.seek(start_block * memo_block_size)
|
99
102
|
|
100
103
|
memo_type, memo_size, memo_string = @memo.read(memo_block_size).unpack("NNa*")
|
101
|
-
return nil unless memo_type == 1
|
104
|
+
return nil unless memo_type == 1 && memo_size > 0
|
102
105
|
|
103
106
|
if memo_size > memo_block_content_size
|
104
107
|
memo_string << @memo.read(memo_content_size(memo_size))
|
data/lib/dbf/table.rb
CHANGED
@@ -3,6 +3,24 @@ module DBF
|
|
3
3
|
# DBF::Table is the primary interface to a single DBF file and provides
|
4
4
|
# methods for enumerating and searching the records.
|
5
5
|
class Table
|
6
|
+
DBF_HEADER_SIZE = 32
|
7
|
+
FPT_HEADER_SIZE = 512
|
8
|
+
|
9
|
+
VERSION_DESCRIPTIONS = {
|
10
|
+
"02" => "FoxBase",
|
11
|
+
"03" => "dBase III without memo file",
|
12
|
+
"04" => "dBase IV without memo file",
|
13
|
+
"05" => "dBase V without memo file",
|
14
|
+
"30" => "Visual FoxPro",
|
15
|
+
"31" => "Visual FoxPro with AutoIncrement field",
|
16
|
+
"7b" => "dBase IV with memo file",
|
17
|
+
"83" => "dBase III with memo file",
|
18
|
+
"8b" => "dBase IV with memo file",
|
19
|
+
"8e" => "dBase IV with SQL table",
|
20
|
+
"f5" => "FoxPro with memo file",
|
21
|
+
"fb" => "FoxPro without memo file"
|
22
|
+
}
|
23
|
+
|
6
24
|
attr_reader :column_count # The total number of columns
|
7
25
|
attr_reader :columns # An array of DBF::Column
|
8
26
|
attr_reader :version # Internal dBase version number
|
@@ -35,7 +53,7 @@ module DBF
|
|
35
53
|
def reload!
|
36
54
|
@records = nil
|
37
55
|
get_header_info
|
38
|
-
get_memo_header_info
|
56
|
+
get_memo_header_info
|
39
57
|
get_column_descriptors
|
40
58
|
end
|
41
59
|
|
@@ -59,10 +77,7 @@ module DBF
|
|
59
77
|
#
|
60
78
|
# @yield [nil, DBF::Record]
|
61
79
|
def each
|
62
|
-
0.upto(@record_count - 1)
|
63
|
-
seek_to_record(n)
|
64
|
-
yield current_record
|
65
|
-
end
|
80
|
+
0.upto(@record_count - 1) {|index| yield record(index)}
|
66
81
|
end
|
67
82
|
|
68
83
|
# Retrieve a record by index number.
|
@@ -189,9 +204,9 @@ module DBF
|
|
189
204
|
def find_all(options, &block)
|
190
205
|
results = []
|
191
206
|
each do |record|
|
192
|
-
if record
|
207
|
+
if record.try(:match?, options)
|
193
208
|
if block_given?
|
194
|
-
yield
|
209
|
+
yield record
|
195
210
|
else
|
196
211
|
results << record
|
197
212
|
end
|
@@ -206,20 +221,11 @@ module DBF
|
|
206
221
|
# @return [DBF::Record, nil]
|
207
222
|
def find_first(options)
|
208
223
|
each do |record|
|
209
|
-
return record if record
|
224
|
+
return record if record.try(:match?, options)
|
210
225
|
end
|
211
226
|
nil
|
212
227
|
end
|
213
228
|
|
214
|
-
# Do all search parameters match?
|
215
|
-
#
|
216
|
-
# @param [DBF::Record] record
|
217
|
-
# @param [Hash] options
|
218
|
-
# @return [Boolean]
|
219
|
-
def all_values_match?(record, options)
|
220
|
-
options.all? {|key, value| record.attributes[key.to_s.underscore] == value}
|
221
|
-
end
|
222
|
-
|
223
229
|
# Open memo file
|
224
230
|
#
|
225
231
|
# @params [String] path
|
@@ -279,13 +285,15 @@ module DBF
|
|
279
285
|
|
280
286
|
# Determines the memo block size and next available block
|
281
287
|
def get_memo_header_info
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
288
|
+
if has_memo_file?
|
289
|
+
@memo.rewind
|
290
|
+
if @memo_file_format == :fpt
|
291
|
+
@memo_next_available_block, @memo_block_size = @memo.read(FPT_HEADER_SIZE).unpack('N x2 n')
|
292
|
+
@memo_block_size = 0 if @memo_block_size.nil?
|
293
|
+
else
|
294
|
+
@memo_block_size = 512
|
295
|
+
@memo_next_available_block = File.size(@memo.path) / @memo_block_size
|
296
|
+
end
|
289
297
|
end
|
290
298
|
end
|
291
299
|
|
data/lib/dbf/version.rb
ADDED
data/spec/unit/column_spec.rb
CHANGED
@@ -7,19 +7,19 @@ describe DBF::Column do
|
|
7
7
|
@column = DBF::Column.new "ColumnName", "N", 1, 0
|
8
8
|
end
|
9
9
|
|
10
|
-
it "
|
10
|
+
it "sets the #name accessor" do
|
11
11
|
@column.name.should == "ColumnName"
|
12
12
|
end
|
13
13
|
|
14
|
-
it "
|
14
|
+
it "sets the #type accessor" do
|
15
15
|
@column.type.should == "N"
|
16
16
|
end
|
17
17
|
|
18
|
-
it "
|
18
|
+
it "sets the #length accessor" do
|
19
19
|
@column.length.should == 1
|
20
20
|
end
|
21
21
|
|
22
|
-
it "
|
22
|
+
it "sets the #decimal accessor" do
|
23
23
|
@column.decimal.should == 0
|
24
24
|
end
|
25
25
|
|
@@ -36,20 +36,20 @@ describe DBF::Column do
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
context
|
39
|
+
context '#type_cast' do
|
40
40
|
context 'with type N (number)' do
|
41
|
-
context '
|
42
|
-
it '
|
43
|
-
value =
|
41
|
+
context 'and 0 decimals' do
|
42
|
+
it 'casts value to Fixnum' do
|
43
|
+
value = '135'
|
44
44
|
column = DBF::Column.new "ColumnName", "N", 3, 0
|
45
45
|
column.type_cast(value).should be_a Fixnum
|
46
46
|
column.type_cast(value).should == 135
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
context '
|
51
|
-
it
|
52
|
-
value =
|
50
|
+
context 'and more than 0 decimals' do
|
51
|
+
it 'casts value to Float' do
|
52
|
+
value = '13.5'
|
53
53
|
column = DBF::Column.new "ColumnName", "N", 2, 1
|
54
54
|
column.type_cast(value).should be_a Float
|
55
55
|
column.type_cast(value).should == 13.5
|
@@ -58,8 +58,8 @@ describe DBF::Column do
|
|
58
58
|
end
|
59
59
|
|
60
60
|
context 'with type F (float)' do
|
61
|
-
it
|
62
|
-
value =
|
61
|
+
it 'casts value to Float' do
|
62
|
+
value = '135'
|
63
63
|
column = DBF::Column.new "ColumnName", "F", 3, 0
|
64
64
|
column.type_cast(value).should be_a Float
|
65
65
|
column.type_cast(value).should == 135.0
|
@@ -67,33 +67,30 @@ describe DBF::Column do
|
|
67
67
|
end
|
68
68
|
|
69
69
|
context 'with type I (integer)' do
|
70
|
-
it "
|
70
|
+
it "casts value to Fixnum" do
|
71
71
|
value = "\203\171\001\000"
|
72
72
|
column = DBF::Column.new "ColumnName", "I", 3, 0
|
73
|
-
column.type_cast(value).should be_a Fixnum
|
74
73
|
column.type_cast(value).should == 96643
|
75
74
|
end
|
76
75
|
end
|
77
76
|
|
78
77
|
context 'with type L (logical/boolean)' do
|
79
|
-
it "
|
78
|
+
it "casts 'y' to true" do
|
80
79
|
value = "y"
|
81
80
|
column = DBF::Column.new "ColumnName", "L", 1, 0
|
82
|
-
column.type_cast(value).should be_a TrueClass
|
83
81
|
column.type_cast(value).should == true
|
84
82
|
end
|
85
83
|
|
86
|
-
it "
|
84
|
+
it "casts 'n' to false" do
|
87
85
|
value = "n"
|
88
86
|
column = DBF::Column.new "ColumnName", "L", 1, 0
|
89
|
-
column.type_cast(value).should be_a FalseClass
|
90
87
|
column.type_cast(value).should == false
|
91
88
|
end
|
92
89
|
end
|
93
90
|
|
94
91
|
context 'with type T (datetime)' do
|
95
92
|
context 'with valid datetime' do
|
96
|
-
it "
|
93
|
+
it "casts to DateTime" do
|
97
94
|
value = "Nl%\000\300Z\252\003"
|
98
95
|
column = DBF::Column.new "ColumnName", "T", 16, 0
|
99
96
|
column.type_cast(value).should == "2002-10-10T17:04:56+00:00"
|
@@ -101,7 +98,7 @@ describe DBF::Column do
|
|
101
98
|
end
|
102
99
|
|
103
100
|
context 'with invalid datetime' do
|
104
|
-
it "
|
101
|
+
it "casts to nil" do
|
105
102
|
value = "Nl%\000\000A\000\999"
|
106
103
|
column = DBF::Column.new "ColumnName", "T", 16, 0
|
107
104
|
column.type_cast(value).should be_nil
|
@@ -111,7 +108,7 @@ describe DBF::Column do
|
|
111
108
|
|
112
109
|
context 'with type D (date)' do
|
113
110
|
context 'with valid date' do
|
114
|
-
it "
|
111
|
+
it "casts to Date" do
|
115
112
|
value = "20050712"
|
116
113
|
column = DBF::Column.new "ColumnName", "D", 8, 0
|
117
114
|
column.type_cast(value).should == Date.new(2005,7,12)
|
@@ -119,7 +116,7 @@ describe DBF::Column do
|
|
119
116
|
end
|
120
117
|
|
121
118
|
context 'with invalid date' do
|
122
|
-
it "
|
119
|
+
it "casts to nil" do
|
123
120
|
value = "0"
|
124
121
|
column = DBF::Column.new "ColumnName", "D", 8, 0
|
125
122
|
column.type_cast(value).should be_nil
|
@@ -128,7 +125,7 @@ describe DBF::Column do
|
|
128
125
|
end
|
129
126
|
|
130
127
|
context 'with type M (memo)' do
|
131
|
-
it "
|
128
|
+
it "casts to string" do
|
132
129
|
value = 'abc'
|
133
130
|
column = DBF::Column.new "ColumnName", "M", 3, 0
|
134
131
|
column.type_cast(value).should be_a String
|
@@ -138,38 +135,38 @@ describe DBF::Column do
|
|
138
135
|
|
139
136
|
context "#schema_definition" do
|
140
137
|
context 'with type N (number)' do
|
141
|
-
it "
|
138
|
+
it "outputs an integer column" do
|
142
139
|
column = DBF::Column.new "ColumnName", "N", 1, 0
|
143
140
|
column.schema_definition.should == "\"column_name\", :integer\n"
|
144
141
|
end
|
145
142
|
end
|
146
143
|
|
147
|
-
it "
|
144
|
+
it "defines a float colmn if type is (N)umber with more than 0 decimals" do
|
148
145
|
column = DBF::Column.new "ColumnName", "N", 1, 2
|
149
146
|
column.schema_definition.should == "\"column_name\", :float\n"
|
150
147
|
end
|
151
148
|
|
152
|
-
it "
|
149
|
+
it "defines a date column if type is (D)ate" do
|
153
150
|
column = DBF::Column.new "ColumnName", "D", 8, 0
|
154
151
|
column.schema_definition.should == "\"column_name\", :date\n"
|
155
152
|
end
|
156
153
|
|
157
|
-
it "
|
154
|
+
it "defines a datetime column if type is (D)ate" do
|
158
155
|
column = DBF::Column.new "ColumnName", "T", 16, 0
|
159
156
|
column.schema_definition.should == "\"column_name\", :datetime\n"
|
160
157
|
end
|
161
158
|
|
162
|
-
it "
|
159
|
+
it "defines a boolean column if type is (L)ogical" do
|
163
160
|
column = DBF::Column.new "ColumnName", "L", 1, 0
|
164
161
|
column.schema_definition.should == "\"column_name\", :boolean\n"
|
165
162
|
end
|
166
163
|
|
167
|
-
it "
|
164
|
+
it "defines a text column if type is (M)emo" do
|
168
165
|
column = DBF::Column.new "ColumnName", "M", 1, 0
|
169
166
|
column.schema_definition.should == "\"column_name\", :text\n"
|
170
167
|
end
|
171
168
|
|
172
|
-
it "
|
169
|
+
it "defines a string column with length for any other data types" do
|
173
170
|
column = DBF::Column.new "ColumnName", "X", 20, 0
|
174
171
|
column.schema_definition.should == "\"column_name\", :string, :limit => 20\n"
|
175
172
|
end
|
@@ -180,11 +177,11 @@ describe DBF::Column do
|
|
180
177
|
@column = DBF::Column.new "ColumnName", "N", 1, 0
|
181
178
|
end
|
182
179
|
|
183
|
-
it "
|
180
|
+
it "strips characters below decimal 32 and above decimal 127" do
|
184
181
|
@column.strip_non_ascii_chars("--\x1F-\x68\x65\x6C\x6C\x6F world-\x80--").should == "---hello world---"
|
185
182
|
end
|
186
183
|
|
187
|
-
it "
|
184
|
+
it "truncates characters with decimal 0" do
|
188
185
|
@column.strip_non_ascii_chars("--\x1F-\x68\x65\x6C\x6C\x6F \x00 world-\x80--").should == "---hello "
|
189
186
|
end
|
190
187
|
end
|
data/spec/unit/record_spec.rb
CHANGED
@@ -10,14 +10,14 @@ describe DBF::Record do
|
|
10
10
|
def mock_table(data = '')
|
11
11
|
@column1 = DBF::Column.new 'ColumnName', 'N', 1, 0
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
21
|
end
|
22
22
|
|
23
23
|
describe '#memo_block_content_size' do
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dbf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 13
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 1
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 1.
|
7
|
+
- 3
|
8
|
+
- 0
|
9
|
+
version: 1.3.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Keith Morrison
|
@@ -15,7 +14,7 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2010-
|
17
|
+
date: 2010-10-08 00:00:00 -07:00
|
19
18
|
default_executable: dbf
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
@@ -24,14 +23,13 @@ dependencies:
|
|
24
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
24
|
none: false
|
26
25
|
requirements:
|
27
|
-
- - "
|
26
|
+
- - "="
|
28
27
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 9
|
30
28
|
segments:
|
31
|
-
- 2
|
32
29
|
- 3
|
33
|
-
-
|
34
|
-
|
30
|
+
- 0
|
31
|
+
- 0
|
32
|
+
version: 3.0.0
|
35
33
|
type: :runtime
|
36
34
|
version_requirements: *id001
|
37
35
|
- !ruby/object:Gem::Dependency
|
@@ -40,16 +38,30 @@ dependencies:
|
|
40
38
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
39
|
none: false
|
42
40
|
requirements:
|
43
|
-
- - "
|
41
|
+
- - "="
|
44
42
|
- !ruby/object:Gem::Version
|
45
|
-
hash: 7
|
46
43
|
segments:
|
47
44
|
- 1
|
48
|
-
-
|
49
|
-
-
|
50
|
-
version: 1.
|
45
|
+
- 5
|
46
|
+
- 3
|
47
|
+
version: 1.5.3
|
51
48
|
type: :runtime
|
52
49
|
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: rspec
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 1
|
60
|
+
- 3
|
61
|
+
- 0
|
62
|
+
version: 1.3.0
|
63
|
+
type: :development
|
64
|
+
version_requirements: *id003
|
53
65
|
description: A small fast library for reading dBase, xBase, Clipper and FoxPro database files.
|
54
66
|
email: keithm@infused.org
|
55
67
|
executables:
|
@@ -57,23 +69,23 @@ executables:
|
|
57
69
|
extensions: []
|
58
70
|
|
59
71
|
extra_rdoc_files:
|
60
|
-
- README.
|
72
|
+
- README.md
|
73
|
+
- CHANGELOG.md
|
61
74
|
files:
|
62
|
-
- .
|
63
|
-
-
|
64
|
-
-
|
75
|
+
- CHANGELOG.md
|
76
|
+
- Gemfile
|
77
|
+
- Gemfile.lock
|
65
78
|
- MIT-LICENSE
|
66
|
-
- README.markdown
|
67
79
|
- Rakefile
|
68
|
-
-
|
80
|
+
- README.md
|
69
81
|
- bin/dbf
|
70
|
-
- dbf.gemspec
|
71
82
|
- docs/supported_types.markdown
|
72
|
-
- lib/dbf.rb
|
83
|
+
- lib/dbf/attributes.rb
|
73
84
|
- lib/dbf/column.rb
|
74
|
-
- lib/dbf/globals.rb
|
75
85
|
- lib/dbf/record.rb
|
76
86
|
- lib/dbf/table.rb
|
87
|
+
- lib/dbf/version.rb
|
88
|
+
- lib/dbf.rb
|
77
89
|
- spec/fixtures/dbase_03.dbf
|
78
90
|
- spec/fixtures/dbase_30.dbf
|
79
91
|
- spec/fixtures/dbase_30.fpt
|
@@ -110,7 +122,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
110
122
|
requirements:
|
111
123
|
- - ">="
|
112
124
|
- !ruby/object:Gem::Version
|
113
|
-
hash: 3
|
114
125
|
segments:
|
115
126
|
- 0
|
116
127
|
version: "0"
|
@@ -119,10 +130,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
119
130
|
requirements:
|
120
131
|
- - ">="
|
121
132
|
- !ruby/object:Gem::Version
|
122
|
-
hash: 3
|
123
133
|
segments:
|
134
|
+
- 1
|
135
|
+
- 3
|
124
136
|
- 0
|
125
|
-
version:
|
137
|
+
version: 1.3.0
|
126
138
|
requirements: []
|
127
139
|
|
128
140
|
rubyforge_project:
|
@@ -131,14 +143,12 @@ signing_key:
|
|
131
143
|
specification_version: 3
|
132
144
|
summary: Read xBase files
|
133
145
|
test_files:
|
134
|
-
- spec/functional/dbf_shared.rb
|
135
146
|
- spec/functional/format_03_spec.rb
|
136
147
|
- spec/functional/format_30_spec.rb
|
137
148
|
- spec/functional/format_31_spec.rb
|
138
149
|
- spec/functional/format_83_spec.rb
|
139
150
|
- spec/functional/format_8b_spec.rb
|
140
151
|
- spec/functional/format_f5_spec.rb
|
141
|
-
- spec/spec_helper.rb
|
142
152
|
- spec/unit/column_spec.rb
|
143
153
|
- spec/unit/record_spec.rb
|
144
154
|
- spec/unit/table_spec.rb
|
data/.autotest
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
Autotest.add_hook :initialize do |autotest|
|
2
|
-
autotest.clear_mappings
|
3
|
-
|
4
|
-
autotest.add_mapping(%r%^lib/dbf/(.*)\.rb$%) do |filename, m|
|
5
|
-
autotest.files_matching %r!spec/(unit|functional)/#{m[1]}_spec.rb!
|
6
|
-
end
|
7
|
-
|
8
|
-
autotest.add_mapping(%r%^spec/(unit|functional)/.*\.rb$%) do |filename, m|
|
9
|
-
filename
|
10
|
-
end
|
11
|
-
|
12
|
-
%w{.svn .hg .git .dbf .dbt .fpt .txt bin Rakefile .gemspec .autotest}.each do |exception|
|
13
|
-
autotest.add_exception(exception)
|
14
|
-
end
|
15
|
-
end
|
data/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
.DS_Store
|
data/History.txt
DELETED
@@ -1,118 +0,0 @@
|
|
1
|
-
== 1.2.7
|
2
|
-
|
3
|
-
* MIT License
|
4
|
-
|
5
|
-
== 1.2.6
|
6
|
-
|
7
|
-
* Support for Ruby 1.9.2
|
8
|
-
|
9
|
-
== 1.2.5
|
10
|
-
|
11
|
-
* Remove ruby warning switch
|
12
|
-
* Requires activesupport version 2.3.5
|
13
|
-
|
14
|
-
== 1.2.4
|
15
|
-
|
16
|
-
* Add csv output option to dbf command-line utility
|
17
|
-
* Read Visual FoxPro memos
|
18
|
-
|
19
|
-
== 1.2.3
|
20
|
-
|
21
|
-
* Small performance gain when unpacking values from the dbf file
|
22
|
-
* Correctly handle FoxPro's integer data type
|
23
|
-
|
24
|
-
== 1.2.2
|
25
|
-
|
26
|
-
* Handle invalid date fields
|
27
|
-
|
28
|
-
== 1.2.1
|
29
|
-
|
30
|
-
* Add support for F field type (Float)
|
31
|
-
|
32
|
-
== 1.2.0
|
33
|
-
|
34
|
-
* Add Table#to_a
|
35
|
-
|
36
|
-
== 1.1.1
|
37
|
-
|
38
|
-
* Return invalid DateTime columns as nil
|
39
|
-
|
40
|
-
== 1.1.0
|
41
|
-
|
42
|
-
* Add support for large table that will not fit into memory
|
43
|
-
|
44
|
-
== 1.0.13
|
45
|
-
|
46
|
-
* Allow passing an array of ids to find
|
47
|
-
|
48
|
-
== 1.0.11
|
49
|
-
|
50
|
-
* Attributes are now accessible by original or underscored name
|
51
|
-
|
52
|
-
== 1.0.9
|
53
|
-
|
54
|
-
* Fix incorrect integer column values (only affecting some dbf files)
|
55
|
-
* Add CSV export
|
56
|
-
|
57
|
-
== 1.0.8
|
58
|
-
|
59
|
-
* Truncate column names on NULL
|
60
|
-
* Fix schema dump for date and datetime columns
|
61
|
-
* Replace internal helpers with ActiveSupport
|
62
|
-
* Always underscore attribute names
|
63
|
-
|
64
|
-
== 1.0.7
|
65
|
-
|
66
|
-
* Remove support for original column names. All columns names are now downcased/underscored.
|
67
|
-
|
68
|
-
== 1.0.6
|
69
|
-
|
70
|
-
* DBF::Table now includes the Enumerable module
|
71
|
-
* Return nil for memo values if the memo file is missing
|
72
|
-
* Finder conditions now support the original and downcased/underscored column names
|
73
|
-
|
74
|
-
== 1.0.5
|
75
|
-
|
76
|
-
* Strip non-ascii characters from column names
|
77
|
-
|
78
|
-
== 1.0.4
|
79
|
-
|
80
|
-
* Underscore column names when dumping schemas (FieldId becomes field_id)
|
81
|
-
|
82
|
-
== 1.0.3
|
83
|
-
|
84
|
-
* Add support for Visual Foxpro Integer and Datetime columns
|
85
|
-
|
86
|
-
== 1.0.2
|
87
|
-
|
88
|
-
* Compatibility fix for Visual Foxpro memo files (ignore negative memo index values)
|
89
|
-
|
90
|
-
== 1.0.1
|
91
|
-
|
92
|
-
* Fixes error when using the command-line interface [#11984]
|
93
|
-
|
94
|
-
== 1.0.0
|
95
|
-
|
96
|
-
* Renamed classes and refactored code in preparation for adding the
|
97
|
-
ability to save records and create/compact databases.
|
98
|
-
* The Reader class has been renamed to Table
|
99
|
-
* Attributes are no longer accessed directly from the record. Use record.attribute['column_name']
|
100
|
-
instead, or use the new attribute accessors detailed under Basic Usage.
|
101
|
-
|
102
|
-
== 0.5.4
|
103
|
-
|
104
|
-
* Ignore deleted records in both memory modes
|
105
|
-
|
106
|
-
== 0.5.3
|
107
|
-
|
108
|
-
* Added a standalone dbf utility (try dbf -h for help)
|
109
|
-
|
110
|
-
== 0.5.0 / 2007-05-25
|
111
|
-
|
112
|
-
* New find method
|
113
|
-
* Full compatibility with the two flavors of memo file
|
114
|
-
* Two modes of operation:
|
115
|
-
* In memory (default): All records are loaded into memory on the first
|
116
|
-
request. Records are retrieved from memory for all subsequent requests.
|
117
|
-
* File I/O: All records are retrieved from disk on every request
|
118
|
-
* Improved documentation and more usage examples
|
data/VERSION.yml
DELETED
data/dbf.gemspec
DELETED
@@ -1,94 +0,0 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
-
# -*- encoding: utf-8 -*-
|
5
|
-
|
6
|
-
Gem::Specification.new do |s|
|
7
|
-
s.name = %q{dbf}
|
8
|
-
s.version = "1.2.9"
|
9
|
-
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = ["Keith Morrison"]
|
12
|
-
s.date = %q{2010-07-22}
|
13
|
-
s.default_executable = %q{dbf}
|
14
|
-
s.description = %q{A small fast library for reading dBase, xBase, Clipper and FoxPro database files.}
|
15
|
-
s.email = %q{keithm@infused.org}
|
16
|
-
s.executables = ["dbf"]
|
17
|
-
s.extra_rdoc_files = [
|
18
|
-
"README.markdown"
|
19
|
-
]
|
20
|
-
s.files = [
|
21
|
-
".autotest",
|
22
|
-
".gitignore",
|
23
|
-
"History.txt",
|
24
|
-
"MIT-LICENSE",
|
25
|
-
"README.markdown",
|
26
|
-
"Rakefile",
|
27
|
-
"VERSION.yml",
|
28
|
-
"bin/dbf",
|
29
|
-
"dbf.gemspec",
|
30
|
-
"docs/supported_types.markdown",
|
31
|
-
"lib/dbf.rb",
|
32
|
-
"lib/dbf/column.rb",
|
33
|
-
"lib/dbf/globals.rb",
|
34
|
-
"lib/dbf/record.rb",
|
35
|
-
"lib/dbf/table.rb",
|
36
|
-
"spec/fixtures/dbase_03.dbf",
|
37
|
-
"spec/fixtures/dbase_30.dbf",
|
38
|
-
"spec/fixtures/dbase_30.fpt",
|
39
|
-
"spec/fixtures/dbase_31.dbf",
|
40
|
-
"spec/fixtures/dbase_83.dbf",
|
41
|
-
"spec/fixtures/dbase_83.dbt",
|
42
|
-
"spec/fixtures/dbase_83_schema.txt",
|
43
|
-
"spec/fixtures/dbase_8b.dbf",
|
44
|
-
"spec/fixtures/dbase_8b.dbt",
|
45
|
-
"spec/fixtures/dbase_f5.dbf",
|
46
|
-
"spec/fixtures/dbase_f5.fpt",
|
47
|
-
"spec/functional/dbf_shared.rb",
|
48
|
-
"spec/functional/format_03_spec.rb",
|
49
|
-
"spec/functional/format_30_spec.rb",
|
50
|
-
"spec/functional/format_31_spec.rb",
|
51
|
-
"spec/functional/format_83_spec.rb",
|
52
|
-
"spec/functional/format_8b_spec.rb",
|
53
|
-
"spec/functional/format_f5_spec.rb",
|
54
|
-
"spec/spec_helper.rb",
|
55
|
-
"spec/unit/column_spec.rb",
|
56
|
-
"spec/unit/record_spec.rb",
|
57
|
-
"spec/unit/table_spec.rb"
|
58
|
-
]
|
59
|
-
s.homepage = %q{http://github.com/infused/dbf}
|
60
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
61
|
-
s.require_paths = ["lib"]
|
62
|
-
s.rubygems_version = %q{1.3.7}
|
63
|
-
s.summary = %q{Read xBase files}
|
64
|
-
s.test_files = [
|
65
|
-
"spec/functional/dbf_shared.rb",
|
66
|
-
"spec/functional/format_03_spec.rb",
|
67
|
-
"spec/functional/format_30_spec.rb",
|
68
|
-
"spec/functional/format_31_spec.rb",
|
69
|
-
"spec/functional/format_83_spec.rb",
|
70
|
-
"spec/functional/format_8b_spec.rb",
|
71
|
-
"spec/functional/format_f5_spec.rb",
|
72
|
-
"spec/spec_helper.rb",
|
73
|
-
"spec/unit/column_spec.rb",
|
74
|
-
"spec/unit/record_spec.rb",
|
75
|
-
"spec/unit/table_spec.rb"
|
76
|
-
]
|
77
|
-
|
78
|
-
if s.respond_to? :specification_version then
|
79
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
80
|
-
s.specification_version = 3
|
81
|
-
|
82
|
-
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
83
|
-
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.5"])
|
84
|
-
s.add_runtime_dependency(%q<fastercsv>, [">= 1.4.0"])
|
85
|
-
else
|
86
|
-
s.add_dependency(%q<activesupport>, [">= 2.3.5"])
|
87
|
-
s.add_dependency(%q<fastercsv>, [">= 1.4.0"])
|
88
|
-
end
|
89
|
-
else
|
90
|
-
s.add_dependency(%q<activesupport>, [">= 2.3.5"])
|
91
|
-
s.add_dependency(%q<fastercsv>, [">= 1.4.0"])
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
data/lib/dbf/globals.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
module DBF
|
2
|
-
DBF_HEADER_SIZE = 32
|
3
|
-
FPT_HEADER_SIZE = 512
|
4
|
-
BLOCK_HEADER_SIZE = 8
|
5
|
-
VERSION_DESCRIPTIONS = {
|
6
|
-
"02" => "FoxBase",
|
7
|
-
"03" => "dBase III without memo file",
|
8
|
-
"04" => "dBase IV without memo file",
|
9
|
-
"05" => "dBase V without memo file",
|
10
|
-
"30" => "Visual FoxPro",
|
11
|
-
"31" => "Visual FoxPro with AutoIncrement field",
|
12
|
-
"7b" => "dBase IV with memo file",
|
13
|
-
"83" => "dBase III with memo file",
|
14
|
-
"8b" => "dBase IV with memo file",
|
15
|
-
"8e" => "dBase IV with SQL table",
|
16
|
-
"f5" => "FoxPro with memo file",
|
17
|
-
"fb" => "FoxPro without memo file"
|
18
|
-
}
|
19
|
-
|
20
|
-
class DBFError < StandardError
|
21
|
-
end
|
22
|
-
end
|