rbase 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -7,11 +7,10 @@ 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.2'
10
+ s.version = '0.1.3'
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'
14
- s.autorequire = 'rbase'
15
14
  s.authors = 'Maxim Kulkin, Leonardo Augusto Pires'
16
15
  s.email = 'maxim.kulkin@gmail.com, leonardo.pires@gmail.com'
17
16
  s.homepage = 'http://rbase.rubyforge.com/'
@@ -21,6 +20,5 @@ task :gem do
21
20
  s.required_ruby_version = '>= 1.8.2'
22
21
  end
23
22
 
24
- Gem.manage_gems
25
23
  Gem::Builder.new(spec).build
26
24
  end
@@ -1,5 +1,7 @@
1
1
  module RBase
2
2
  module Columns
3
+
4
+ require 'iconv'
3
5
 
4
6
  # Base class for all column types
5
7
  class Column
@@ -57,6 +59,10 @@ module RBase
57
59
  def unpack(value)
58
60
  throw "Not implemented"
59
61
  end
62
+
63
+ def inspect
64
+ "#{name}(type=#{type}, size=#{size})"
65
+ end
60
66
 
61
67
  protected
62
68
 
@@ -77,14 +83,27 @@ module RBase
77
83
  end
78
84
 
79
85
  super name, options.merge(:size => size)
86
+
87
+ if options[:encoding]
88
+ @unpack_converter = Iconv.new('utf-8', options[:encoding])
89
+ @pack_converter = Iconv.new(options[:encoding], 'utf-8')
90
+ end
80
91
  end
81
92
 
82
93
  def pack(value)
94
+ value = value.to_s
95
+ value = @pack_converter.iconv(value) if @pack_converter
83
96
  [value].pack("A#{size}")
84
97
  end
85
98
 
86
99
  def unpack(data)
87
- data.rstrip
100
+ value = data.rstrip
101
+ value = @unpack_converter.iconv(value) if @unpack_converter
102
+ value
103
+ end
104
+
105
+ def inspect
106
+ "#{name}(string #{size})"
88
107
  end
89
108
  end
90
109
 
@@ -100,17 +119,33 @@ module RBase
100
119
  end
101
120
 
102
121
  def pack(value)
103
- if decimal && decimal!=0
104
- [format("%-#{size-decimal-1}.#{decimal}f", value)].pack("A#{size}")
122
+ if value
123
+ if float?
124
+ [format("%#{size-decimal-1}.#{decimal}f", value)].pack("A#{size}")
125
+ else
126
+ [format("%#{size}d", value)].pack("A#{size}")
127
+ end
105
128
  else
106
- [format("%-#{size}d", value)].pack("A#{size}")
129
+ " "*size
107
130
  end
108
131
  end
109
132
 
110
133
  def unpack(data)
111
- return nil if data.rstrip == ''
134
+ return nil if data.strip == ''
112
135
  data.rstrip.to_i
113
136
  end
137
+
138
+ def inspect
139
+ if float?
140
+ "#{name}(decimal)"
141
+ else
142
+ "#{name}(integer)"
143
+ end
144
+ end
145
+
146
+ def float?
147
+ decimal && decimal != 0
148
+ end
114
149
  end
115
150
 
116
151
 
@@ -139,6 +174,10 @@ module RBase
139
174
  nil
140
175
  end
141
176
  end
177
+
178
+ def inspect
179
+ "#{name}(boolean)"
180
+ end
142
181
  end
143
182
 
144
183
 
@@ -157,6 +196,10 @@ module RBase
157
196
  return nil if data.rstrip == ''
158
197
  Date.new(*data.unpack("a4a2a2").map { |s| s.to_i})
159
198
  end
199
+
200
+ def inspect
201
+ "#{name}(date)"
202
+ end
160
203
  end
161
204
 
162
205
 
@@ -175,6 +218,10 @@ module RBase
175
218
  def unpack(data)
