dbf 1.5.2 → 1.5.3

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/Gemfile.lock CHANGED
@@ -3,92 +3,28 @@ PATH
3
3
  specs:
4
4
  dbf (1.5.2)
5
5
  activesupport (~> 3.0.0)
6
- fastercsv (= 1.5.3)
7
- i18n (~> 0.4.2)
6
+ fastercsv (= 1.5.4)
7
+ i18n (~> 0.5.0)
8
8
 
9
9
  GEM
10
10
  remote: http://rubygems.org/
11
11
  specs:
12
- Saikuro (1.1.0)
13
- activesupport (3.0.3)
14
- arrayfields (4.7.4)
15
- chronic (0.2.3)
16
- hoe (>= 1.2.1)
17
- churn (0.0.12)
18
- chronic (~> 0.2.3)
19
- hirb
20
- json_pure
21
- main
22
- ruby_parser (~> 2.0.4)
23
- sexp_processor (~> 3.0.3)
24
- colored (1.2)
12
+ activesupport (3.0.5)
25
13
  diff-lcs (1.1.2)
26
- fastercsv (1.5.3)
27
- fattr (2.2.0)
28
- flay (1.4.1)
29
- ruby_parser (~> 2.0)
30
- sexp_processor (~> 3.0)
31
- flog (2.5.0)
32
- ruby_parser (~> 2.0)
33
- sexp_processor (~> 3.0)
34
- hirb (0.3.5)
35
- hoe (2.7.0)
36
- rake (>= 0.8.7)
37
- rubyforge (>= 2.0.4)
38
- i18n (0.4.2)
39
- json_pure (1.4.6)
40
- main (4.3.0)
41
- arrayfields (>= 4.7.4)
42
- fattr (>= 2.1.0)
43
- metric_fu (2.0.1)
44
- Saikuro (>= 1.1.0)
45
- activesupport (>= 2.0.0)
46
- chronic (~> 0.2.3)
47
- churn (>= 0.0.7)
48
- flay (>= 1.2.1)
49
- flog (>= 2.2.0)
50
- rails_best_practices (>= 0.3.16)
51
- rcov (>= 0.8.3.3)
52
- reek (>= 1.2.6)
53
- roodi (>= 2.1.0)
54
- progressbar (0.9.0)
55
- rails_best_practices (0.5.0)
56
- activesupport
57
- colored (~> 1.2)
58
- progressbar (~> 0.9.0)
59
- ruby_parser (~> 2.0.4)
60
- rake (0.8.7)
61
- rcov (0.9.9)
62
- reek (1.2.8)
63
- ruby2ruby (~> 1.2)
64
- ruby_parser (~> 2.0)
65
- sexp_processor (~> 3.0)
66
- roodi (2.1.0)
67
- ruby_parser
68
- rspec (2.1.0)
69
- rspec-core (~> 2.1.0)
70
- rspec-expectations (~> 2.1.0)
71
- rspec-mocks (~> 2.1.0)
72
- rspec-core (2.1.0)
73
- rspec-expectations (2.1.0)
14
+ fastercsv (1.5.4)
15
+ i18n (0.5.0)
16
+ rspec (2.5.0)
17
+ rspec-core (~> 2.5.0)
18
+ rspec-expectations (~> 2.5.0)
19
+ rspec-mocks (~> 2.5.0)
20
+ rspec-core (2.5.1)
21
+ rspec-expectations (2.5.0)
74
22
  diff-lcs (~> 1.1.2)
75
- rspec-mocks (2.1.0)
76
- ruby2ruby (1.2.5)
77
- ruby_parser (~> 2.0)
78
- sexp_processor (~> 3.0)
79
- ruby_parser (2.0.5)
80
- sexp_processor (~> 3.0)
81
- rubyforge (2.0.4)
82
- json_pure (>= 1.1.7)
83
- sexp_processor (3.0.5)
23
+ rspec-mocks (2.5.0)
84
24
 
85
25
  PLATFORMS
86
26
  ruby
87
27
 
88
28
  DEPENDENCIES
89
- activesupport (~> 3.0.0)
90
29
  dbf!
