dbf 1.0.8 → 1.0.9

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/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ == 1.0.9
2
+
3
+ * Fix incorrect integer column values (only affecting some dbf files)
4
+ * Add CSV export
5
+
1
6
  == 1.0.8
2
7
 
3
8
  * Truncate column names on NULL
data/Rakefile CHANGED
@@ -2,20 +2,22 @@ require 'hoe'
2
2
  require 'spec/rake/spectask'
3
3
 
4
4
  PKG_NAME = "dbf"
5
- PKG_VERSION = "1.0.8"
5
+ PKG_VERSION = "1.0.9"
6
6
  PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
7
7
 
8
- Hoe.new PKG_NAME, PKG_VERSION do |p|
9
- p.rubyforge_name = PKG_NAME
10
- p.author = "Keith Morrison"
11
- p.email = "keithm@infused.org"
12
- p.summary = "A small fast library for reading dBase, xBase, Clipper and FoxPro database files."
13
- p.description = p.paragraphs_of("README.txt", 1..3).join("\n\n")
14
- p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
15
- p.url = "http://github.com/infused/dm-dbf/tree/master"
16
- p.need_tar = true
17
- p.need_zip = true
18
- p.extra_deps << ['activesupport', '>= 2.1.0']
8
+ Hoe.spec PKG_NAME do |s|
9
+ s.version = PKG_VERSION
10
+ s.rubyforge_name = PKG_NAME
11
+ s.author = "Keith Morrison"
12
+ s.email = "keithm@infused.org"
13
+ s.summary = "A small fast library for reading dBase, xBase, Clipper and FoxPro database files."
14
+ s.description = s.paragraphs_of("README.txt", 1..3).join("\n\n")
15
+ s.changes = s.paragraphs_of("History.txt", 0..1).join("\n\n")
16
+ s.url = "http://github.com/infused/dm-dbf/tree/master"
17
+ s.need_tar = true
18
+ s.need_zip = true
19
+ s.extra_deps << ['activesupport', '>= 2.1.0']
20
+ s.extra_deps << ['fastercsv', '>= 1.4.0']
19
21
  end
20
22
 
21
23
  task :default => :spec
data/dbf.gemspec CHANGED
@@ -1,10 +1,10 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{dbf}
3
- s.version = "1.0.8"
3
+ s.version = "1.0.9"
4
4
 
5
5
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6
6
  s.authors = ["Keith Morrison"]
7
- s.date = %q{2009-01-02}
7
+ s.date = %q{2009-01-15}
8
8
  s.default_executable = %q{dbf}
