Class: DBF::Table
- Inherits:
-
Object
- Object
- DBF::Table
- Includes:
- Enumerable
- Defined in:
- lib/dbf/table.rb,
lib/dbf/table/encodings.rb
Overview
DBF::Table is the primary interface to a single DBF file and provides methods for enumerating and searching the records.
Constant Summary
- DBF_HEADER_SIZE =
32- VERSIONS =
{ "02" => "FoxBase", "03" => "dBase III without memo file", "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" }
- ENCODINGS =
inspired by trac.osgeo.org/gdal/ticket/2864
{ "01" => "cp437", # U.S. MS–DOS "02" => "cp850", # International MS–DOS "03" => "cp1252", # Windows ANSI "08" => "cp865", # Danish OEM "09" => "cp437", # Dutch OEM "0a" => "cp850", # Dutch OEM* "0b" => "cp437", # Finnish OEM "0d" => "cp437", # French OEM "0e" => "cp850", # French OEM* "0f" => "cp437", # German OEM "10" => "cp850", # German OEM* "11" => "cp437", # Italian OEM "12" => "cp850", # Italian OEM* "13" => "cp932", # Japanese Shift-JIS "14" => "cp850", # Spanish OEM* "15" => "cp437", # Swedish OEM "16" => "cp850", # Swedish OEM* "17" => "cp865", # Norwegian OEM "18" => "cp437", # Spanish OEM "19" => "cp437", # English OEM (Britain) "1a" => "cp850", # English OEM (Britain)* "1b" => "cp437", # English OEM (U.S.) "1c" => "cp863", # French OEM (Canada) "1d" => "cp850", # French OEM* "1f" => "cp852", # Czech OEM "22" => "cp852", # Hungarian OEM "23" => "cp852", # Polish OEM "24" => "cp860", # Portuguese OEM "25" => "cp850", # Portuguese OEM* "26" => "cp866", # Russian OEM "37" => "cp850", # English OEM (U.S.)* "40" => "cp852", # Romanian OEM "4d" => "cp936", # Chinese GBK (PRC) "4e" => "cp949", # Korean (ANSI/OEM) "4f" => "cp950", # Chinese Big5 (Taiwan) "50" => "cp874", # Thai (ANSI/OEM) "57" => "cp1252", # ANSI "58" => "cp1252", # Western European ANSI "59" => "cp1252", # Spanish ANSI "64" => "cp852", # Eastern European MS–DOS "65" => "cp866", # Russian MS–DOS "66" => "cp865", # Nordic MS–DOS "67" => "cp861", # Icelandic MS–DOS "6a" => "cp737", # Greek MS–DOS (437G) "6b" => "cp857", # Turkish MS–DOS "6c" => "cp863", # French–Canadian MS–DOS "78" => "cp950", # Taiwan Big 5 "79" => "cp949", # Hangul (Wansung) "7a" => "cp936", # PRC GBK "7b" => "cp932", # Japanese Shift-JIS "7c" => "cp874", # Thai Windows/MS–DOS "86" => "cp737", # Greek OEM "87" => "cp852", # Slovenian OEM "88" => "cp857", # Turkish OEM "c8" => "cp1250", # Eastern European Windows "c9" => "cp1251", # Russian Windows "ca" => "cp1254", # Turkish Windows "cb" => "cp1253", # Greek Windows "cc" => "cp1257", # Baltic Windows }
Instance Attribute Summary (collapse)
-
- (Object) encoding
Internal dBase version number Total number of records Source encoding (for ex. :cp1251).
-
- (Object) record_count
readonly
Returns the value of attribute record_count.
-
- (Object) version
readonly
Returns the value of attribute version.
Instance Method Summary (collapse)
-
- (TrueClass, FalseClass) close
Closes the table and memo file.
- - (TrueClass, FalseClass) closed?
-
- (Object) columns
Retrieves column information from the database.
-
- (Object) each {|nil, DBF::Record| ... }
Calls block once for each record in the table.
-
- (Object) filename
String.
-
- (Object) find(command, options = {}) {|optional, DBF::Record, NilClass| ... }
Find records using a simple ActiveRecord-like syntax.
- - (Boolean) foxpro?
- - (TrueClass, FalseClass) has_memo_file?
-
- (Table) initialize(data, memo = nil, encoding = nil)
constructor
Opens a DBF::Table Examples:.
-
- (DBF::Record, NilClass) record(index)
(also: #row)
Retrieve a record by index number.
-
- (String) schema
Generate an ActiveRecord::Schema.
- - (Boolean) supports_encoding?
- - (Boolean) supports_iconv?
-
- (Object) to_csv(path = nil)
Dumps all records to a CSV file.
-
- (String) version_description
Human readable version description.
Constructor Details
- (Table) initialize(data, memo = nil, encoding = nil)
Opens a DBF::Table Examples:
# working with a file stored on the filesystem
table = DBF::Table.new 'data.dbf'
# working with a misnamed memo file
table = DBF::Table.new 'data.dbf', 'memo.dbt'
# working with a dbf in memory
table = DBF::Table.new StringIO.new(dbf_data)
# working with a dbf and memo in memory
table = DBF::Table.new StringIO.new(dbf_data), StringIO.new(memo_data)
# working with a dbf overriding specified in the dbf encoding
table = DBF::Table.new 'data.dbf', nil, 'cp437'
table = DBF::Table.new 'data.dbf', 'memo.dbt', Encoding::US_ASCII
62 63 64 65 66 67 |
# File 'lib/dbf/table.rb', line 62 def initialize(data, memo = nil, encoding = nil) @data = open_data(data) @version, @record_count, @header_length, @record_length, @encoding_key, @encoding = get_header_info @encoding = encoding if encoding @memo = open_memo(data, memo) end |
Instance Attribute Details
- (Object) encoding
Internal dBase version number Total number of records Source encoding (for ex. :cp1251)
39 40 41 |
# File 'lib/dbf/table.rb', line 39 def encoding @encoding end |
- (Object) record_count (readonly)
Returns the value of attribute record_count
38 39 40 |
# File 'lib/dbf/table.rb', line 38 def record_count @record_count end |
- (Object) version (readonly)
Returns the value of attribute version
37 38 39 |
# File 'lib/dbf/table.rb', line 37 def version @version end |
Instance Method Details
- (TrueClass, FalseClass) close
Closes the table and memo file
77 78 79 80 |
# File 'lib/dbf/table.rb', line 77 def close @data.close @memo && @memo.close end |
- (TrueClass, FalseClass) closed?
83 84 85 86 87 88 89 |
# File 'lib/dbf/table.rb', line 83 def closed? if @memo @data.closed? && @memo.closed? else @data.closed? end end |
- (Object) columns
Retrieves column information from the database
205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/dbf/table.rb', line 205 def columns @columns ||= begin @data.seek(DBF_HEADER_SIZE) columns = [] while !["\0", "\r"].include?(first_byte = @data.read(1)) column_data = first_byte + @data.read(31) name, type, length, decimal = column_data.unpack('a10 x a x4 C2') if length > 0 columns << column_class.new(name.strip, type, length, decimal, version, @encoding) end end columns end end |
- (Object) each {|nil, DBF::Record| ... }
Calls block once for each record in the table. The record may be nil if the record has been marked as deleted.
100 101 102 |
# File 'lib/dbf/table.rb', line 100 def each @record_count.times {|i| yield record(i)} end |
- (Object) filename
String
92 93 94 |
# File 'lib/dbf/table.rb', line 92 def filename File.basename @data.path end |
- (Object) find(command, options = {}) {|optional, DBF::Record, NilClass| ... }
Find records using a simple ActiveRecord-like syntax.
Examples:
table = DBF::Table.new 'mydata.dbf'
# Find record number 5
table.find(5)
# Find all records for Keith Morrison
table.find :all, :first_name => "Keith", :last_name => "Morrison"
# Find first record
table.find :first, :first_name => "Keith"
The command may be a record index, :all, or :first. options is optional and, if specified, should be a hash where the keys correspond to column names in the database. The values will be matched exactly with the value in the database. If you specify more than one key, all values must match in order for the record to be returned. The equivalent SQL would be “WHERE key1 = 'value1' AND key2 = 'value2'”.
191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/dbf/table.rb', line 191 def find(command, = {}, &block) case command when Fixnum record(command) when Array command.map {|i| record(i)} when :all find_all(, &block) when :first find_first() end end |
- (Boolean) foxpro?
231 232 233 |
# File 'lib/dbf/table.rb', line 231 def foxpro? FOXPRO_VERSIONS.keys.include? @version end |
- (TrueClass, FalseClass) has_memo_file?
70 71 72 |
# File 'lib/dbf/table.rb', line 70 def has_memo_file? !!@memo end |
- (DBF::Record, NilClass) record(index) Also known as: row
Retrieve a record by index number. The record will be nil if it has been deleted, but not yet pruned from the database.
110 111 112 113 114 115 |
# File 'lib/dbf/table.rb', line 110 def record(index) seek(index * @record_length) if !deleted_record? DBF::Record.new(@data.read(@record_length), columns, version, @memo) end end |
- (String) schema
Generate an ActiveRecord::Schema
xBase data types are converted to generic types as follows:
-
Number columns with no decimals are converted to :integer
-
Number columns with decimals are converted to :float
-
Date columns are converted to :datetime
-
Logical columns are converted to :boolean
-
Memo columns are converted to :text
-
Character columns are converted to :string and the :limit option is set to the length of the character column
Example:
create_table "mydata" do |t|
t.column :name, :string, :limit => 30
t.column :last_update, :datetime
t.column :is_active, :boolean
t.column :age, :integer
t.column :notes, :text
end
147 148 149 150 151 152 153 154 155 |
# File 'lib/dbf/table.rb', line 147 def schema s = "ActiveRecord::Schema.define do\n" s << " create_table \"#{File.basename(@data.path, ".*")}\" do |t|\n" columns.each do |column| s << " t.column #{column.schema_definition}" end s << " end\nend" s end |
- (Boolean) supports_encoding?
220 221 222 |
# File 'lib/dbf/table.rb', line 220 def supports_encoding? String.new.respond_to?(:encoding) end |
- (Boolean) supports_iconv?
224 225 226 227 228 229 |
# File 'lib/dbf/table.rb', line 224 def supports_iconv? require 'iconv' true rescue false end |
- (Object) to_csv(path = nil)
Dumps all records to a CSV file. If no filename is given then CSV is output to STDOUT.
161 162 163 164 165 |
# File 'lib/dbf/table.rb', line 161 def to_csv(path = nil) csv = csv_class.new((path ? File.open(path, 'w') : $stdout), :force_quotes => true) csv << columns.map {|c| c.name} each {|record| csv << record.to_a} end |
- (String) version_description
Human readable version description
122 123 124 |
# File 'lib/dbf/table.rb', line 122 def version_description VERSIONS[version] end |