91
- fastercsv (= 1.5.3)
92
- i18n (~> 0.4.2)
93
- metric_fu (= 2.0.1)
94
- rspec (= 2.1.0)
30
+ rspec (= 2.5.0)
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2006-2010 Keith Morrison <keithm@infused.org>
1
+ Copyright (c) 2006-2011 Keith Morrison <keithm@infused.org>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -115,7 +115,7 @@ for a full list of supported column types.
115
115
 
116
116
  ## License
117
117
 
118
- Copyright (c) 2006-2010 Keith Morrison <keithm@infused.org>
118
+ Copyright (c) 2006-2011 Keith Morrison <keithm@infused.org>
119
119
 
120
120
  Permission is hereby granted, free of charge, to any person
121
121
  obtaining a copy of this software and associated documentation
data/Rakefile CHANGED
@@ -24,8 +24,8 @@ task :console do
24
24
  sh "irb -rubygems -I lib -r dbf.rb"
25
25
  end
26
26
 
27
- require 'metric_fu'
28
- MetricFu::Configuration.run do |config|
29
- config.rcov[:test_files] = ['spec/**/*_spec.rb']
30
- config.rcov[:rcov_opts] << "-Ispec"
31
- end
27
+ # require 'metric_fu'
28
+ # MetricFu::Configuration.run do |config|
29
+ # config.rcov[:test_files] = ['spec/**/*_spec.rb']
30
+ # config.rcov[:rcov_opts] << "-Ispec"
31
+ # end
data/lib/dbf.rb CHANGED
@@ -5,7 +5,6 @@ require 'active_support/core_ext/date/conversions'
5
5
  require 'active_support/core_ext/time/conversions'
6
6
  require 'active_support/core_ext/date_time/conversions'
7
7
  require 'active_support/core_ext/string/conversions'
8
- require 'active_support/core_ext/module/delegation'
9
8
  require 'active_support/core_ext/string/inflections'
10
9
  require 'active_support/core_ext/enumerable'
11
10
 
data/lib/dbf/column.rb CHANGED
@@ -1,91 +1,87 @@
1
1
  module DBF
2
2
  class ColumnLengthError < StandardError; end
3
3
  class ColumnNameError < StandardError; end
4
-
4
+
5
5
  # DBF::Column stores all the information about a column including its name,
6
6
  # type, length and number of decimal places (if any)
7
7
  class Column
8
8
  attr_reader :name, :type, :length, :decimal
9
-
9
+
10
10
  # Initialize a new DBF::Column
11
11
  #
12
12
  # @param [String] name
13
13
  # @param [String] type
14
14
  # @param [Fixnum] length
15
15
  # @param [Fixnum] decimal
16
- def initialize(name, type, length, decimal)
17
- @name, @type, @length, @decimal = clean(name), type, length, decimal
18
-
16
+ def initialize(name, type, length, decimal, encoding=nil)
17
+ @name, @type, @length, @decimal, @encoding = clean(name), type, length, decimal, encoding
18
+
19
19
  raise ColumnLengthError, "field length must be greater than 0" unless length > 0
20
20
  raise ColumnNameError, "column name cannot be empty" if @name.length == 0
21
21
  end
22
-
22
+
23
23
  # Cast value to native type
24
24
  #
25
25
  # @param [String] value
26
- # @return [Fixnum, Float, Date, DateTime, Boolean, String]
26
+ # @return [Fixnum, Float, Date, DateTime, Boolean, String]
27
27
  def type_cast(value)
28
28
  case type
29
29
  when 'N' then unpack_number(value)
30
30
  when 'I' then unpack_unsigned_long(value)
31
- when 'F' then unpack_float(value)
31
+ when 'F' then value.to_f
32
32
  when 'D' then decode_date(value)
33
33
  when 'T' then decode_datetime(value)
34
34
  when 'L' then boolean(value)
35
- else value.to_s.strip
35
+ else encode_string(value.to_s).strip
36
36
  end
37
37
  end
38
-
38
+
39
39
  def memo?
40
40
  @memo ||= type == 'M'
41
41
  end
42
-
42
+
43
43
  # Schema definition
44
44
  #
45
45
  # @return [String]
46
46
  def schema_definition
47
- "\"#{name.underscore}\", #{schema_data_type}\n"
47
+ "\"#{underscored_name}\", #{schema_data_type}\n"
48
48
  end
