dbf 0.5.3 → 0.5.4
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/README.txt +14 -15
- data/Rakefile +2 -1
- data/lib/dbf/field.rb +1 -1
- data/lib/dbf/reader.rb +23 -12
- data/spec/functional/dbf_shared.rb +0 -4
- data/spec/unit/reader_spec.rb +9 -7
- metadata +3 -3
data/README.txt
CHANGED
@@ -46,24 +46,23 @@ Copyright (c) 2006-2007 Keith Morrison <keithm@infused.org, www.infused.org>
|
|
46
46
|
reader.find :first, :first_name => 'Keith'
|
47
47
|
reader.find(10)
|
48
48
|
|
49
|
-
==
|
50
|
-
xBase database systems do not physically delete records, but merely mark the
|
51
|
-
records for deletion. The file must be compacted using a special utility to
|
52
|
-
remove the deleted records.
|
49
|
+
== Large databases
|
53
50
|
|
54
|
-
DBF
|
55
|
-
|
56
|
-
|
51
|
+
DBF::Reader defaults to loading all records into memory. This may not be what
|
52
|
+
you want, especially if the database is large. To disable this behavior, set
|
53
|
+
the in_memory option to false during initialization.
|
57
54
|
|
58
|
-
reader.
|
59
|
-
|
60
|
-
Therefore, it's a good idea to compact the records array to remove any nil
|
61
|
-
records before iterating over it:
|
55
|
+
reader = DBF::Reader.new("old_data.dbf", :in_memory => false)
|
62
56
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
57
|
+
== Command-line utility
|
58
|
+
|
59
|
+
A small command-line utility called dbf is installed along with the gem.
|
60
|
+
|
61
|
+
$ dbf -h
|
62
|
+
usage: dbf [-h|-s|-a] filename
|
63
|
+
-h = print this message
|
64
|
+
-s = print summary information
|
65
|
+
-a = create an ActiveRecord::Schema
|
67
66
|
|
68
67
|
== Limitations and known bugs
|
69
68
|
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@ require 'hoe'
|
|
2
2
|
require 'spec/rake/spectask'
|
3
3
|
|
4
4
|
PKG_NAME = "dbf"
|
5
|
-
PKG_VERSION = "0.5.
|
5
|
+
PKG_VERSION = "0.5.4"
|
6
6
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
7
7
|
|
8
8
|
Hoe.new PKG_NAME, PKG_VERSION do |p|
|
@@ -10,6 +10,7 @@ Hoe.new PKG_NAME, PKG_VERSION do |p|
|
|
10
10
|
p.author = "Keith Morrison"
|
11
11
|
p.email = "keithm@infused.org"
|
12
12
|
p.summary = "A small fast library for reading dBase, xBase, Clipper and FoxPro database files."
|
13
|
+
p.description = p.paragraphs_of("README.txt", 1..3).join("\n\n")
|
13
14
|
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
14
15
|
p.url = "http://dbf.rubyforge.org"
|
15
16
|
p.need_tar = true
|
data/lib/dbf/field.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module DBF
|
2
2
|
class FieldLengthError < DBFError; end
|
3
|
+
|
3
4
|
class Field
|
4
5
|
attr_reader :name, :type, :length, :decimal
|
5
6
|
|
@@ -7,6 +8,5 @@ module DBF
|
|
7
8
|
raise FieldLengthError, "field length must be greater than 0" unless length > 0
|
8
9
|
@name, @type, @length, @decimal = name.gsub(/\0/, ''), type, length, decimal
|
9
10
|
end
|
10
|
-
|
11
11
|
end
|
12
12
|
end
|
data/lib/dbf/reader.rb
CHANGED
@@ -6,9 +6,6 @@ module DBF
|
|
6
6
|
# An array of DBF::Field records
|
7
7
|
attr_reader :fields
|
8
8
|
|
9
|
-
# The total number of records. This number includes records marked as deleted.
|
10
|
-
attr_reader :record_count
|
11
|
-
|
12
9
|
# Internal dBase version number
|
13
10
|
attr_reader :version
|
14
11
|
|
@@ -24,8 +21,10 @@ module DBF
|
|
24
21
|
# Initialize a new DBF::Reader.
|
25
22
|
# Example:
|
26
23
|
# reader = DBF::Reader.new 'data.dbf'
|
27
|
-
def initialize(filename)
|
28
|
-
|
24
|
+
def initialize(filename, options = {})
|
25
|
+
options = {:in_memory => true}.merge(options)
|
26
|
+
|
27
|
+
@in_memory = options[:in_memory]
|
29
28
|
@data_file = File.open(filename, 'rb')
|
30
29
|
@memo_file = open_memo(filename)
|
31
30
|
reload!
|
@@ -37,6 +36,7 @@ module DBF
|
|
37
36
|
get_header_info
|
38
37
|
get_memo_header_info if @memo_file
|
39
38
|
get_field_descriptors
|
39
|
+
build_db_index
|
40
40
|
end
|
41
41
|
|
42
42
|
# Returns true if there is a corresponding memo file
|
@@ -45,14 +45,15 @@ module DBF
|
|
45
45
|
end
|
46
46
|
|
47
47
|
# If true, DBF::Reader will load all records into memory. If false, records are retrieved using file I/O.
|
48
|
+
# You can set this option is set during initialization of the DBF::Reader. Defaults to true. Example:
|
49
|
+
# reader = DBF::Reader.new 'data.dbf', :in_memory => false
|
48
50
|
def in_memory?
|
49
51
|
@in_memory
|
50
52
|
end
|
51
53
|
|
52
|
-
#
|
53
|
-
|
54
|
-
|
55
|
-
@in_memory = boolean
|
54
|
+
# The total number of active records.
|
55
|
+
def record_count
|
56
|
+
@db_index.size
|
56
57
|
end
|
57
58
|
|
58
59
|
# Returns an instance of DBF::Field for <b>field_name</b>. <b>field_name</b>
|
@@ -239,7 +240,7 @@ module DBF
|
|
239
240
|
# physical database file. See the documentation for the records method for
|
240
241
|
# information on how these two methods differ.
|
241
242
|
def get_record_from_file(index)
|
242
|
-
seek_to_record(index)
|
243
|
+
seek_to_record(@db_index[index])
|
243
244
|
active_record? ? Record.new(self, @data_file, @memo_file) : nil
|
244
245
|
end
|
245
246
|
|
@@ -249,13 +250,23 @@ module DBF
|
|
249
250
|
seek_to_record(n)
|
250
251
|
if active_record?
|
251
252
|
all_records << DBF::Record.new(self, @data_file, @memo_file)
|
252
|
-
else
|
253
|
-
all_records << nil
|
254
253
|
end
|
255
254
|
end
|
256
255
|
all_records
|
257
256
|
end
|
258
257
|
|
258
|
+
def build_db_index
|
259
|
+
@db_index = []
|
260
|
+
@deleted_records = []
|
261
|
+
0.upto(@record_count - 1) do |n|
|
262
|
+
seek_to_record(n)
|
263
|
+
if active_record?
|
264
|
+
@db_index << n
|
265
|
+
else
|
266
|
+
@deleted_records << n
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
259
270
|
end
|
260
271
|
|
261
272
|
end
|
@@ -1,8 +1,4 @@
|
|
1
1
|
describe DBF, :shared => true do
|
2
|
-
specify "number of records found should equal number of records calculated from the header information" do
|
3
|
-
@reader.record_count.should == @reader.records.size
|
4
|
-
end
|
5
|
-
|
6
2
|
specify "sum of field lengths should equal record length specified in header" do
|
7
3
|
header_record_length = @reader.instance_eval {@record_length}
|
8
4
|
sum_of_field_lengths = @reader.fields.inject(1) {|sum, field| sum + field.length}
|
data/spec/unit/reader_spec.rb
CHANGED
@@ -39,6 +39,12 @@ describe DBF::Reader, "when initialized" do
|
|
39
39
|
@reader.version.should == "83"
|
40
40
|
end
|
41
41
|
|
42
|
+
it "should set the in_memory option" do
|
43
|
+
@reader.in_memory?.should be_true
|
44
|
+
reader = DBF::Reader.new "#{DB_PATH}/dbase_83.dbf", :in_memory => false
|
45
|
+
reader.in_memory?.should be_false
|
46
|
+
end
|
47
|
+
|
42
48
|
end
|
43
49
|
|
44
50
|
describe DBF::Reader, "when the in_memory flag is true" do
|
@@ -64,14 +70,10 @@ end
|
|
64
70
|
|
65
71
|
describe DBF::Reader, "when the in_memory flag is false" do
|
66
72
|
|
67
|
-
before(:each) do
|
68
|
-
@reader = DBF::Reader.new "#{DB_PATH}/dbase_83.dbf"
|
69
|
-
end
|
70
|
-
|
71
73
|
it "should read the records from disk on every request" do
|
72
|
-
|
73
|
-
|
74
|
-
3.times {
|
74
|
+
reader = DBF::Reader.new "#{DB_PATH}/dbase_83.dbf", :in_memory => false
|
75
|
+
reader.expects(:get_all_records_from_file).times(3).returns([])
|
76
|
+
3.times { reader.records }
|
75
77
|
end
|
76
78
|
end
|
77
79
|
|
metadata
CHANGED
@@ -3,15 +3,15 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: dbf
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.5.
|
7
|
-
date: 2007-06-
|
6
|
+
version: 0.5.4
|
7
|
+
date: 2007-06-22 00:00:00 -07:00
|
8
8
|
summary: A small fast library for reading dBase, xBase, Clipper and FoxPro database files.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
11
|
email: keithm@infused.org
|
12
12
|
homepage: http://dbf.rubyforge.org
|
13
13
|
rubyforge_project: dbf
|
14
|
-
description:
|
14
|
+
description: "DBF is a small fast library for reading dBase, xBase, Clipper and FoxPro database files. It is written completely in Ruby and has no external dependencies. Copyright (c) 2006-2007 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"
|
15
15
|
autorequire:
|
16
16
|
default_executable:
|
17
17
|
bindir: bin
|