dbf 1.0.10 → 1.0.11

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/.autotest CHANGED
@@ -2,10 +2,10 @@ Autotest.add_hook :initialize do |autotest|
2
2
  autotest.clear_mappings
3
3
 
4
4
  autotest.add_mapping(%r%^lib/dbf/(.*)\.rb$%) do |filename, m|
5
- autotest.files_matching %r!spec/(unit|integration)/#{m[1]}_spec.rb!
5
+ autotest.files_matching %r!spec/(unit|functional)/#{m[1]}_spec.rb!
6
6
  end
7
7
 
8
- autotest.add_mapping(%r%^spec/(unit|integration)/.*\.rb$%) do |filename, m|
8
+ autotest.add_mapping(%r%^spec/(unit|functional)/.*\.rb$%) do |filename, m|
9
9
  filename
10
10
  end
11
11
 
@@ -0,0 +1 @@
1
+ .DS_Store
@@ -1,3 +1,11 @@
1
+ == 1.0.11
2
+
3
+ * Attributes are now accessible by original or underscored name
4
+
5
+ == 1.0.11
6
+
7
+ * Minor performance improvements
8
+
1
9
  == 1.0.9
2
10
 
3
11
  * Fix incorrect integer column values (only affecting some dbf files)
@@ -2,20 +2,16 @@
2
2
 
3
3
  DBF is a small fast library for reading dBase, xBase, Clipper and FoxPro database files
4
4
 
5
- Copyright (c) 2006-2009 Keith Morrison <keithm@infused.org>, <www.infused.org>
6
-
7
- * Official project page: <http://rubyforge.org/projects/dbf>
8
- * API Documentation: <http://dbf.rubyforge.org/docs>
9
- * To report bugs: <http://www.rubyforge.org/tracker/?group_id=2009>
10
- * Questions: Email keithm@infused.org and put DBF somewhere in the subject
11
- line
5
+ * Project page: <http://github.com/infused/dbf>
6
+ * API Documentation: <http://rdoc.info/projects/infused/dbf>
7
+ * Report bugs: <http://github.com/infused/dbf/issues>
8
+ * Questions: Email <mailto:keithm@infused.org> and put DBF somewhere in the subject line
12
9
 
13
10
  ## Features
14
11
 
15
12
  * No external dependencies
16
13
  * Fields are type cast to the appropriate Ruby types
17
- * Ability to dump the database schema in the portable ActiveRecord::Schema
18
- format
14
+ * Ability to dump the database schema in the portable ActiveRecord::Schema format
19
15
 
20
16
  ## Installation
21
17
 
@@ -30,7 +26,7 @@ Copyright (c) 2006-2009 Keith Morrison <keithm@infused.org>, <www.infused.org>
30
26
 
31
27
  # Tables are enumerable
32
28
  widget_ids = table.map { |row| row.id }
33
- abc_names = table.select { |row| row.name =~ /^[a-cA-C] }
29
+ abc_names = table.select { |row| row.name =~ /^[a-cA-C]/ }
34
30
  sorted = table.sort_by { |row| row.name }
35
31
 
36
32
  # Print the 'name' field from record number 4
@@ -91,7 +87,7 @@ A small command-line utility called dbf is installed along with the gem.
91
87
 
92
88
  (The MIT Licence)
93
89
 
94
- Copyright (c) 2006-2009 Keith Morrison <keithm@infused.org, www.infused.org>
90
+ Copyright (c) 2006-2009 Keith Morrison <mailto:keithm@infused.org>, <http://www.infused.org>
95
91
 
96
92
  Permission is hereby granted, free of charge, to any person
97
93
  obtaining a copy of this software and associated documentation
data/Rakefile CHANGED
@@ -4,10 +4,10 @@ $: << File.join(PROJECT_ROOT, 'lib')
4
4
  require 'rubygems'
5
5
  require 'jeweler'
6
6
  require 'spec/rake/spectask'
7
+ require 'metric_fu'
7
8
 
8
9
  Jeweler::Tasks.new do |s|
9
10
  s.name = 'dbf'
10
- s.version = '1.0.9'
11
11
  s.description = 'A small fast library for reading dBase, xBase, Clipper and FoxPro database files.'
12
12
  s.summary = 'Read xBase files'
13
13
  s.platform = Gem::Platform::RUBY
@@ -16,11 +16,9 @@ Jeweler::Tasks.new do |s|
16
16
  s.add_dependency('activesupport', ['>= 2.1.0'])
17
17
  s.add_dependency('fastercsv', ['>= 1.4.0'])
18
18
  s.homepage = 'http://github.com/infused/dbf'
19
- s.rubyforge_project = 'dbf'
20
19
  end
21
20
 
22
21
  Jeweler::GemcutterTasks.new
23
- Jeweler::RubyforgeTasks.new
24
22
 
25
23
  task :default => :spec