49
-
49
+
50
50
  def underscored_name
51
51
  @underscored_name ||= name.underscore
52
52
  end
53
-
53
+
54
54
  private
55
-
55
+
56
56
  def decode_date(value) #nodoc
57
57
  value.gsub!(' ', '0')
58
58
  value.blank? ? nil : value.to_date
59
59
  rescue
60
60
  nil
61
61
  end
62
-
62
+
63
63
  def decode_datetime(value) #nodoc
64
64
  days, milliseconds = value.unpack('l2')
65
65
  seconds = milliseconds / 1000
66
66
  DateTime.jd(days, seconds/3600, seconds/60 % 60, seconds % 60) rescue nil
67
67
  end
68
-
68
+
69
69
  def unpack_number(value) #nodoc
70
- decimal.zero? ? unpack_integer(value) : value.to_f
70
+ decimal.zero? ? value.to_i : value.to_f
71
71
  end
72
-
73
- def unpack_float(value) #nodoc
74
- value.to_f
75
- end
76
-
77
- def unpack_integer(value) #nodoc
78
- value.to_i
79
- end
80
-
72
+
81
73
  def unpack_unsigned_long(value) #nodoc
82
74
  value.unpack('V')[0]
83
75
  end
84
-
76
+
85
77
  def boolean(value) #nodoc
86
78
  value.strip =~ /^(y|t)$/i ? true : false
87
79
  end
88
-
80
+
81
+ def encode_string(value)
82
+ @encoding ? value.force_encoding(@encoding).encode(Encoding.default_external) : value
83
+ end
84
+
89
85
  def schema_data_type #nodoc
90
86
  case type
91
87
  when "N", "F"
@@ -104,13 +100,13 @@ module DBF
104
100
  ":string, :limit => #{length}"
105
101
  end
106
102
  end
107
-
103
+
108
104
  def clean(s) #nodoc
109
105
  first_null = s.index("\x00")
110
106
  s = s[0, first_null] if first_null
111
107
  s.gsub(/[^\x20-\x7E]/, "")
112
108
  end
113
-
109
+
114
110
  end
115
-
111
+
116
112
  end
@@ -0,0 +1,61 @@
1
+ # inspired by http://trac.osgeo.org/gdal/ticket/2864
2
+
3
+ "01": cp437 # U.S. MS–DOS
4
+ "02": cp850 # International MS–DOS
5
+ "03": cp1252 # Windows ANSI
6
+ "08": cp865 # Danish OEM
7
+ "09": cp437 # Dutch OEM
8
+ "0a": cp850 # Dutch OEM*
9
+ "0b": cp437 # Finnish OEM
10
+ "0d": cp437 # French OEM
11
+ "0e": cp850 # French OEM*
12
+ "0f": cp437 # German OEM
13
+ "10": cp850 # German OEM*
14
+ "11": cp437 # Italian OEM
15
+ "12": cp850 # Italian OEM*
16
+ "13": cp932 # Japanese Shift-JIS
17
+ "14": cp850 # Spanish OEM*
18
+ "15": cp437 # Swedish OEM
19
+ "16": cp850 # Swedish OEM*
20
+ "17": cp865 # Norwegian OEM
21
+ "18": cp437 # Spanish OEM
22
+ "19": cp437 # English OEM (Britain)
23
+ "1a": cp850 # English OEM (Britain)*
24
+ "1b": cp437 # English OEM (U.S.)
25
+ "1c": cp863 # French OEM (Canada)
26
+ "1d": cp850 # French OEM*
27
+ "1f": cp852 # Czech OEM
28
+ "22": cp852 # Hungarian OEM
29
+ "23": cp852 # Polish OEM
30
+ "24": cp860 # Portuguese OEM
31
+ "25": cp850 # Portuguese OEM*
32
+ "26": cp866 # Russian OEM
33
+ "37": cp850 # English OEM (U.S.)*
34
+ "40": cp852 # Romanian OEM
35
+ "4d": cp936 # Chinese GBK (PRC)
36
+ "4e": cp949 # Korean (ANSI/OEM)
37
+ "4f": cp950 # Chinese Big5 (Taiwan)
38
+ "50": cp874 # Thai (ANSI/OEM)
39
+ "57": cp1252 # ANSI
40
+ "58": cp1252 # Western European ANSI
41
+ "59": cp1252 # Spanish ANSI
42
+ "64": cp852 # Eastern European MS–DOS
43
+ "65": cp866 # Russian MS–DOS
44
+ "66": cp865 # Nordic MS–DOS
45
+ "67": cp861 # Icelandic MS–DOS
46
+ "6a": cp737 # Greek MS–DOS (437G)
47
+ "6b": cp857 # Turkish MS–DOS
48
+ "6c": cp863 # French–Canadian MS–DOS
49
+ "78": cp950 # Taiwan Big 5
50
+ "79": cp949 # Hangul (Wansung)
51
+ "7a": cp936 # PRC GBK
52
+ "7b": cp932 # Japanese Shift-JIS
53
+ "7c": cp874 # Thai Windows/MS–DOS
54
+ "86": cp737 # Greek OEM
55
+ "87": cp852 # Slovenian OEM
56
+ "88": cp857 # Turkish OEM
57
+ "c8": cp1250 # Eastern European Windows
58
+ "c9": cp1251 # Russian Windows
59
+ "ca": cp1254 # Turkish Windows
60
+ "cb": cp1253 # Greek Windows
61
+ "cc": cp1257 # Baltic Windows
data/lib/dbf/memo.rb CHANGED
@@ -47,10 +47,12 @@ module DBF
47
47
  build_dbt_83_memo(start_block)
