rbase 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/lib/rbase/builder.rb +2 -2
- data/lib/rbase/record.rb +32 -12
- data/lib/rbase/schema_dumper.rb +3 -3
- data/lib/rbase/table.rb +18 -18
- metadata +31 -22
data/Rakefile
CHANGED
@@ -7,7 +7,7 @@ desc 'Create a gem'
|
|
7
7
|
task :gem do
|
8
8
|
spec = Gem::Specification.new do |s|
|
9
9
|
s.name = 'rbase'
|
10
|
-
s.version = '0.1.
|
10
|
+
s.version = '0.1.2'
|
11
11
|
s.summary = 'Library to create/read/write to XBase databases (*.DBF files)'
|
12
12
|
s.files = Dir.glob('**/*').delete_if { |item| item.include?('.svn') }
|
13
13
|
s.require_path = 'lib'
|
data/lib/rbase/builder.rb
CHANGED
@@ -10,14 +10,14 @@ module RBase
|
|
10
10
|
#
|
11
11
|
# == Example
|
12
12
|
#
|
13
|
-
#
|
13
|
+
# RBase.create_table 'people' do |t|
|
14
14
|
# t.column :name, :string, :size => 30
|
15
15
|
# t.column :birthdate, :date
|
16
16
|
# t.column :active, :boolean
|
17
17
|
# t.column :tax, :integer, :size => 10, :decimal => 2
|
18
18
|
# end
|
19
19
|
#
|
20
|
-
# For documentation on column parameters see
|
20
|
+
# For documentation on column parameters see RBase::Schema.column documentation.
|
21
21
|
#
|
22
22
|
def self.create_table(name, options = {})
|
23
23
|
options[:language] ||= LANGUAGE_RUSSIAN_WINDOWS
|
data/lib/rbase/record.rb
CHANGED
@@ -1,4 +1,14 @@
|
|
1
1
|
module RBase
|
2
|
+
class Error < Exception; end
|
3
|
+
|
4
|
+
class UnknownColumnError < RBase::Error
|
5
|
+
attr_reader :name
|
6
|
+
|
7
|
+
def initialize(name)
|
8
|
+
super("Unknown column '#{name}'")
|
9
|
+
@name = name
|
10
|
+
end
|
11
|
+
end
|
2
12
|
|
3
13
|
# Class that contains data for particular table row.
|
4
14
|
# Should not be created explicitly (use Table#create to create records)
|
@@ -17,25 +27,25 @@ module RBase
|
|
17
27
|
#
|
18
28
|
class Record
|
19
29
|
attr_reader :table, :index
|
20
|
-
|
30
|
+
|
21
31
|
def initialize(table, attributes = {})
|
22
32
|
@table = table
|
23
33
|
@values_cached = {}
|
24
34
|
@values_changed = {}
|
25
|
-
|
35
|
+
|
26
36
|
attributes.each { |k, v| @values_changed[k.to_s.upcase] = v }
|
27
37
|
end
|
28
38
|
|
29
39
|
private
|
30
|
-
|
40
|
+
|
31
41
|
def load(index, data)
|
32
42
|
@table = table
|
33
43
|
@index = index
|
34
44
|
@data = data.dup
|
35
45
|
end
|
36
|
-
|
46
|
+
|
37
47
|
public
|
38
|
-
|
48
|
+
|
39
49
|
# Returns true if record was never saved to database; otherwise return false.
|
40
50
|
def new_record?
|
41
51
|
@data.nil?
|
@@ -52,12 +62,20 @@ module RBase
|
|
52
62
|
@deleted = true
|
53
63
|
save
|
54
64
|
end
|
55
|
-
|
65
|
+
|
56
66
|
# Returns true if record was marked as deleted; otherwise return false.
|
57
67
|
def deleted?
|
58
68
|
@deleted ||= new_record? ? false : @data[0, 1] == '*'
|
59
69
|
end
|
60
70
|
|
71
|
+
# Returns cloned copy of current record
|
72
|
+
def clone
|
73
|
+
c = self.class.new(@table, @values_changed)
|
74
|
+
c.instance_variable_set("@values_cached", @values_cached)
|
75
|
+
c.instance_variable_set("@data", @data)
|
76
|
+
c
|
77
|
+
end
|
78
|
+
|
61
79
|
def method_missing(sym, *args)
|
62
80
|
name = sym.to_s
|
63
81
|
if /=$/ =~ name && args.size == 1
|
@@ -66,7 +84,7 @@ module RBase
|
|
66
84
|
get_value(name)
|
67
85
|
end
|
68
86
|
end
|
69
|
-
|
87
|
+
|
70
88
|
def serialize
|
71
89
|
if new_record?
|
72
90
|
@data = deleted? ? '*' : ' '
|
@@ -75,23 +93,24 @@ module RBase
|
|
75
93
|
end.join
|
76
94
|
else
|
77
95
|
@data[0, 1] = deleted? ? '*' : ' '
|
78
|
-
values_changed.each do |k, v|
|
79
|
-
column = @table.column(
|
80
|
-
@data[column.offset, column.size] = column.pack(
|
81
|
-
values_cached[k] = v
|
96
|
+
@values_changed.each do |k, v|
|
97
|
+
column = @table.column(k)
|
98
|
+
@data[column.offset, column.size] = column.pack(v)
|
99
|
+
@values_cached[k] = v
|
82
100
|
end
|
83
101
|
end
|
84
102
|
@data
|
85
103
|
end
|
86
104
|
|
87
105
|
protected
|
88
|
-
|
106
|
+
|
89
107
|
# Returns value of specified column
|
90
108
|
def get_value(name)
|
91
109
|
name = name.to_s.upcase.to_sym
|
92
110
|
return @values_changed[name] if @values_changed.has_key?(name)
|
93
111
|
return nil if new_record?
|
94
112
|
column = @table.column(name)
|
113
|
+
raise UnknownColumnError.new(name) unless column
|
95
114
|
@values_cached[name] ||= column.unpack(@data[column.offset, column.size])
|
96
115
|
end
|
97
116
|
|
@@ -103,3 +122,4 @@ module RBase
|
|
103
122
|
end
|
104
123
|
|
105
124
|
end
|
125
|
+
|
data/lib/rbase/schema_dumper.rb
CHANGED
@@ -4,13 +4,13 @@ module RBase
|
|
4
4
|
# Produce ruby schema for a given table.
|
5
5
|
#
|
6
6
|
# Parameters
|
7
|
-
# table - instance of
|
7
|
+
# table - instance of RBase::Table opened
|
8
8
|
#
|
9
9
|
# == Example
|
10
10
|
#
|
11
|
-
# users =
|
11
|
+
# users = RBase::Table.open('users')
|
12
12
|
# File.open('users.dump.rb', 'w') do |f|
|
13
|
-
# f.write
|
13
|
+
# f.write RBase::SchemaDumper.dump(users)
|
14
14
|
# end
|
15
15
|
# users.close
|
16
16
|
#
|
data/lib/rbase/table.rb
CHANGED
@@ -2,7 +2,7 @@ module RBase
|
|
2
2
|
|
3
3
|
class Table
|
4
4
|
private_class_method :new
|
5
|
-
|
5
|
+
|
6
6
|
# Create new XBase table file. Table file name will be equal to name with ".dbf" suffix.
|
7
7
|
#
|
8
8
|
# Allowed options
|
@@ -17,7 +17,7 @@ module RBase
|
|
17
17
|
#data << [0x3].pack('C') # version
|
18
18
|
data << [date.year % 100, date.month, date.day].pack('CCC') # last modification date
|
19
19
|
data << [0].pack('L') # number of records
|
20
|
-
# data << [32+schema.columns.size*32+263+1].pack('v') # data size
|
20
|
+
# data << [32+schema.columns.size*32+263+1].pack('v') # data size
|
21
21
|
data << [32+schema.columns.size*32+1].pack('v') # data size
|
22
22
|
data << [record_size].pack('v') # record size
|
23
23
|
data << [].pack('x2') # reserved
|
@@ -55,7 +55,7 @@ module RBase
|
|
55
55
|
f.write data
|
56
56
|
end
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
# Open table with given name.
|
60
60
|
# Table name should be like file name without ".dbf" suffix.
|
61
61
|
def self.open(name)
|
@@ -69,7 +69,7 @@ module RBase
|
|
69
69
|
table
|
70
70
|
end
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
# Physically remove records that were marked as deleted from file.
|
74
74
|
def pack
|
75
75
|
packed_count = 0
|
@@ -84,12 +84,12 @@ module RBase
|
|
84
84
|
packed_count += 1
|
85
85
|
end
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
file_end = @record_offset + @record_size*packed_count
|
89
89
|
@file.pos = file_end
|
90
90
|
@file.write "\x1a"
|
91
91
|
@file.truncate file_end+1
|
92
|
-
|
92
|
+
|
93
93
|
self.count = packed_count
|
94
94
|
update_header
|
95
95
|
end
|
@@ -100,11 +100,11 @@ module RBase
|
|
100
100
|
|
101
101
|
attr_reader :name, :count, :columns, :last_modified_on, :language
|
102
102
|
|
103
|
-
# Return instance of
|
103
|
+
# Return instance of RBase::Column for given column name
|
104
104
|
def column(name)
|
105
105
|
@name_to_columns[name]
|
106
106
|
end
|
107
|
-
|
107
|
+
|
108
108
|
# Returns instance of MemoFile that is associated with table
|
109
109
|
def memo
|
110
110
|
return @memo_file
|
@@ -121,7 +121,7 @@ module RBase
|
|
121
121
|
record.save
|
122
122
|
record
|
123
123
|
end
|
124
|
-
|
124
|
+
|
125
125
|
# Load record stored in position 'index'
|
126
126
|
def load(index)
|
127
127
|
@file.pos = @record_offset + @record_size*index
|
@@ -130,18 +130,18 @@ module RBase
|
|
130
130
|
record.instance_eval { load(index, data) }
|
131
131
|
record
|
132
132
|
end
|
133
|
-
|
133
|
+
|
134
134
|
alias_method :[], :load
|
135
|
-
|
135
|
+
|
136
136
|
def []=(index, record)
|
137
137
|
record.instance_eval { @index = index }
|
138
138
|
save(record)
|
139
139
|
end
|
140
|
-
|
140
|
+
|
141
141
|
# Iterate through all (even deleted) records
|
142
142
|
def each_with_deleted
|
143
143
|
return unless block_given?
|
144
|
-
|
144
|
+
|
145
145
|
count.times do |i|
|
146
146
|
yield load(i)
|
147
147
|
end
|
@@ -185,12 +185,12 @@ module RBase
|
|
185
185
|
@columns << Columns::Column.column_for(type).new(name, :offset => offset, :size => size, :decimal => decimal)
|
186
186
|
@name_to_columns[name.upcase.to_sym] = @columns.last
|
187
187
|
end
|
188
|
-
|
188
|
+
|
189
189
|
@columns.each { |column| column.attach_to(self) }
|
190
|
-
|
190
|
+
|
191
191
|
@memo_file = MemoFile::DummyMemoFile.new
|
192
192
|
end
|
193
|
-
|
193
|
+
|
194
194
|
def save(record)
|
195
195
|
if !record.index
|
196
196
|
@file.pos = @record_offset + @record_size*count
|
@@ -198,8 +198,8 @@ module RBase
|
|
198
198
|
@file.write [26].pack('c')
|
199
199
|
self.count += 1
|
200
200
|
else
|
201
|
-
throw "Index out of bound" if index>=count
|
202
|
-
@file.pos = @record_offset + @record_size*index
|
201
|
+
throw "Index out of bound" if record.index>=count
|
202
|
+
@file.pos = @record_offset + @record_size*record.index
|
203
203
|
@file.write record.serialize
|
204
204
|
end
|
205
205
|
update_header
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.
|
2
|
+
rubygems_version: 0.9.2
|
3
3
|
specification_version: 1
|
4
4
|
name: rbase
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.1.
|
7
|
-
date:
|
6
|
+
version: 0.1.2
|
7
|
+
date: 2007-05-30 00:00:00 +04:00
|
8
8
|
summary: Library to create/read/write to XBase databases (*.DBF files)
|
9
9
|
require_paths:
|
10
|
-
|
11
|
-
email:
|
10
|
+
- lib
|
11
|
+
email: maxim.kulkin@gmail.com, leonardo.pires@gmail.com
|
12
12
|
homepage: http://rbase.rubyforge.com/
|
13
13
|
rubyforge_project: rbase
|
14
14
|
description:
|
@@ -18,30 +18,39 @@ bindir: bin
|
|
18
18
|
has_rdoc: true
|
19
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
20
|
requirements:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
version: 1.8.2
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.8.2
|
25
24
|
version:
|
26
25
|
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
27
29
|
authors:
|
28
|
-
|
30
|
+
- Maxim Kulkin, Leonardo Augusto Pires
|
29
31
|
files:
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
32
|
+
- lib
|
33
|
+
- Rakefile
|
34
|
+
- lib/rbase
|
35
|
+
- lib/rbase.rb
|
36
|
+
- lib/rbase/record.rb
|
37
|
+
- lib/rbase/columns.rb
|
38
|
+
- lib/rbase/schema.rb
|
39
|
+
- lib/rbase/builder.rb
|
40
|
+
- lib/rbase/table.rb
|
41
|
+
- lib/rbase/memo_file.rb
|
42
|
+
- lib/rbase/schema_dumper.rb
|
41
43
|
test_files: []
|
44
|
+
|
42
45
|
rdoc_options: []
|
46
|
+
|
43
47
|
extra_rdoc_files: []
|
48
|
+
|
44
49
|
executables: []
|
50
|
+
|
45
51
|
extensions: []
|
52
|
+
|
46
53
|
requirements: []
|
47
|
-
|
54
|
+
|
55
|
+
dependencies: []
|
56
|
+
|