176
219
  table.memo.read(data.to_i)
177
220
  end
221
+
222
+ def inspect
223
+ "#{name}(memo)"
224
+ end
178
225
  end
179
226
 
180
227
 
@@ -190,12 +237,16 @@ module RBase
190
237
  end
191
238
 
192
239
  def pack(value)
193
- [format("%-#{size-decimal-1}.#{decimal}f", value)].pack("A#{size}")
240
+ [format("%-#{size-decimal-1}.#{decimal}f", value || 0.0)].pack("A#{size}")
194
241
  end
195
242
 
196
243
  def unpack(data)
197
244
  data.rstrip.to_f
198
245
  end
246
+
247
+ def inspect
248
+ "#{name}(float)"
249
+ end
199
250
  end
200
251
 
201
252
  end
@@ -1,7 +1,8 @@
1
1
  module RBase
2
- class Error < Exception; end
3
2
 
4
- class UnknownColumnError < RBase::Error
3
+ class StandardError < Exception; end
4
+
5
+ class UnknownColumnError < StandardError
5
6
  attr_reader :name
6
7
 
7
8
  def initialize(name)
@@ -10,6 +11,15 @@ module RBase
10
11
  end
11
12
  end
12
13
 
14
+ class InvalidValueError < StandardError
15
+ attr_reader :column, :value
16
+
17
+ def initialize(column, value)
18
+ super("Invalid value #{value.inspect} for column #{column.inspect}")
19
+ @column, @value = column, value
20
+ end
21
+ end
22
+
13
23
  # Class that contains data for particular table row.
14
24
  # Should not be created explicitly (use Table#create to create records)
15
25
  #
@@ -68,7 +78,7 @@ module RBase
68
78
  @deleted ||= new_record? ? false : @data[0, 1] == '*'
69
79
  end
70
80
 
71
- # Returns cloned copy of current record
81
+ # Clone record.
72
82
  def clone
73
83
  c = self.class.new(@table, @values_changed)
74
84
  c.instance_variable_set("@values_cached", @values_cached)
@@ -95,7 +105,12 @@ module RBase
95
105
  @data[0, 1] = deleted? ? '*' : ' '
96
106
  @values_changed.each do |k, v|
97
107
  column = @table.column(k)
98
- @data[column.offset, column.size] = column.pack(v)
108
+ raise UnknownColumnError.new(k) unless column
109
+ begin
110
+ @data[column.offset, column.size] = column.pack(v)
111
+ rescue Object => e
112
+ raise InvalidValueError.new(column, v)
113
+ end
99
114
  @values_cached[k] = v
100
115
  end
101
116
  end
@@ -117,6 +132,7 @@ module RBase
117
132
  # Sets value of specified column.
118
133
  def set_value(name, value)
119
134
  name = name.to_s.upcase.to_sym
135
+ raise UnknownColumnError.new(name) unless @table.column(name)
120
136
  @values_changed[name] = value
121
137
  end
122
138
  end
@@ -3,6 +3,8 @@ module RBase
3
3
  class Table
4
4
  private_class_method :new
5
5
 
6
+ include Enumerable
7
+
6
8
  # Create new XBase table file. Table file name will be equal to name with ".dbf" suffix.
7
9
  #
8
10
  # Allowed options
@@ -58,9 +60,9 @@ module RBase
58
60
 
59
61
  # Open table with given name.
60
62
  # Table name should be like file name without ".dbf" suffix.
61
- def self.open(name)
63
+ def self.open(name, options = {})
62
64
  table = new
63
- table.instance_eval { open("#{name}.dbf") }
65
+ table.instance_eval { open("#{name}.dbf", options) }
64
66
  if block_given?
65
67
  result = yield table
66
68
  table.close
@@ -94,6 +96,16 @@ module RBase
94
96
  update_header
95
97
  end
96
98
 