48
48
  when "8b" # dbase iv
49
49
  build_dbt_8b_memo(start_block)
50
+ else
51
+ nil
50
52
  end
51
53
  end
52
54
 
53
- def build_dbt_83_memo(start_block)
55
+ def build_dbt_83_memo(start_block) #nodoc
54
56
  @data.seek offset(start_block)
55
57
  memo_string = ""
56
58
  begin
@@ -60,7 +62,7 @@ module DBF
60
62
  memo_string
61
63
  end
62
64
 
63
- def build_dbt_8b_memo(start_block)
65
+ def build_dbt_8b_memo(start_block) #nodoc
64
66
  @data.seek offset(start_block)
65
67
  @data.read(@data.read(BLOCK_HEADER_SIZE).unpack("x4L").first)
66
68
  end
data/lib/dbf/table.rb CHANGED
@@ -1,14 +1,14 @@
1
1
  module DBF
2
2
 
3
- # DBF::Table is the primary interface to a single DBF file and provides
3
+ # DBF::Table is the primary interface to a single DBF file and provides
4
4
  # methods for enumerating and searching the records.
5
-
5
+
6
6
  # TODO set record_length to length of actual used column lengths
7
7
  class Table
8
8
  include Enumerable
9
-
9
+
10
10
  DBF_HEADER_SIZE = 32
11
-
11
+
12
12
  VERSION_DESCRIPTIONS = {
13
13
  "02" => "FoxBase",
14
14
  "03" => "dBase III without memo file",
@@ -23,10 +23,11 @@ module DBF
23
23
  "f5" => "FoxPro with memo file",
24
24
  "fb" => "FoxPro without memo file"
25
25
  }
26
-
27
- attr_reader :version # Internal dBase version number
28
- attr_reader :record_count # Total number of records
29
-
26
+
27
+ attr_reader :version # Internal dBase version number
28
+ attr_reader :record_count # Total number of records
29
+ attr_accessor :encoding # Source encoding (for ex. :cp1251)
30
+
30
31
  # Opens a DBF::Table
31
32
  # Example:
32
33
  # table = DBF::Table.new 'data.dbf'
@@ -37,13 +38,13 @@ module DBF
37
38
  get_header_info
38
39
  @memo = open_memo(path)
39
40
  end
40
-
41
+
41
42
  # Closes the table and memo file
42
43
  def close
43
44
  @memo && @memo.close
44
45
  @data.close
45
46
  end
46
-
47
+
47
48
  # Calls block once for each record in the table. The record may be nil
48
49
  # if the record has been marked as deleted.
49
50
  #
@@ -51,7 +52,7 @@ module DBF
51
52
  def each
52
53
  @record_count.times {|i| yield record(i)}
53
54
  end
54
-
55
+
55
56
  # Retrieve a record by index number.
