lib/dbf/table.rb in dbf-3.1.1 vs lib/dbf/table.rb in dbf-3.1.2
- old
+ new
@@ -26,18 +26,18 @@
'8b' => 'dBase IV with memo file',
'8e' => 'dBase IV with SQL table',
'cb' => 'dBASE IV SQL table files, with memo',
'f5' => 'FoxPro with memo file',
'fb' => 'FoxPro without memo file'
- }
+ }.freeze
FOXPRO_VERSIONS = {
'30' => 'Visual FoxPro',
'31' => 'Visual FoxPro with AutoIncrement field',
'f5' => 'FoxPro with memo file',
'fb' => 'FoxPro without memo file'
- }
+ }.freeze
attr_accessor :encoding
attr_writer :name
# Opens a DBF::Table
@@ -155,11 +155,11 @@
!!@memo
end
# @return [String]
def name
- @name ||= filename && File.basename(filename, ".*")
+ @name ||= filename && File.basename(filename, '.*')
end
# Retrieve a record by index number.
# The record will be nil if it has been deleted, but not yet pruned from
# the database.
@@ -170,11 +170,11 @@
seek_to_record(index)
return nil if deleted_record?
DBF::Record.new(@data.read(header.record_length), columns, version, @memo)
end
- alias_method :row, :record
+ alias row record
# Total number of records
#
# @return [Integer]
def record_count
@@ -206,90 +206,97 @@
VERSIONS[version]
end
private
- def build_columns # nodoc
- @data.seek(DBF_HEADER_SIZE)
- columns = []
- until end_of_record?
- column_data = @data.read(DBF_HEADER_SIZE)
- name, type, length, decimal = column_data.unpack('a10 x a x4 C2')
- columns << Column.new(self, name, type, length, decimal)
+ def build_columns # :nodoc:
+ safe_seek do
+ @data.seek(DBF_HEADER_SIZE)
+ columns = []
+ until end_of_record?
+ column_data = @data.read(DBF_HEADER_SIZE)
+ name, type, length, decimal = column_data.unpack('a10 x a x4 C2')
+ columns << Column.new(self, name, type, length, decimal)
+ end
+ columns
end
- columns
end
- def deleted_record? # nodoc
+ def deleted_record? # :nodoc:
flag = @data.read(1)
flag ? flag.unpack('a') == ['*'] : true
end
- def end_of_record? # nodoc
- original_pos = @data.pos
- byte = @data.read(1)
- @data.seek(original_pos)
- byte.ord == 13
+ def end_of_record? # :nodoc:
+ safe_seek { @data.read(1).ord == 13 }
end
- def find_all(options) # nodoc
+ def find_all(options) # :nodoc:
map do |record|
if record && record.match?(options)
yield record if block_given?
record
end
end.compact
end
- def find_first(options) # nodoc
+ def find_first(options) # :nodoc:
detect { |record| record && record.match?(options) }
end
- def foxpro? # nodoc
+ def foxpro? # :nodoc:
FOXPRO_VERSIONS.keys.include? version
end
- def header
- @header ||= Header.new(@data.read DBF_HEADER_SIZE)
+ def header # :nodoc:
+ @header ||= safe_seek do
+ @data.seek(0)
+ Header.new(@data.read DBF_HEADER_SIZE)
+ end
end
- def memo_class # nodoc
+ def memo_class # :nodoc:
@memo_class ||= begin
if foxpro?
Memo::Foxpro
else
version == '83' ? Memo::Dbase3 : Memo::Dbase4
end
end
end
- def memo_search_path(io) # nodoc
+ def memo_search_path(io) # :nodoc:
dirname = File.dirname(io)
basename = File.basename(io, '.*')
"#{dirname}/#{basename}*.{fpt,FPT,dbt,DBT}"
end
- def open_data(data) # nodoc
+ def open_data(data) # :nodoc:
data.is_a?(StringIO) ? data : File.open(data, 'rb')
rescue Errno::ENOENT
raise DBF::FileNotFoundError, "file not found: #{data}"
end
- def open_memo(data, memo = nil) # nodoc
+ def open_memo(data, memo = nil) # :nodoc:
if memo
meth = memo.is_a?(StringIO) ? :new : :open
memo_class.send(meth, memo, version)
elsif !data.is_a?(StringIO)
- files = Dir.glob(memo_search_path data)
+ files = Dir.glob(memo_search_path(data))
files.any? ? memo_class.open(files.first, version) : nil
end
end
- def seek(offset) # nodoc
+ def safe_seek # :nodoc:
+ original_pos = @data.pos
+ yield.tap { @data.seek(original_pos) }
+ end
+
+ def seek(offset) # :nodoc:
@data.seek(header.header_length + offset)
end
- def seek_to_record(index) # nodoc
+ def seek_to_record(index) # :nodoc:
seek(index * header.record_length)
end
end
end