rbase 0.1 → 0.1.1

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/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.1'
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'
@@ -1,5 +1,6 @@
1
1
  require 'rbase/columns'
2
2
  require 'rbase/schema'
3
+ require 'rbase/memo_file'
3
4
  require 'rbase/table'
4
5
  require 'rbase/record'
5
6
  require 'rbase/schema_dumper'
@@ -42,6 +42,11 @@ module RBase
42
42
  def initialize(name, options = {})
43
43
  options.merge({:name => name, :type => self.class.type}).each { |k, v| self.instance_variable_set("@#{k}", v) }
44
44
  end
45
+
46
+
47
+ def attach_to(table)
48
+ @table = table
49
+ end
45
50
 
46
51
  # Packs column value for storing it in XBase file.
47
52
  def pack(value)
@@ -52,6 +57,12 @@ module RBase
52
57
  def unpack(value)
53
58
  throw "Not implemented"
54
59
  end
60
+
61
+ protected
62
+
63
+ def table
64
+ @table
65
+ end
55
66
  end
56
67
 
57
68
 
@@ -157,13 +168,12 @@ module RBase
157
168
  end
158
169
 
159
170
  def pack(value)
160
- # Not implemented yet.. using stub
161
- [].pack('A10')
171
+ packed_value = table.memo.write(value)
172
+ [format("%-10d", packed_value)].pack('A10')
162
173
  end
163
174
 
164
175
  def unpack(data)
165
- # Not implemented yet.. using stub
166
- ''
176
+ table.memo.read(data.to_i)
167
177
  end
168
178
  end
169
179
 
@@ -0,0 +1,63 @@
1
+ module RBase
2
+ module MemoFile
3
+
4
+ class DummyMemoFile
5
+ def read(index)
6
+ ''
7
+ end
8
+
9
+ def write(value)
10
+ nil
11
+ end
12
+ end
13
+
14
+ class DBase3MemoFile
15
+ HEADER_SIZE = 512
16
+ BLOCK_SIZE = 512
17
+ BLOCK_TERMINATOR = "\x1a\x1a"
18
+
19
+ def initialize(name)
20
+ @file = File.open(name)
21
+
22
+ @header = @file.read(HEADER_SIZE)
23
+ @next_block = header.unpack('@0L')
24
+ @version = header.unpack('@16c')
25
+ end
26
+
27
+ def read(index)
28
+ @file.pos = index*BLOCK_SIZE + HEADER_SIZE
29
+
30
+ result = ''
31
+ loop do
32
+ data = @file.read(BLOCK_SIZE)
33
+ terminator_pos = data.index(BLOCK_TERMINATOR)
34
+ if terminator_pos
35
+ break result + data[0, terminator_pos]
36
+ end
37
+ result += data
38
+ end
39
+ end
40
+
41
+ def write(value)
42
+ @file.pos = @next_block*BLOCK_SIZE + HEADER_SIZE
43
+ value += BLOCK_TERMINATOR
44
+ blocks_num = (value.length+511)/512
45
+ @file.write [value].pack("a#{512*blocks_num}")
46
+
47
+ position = @next_block
48
+ @next_block += blocks_num
49
+ update_header
50
+
51
+ position
52
+ end
53
+
54
+ protected
55
+
56
+ def update_header
57
+ @file.pos = 0
58
+ @file.write [@next_block].pack("L")
59
+ end
60
+ end
61
+
62
+ end
63
+ end
@@ -18,10 +18,12 @@ module RBase
18
18
  class Record
19
19
  attr_reader :table, :index
20
20
 
21
- def initialize(table)
21
+ def initialize(table, attributes = {})
22
22
  @table = table
23
23
  @values_cached = {}
24
24
  @values_changed = {}
25
+
26
+ attributes.each { |k, v| @values_changed[k.to_s.upcase] = v }
25
27
  end
26
28
 
27
29
  private
@@ -32,10 +34,6 @@ module RBase
32
34
  @data = data.dup
33
35
  end
34
36
 
35
- def create(attributes = {})
36
- attributes.each { |k, v| @values_changed[k.to_s.upcase] = v }
37
- end
38
-
39
37
  public
40
38
 