56
57
  # The record will be nil if it has been deleted, but not yet pruned from
57
58
  # the database.
@@ -62,18 +63,18 @@ module DBF
62
63
  seek_to_record(index)
63
64
  current_record
64
65
  end
65
-
66
+
66
67
  alias_method :row, :record
67
-
68
+
68
69
  # Human readable version description
69
70
  #
70
71
  # @return [String]
71
72
  def version_description
72
73
  VERSION_DESCRIPTIONS[version]
73
74
  end
74
-
75
+
75
76
  # Generate an ActiveRecord::Schema
76
- #
77
+ #
77
78
  # xBase data types are converted to generic types as follows:
78
79
  # - Number columns with no decimals are converted to :integer
79
80
  # - Number columns with decimals are converted to :float
@@ -99,40 +100,39 @@ module DBF
99
100
  columns.each do |column|
100
101
  s << " t.column #{column.schema_definition}"
101
102
  end
102
- s << " end\nend"
103
+ s << " end\nend"
103
104
  s
104
105
  end
105
-
106
+
106
107
  # Dumps all records to a CSV file. If no filename is given then CSV is
107
108
  # output to STDOUT.
108
109
  #
109
110
  # @param [optional String] path Defaults to basename of dbf file
110
111
  def to_csv(path = nil)
111
- path = default_csv_path unless path
112
- csv_class.open(path, 'w', :force_quotes => true) do |csv|
112
+ csv_class.open(path || default_csv_path, 'w', :force_quotes => true) do |csv|
113
113
  csv << columns.map {|c| c.name}
114
114
  each {|record| csv << record.to_a}
115
115
  end
116
116
  end
117
-
117
+
118
118
  # Find records using a simple ActiveRecord-like syntax.
119
119
  #
120
120
  # Examples:
121
121
  # table = DBF::Table.new 'mydata.dbf'
122
- #
122
+ #
123
123
  # # Find record number 5
124
124
  # table.find(5)
125
125
  #
126
126
  # # Find all records for Keith Morrison
127
127
  # table.find :all, :first_name => "Keith", :last_name => "Morrison"
128
- #
128
+ #
129
129
  # # Find first record
130
130
  # table.find :first, :first_name => "Keith"
131
131
  #
132
132
  # The <b>command</b> may be a record index, :all, or :first.
133
133
  # <b>options</b> is optional and, if specified, should be a hash where the keys correspond
134
134
  # to column names in the database. The values will be matched exactly with the value
135
- # in the database. If you specify more than one key, all values must match in order
135
+ # in the database. If you specify more than one key, all values must match in order
136
136
  # for the record to be returned. The equivalent SQL would be "WHERE key1 = 'value1'
137
137
  # AND key2 = 'value2'".
138
138
  #
@@ -151,23 +151,24 @@ module DBF
151
151
  find_first(options)
152
152
  end
153
153
  end
154
-
154
+
155
155
  # Retrieves column information from the database
156
156
  def columns
157
- return @columns if @columns
158
-
159
- @data.seek(DBF_HEADER_SIZE)
160
- @columns = []
161
- column_count = (@header_length - DBF_HEADER_SIZE + 1) / DBF_HEADER_SIZE
162
- column_count.times do
163
- name, type, length, decimal = @data.read(32).unpack('a10 x a x4 C2')
164
- @columns << Column.new(name.strip, type, length, decimal) if length > 0
157
+ @columns ||= begin
158
+ column_count = (@header_length - DBF_HEADER_SIZE + 1) / DBF_HEADER_SIZE
159
+
160
+ @data.seek(DBF_HEADER_SIZE)
161
+ columns = []
162
+ column_count.times do
163
+ name, type, length, decimal = @data.read(32).unpack('a10 x a x4 C2')
164
+ columns << Column.new(name.strip, type, length, decimal, @encoding) if length > 0
165
+ end
166
+ columns
165
167
  end
166
- @columns
167
168
  end
168
-
169
+
169
170
  private
170
-
171
+
171
172
  def open_memo(path) #nodoc
172
173
  %w(fpt FPT dbt DBT).each do |extname|
