dbf 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/README.txt +21 -6
- data/Rakefile +1 -1
- data/lib/dbf/globals.rb +4 -0
- data/lib/dbf/record.rb +17 -1
- data/spec/unit/record_spec.rb +25 -0
- metadata +3 -3
data/History.txt
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
== 1.0.3
|
2
|
+
* Add support for Visual Foxpro Integer and Datetime columns
|
3
|
+
|
1
4
|
== 1.0.2
|
2
5
|
|
3
6
|
* Compatibility fix for Visual Foxpro memo files (ignore negative memo index values)
|
@@ -10,6 +13,9 @@
|
|
10
13
|
|
11
14
|
* Renamed classes and refactored code in preparation for adding the
|
12
15
|
ability to save records and create/compact databases.
|
16
|
+
* The Reader class has been renamed to Table
|
17
|
+
* Attributes are no longer accessed directly from the record. Use record.attribute['column_name']
|
18
|
+
instead, or use the new attribute accessors detailed under Basic Usage.
|
13
19
|
|
14
20
|
== 0.5.4
|
15
21
|
|
data/README.txt
CHANGED
@@ -49,6 +49,27 @@ Copyright (c) 2006-2007 Keith Morrison <keithm@infused.org, www.infused.org>
|
|
49
49
|
table.find :first, :first_name => 'Keith'
|
50
50
|
table.find(10)
|
51
51
|
|
52
|
+
== Migrating to ActiveRecord
|
53
|
+
|
54
|
+
An example of migrating a DBF book table to ActiveRecord using a migration:
|
55
|
+
|
56
|
+
require 'dbf'
|
57
|
+
|
58
|
+
class CreateBooks < ActiveRecord::Migration
|
59
|
+
def self.up
|
60
|
+
table = DBF::Table.new('db/dbf/books.dbf')
|
61
|
+
eval(table.schema)
|
62
|
+
|
63
|
+
table.records.each do |record|
|
64
|
+
Book.create(record.attributes)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.down
|
69
|
+
drop_table :books
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
52
73
|
== Large databases
|
53
74
|
|
54
75
|
DBF::Table defaults to loading all records into memory. This may not be what
|
@@ -66,12 +87,6 @@ A small command-line utility called dbf is installed along with the gem.
|
|
66
87
|
-h = print this message
|
67
88
|
-s = print summary information
|
68
89
|
-a = create an ActiveRecord::Schema
|
69
|
-
|
70
|
-
== Changes from 0.5.x
|
71
|
-
|
72
|
-
* The Reader class has been renamed to Table
|
73
|
-
* Attributes are no longer accessed directly from the record. Use record.attribute['column_name']
|
74
|
-
instead, or use the new attribute accessors detailed under Basic Usage.
|
75
90
|
|
76
91
|
== Limitations and known bugs
|
77
92
|
|
data/Rakefile
CHANGED
data/lib/dbf/globals.rb
CHANGED
data/lib/dbf/record.rb
CHANGED
@@ -48,6 +48,10 @@ module DBF
|
|
48
48
|
@attributes[column.name] = read_memo(starting_block)
|
49
49
|
when 'L' # logical
|
50
50
|
@attributes[column.name] = unpack_string(column) =~ /^(y|t)$/i ? true : false
|
51
|
+
when 'I' # integer
|
52
|
+
@attributes[column.name] = unpack_integer(column)
|
53
|
+
when 'T' # datetime
|
54
|
+
@attributes[column.name] = unpack_datetime(column)
|
51
55
|
else
|
52
56
|
@attributes[column.name] = unpack_string(column).strip
|
53
57
|
end
|
@@ -61,9 +65,21 @@ module DBF
|
|
61
65
|
def unpack_string(column)
|
62
66
|
unpack_column(column).to_s
|
63
67
|
end
|
68
|
+
|
69
|
+
def unpack_integer(column)
|
70
|
+
@data.read(column.length).unpack("v").first
|
71
|
+
end
|
72
|
+
|
73
|
+
def unpack_datetime(column)
|
74
|
+
days, milliseconds = @data.read(column.length).unpack('l2')
|
75
|
+
hours = (milliseconds / MS_PER_HOUR).to_i
|
76
|
+
minutes = ((milliseconds - (hours * MS_PER_HOUR)) / MS_PER_MINUTE).to_i
|
77
|
+
seconds = ((milliseconds - (hours * MS_PER_HOUR) - (minutes * MS_PER_MINUTE)) / MS_PER_SECOND).to_i
|
78
|
+
DateTime.jd(days, hours, minutes, seconds)
|
79
|
+
end
|
64
80
|
|
65
81
|
def read_memo(start_block)
|
66
|
-
return nil if start_block <= 0
|
82
|
+
return nil if start_block <= 0 || @table.memo_block_size.nil?
|
67
83
|
@memo.seek(start_block * @table.memo_block_size)
|
68
84
|
if @table.memo_file_format == :fpt
|
69
85
|
memo_type, memo_size, memo_string = @memo.read(@table.memo_block_size).unpack("NNa56")
|
data/spec/unit/record_spec.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/../spec_helper"
|
2
2
|
|
3
3
|
describe DBF::Record, "when initialized" do
|
4
|
+
|
5
|
+
def standalone_record(binary_data)
|
6
|
+
table = mock
|
7
|
+
table.stubs(:data)
|
8
|
+
table.data.stubs(:read).returns(binary_data)
|
9
|
+
table.stubs(:memo).returns(nil)
|
10
|
+
table.stubs(:columns).returns([])
|
11
|
+
DBF::Record.new(table)
|
12
|
+
end
|
4
13
|
|
5
14
|
it "should typecast number columns with decimals == 0 to Integer" do
|
6
15
|
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
@@ -27,5 +36,21 @@ describe DBF::Record, "when initialized" do
|
|
27
36
|
table.column("WEBINCLUDE").type.should == "L"
|
28
37
|
table.records.all? {|record| record.attributes["WEBINCLUDE"].should satisfy {|v| v == true || v == false}}
|
29
38
|
end
|
39
|
+
|
40
|
+
it "should typecast datetime columns to DateTime" do
|
41
|
+
binary_data = "Nl%\000\300Z\252\003"
|
42
|
+
record = standalone_record(binary_data)
|
43
|
+
column = stub(:length => 8)
|
44
|
+
|
45
|
+
record.instance_eval {unpack_datetime(column)}.to_s.should == "2002-10-10T17:04:56+00:00"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should typecast integers to Fixnum" do
|
49
|
+
binary_data = "\017\020\000\000"
|
50
|
+
record = standalone_record(binary_data)
|
51
|
+
column = stub(:length => 4)
|
52
|
+
|
53
|
+
record.instance_eval {unpack_integer(column)}.should == 4111
|
54
|
+
end
|
30
55
|
|
31
56
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: dbf
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.0.
|
7
|
-
date: 2007-
|
6
|
+
version: 1.0.3
|
7
|
+
date: 2007-09-02 00:00:00 -07:00
|
8
8
|
summary: A small fast library for reading dBase, xBase, Clipper and FoxPro database files.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -85,5 +85,5 @@ dependencies:
|
|
85
85
|
requirements:
|
86
86
|
- - ">="
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: 1.
|
88
|
+
version: 1.3.0
|
89
89
|
version:
|