41
39
  # Returns true if record was never saved to database; otherwise return false.
@@ -16,7 +16,7 @@ module RBase
16
16
  #
17
17
  def self.dump(table)
18
18
  output = ''
19
- output << "XBase.create_table :#{table.name} do |t|\n"
19
+ output << "RBase.create_table :#{table.name} do |t|\n"
20
20
 
21
21
  table.columns.each do |column|
22
22
  output << " t.column '#{column.name}', '#{column.type}', :size => #{column.size}#{ (column.decimal && column.decimal > 0) ? ", :decimal => #{column.decimal}" : ''}\n"
@@ -61,7 +61,13 @@ module RBase
61
61
  def self.open(name)
62
62
  table = new
63
63
  table.instance_eval { open("#{name}.dbf") }
64
- table
64
+ if block_given?
65
+ result = yield table
66
+ table.close
67
+ result
68
+ else
69
+ table
70
+ end
65
71
  end
66
72
 
67
73
  # Physically remove records that were marked as deleted from file.
@@ -98,11 +104,21 @@ module RBase
98
104
  def column(name)
99
105
  @name_to_columns[name]
100
106
  end
107
+
108
+ # Returns instance of MemoFile that is associated with table
109
+ def memo
110
+ return @memo_file
111
+ end
101
112
 
102
- # Create new record and populate it with given attributes
113
+ # Create new record, populate it with given attributes
114
+ def build(attributes = {})
115
+ Record.new(self, attributes)
116
+ end
117
+
118
+ # Create new record, populate it with given attributes and save it
103
119
  def create(attributes = {})
104
- record = Record.new(self)
105
- record.instance_eval { create(attributes) }
120
+ record = build(attributes)
121
+ record.save
106
122
  record
107
123
  end
108
124
 
@@ -169,6 +185,10 @@ module RBase
169
185
  @columns << Columns::Column.column_for(type).new(name, :offset => offset, :size => size, :decimal => decimal)
170
186
  @name_to_columns[name.upcase.to_sym] = @columns.last
171
187
  end
188
+
189
+ @columns.each { |column| column.attach_to(self) }
190
+
191
+ @memo_file = MemoFile::DummyMemoFile.new
172
192
  end
173
193
 
174
194
  def save(record)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.11
2
+ rubygems_version: 0.8.10
3
3
  specification_version: 1
4
4
  name: rbase
5
5
  version: !ruby/object:Gem::Version
6
- version: "0.1"
7
- date: 2006-09-11 00:00:00 +04:00
6
+ version: 0.1.1
7
+ date: 2006-09-26
8
8
  summary: Library to create/read/write to XBase databases (*.DBF files)
9
9
  require_paths:
10
- - lib
11
- email: maxim.kulkin@gmail.com, leonardo.pires@gmail.com
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,37 +18,30 @@ bindir: bin
18
18
  has_rdoc: true
19
19
  required_ruby_version: !ruby/object:Gem::Version::Requirement
20
20
  requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: 1.8.2
21
+ -
22
+ - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 1.8.2
24
25
  version:
25
26
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
27
  authors:
29
- - Maxim Kulkin, Leonardo Augusto Pires
28
+ - "Maxim Kulkin, Leonardo Augusto Pires"
30
29
  files:
31
- - Rakefile
32
- - lib
33
- - lib/rbase
34
- - lib/rbase.rb
35
- - lib/rbase/schema_dumper.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
30
+ - lib
31
+ - Rakefile
32
+ - lib/rbase
33
+ - lib/rbase.rb
34
+ - lib/rbase/builder.rb
35
+ - lib/rbase/columns.rb
36
+ - lib/rbase/memo_file.rb
37
+ - lib/rbase/record.rb
38
+ - lib/rbase/schema.rb
39
+ - lib/rbase/schema_dumper.rb
40
+ - lib/rbase/table.rb
41
41
  test_files: []
42
-
43
42
  rdoc_options: []
44
-
45
43
  extra_rdoc_files: []
46
-
47
44
  executables: []
48
-
49
45
  extensions: []
50
-
51
46
  requirements: []
52
-
53
- dependencies: []
54
-
47
+ dependencies: []