173
174
  filename = path.sub(/#{File.extname(path)[1..-1]}$/, extname)
@@ -177,7 +178,7 @@ module DBF
177
178
  end
178
179
  nil
179
180
  end
180
-
181
+
181
182
  def find_all(options) #nodoc
182
183
  map do |record|
183
184
  if record.try(:match?, options)
@@ -186,43 +187,45 @@ module DBF
186
187
  end
187
188
  end.compact
188
189
  end
189
-
190
+
190
191
  def find_first(options) #nodoc
191
- each do |record|
192
- return record if record.try(:match?, options)
193
- end
194
- nil
192
+ detect {|record| record.try(:match?, options)}
195
193
  end
196
-
194
+
197
195
  def deleted_record? #nodoc
198
196
  @data.read(1).unpack('a') == ['*']
199
197
  end
200
-
201
- def current_record
198
+
199
+ def current_record #nodoc
202
200
  deleted_record? ? nil : DBF::Record.new(@data.read(@record_length), columns, version, @memo)
203
201
  end
204
-
202
+
205
203
  def get_header_info #nodoc
206
204
  @data.rewind
207
- @version, @record_count, @header_length, @record_length = @data.read(DBF_HEADER_SIZE).unpack('H2 x3 V v2')
205
+ @version, @record_count, @header_length, @record_length, encoding_key =
206
+ @data.read(DBF_HEADER_SIZE).unpack("H2 x3 V v2 x17H2")
207
+ @encoding = self.class.encodings[encoding_key] if "".respond_to? :encoding
208
208
  end
209
-
209
+
210
210
  def seek(offset) #nodoc
211
211
  @data.seek @header_length + offset
212
212
  end
213
-
213
+
214
214
  def seek_to_record(index) #nodoc
215
215
  seek index * @record_length
216
216
  end
217
-
217
+
218
218
  def csv_class #nodoc
219
219
  CSV.const_defined?(:Reader) ? FCSV : CSV
220
220
  end
221
-
221
+
222
222
  def default_csv_path #nodoc
223
223
  File.basename(@data.path, '.dbf') + '.csv'
224
224
  end
225
-
225
+
226
+ def self.encodings
227
+ @encodings ||= YAML.load_file(File.expand_path("../encodings.yml", __FILE__))
228
+ end
226
229
  end
227
-
228
- end
230
+
231
+ end
data/lib/dbf/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module DBF
2
- VERSION = '1.5.2'
2
+ VERSION = '1.5.3'
3
3
  end
@@ -1,29 +1,29 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe DBF::Record do
4
-
4
+
5
5
  describe '#to_a' do
6
6
  it 'should return an ordered array of attribute values' do
7
7
  table = DBF::Table.new "#{DB_PATH}/dbase_8b.dbf"
8
-
8
+
9
9
  record = table.record(0)
10
10
  record.to_a.should == ["One", 1.0, Date.new(1970, 1, 1), true, 1.23456789012346, "First memo\r\n\037 \037 \037 \037 "]
11
-
11
+
12
12
  record = table.record(9)
13
13
  record.to_a.should == ["Ten records stored in this database", 10.0, nil, false, 0.1, nil]
14
14
  end
15
15
  end
16
-
16
+
17
17
  describe '#==' do
18
18
  before do
19
19
  table = DBF::Table.new "#{DB_PATH}/dbase_8b.dbf"
20
20
  @record = table.record(9)
21
21
  end
22
-
22
+
23
23
  it 'should be false if other does not have attributes' do
24
24
  (@record == mock('other')).should be_false
25
25
  end
26
-
26
+
27
27
  it 'should be true if other attributes match' do
28
28
  attributes = {:x => 1, :y => 2}
29
29
  @record.stub!(:attributes).and_return(attributes)
@@ -31,10 +31,10 @@ describe DBF::Record do
31
31
  (@record == other).should be_true
32
32
  end
33
33
  end
34
-
34
+
35
35
  describe 'column accessors' do
36
36
  let(:table) { DBF::Table.new "#{DB_PATH}/dbase_8b.dbf"}
37
-
37
+
38
38
  it 'should define accessor methods for each column' do
39
39
  record = table.find(0)
40
40
  record.should respond_to(:character)
@@ -42,4 +42,15 @@ describe DBF::Record do
42
42
  end
43
43
  end
44
44
 
45
+ describe 'column data for table' do
46
+ let(:table) { DBF::Table.new "#{DB_PATH}/cp1251.dbf"}
47
+
48
+ let(:record) { table.find(0) }
49
+ it 'should automatically encodes to default system encoding' do
50
+ if "".respond_to? :encoding
51
+ record.name.encoding.should == Encoding.default_external
52
+ record.name.encode("UTF-8").unpack("H4").should == ["d0b0"] # russian a
53
+ end
54
+ end
55
+ end
45
56
  end
Binary file
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbf
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
5
- prerelease: false
4
+ hash: 5
5
+ prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 5
9
- - 2
10
- version: 1.5.2
9
+ - 3
10
+ version: 1.5.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Keith Morrison
@@ -15,8 +15,8 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-22 00:00:00 -08:00
19
- default_executable: dbf
18
+ date: 2011-04-06 00:00:00 -07:00
19
+ default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: activesupport
@@ -45,9 +45,9 @@ dependencies:
45
45
  hash: 11
46
46
  segments:
47
47
  - 0
48
- - 4
49
- - 2
50
- version: 0.4.2
48
+ - 5
49
+ - 0
50
+ version: 0.5.0
51
51
  type: :runtime
52
52
  version_requirements: *id002
53
53
  - !ruby/object:Gem::Dependency
@@ -58,12 +58,12 @@ dependencies:
58
58
  requirements:
59
59
  - - "="
60
60
  - !ruby/object:Gem::Version
61
- hash: 5
61
+ hash: 11
62
62
  segments:
63
63
  - 1
64
64
  - 5
65
- - 3
66
- version: 1.5.3
65
+ - 4
66
+ version: 1.5.4
67
67
  type: :runtime
68
68
  version_requirements: *id003
69
69
  - !ruby/object:Gem::Dependency
@@ -74,30 +74,14 @@ dependencies:
74
74
  requirements:
75
75
  - - "="
76
76
  - !ruby/object:Gem::Version
77
- hash: 11
77
+ hash: 27
78
78
  segments:
79
79
  - 2
80
- - 1
80
+ - 5
81
81
  - 0
82
- version: 2.1.0
82
+ version: 2.5.0
83
83
  type: :development
84
84
  version_requirements: *id004
85
- - !ruby/object:Gem::Dependency
86
- name: metric_fu
87
- prerelease: false
88
- requirement: &id005 !ruby/object:Gem::Requirement
89
- none: false
90
- requirements:
91
- - - "="
92
- - !ruby/object:Gem::Version
93
- hash: 13
94
- segments:
95
- - 2
96
- - 0
97
- - 1
98
- version: 2.0.1
99
- type: :development
100
- version_requirements: *id005
101
85
  description: A small fast library for reading dBase, xBase, Clipper and FoxPro database files.
102
86
  email: keithm@infused.org
103
87
  executables:
@@ -107,6 +91,7 @@ extensions: []
107
91
  extra_rdoc_files:
108
92
  - README.md
109
93
  - CHANGELOG.md
94
+ - MIT-LICENSE
110
95
  files:
111
96
  - CHANGELOG.md
112
97
  - Gemfile
@@ -118,6 +103,7 @@ files:
118
103
  - docs/supported_types.markdown
119
104
  - lib/dbf/attributes.rb
120
105
  - lib/dbf/column.rb
106
+ - lib/dbf/encodings.yml
121
107
  - lib/dbf/memo.rb
122
108
  - lib/dbf/record.rb
123
109
  - lib/dbf/table.rb
@@ -127,6 +113,7 @@ files:
127
113
  - spec/dbf/file_formats_spec.rb
128
114
  - spec/dbf/record_spec.rb
129
115
  - spec/dbf/table_spec.rb
116
+ - spec/fixtures/cp1251.dbf
130
117
  - spec/fixtures/dbase_03.dbf
131
118
  - spec/fixtures/dbase_30.dbf
132
119
  - spec/fixtures/dbase_30.fpt
@@ -171,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
171
158
  requirements: []
172
159
 
173
160
  rubyforge_project:
174
- rubygems_version: 1.3.7
161
+ rubygems_version: 1.6.2
175
162
  signing_key:
176
163
  specification_version: 3
177
164
  summary: Read xBase files