9
9
  s.description = %q{DBF is a small fast library for reading dBase, xBase, Clipper and FoxPro database files Copyright (c) 2006-2009 Keith Morrison <keithm@infused.org, www.infused.org> * Official project page: http://rubyforge.org/projects/dbf * API Documentation: http://dbf.rubyforge.org/docs * To report bugs: http://www.rubyforge.org/tracker/?group_id=2009 * Questions: Email keithm@infused.org and put DBF somewhere in the subject line}
10
10
  s.email = %q{keithm@infused.org}
@@ -25,13 +25,16 @@ Gem::Specification.new do |s|
25
25
 
26
26
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
27
  s.add_runtime_dependency(%q<activesupport>, [">= 2.1.0"])
28
+ s.add_runtime_dependency(%q<fastercsv>, [">= 1.4.0"])
28
29
  s.add_development_dependency(%q<hoe>, [">= 1.8.2"])
29
30
  else
30
31
  s.add_dependency(%q<activesupport>, [">= 2.1.0"])
32
+ s.add_dependency(%q<fastercsv>, [">= 1.4.0"])
31
33
  s.add_dependency(%q<hoe>, [">= 1.8.2"])
32
34
  end
33
35
  else
34
36
  s.add_dependency(%q<activesupport>, [">= 2.1.0"])
37
+ s.add_dependency(%q<fastercsv>, [">= 1.4.0"])
35
38
  s.add_dependency(%q<hoe>, [">= 1.8.2"])
36
39
  end
37
40
  end
data/lib/dbf.rb CHANGED
@@ -1,6 +1,18 @@
1
1
  require 'date'
2
2
  require 'activesupport'
3
3
 
4
+ if RUBY_VERSION > '1.9'
5
+ require 'csv'
6
+ unless defined? FCSV
7
+ class Object
8
+ FCSV = CSV
9
+ alias_method :FCSV, :CSV
10
+ end
11
+ end
12
+ else
13
+ require 'fastercsv'
14
+ end
15
+
4
16
  require 'dbf/globals'
5
17
  require 'dbf/record'
6
18
  require 'dbf/column'
data/lib/dbf/column.rb CHANGED
@@ -38,7 +38,7 @@ module DBF
38
38
  end
39
39
 
40
40
  def unpack_integer(value)
41
- value.unpack('v').first.to_i
41
+ value.to_i
42
42
  end
43
43
 
44
44
  def schema_definition
data/lib/dbf/record.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  module DBF
2
2
  class Record
3
3
  attr_reader :attributes
4
+ delegate :columns, :to => :@table
4
5
 
5
6
  def initialize(table)
6
7
  @table, @data, @memo = table, table.data, table.memo
7
- initialize_values(table.columns)
8
+ initialize_values
8
9
  define_accessors
9
10
  end
10
11
 
@@ -12,10 +13,19 @@ module DBF
12
13
  other.respond_to?(:attributes) && other.attributes == attributes
13
14
  end
14
15
 
16
+ def to_a
17
+ columns.map do |column|
18
+ underscored_column_name = column.name.underscore
19
+ value = @attributes[column.name.underscore]
20
+
21
+ value.is_a?(String) ? value.strip : value
22
+ end
23
+ end
24
+
15
25
  private
16
26
 
17
27
  def define_accessors
18
- @table.columns.each do |column|
28
+ columns.each do |column|
19
29
  underscored_column_name = column.name.underscore
20
30
  unless respond_to?(underscored_column_name)
21
31
  self.class.send :define_method, underscored_column_name do
@@ -25,7 +35,7 @@ module DBF
25
35
  end
26
36
  end
27
37
 
28
- def initialize_values(columns)
38
+ def initialize_values
29
39
  @attributes = columns.inject({}) do |hash, column|
30
40
  if column.type == 'M'
31
41
  starting_block = unpack_string(column).to_i
data/lib/dbf/table.rb CHANGED
@@ -65,11 +65,6 @@ module DBF
65
65
  end
66
66
  end
67
67
 
68
- # def get_record_from_file(index)
69
- # seek_to_record(@db_index[index])
70
- # Record.new(self)
71
- # end
72
-
73
68
  # Returns a DBF::Record (or nil if the record has been marked for deletion) for the record at <tt>index</tt>.
74
69
  def record(index)
75
70
  records[index]
@@ -157,6 +152,16 @@ module DBF
157
152
  Record.new(self)
158
153
  end
159
154
 
155
+ # Dumps all records into a CSV file
156
+ def to_csv(filename = nil)
157
+ filename = File.basename(@data.path, '.dbf') + '.csv' if filename.nil?
158
+ FCSV.open(filename, 'w', :force_quotes => true) do |csv|
159
+ records.each do |record|
160
+ csv << record.to_a
161
+ end
162
+ end
163
+ end
164
+
160
165
  private
161
166
 
162
167
  def open_memo(file)
data/spec/spec_helper.rb CHANGED
@@ -7,4 +7,6 @@ DB_PATH = File.dirname(__FILE__) + '/fixtures' unless defined?(DB_PATH)
7
7
 
8
8
  Spec::Runner.configure do |config|
9
9
 
10
- end
10
+ end
11
+
12
+ self.class.send :remove_const, "Test" if defined? Test
@@ -43,13 +43,13 @@ describe DBF::Column do
43
43
  it "should cast numbers with no decimals to Integer" do
44
44
  value = "135"
45
45
  column = DBF::Column.new "ColumnName", "N", 3, 0
46
- column.type_cast(value).should == 13105
46
+ column.type_cast(value).should == 135
47
47
  end
48
48
 
49
49
  it "should cast :integer to Integer" do
50
50
  value = "135"
51
51
  column = DBF::Column.new "ColumnName", "I", 3, 0
52
- column.type_cast(value).should == 13105
52
+ column.type_cast(value).should == 135
53
53
  end
54
54
 
55
55
  it "should cast boolean to True" do
@@ -3,18 +3,19 @@ require File.dirname(__FILE__) + "/../spec_helper"
3
3
  describe DBF::Record do
4
4
 
5
5
  def example_record(data = '')
6
- DBF::Record.new(mock_table(data))
6
+ table = mock_table(data)
7
+ DBF::Record.new(table)
7
8
  end
8
9
 
9
10
  def mock_table(data = '')
10
- table = mock('table')
11
- table.stub!(:memo_block_size).and_return(8)
12
- table.stub!(:memo).and_return(nil)
13
- table.stub!(:columns).and_return([])
14
- table.stub!(:data)
15
- table.stub!(:has_memo_file?).and_return(true)
16
- table.data.stub!(:read).and_return(data)
17
- table
11
+ returning mock('table') do |table|
12
+ table.stub!(:memo_block_size).and_return(8)
13
+ table.stub!(:memo).and_return(nil)
14
+ table.stub!(:columns).and_return([])
15
+ table.stub!(:data)
16
+ table.stub!(:has_memo_file?).and_return(true)
17
+ table.data.stub!(:read).and_return(data)
18
+ end
18
19
  end
19
20
 
20
21
  context "when initialized" do
@@ -43,20 +44,6 @@ describe DBF::Record do
43
44
  table.column("WEBINCLUDE").type.should == "L"
44
45
  table.records.all? {|record| record.attributes["webinclude"].should satisfy {|v| v == true || v == false}}
45
46
  end
46
-
47
- # it "should typecast datetime columns to DateTime" do
48
- # record = example_record("Nl%\000\300Z\252\003")
49
- # column = mock('column', :length => 8)
50
- #
51
- # record.instance_eval {unpack_datetime(column)}.to_s.should == "2002-10-10T17:04:56+00:00"
52
- # end
53
- #
54
- # it "should typecast integers to Fixnum" do
55
- # record = example_record("\017\020\000\000")
56
- # column = mock('column', :length => 4)
57
- #
58
- # record.instance_eval {unpack_integer(column)}.should == 4111
59
- # end
60
47
  end
61
48
 
62
49
  describe '#memo_block_content_size' do
@@ -95,5 +82,13 @@ describe DBF::Record do
95
82
  record.send(:read_memo, 5).should be_nil
96
83
  end
97
84
  end
85
+
86
+ describe '#to_a' do
87
+ it 'should return an ordered array of attribute values' do
88
+ table = DBF::Table.new "#{DB_PATH}/dbase_8b.dbf"
89
+ record = table.records[9]
90
+ record.to_a.should == ["Ten records stored in this database", 10.0, nil, false, "0.100000000000000000", nil]
91
+ end
92
+ end
98
93
 
99
94
  end
@@ -1,4 +1,5 @@
1
1
  require File.dirname(__FILE__) + "/../spec_helper"
2
+ require 'fileutils'
2
3
 
3
4
  describe DBF::Table do
4
5
 
@@ -155,7 +156,27 @@ describe DBF::Table do
155
156
  records.map! { |r| r.attributes }
156
157
  records.should == table.records.map {|r| r.attributes}
157
158
  end
158
-
159
+ end
160
+
161
+ describe '#to_csv' do
162
+ before do
163
+ @table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
164
+ end
165
+
166
+ after do
167
+ FileUtils.rm_f 'dbase_83.csv'
168
+ FileUtils.rm_f 'test.csv'
169
+ end
170
+
171
+ it 'should create default dump.csv' do
172
+ @table.to_csv
173
+ File.exists?('dbase_83.csv').should be_true
174
+ end
175
+
176
+ it 'should create custom csv file' do
177
+ @table.to_csv('test.csv')
178
+ File.exists?('test.csv').should be_true
179
+ end
159
180
  end
160
181
 
161
182
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.8
4
+ version: 1.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Morrison
@@ -9,8 +9,8 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-02 00:00:00 -08:00
13
- default_executable:
12
+ date: 2009-01-15 00:00:00 -08:00
13
+ default_executable: dbf
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -22,6 +22,16 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: 2.1.0
24
24
  version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: fastercsv
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.4.0
34
+ version:
25
35
  - !ruby/object:Gem::Dependency
26
36
  name: hoe
27
37
  type: :development
@@ -40,9 +50,7 @@ extensions: []
40
50
 
41
51
  extra_rdoc_files:
42
52
  - History.txt
43
- - Manifest.txt
44
53
  - README.txt
45
- - spec/fixtures/dbase_83_schema.txt
46
54
  files:
47
55
  - History.txt
48
56
  - Manifest.txt
@@ -77,6 +85,8 @@ files:
77
85
  - spec/unit/table_spec.rb
78
86
  has_rdoc: true
79
87
  homepage: http://github.com/infused/dm-dbf/tree/master
88
+ licenses: []
89
+
80
90
  post_install_message:
81
91
  rdoc_options:
82
92
  - --main
@@ -98,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
108
  requirements: []
99
109
 
100
110
  rubyforge_project: dbf
101
- rubygems_version: 1.3.1
111
+ rubygems_version: 1.3.5
102
112
  signing_key:
103
113
  specification_version: 2
104
114
  summary: A small fast library for reading dBase, xBase, Clipper and FoxPro database files.