99
+ def clear
100
+ file_end = @record_offset
101
+ @file.pos = file_end
102
+ @file.write "\x1a"
103
+ @file.truncate file_end+1
104
+
105
+ self.count = 0
106
+ update_header
107
+ end
108
+
97
109
  def close
98
110
  @file.close
99
111
  end
@@ -158,7 +170,7 @@ module RBase
158
170
 
159
171
  private
160
172
 
161
- def open(name)
173
+ def open(name, options = {})
162
174
  @name = File.basename(name, '.dbf')
163
175
  @file = File.open(name, "r+b")
164
176
  header = @file.read(32)
@@ -177,12 +189,14 @@ module RBase
177
189
 
178
190
  @columns = []
179
191
  @name_to_columns = {}
192
+ column_options = {}
193
+ column_options[:encoding] = options[:encoding] if options[:encoding]
180
194
  while true do
181
195
  column_data = @file.read(32)
182
196
  break if column_data[0, 1] == "\x0d"
183
197
  name, type, offset, size, decimal = *column_data.unpack('@0a11aLCC')
184
198
  name = name.strip
185
- @columns << Columns::Column.column_for(type).new(name, :offset => offset, :size => size, :decimal => decimal)
199
+ @columns << Columns::Column.column_for(type).new(name, options.merge(:offset => offset, :size => size, :decimal => decimal))
186
200
  @name_to_columns[name.upcase.to_sym] = @columns.last
187
201
  end
188
202
 
@@ -196,7 +210,8 @@ module RBase
196
210
  @file.pos = @record_offset + @record_size*count
197
211
  @file.write record.serialize
198
212
  @file.write [26].pack('c')
199
- self.count += 1
213
+ record.instance_variable_set(:@index, count)
214
+ self.count += 1
200
215
  else
201
216
  throw "Index out of bound" if record.index>=count
202
217
  @file.pos = @record_offset + @record_size*record.index
metadata CHANGED
@@ -1,56 +1,64 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.2
3
- specification_version: 1
4
2
  name: rbase
5
3
  version: !ruby/object:Gem::Version
6
- version: 0.1.2
7
- date: 2007-05-30 00:00:00 +04:00
8
- summary: Library to create/read/write to XBase databases (*.DBF files)
9
- require_paths:
10
- - lib
11
- email: maxim.kulkin@gmail.com, leonardo.pires@gmail.com
12
- homepage: http://rbase.rubyforge.com/
13
- rubyforge_project: rbase
14
- description:
15
- autorequire: rbase
16
- default_executable:
17
- bindir: bin
18
- has_rdoc: true
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: 1.8.2
24
- version:
4
+ version: 0.1.3
25
5
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message:
29
6
  authors:
30
7
  - Maxim Kulkin, Leonardo Augusto Pires
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-28 00:00:00 +04:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: maxim.kulkin@gmail.com, leonardo.pires@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
31
24
  files:
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
25
  - lib/rbase/builder.rb
40
- - lib/rbase/table.rb
26
+ - lib/rbase/columns.rb
41
27
  - lib/rbase/memo_file.rb
28
+ - lib/rbase/record.rb
29
+ - lib/rbase/schema.rb
42
30
  - lib/rbase/schema_dumper.rb
43
- test_files: []
31
+ - lib/rbase/table.rb
32
+ - lib/rbase.rb
33
+ - Rakefile
34
+ - rbase-0.1.3.gem
35
+ has_rdoc: true
36
+ homepage: http://rbase.rubyforge.com/
37
+ licenses: []
44
38
 
39
+ post_install_message:
45
40
  rdoc_options: []
46
41
 
47
- extra_rdoc_files: []
48
-
49
- executables: []
50
-
51
- extensions: []
52
-
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: 1.8.2
49
+ version:
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
53
56
  requirements: []
54
57
 
55
- dependencies: []
58
+ rubyforge_project: rbase
59
+ rubygems_version: 1.3.2
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Library to create/read/write to XBase databases (*.DBF files)
63
+ test_files: []
56
64