lib/dbf/table.rb in dbf-2.0.3 vs lib/dbf/table.rb in dbf-2.0.4
- old
+ new
@@ -13,19 +13,22 @@
"04" => "dBase IV without memo file",
"05" => "dBase V without memo file",
"07" => "Visual Objects 1.x",
"30" => "Visual FoxPro",
"31" => "Visual FoxPro with AutoIncrement field",
+ "43" => "dBASE IV SQL table files, no memo",
+ "63" => "dBASE IV SQL system files, no memo",
"7b" => "dBase IV with memo file",
"83" => "dBase III with memo file",
"87" => "Visual Objects 1.x with memo file",
"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"
}
-
+
FOXPRO_VERSIONS = {
"30" => "Visual FoxPro",
"31" => "Visual FoxPro with AutoIncrement field",
"f5" => "FoxPro with memo file",
"fb" => "FoxPro without memo file"
@@ -56,15 +59,15 @@
# @param [String, StringIO] data Path to the dbf file or a StringIO object
# @param [optional String, StringIO] memo Path to the memo file or a StringIO object
# @param [optional String, Encoding] encoding Name of the encoding or an Encoding object
def initialize(data, memo = nil, encoding = nil)
@data = open_data(data)
- get_header_info
- @encoding = encoding || @encoding
+ @version, @record_count, @header_length, @record_length, @encoding_key, @encoding = get_header_info
+ @encoding = encoding if encoding
@memo = open_memo(data, memo)
end
-
+
# @return [TrueClass, FalseClass]
def has_memo_file?
!!@memo
end
@@ -73,20 +76,20 @@
# @return [TrueClass, FalseClass]
def close
@data.close
@memo && @memo.close
end
-
+
# @return [TrueClass, FalseClass]
def closed?
if @memo
@data.closed? && @memo.closed?
else
@data.closed?
end
end
-
+
# @return String
def filename
File.basename @data.path
end
@@ -211,36 +214,32 @@
end
end
columns
end
end
-
+
def supports_encoding?
String.new.respond_to?(:encoding)
end
-
+
def supports_iconv?
require 'iconv'
true
rescue
false
end
-
+
def foxpro?
FOXPRO_VERSIONS.keys.include? @version
end
private
-
+
def column_class #nodoc
- @column_class ||= if foxpro?
- Column::Foxpro
- else
- Column::Dbase
- end
+ @column_class ||= foxpro? ? Column::Foxpro : Column::Dbase
end
-
+
def memo_class #nodoc
@memo_class ||= if foxpro?
Memo::Foxpro
else
if @version == "83"
@@ -248,11 +247,11 @@
else
Memo::Dbase4
end
end
end
-
+
def column_count #nodoc
@column_count ||= ((@header_length - DBF_HEADER_SIZE + 1) / DBF_HEADER_SIZE).to_i
end
def open_data(data) #nodoc
@@ -263,19 +262,23 @@
if memo.is_a? StringIO
memo_class.new(memo, version)
elsif memo
memo_class.open(memo, version)
elsif !data.is_a? StringIO
- dirname = File.dirname(data)
- basename = File.basename(data, '.*')
- files = Dir.glob("#{dirname}/#{basename}*.{fpt,FPT,dbt,DBT}")
+ files = Dir.glob(memo_search_path(data))
files.any? ? memo_class.open(files.first, version) : nil
else
nil
end
end
+ def memo_search_path(io) #nodoc
+ dirname = File.dirname(io)
+ basename = File.basename(io, '.*')
+ "#{dirname}/#{basename}*.{fpt,FPT,dbt,DBT}"
+ end
+
def find_all(options) #nodoc
map do |record|
if record && record.match?(options)
yield record if block_given?
record
@@ -291,13 +294,14 @@
@data.read(1).unpack('a') == ['*']
end
def get_header_info #nodoc
@data.rewind
- @version, @record_count, @header_length, @record_length, @encoding_key = read_header
- @encoding = ENCODINGS[@encoding_key] if supports_encoding? || supports_iconv?
+ version, record_count, header_length, record_length, encoding_key = read_header
+ encoding = ENCODINGS[encoding_key] if supports_encoding? || supports_iconv?
+ [version, record_count, header_length, record_length, encoding_key, encoding]
end
-
+
def read_header #nodoc
@data.read(DBF_HEADER_SIZE).unpack("H2 x3 V v2 x17H2")
end
def seek(offset) #nodoc