lib/dbf/table.rb in dbf-1.2.9 vs lib/dbf/table.rb in dbf-1.3.0
- old
+ new
@@ -1,10 +1,28 @@
module DBF
# DBF::Table is the primary interface to a single DBF file and provides
# methods for enumerating and searching the records.
class Table
+ DBF_HEADER_SIZE = 32
+ FPT_HEADER_SIZE = 512
+
+ VERSION_DESCRIPTIONS = {
+ "02" => "FoxBase",
+ "03" => "dBase III without memo file",
+ "04" => "dBase IV without memo file",
+ "05" => "dBase V without memo file",
+ "30" => "Visual FoxPro",
+ "31" => "Visual FoxPro with AutoIncrement field",
+ "7b" => "dBase IV with memo file",
+ "83" => "dBase III with memo file",
+ "8b" => "dBase IV with memo file",
+ "8e" => "dBase IV with SQL table",
+ "f5" => "FoxPro with memo file",
+ "fb" => "FoxPro without memo file"
+ }
+
attr_reader :column_count # The total number of columns
attr_reader :columns # An array of DBF::Column
attr_reader :version # Internal dBase version number
attr_reader :last_updated # Last updated datetime
attr_reader :memo_file_format # :fpt or :dpt
@@ -33,11 +51,11 @@
# Reloads the database and memo files
def reload!
@records = nil
get_header_info
- get_memo_header_info if @memo
+ get_memo_header_info
get_column_descriptors
end
# Checks if there is a memo file
#
@@ -57,14 +75,11 @@
# Calls block once for each record in the table. The record may be nil
# if the record has been marked as deleted.
#
# @yield [nil, DBF::Record]
def each
- 0.upto(@record_count - 1) do |n|
- seek_to_record(n)
- yield current_record
- end
+ 0.upto(@record_count - 1) {|index| yield record(index)}
end
# Retrieve a record by index number.
# The record will be nil if it has been deleted, but not yet pruned from
# the database.
@@ -187,13 +202,13 @@
# @yield [optional DBF::Record]
# @return [Array]
def find_all(options, &block)
results = []
each do |record|
- if record && all_values_match?(record, options)
+ if record.try(:match?, options)
if block_given?
- yield(record)
+ yield record
else
results << record
end
end
end
@@ -204,24 +219,15 @@
#
# @param [Hash] options
# @return [DBF::Record, nil]
def find_first(options)
each do |record|
- return record if record && all_values_match?(record, options)
+ return record if record.try(:match?, options)
end
nil
end
- # Do all search parameters match?
- #
- # @param [DBF::Record] record
- # @param [Hash] options
- # @return [Boolean]
- def all_values_match?(record, options)
- options.all? {|key, value| record.attributes[key.to_s.underscore] == value}
- end
-
# Open memo file
#
# @params [String] path
# @return [File]
def open_memo(path)
@@ -277,16 +283,18 @@
@columns
end
# Determines the memo block size and next available block
def get_memo_header_info
- @memo.rewind
- if @memo_file_format == :fpt
- @memo_next_available_block, @memo_block_size = @memo.read(FPT_HEADER_SIZE).unpack('N x2 n')
- @memo_block_size = 0 if @memo_block_size.nil?
- else
- @memo_block_size = 512
- @memo_next_available_block = File.size(@memo.path) / @memo_block_size
+ if has_memo_file?
+ @memo.rewind
+ if @memo_file_format == :fpt
+ @memo_next_available_block, @memo_block_size = @memo.read(FPT_HEADER_SIZE).unpack('N x2 n')
+ @memo_block_size = 0 if @memo_block_size.nil?
+ else
+ @memo_block_size = 512
+ @memo_next_available_block = File.size(@memo.path) / @memo_block_size
+ end
end
end
# Seek to a byte offset
#
\ No newline at end of file