26
24
 
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :major: 1
3
3
  :minor: 0
4
- :patch: 10
4
+ :patch: 11
5
5
 
@@ -1,15 +1,15 @@
1
1
  # Generated by jeweler
2
- # DO NOT EDIT THIS FILE
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{dbf}
8
- s.version = "1.0.10"
8
+ s.version = "1.0.11"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Keith Morrison"]
12
- s.date = %q{2009-10-04}
12
+ s.date = %q{2009-12-05}
13
13
  s.default_executable = %q{dbf}
14
14
  s.description = %q{A small fast library for reading dBase, xBase, Clipper and FoxPro database files.}
15
15
  s.email = %q{keithm@infused.org}
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
19
19
  ]
20
20
  s.files = [
21
21
  ".autotest",
22
+ ".gitignore",
22
23
  "History.txt",
23
24
  "README.markdown",
24
25
  "Rakefile",
@@ -54,7 +55,6 @@ Gem::Specification.new do |s|
54
55
  s.homepage = %q{http://github.com/infused/dbf}
55
56
  s.rdoc_options = ["--charset=UTF-8"]
56
57
  s.require_paths = ["lib"]
57
- s.rubyforge_project = %q{dbf}
58
58
  s.rubygems_version = %q{1.3.5}
59
59
  s.summary = %q{Read xBase files}
60
60
  s.test_files = [
@@ -86,3 +86,4 @@ Gem::Specification.new do |s|
86
86
  s.add_dependency(%q<fastercsv>, [">= 1.4.0"])
87
87
  end
88
88
  end
89
+
data/lib/dbf.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'date'
2
- require 'activesupport'
2
+ require 'active_support'
3
3
 
4
4
  if RUBY_VERSION > '1.9'
5
5
  require 'csv'
@@ -13,15 +13,13 @@ module DBF
13
13
  end
14
14
 
15
15
  def type_cast(value)
16
- value = value.is_a?(Array) ? value.first : value
17
-
18
16
  case type
19
17
  when 'N' # number
20
- decimal.zero? ? unpack_integer(value) : value.to_f
18
+ unpack_number(value)
21
19
  when 'D' # date
22
20
  value.to_date unless value.blank?
23
21
  when 'L' # logical
24
- value.strip =~ /^(y|t)$/i ? true : false
22
+ boolean(value)
25
23
  when 'I' # integer
26
24
  unpack_integer(value)
27
25
  when 'T' # datetime
@@ -37,33 +35,39 @@ module DBF
37
35
  DateTime.jd(days, seconds/3600, seconds/60 % 60, seconds % 60)
38
36
  end
39
37
 
38
+ def unpack_number(value)
39
+ decimal.zero? ? unpack_integer(value) : value.to_f
40
+ end
41
+
40
42
  def unpack_integer(value)
41
43
  value.to_i
42
44
  end
43
45
 
46
+ def boolean(value)
47
+ value.strip =~ /^(y|t)$/i ? true : false
48
+ end
49
+
44
50
  def schema_definition
45
- data_type = case type
46
- when "N" # number
47
- if decimal > 0
48
- ":float"
49
- else
50
- ":integer"
51
- end
52
- when "I" # integer
51
+ "\"#{name.underscore}\", #{schema_data_type}\n"
52
+ end
53
+
54
+ def schema_data_type
55
+ case type
56
+ when "N"
57
+ decimal > 0 ? ":float" : ":integer"
58
+ when "I"
53
59
  ":integer"
54
- when "D" # date
60
+ when "D"
55
61
  ":date"
56
- when "T" # datetime
62
+ when "T"
57
63
  ":datetime"
58
- when "L" # boolean
64
+ when "L"
59
65
  ":boolean"
60
- when "M" # memo
66
+ when "M"
61
67
  ":text"
62
68
  else
63
69
  ":string, :limit => #{length}"
64
70
  end
65
-
66
- "\"#{name.underscore}\", #{data_type}\n"
67
71
  end
68
72
 
69
73
  # strip all non-ascii and non-printable characters
@@ -14,12 +14,7 @@ module DBF
14
14
  end
15
15
 
16
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
17
+ columns.map { |column| @attributes[column.name.underscore] }
23
18
  end
24
19
 
25
20
  private
@@ -38,22 +33,20 @@ module DBF
38
33
  def initialize_values
39
34
  @attributes = columns.inject({}) do |hash, column|
40
35
  if column.type == 'M'
41
- starting_block = unpack_string(column).to_i
36
+ starting_block = unpack_data(column.length).to_i
37
+ hash[column.name] = read_memo(starting_block)
42
38
  hash[column.name.underscore] = read_memo(starting_block)
43
39
  else
44
- value = unpack_column(column)
40
+ value = unpack_data(column.length)
41
+ hash[column.name] = column.type_cast(value)
45
42
  hash[column.name.underscore] = column.type_cast(value)
46
43
  end
47
44
  hash
48
45
  end
49
46
  end
50
47
 
51
- def unpack_column(column)
52
- @data.read(column.length).to_s.unpack("a#{column.length}")
53
- end
54
-
55
- def unpack_string(column)
56
- unpack_column(column).to_s
48
+ def unpack_data(length)
49
+ @data.read(length).unpack("a#{length}").first
57
50
  end
58
51
 
59
52
  def read_memo(start_block)
@@ -65,7 +58,7 @@ module DBF
65
58
  def build_fpt_memo(start_block)
66
59
  @memo.seek(start_block * memo_block_size)
67
60
 
68
- memo_type, memo_size, memo_string = @memo.read(memo_block_size).unpack("NNa56")
61
+ memo_type, memo_size, memo_string = @memo.read(memo_block_size).unpack("NNa*")
69
62
  return nil unless memo_type == 1 and memo_size > 0
70
63
 
71
64
  if memo_size > memo_block_content_size
@@ -83,7 +76,8 @@ module DBF
83
76
  when "83" # dbase iii
84
77
  memo_string = ""
85
78
  loop do
86
- memo_string << block = @memo.read(memo_block_size)
79
+ block = @memo.read(memo_block_size)
80
+ memo_string << block
87
81
  break if block.rstrip.size < memo_block_size
88
82
  end
89
83
  when "8b" # dbase iv
@@ -37,9 +37,16 @@ describe DBF, :shared => true do
37
37
 
38
38
  specify "column read accessors should return the attribute after typecast" do
39
39
  @table.columns do |column|
40
- record = table.records.first
40
+ record = @table.records.first
41
41
  record.send(column.name).should == record[column.name]
42
42
  end
43
43
  end
44
44
 
45
+ specify "column attributes should be accessible in underscored form" do
46
+ @table.columns do |column|
47
+ record = @table.records.first
48
+ record.send(column_name).should == record.send(column_name.underscore)
49
+ end
50
+ end
51
+
45
52
  end
@@ -8,18 +8,20 @@ describe DBF::Record do
8
8
  end
9
9
 
10
10
  def mock_table(data = '')
11
+ @column1 = DBF::Column.new 'ColumnName', 'N', 1, 0
12
+
11
13
  returning mock('table') do |table|
12
14
  table.stub!(:memo_block_size).and_return(8)
13
15
  table.stub!(:memo).and_return(nil)
14
- table.stub!(:columns).and_return([])
15
- table.stub!(:data)
16
+ table.stub!(:columns).and_return([@column1])
17
+ table.stub!(:data).and_return(data)
16
18
  table.stub!(:has_memo_file?).and_return(true)
17
19
  table.data.stub!(:read).and_return(data)
18
20
  end
19
21
  end
20
22
 
21
23
  context "when initialized" do
22
- it "should typecast number columns with decimals == 0 to Integer" do
24
+ it "should typecast number columns no decimal places to Integer" do
23
25
  table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
24
26
  table.column("ID").type.should == "N"
25
27
  table.column("ID").decimal.should == 0
@@ -90,5 +92,33 @@ describe DBF::Record do
90
92
  record.to_a.should == ["Ten records stored in this database", 10.0, nil, false, "0.100000000000000000", nil]
91
93
  end
92
94
  end
95
+
96
+ describe '#==' do
97
+ before do
98
+ @record = example_record
99
+ end
100
+
101
+ it 'should be false if other does not have attributes' do
102
+ other = mock('object')
103
+ (@record == other).should be_false
104
+ end
105
+
106
+ it 'should be true if other attributes match' do
107
+ attributes = {:x => 1, :y => 2}
108
+ @record.stub!(:attributes).and_return(attributes)
109
+ other = mock('object', :attributes => attributes)
110
+ (@record == other).should be_true
111
+ end
112
+ end
113
+
114
+ describe 'unpack_data' do
115
+ before do
116
+ @record = example_record('abc')
117
+ end
118
+
119
+ it 'should unpack the data' do
120
+ @record.send(:unpack_data, 3).should == 'abc'
121
+ end
122
+ end
93
123
 
94
124
  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.10
4
+ version: 1.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Morrison
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-04 00:00:00 -07:00
12
+ date: 2009-12-05 00:00:00 -08:00
13
13
  default_executable: dbf
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -42,6 +42,7 @@ extra_rdoc_files:
42
42
  - README.markdown
43
43
  files:
44
44
  - .autotest
45
+ - .gitignore
45
46
  - History.txt
46
47
  - README.markdown
47
48
  - Rakefile
@@ -96,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
97
  version:
97
98
  requirements: []
98
99
 
99
- rubyforge_project: dbf
100
+ rubyforge_project:
100
101
  rubygems_version: 1.3.5
101
102
  signing_key:
102
103
  specification_version: 3