dbf 1.0.10 → 1.0.11

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