dbf 1.5.2 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
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