beezwax 0.5.2 → 0.6.0

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.2
1
+ 0.6.0
@@ -1,57 +1,46 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{beezwax}
8
- s.version = "0.5.2"
8
+ s.version = "0.6.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Patrick Lardin"]
12
- s.date = %q{2010-10-07}
12
+ s.date = %q{2010-12-19}
13
13
  s.description = %q{Access Btrieve database files through a ruby API.}
14
14
  s.email = %q{plardin@gmail.com}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
- "README",
18
- "README.rdoc"
17
+ "README",
18
+ "README.rdoc"
19
19
  ]
20
20
  s.files = [
21
21
  "LICENSE",
22
- "README",
23
- "README.rdoc",
24
- "Rakefile",
25
- "VERSION",
26
- "beezwax.gemspec",
27
- "lib/beezwax.rb",
28
- "lib/btrieve/btrieve_const.rb",
29
- "lib/btrieve/btrieve_core.rb",
30
- "lib/btrieve/btrieve_model.rb",
31
- "lib/btrieve/btrieve_record.rb",
32
- "lib/btrieve/btrieve_schema.rb",
33
- "lib/btrieve/btrieve_session.rb",
34
- "lib/btrieve/btrieve_table.rb",
35
- "pkg/beezwax-0.0.0.gem",
36
- "pkg/beezwax-0.1.0.gem",
37
- "pkg/beezwax-0.1.1.gem",
38
- "pkg/beezwax-0.1.2.gem",
39
- "pkg/beezwax-0.1.3.gem",
40
- "pkg/beezwax-0.1.4.gem",
41
- "pkg/beezwax-0.2.0.gem",
42
- "pkg/beezwax-0.3.0.gem",
43
- "pkg/beezwax-0.4.0.gem",
44
- "test/helper.rb",
45
- "test/test_beezwax.rb"
22
+ "README",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "beezwax.gemspec",
27
+ "lib/beezwax.rb",
28
+ "lib/btrieve/btrieve_const.rb",
29
+ "lib/btrieve/btrieve_core.rb",
30
+ "lib/btrieve/btrieve_record.rb",
31
+ "lib/btrieve/btrieve_schema.rb",
32
+ "lib/btrieve/btrieve_session.rb",
33
+ "lib/btrieve/btrieve_table.rb",
34
+ "test/btrieve/test_beezwax.rb",
35
+ "test/helper.rb"
46
36
  ]
47
37
  s.homepage = %q{http://github.com/plardin/beezwax}
48
- s.rdoc_options = ["--charset=UTF-8"]
49
38
  s.require_paths = ["lib"]
50
39
  s.rubygems_version = %q{1.3.7}
51
40
  s.summary = %q{Btrieve API wrapper.}
52
41
  s.test_files = [
53
- "test/test_beezwax.rb",
54
- "test/helper.rb"
42
+ "test/btrieve/test_beezwax.rb",
43
+ "test/helper.rb"
55
44
  ]
56
45
 
57
46
  if s.respond_to? :specification_version then
@@ -1 +1,3 @@
1
- require_relative 'btrieve/btrieve_core.rb'
1
+ require_relative 'btrieve/btrieve_core.rb'
2
+
3
+ # Loads the btrieve API
@@ -1,5 +1,9 @@
1
+ # Btrieve codes used to talk with the BTR engine.
1
2
  module BtrCodes
2
3
  OK = 0
4
+ KEY_NOT_FOUND = 4
5
+ EOF = 9
6
+
3
7
  OPEN = 0
4
8
  CLOSE = 1
5
9
  INSERT = 2
@@ -7,14 +11,18 @@ module BtrCodes
7
11
  DELETE = 4
8
12
  GET_EQUAL = 5
9
13
  GET_NEXT = 6
14
+ GET_PREVIOUS = 7
10
15
  GET_GREATER_THAN_OR_EQUAL = 9
11
16
  GET_LESS_THAN_OR_EQUAL = 11
12
- SET_DIRECTORY = 17
17
+ GET_FIRST=12
13
18
  BEGIN_TRANSACTION = 19
14
19
  END_TRANSACTION = 20
15
20
  ABORT_TRANSACTION = 21
16
21
  STEP_NEXT = 24
17
- EOF = 9
22
+ STOP = 25
23
+ RESET = 28
24
+ GET_EQUAL_KEY = 55
25
+ GET_NEXT_KEY = 56
18
26
  POS_BLOCK_SIZE = 128
19
27
  NULL_KEY = 0x00
20
28
  NULL_BUFFER = ''
@@ -34,6 +42,7 @@ module BtrCodes
34
42
  NO_CURRENCY_CHANGE = 0xFF
35
43
  MAX_DATATYPE = 200
36
44
 
45
+ # Exception messages potentially returned by the BTR engine
37
46
  EXCEPTION_MESSAGES = {
38
47
  1=>"The operation parameter is invalid.",
39
48
  2=>"The application encountered an I/O error.",
@@ -1,10 +1,12 @@
1
1
  require 'ffi'
2
2
  require_relative 'btrieve_const'
3
3
 
4
+ # Main interface with the BTR engine.
4
5
  module Btrieve
5
6
  extend FFI::Library
6
7
  include BtrCodes
7
8
 
9
+ # Detects the ruby platform to point ot the proper shared lib.
8
10
  if(RUBY_PLATFORM.match('mswin|mingw|cygwin'))
9
11
  ffi_lib 'w3btrv7.dll'
10
12
  elsif(RUBY_PLATFORM.match('linux'))
@@ -13,42 +15,29 @@ module Btrieve
13
15
  raise Exception.new("Unknown RUBY_PLATFORM #{RUBY_PLATFORM} to perform FFI calls into PSQL.")
14
16
  end
15
17
 
18
+ # FFI declaration for the BTRCALLID method of the BTR engine.
16
19
  attach_function :BTRCALLID, [:int, :pointer, :pointer, :pointer, :pointer, :uchar, :uchar, :pointer], :int
17
20
 
18
- def btr_op(session, ops, pos_buffer, data_buffer, key_buffer, key_number, valid_return_codes=[0])
19
- data_length = [data_buffer.size].pack('L')
20
- key_length = key_buffer.size
21
- result_code = BTRCALLID(ops, pos_buffer, data_buffer, data_length, key_buffer, key_length, key_number, session.client_id)
22
- unless valid_return_codes.include?(result_code)
23
- p "ops=#{ops} data_buffer.length=#{data_buffer.length} key_buffer=#{key_buffer}, key_buffer.length=#{key_buffer.length}, key_number=#{key_number}, session.client_id=#{session.client_id}"
24
- raise Exception.new("PSQL Exception Code #{result_code} - #{EXCEPTION_MESSAGES[result_code]}")
25
- end
21
+ # Single entry point into the BTR engine.
22
+ def btr_op(ops, pos_buffer, data_buffer, key_buffer, key_number, valid_return_codes=[BtrCodes::OK])
23
+ session=BtrieveSession.get_session
24
+ data_length = [data_buffer.size].pack('L')
25
+ key_length = key_buffer.size
26
+ result_code = BTRCALLID(ops, pos_buffer, data_buffer, data_length, key_buffer, key_length, key_number, session.client_id)
27
+ unless valid_return_codes.include?(result_code)
28
+ raise "PSQL Exception Code #{result_code} - #{EXCEPTION_MESSAGES[result_code]}"
29
+ end
26
30
  result_code
27
31
  end
28
32
 
33
+ # Utility method to create a buffer of a given size.
29
34
  def self.create_string_buffer(size)
30
35
  0.chr*(size)
31
- end
32
-
33
- end
34
-
35
- module Timer
36
- def timer(&block)
37
- start_time = Time.now
38
- yield
39
- end_time = Time.now
40
- end_time - start_time
41
- end
42
-
43
- def timer2(out=nil, &block)
44
- start_time = Time.now
45
- out = yield out
46
- [Time.now - start_time, out]
47
- end
36
+ end
48
37
  end
49
38
 
39
+ # Loads the rest of the BTR implementation.
50
40
  require_relative 'btrieve_session'
51
41
  require_relative 'btrieve_table'
52
42
  require_relative 'btrieve_schema'
53
43
  require_relative 'btrieve_record'
54
- require_relative 'btrieve_model'
@@ -1,174 +1,85 @@
1
1
  require 'digest/md5'
2
2
 
3
+ # Represents a single btrieve record for a particular BTR table.
3
4
  class BtrieveRecord
4
5
  include Btrieve
5
6
  attr_reader :data_buffer, :btrieve_table
6
7
 
7
- def initialize(btrieve_table, data_buffer = nil )
8
+ # Initializes a btrieve record.
9
+ def initialize(btrieve_table, data_buffer=nil)
8
10
  @btrieve_table = btrieve_table
9
11
  @data_buffer = data_buffer.nil? ? Btrieve.create_string_buffer(@btrieve_table.schema[:record_size]) : data_buffer
10
- @session = @btrieve_table.session
11
12
  end
12
13
 
14
+ # Inserts a new btrieve record through the transactional BTR engine.
13
15
  def insert
14
- btr_op(@session, INSERT, @btrieve_table.pos_buffer, @data_buffer, NULL_BUFFER, NO_CURRENCY_CHANGE)
16
+ btr_op(@btrieve_table.session, INSERT, @btrieve_table.pos_buffer, @data_buffer, NULL_BUFFER, NO_CURRENCY_CHANGE)
15
17
  end
16
18
 
19
+ # Updates an existing btrieve record through the transactional BTR engine.
17
20
  def update
18
- btr_op(@session, UPDATE, @btrieve_table.pos_buffer, @data_buffer, NULL_BUFFER, NO_CURRENCY_CHANGE)
19
- end
20
-
21
- def delete
22
- btr_op(@session, DELETE, @btrieve_table.pos_buffer, NULL_BUFFER, NULL_BUFFER, NULL_KEY)
23
- end
24
-
25
- def get_relation_bindings(key)
26
- table_map=@session.relations[@btrieve_table.tablename]
27
- raise Exception.new("No relations defined for table #{@btrieve_table.tablename}") if table_map.nil?
28
- relation=table_map[key]
29
- raise Exception.new("No relation found named #{key.to_s} in table #{@btrieve_table.tablename}") if relation.nil?
30
- bindings=relation[:join].inject({}) do |map,join|
31
- value=join[1][:match]
32
- map[join[0]]=join[1][:source]==:table ? self[value] : value
33
- map
34
- end
35
- {:table=>relation[:target],:index=>relation[:index],:bindings=>bindings}
36
- end
37
-
38
- def get_relations_bindings(keys)
39
- keys.inject({}){|map,key|map[key]=self.get_relation_bindings(key);map}
40
- end
41
-
42
- def get_all_relations_bindings()
43
- relations=@session.relations[@btrieve_table.tablename]||={}
44
- get_relations_bindings(relations.keys)
45
- end
46
-
47
- def get_relation(key)
48
- match=get_relation_bindings(key)
49
- target_table=BtrieveTable.new(relation[:target], @session)
50
- index_number=relation[:index]
51
- target_table.find(match,index_number)
52
- end
53
-
54
- def get_relations(keys)
55
- keys.inject({}){|map,key|map[key]=self.get_relation(key);map}
56
- end
57
-
58
- def get_all_relations()
59
- relations=@session.relations[@btrieve_table.tablename]||={}
60
- get_relations(relations.keys)
21
+ btr_op(@btrieve_table.session, UPDATE, @btrieve_table.pos_buffer, @data_buffer, NULL_BUFFER, NO_CURRENCY_CHANGE)
61
22
  end
62
23
 
63
- def get_mapping(key)
64
- table_map=@session.mappings[@btrieve_table.tablename]
65
- raise Exception.new("No mappings defined for table #{@btrieve_table.tablename}") if table_map.nil?
66
- mapping=table_map[key]
67
- raise Exception.new("No mapping found named #{key.to_s} in table #{@btrieve_table.tablename}") if mapping.nil?
68
- @session.mapping_functions[mapping[:transform]].call(self[mapping[:column]])
69
- end
70
-
71
- def get_mappings(keys)
72
- keys.inject({}){|map,key|map[key]=self.get_mapping(key);map}
73
- end
74
-
75
- def get_all_mappings()
76
- mappings=@session.mappings[@btrieve_table.tablename]||={}
77
- get_mappings(mappings.keys)
78
- end
79
-
80
- def get_attributes(keys)
81
- keys.inject({}){|vals, key| vals[key]=self[key]; vals}
24
+ # Deletes an existing btrieve record through the transactional BTR engine.
25
+ def delete
26
+ btr_op(@btrieve_table.session, DELETE, @btrieve_table.pos_buffer, NULL_BUFFER, NULL_BUFFER, NULL_KEY)
82
27
  end
83
28
 
84
- def get_all_attributes()
85
- cols=@btrieve_table.schema[:columns].keys.sort
86
- get_attributes(cols)
29
+ # Returns hash of column-value pairs for this btrieve record, given an array of named columns.
30
+ # If the array is nil, the hash will contain ALL the column-value pairs defined by the schema.
31
+ def values(column_names=nil)
32
+ if(column_names.nil?)
33
+ column_names=@btrieve_table.schema[:columns].keys.sort.inject([]){|array,column|array<< column;array}
34
+ end
35
+ column_names.inject({}){|vals, key| vals[key]=self[key]; vals}
87
36
  end
88
37
 
38
+ # Returns this record's primary key value. Supports composite keys.
89
39
  def primary_key()
90
- get_composite_key(@btrieve_table.primary_key)
91
- end
92
-
93
- def foreign_key(prefix)
94
- keys=@btrieve_table.primary_key.map{|key|:"#{prefix} #{key.to_s}"}
95
- get_composite_key(keys)
96
- end
97
-
98
- def get_unique_reference(association_name)
99
- dereference(:one_to_one, association_name) do |map, target, index|
100
- fk_columns = map.keys.inject([]){|vals, column| vals << column; vals}
101
- fk_values = get_attributes(fk_columns)
102
- pk_values = map.keys.inject({}){|vals, column| vals[map[column]] = fk_values[column]; vals}
103
- target.find_in_unique_index(pk_values, index)
104
- end
105
- end
106
-
107
- def get_multiple_references(association_name)
108
- dereference(:one_to_many, association_name) do |map, target, index|
109
- pk_columns = map.keys.inject([]){|vals, column| vals << map[column] unless map[column] == nil; vals}
110
- pk_values = get_attributes(pk_columns)
111
- fk_values = map.keys.inject({}){|vals, column| vals[column] = pk_values[map[column]]; vals}
112
- target.find_in_index(fk_values, index)
113
- end
40
+ values(@btrieve_table.primary_key)
114
41
  end
115
-
42
+
43
+ # Returns this record's value of the column passed in.
116
44
  def [](key_name)
117
- schema_key=get_schema_key(key_name)
118
- return nil if(schema_key.nil?)
119
- @data_buffer.unpack(schema_key[:unpacker])[0]
45
+ column_info = get_column_info(key_name)
46
+ return nil if(column_info.nil?)
47
+ @data_buffer.unpack(column_info[:unpacker])[0]
120
48
  end
121
49
 
50
+ # Sets this record's value for a particular column.
122
51
  def []=(key_name, value)
123
52
  schema_key = get_schema_key(key_name)
124
53
  packer_string = schema_key[:unpacker]
125
54
  match = packer_string.match(/@(\d+)([a-zA-Z]+)(\d*)/)
126
55
  offset = match[1].to_i
127
56
  datatype = match[2]
128
- sizeof = BtrieveSchema.sizeof(datatype)
129
- sizeof *= match[3].empty? ? 1 : match[3].to_i
130
- packer = "#{datatype}#{sizeof}"
57
+ thesizeof = BtrieveSchema.sizeof(datatype)
58
+ thesizeof *= match[3].empty? ? 1 : match[3].to_i
59
+ packer = "#{datatype}#{thesizeof}"
131
60
  array = [value]
132
61
  packed_value = array.pack(packer)
133
62
  range = (offset..offset+packed_value.size-1)
134
63
  @data_buffer[range] = packed_value
135
64
  end
136
-
65
+
66
+ def nil?()
67
+ data_buffer.gsub("\x00", "").size==0
68
+ end
69
+
70
+ # Returns a string representation of this record.
137
71
  def to_s()
138
- @btrieve_table.schema[:columns].keys.inject('') { |pretty_print, key| pretty_print = "#{pretty_print} #{key}=>#{self[key]}"; pretty_print }
72
+ @btrieve_table.schema[:columns].keys.inject(''){|pretty_print, key| pretty_print = "#{pretty_print} #{key}=>#{self[key]}"; pretty_print}
139
73
  end
140
74
 
75
+ # Returns this record's version as a MD5 Digest value.
141
76
  def version()
142
77
  Digest::MD5.hexdigest(@data_buffer)
143
78
  end
144
79
 
145
- def method_missing(symbol)
146
- return get_unique_reference(symbol) if(@btrieve_table.schema[:one_to_one][symbol])
147
- return get_multiple_references(symbol) if(@btrieve_table.schema[:one_to_many][symbol])
148
- super(symbol)
149
- end
150
-
151
80
  private
152
81
 
153
- def dereference(association_group, association_name, &block)
154
- association = @btrieve_table.schema[association_group][association_name]
155
- raise Exception.new("Unknown association '#{association_name}' for table '#{@btrieve_table.tablename}'.") unless association != nil
156
- map = association[:map]
157
- target = eval(association[:class].to_s)
158
- index = association[:index]
159
- yield(map, target, index)
160
- end
161
-
162
- def get_schema_key(key_name)
163
- schema_key = @btrieve_table.schema[:columns][key_name]
164
- # raising this exception is hurting the dbr process since I use keys that dont exist
165
- # raise Exception.new("Unknown column '#{key_name}' for table '#{@btrieve_table.tablename}'.") unless schema_key != nil
166
- schema_key
167
- end
168
-
169
- def get_composite_key(keys)
170
- pk=keys.inject([]){|arr,col|arr<<self[col];arr}
171
- pk[2]=pk[2].strip
172
- pk.join('.')
82
+ def get_column_info(column_name)
83
+ @btrieve_table.schema[:columns][column_name]
173
84
  end
174
85
  end
@@ -1,28 +1,52 @@
1
+ # Represents the btrieve schema (DDF files) of a particular BTR database.
1
2
  class BtrieveSchema
2
3
  include Btrieve
3
- attr_reader :session, :xfile_records, :xfield_records
4
-
5
- def initialize(session)
6
- @session = session
7
- if(!@session.cache[:schemas_loaded])
4
+ attr_reader :xfile_records, :xfield_records
5
+
6
+ # Datatypes used to transact with the BTR engine.
7
+ CHAR = { :name=>'CHAR', :unpacker=>'a', :size=>1 }
8
+ TINYINT = { :name=>'TINYINT', :unpacker=>'c', :size=>1 }
9
+ SMALLINT = { :name=>'SMALLINT', :unpacker=>'s', :size=>1 }
10
+ INTEGER = { :name=>'INTEGER', :unpacker=>'i', :size=>1 }
11
+ REAL = { :name=>'REAL', :unpacker=>'f', :size=>1 }
12
+ DOUBLE = { :name=>'DOUBLE', :unpacker=>'d', :size=>1 }
13
+ DATE = { :name=>'DATE', :unpacker=>'ccs', :size=>4 } #day month year
14
+ TIME = { :name=>'TIME', :unpacker=>'cccc', :size=>4 } #100th sec min hour
15
+ BIT = { :name=>'BIT', :unpacker=>'c', :size=>1 }
16
+ VARCHAR = { :name=>'VARCHAR', :unpacker=>'A', :size=>1 }
17
+ LONGVARCHAR = { :name=>'LONGVARCHAR', :unpacker=>'A', :size=>1 }
18
+ UTINYINT = { :name=>'UTINYINT', :unpacker=>'C', :size=>1, :size=>1 }
19
+ USMALLINT = { :name=>'USMALLINT', :unpacker=>'S', :size=>1 }
20
+ UINTEGER = { :name=>'UINTEGER', :unpacker=>'I', :size=>1 }
21
+ UBIGINT = { :name=>'UBIGINT', :unpacker=>'Q', :size=>1 }
22
+
23
+ # Array of all datatypes supported by the BTR engine.
24
+ SIZEOF = {'a'=>1, 'c'=>1, 's'=>1, 'i'=>1, 'f'=>1, 'd'=>1, 'ccs'=>4, 'cccc'=>4, 'A'=>1, 'C'=>1, 'S'=>1, 'I'=>1, 'Q'=>1}
25
+
26
+ # Creates a new instance of btrieve schema for a given session.
27
+ def initialize()
28
+ session=BtrieveSession.get_session
29
+ if(!session.cache[:schemas_loaded])
8
30
  cache_system_table(:'x$file')
9
31
  cache_system_table(:'x$field')
10
32
  cache_system_table(:'x$index')
11
- @session.cache[:schemas_loaded] = true
33
+ session.cache[:schemas_loaded] = true
12
34
  end
13
35
  end
14
36
 
15
- def load_schema(tablename)
37
+ # Loads the schema of a particular btrieve table.
38
+ def get_table_schema(tablename)
39
+ session=BtrieveSession.get_session
16
40
  schema = nil
17
41
  xfile_index = nil
18
- @session.cache[:'x$file'].each do |xfile|
42
+ session.cache[:'x$file'].each do |xfile|
19
43
  next unless xfile[:'xf$name'].downcase.strip.to_sym == tablename
20
44
  schema = {:filename=>xfile[:'xf$loc'].downcase.strip, :record_size=>0, :columns=>{}}
21
45
  xfile_index = xfile[:'xf$id']
22
46
  break
23
47
  end
24
48
  xfield_index = []
25
- @session.cache[:'x$field'].each do |xfield|
49
+ session.cache[:'x$field'].each do |xfield|
26
50
  next unless xfile_index == xfield[:'xe$file']
27
51
  next unless xfield[:'xe$datatype'] < MAX_DATATYPE
28
52
  id = xfield[:'xe$id']
@@ -33,10 +57,9 @@ class BtrieveSchema
33
57
  datatype = (name == 'kid - mult') ? 14 : datatype # Absolute BS line of code... Needed for CTA-FOS
34
58
  unpacker = BtrieveSchema.unpacker(offset, datatype, size)
35
59
  schema[:columns][name.to_sym] = {:unpacker=>unpacker, :id=>id, :offset=>offset, :datatype=>datatype, :size=>size}
36
- schema[:record_size] += size
37
60
  xfield_index[id] = name.to_sym
38
61
  end
39
- @session.cache[:'x$index'].each do |xindex|
62
+ session.cache[:'x$index'].each do |xindex|
40
63
  next unless xfile_index == xindex[:'xi$file']
41
64
  indices = schema[:indices] ||= []
42
65
  index = indices[xindex[:'xi$number']] ||= []
@@ -44,16 +67,12 @@ class BtrieveSchema
44
67
  flags = schema[:index_flags] ||= []
45
68
  flags[xindex[:'xi$number']] = flags[xindex[:'xi$number']].to_i | xindex[:'xi$flags'].to_i
46
69
  end
70
+ last_field=schema[:columns].values.sort{|a,b| a[:offset] <=> b[:offset]}.last
71
+ schema[:record_size] = last_field[:offset]+last_field[:size]
47
72
  raise Exception.new("Unknown table '#{tablename}'.") if schema.nil?
48
- schema[:one_to_one] = {}
49
- schema[:one_to_many] = {}
50
73
  schema
51
74
  end
52
75
 
53
- def self.sizeof(code)
54
- SIZEOF[code]
55
- end
56
-
57
76
  private
58
77
 
59
78
  SYS_DDF = {
@@ -61,25 +80,7 @@ class BtrieveSchema
61
80
  :'x$field'=>{:filename=>'field.ddf', :record_size=>32, :columns=>{:'xe$id'=>{:unpacker=>'@0S'}, :'xe$file'=>{:unpacker=>'@2S'}, :'xe$name'=>{:unpacker=>'@4a20'}, :'xe$datatype'=>{:unpacker=>'@24C'}, :'xe$offset'=>{:unpacker=>'@25S'}, :'xe$size'=>{:unpacker=>'@27S'}, :'xe$dec'=>{:unpacker=>'@29C'}, :'xe$flags'=>{:unpacker=>'@30S'}}},
62
81
  :'x$index'=>{:filename=>'index.ddf', :record_size=>32, :columns=>{:'xi$file'=>{:unpacker=>'@0S'},:'xi$field'=>{:unpacker=>'@2S'},:'xi$number'=>{:unpacker=>'@4S'},:'xi$part'=>{:unpacker=>'@6S'},:'xi$flags'=>{:unpacker=>'@8S'}}}
63
82
  }
64
-
65
- CHAR = { :name=>'CHAR', :unpacker=>'a' }
66
- TINYINT = { :name=>'TINYINT', :unpacker=>'c' }
67
- SMALLINT = { :name=>'SMALLINT', :unpacker=>'s' }
68
- INTEGER = { :name=>'INTEGER', :unpacker=>'i' }
69
- REAL = { :name=>'REAL', :unpacker=>'f' }
70
- DOUBLE = { :name=>'DOUBLE', :unpacker=>'d' }
71
- DATE = { :name=>'DATE', :unpacker=>'ccs' } #day month year
72
- TIME = { :name=>'TIME', :unpacker=>'cccc' } #100th sec min hour
73
- BIT = { :name=>'BIT', :unpacker=>'c' }
74
- VARCHAR = { :name=>'VARCHAR', :unpacker=>'A' }
75
- LONGVARCHAR = { :name=>'LONGVARCHAR', :unpacker=>'A' }
76
- UTINYINT = { :name=>'UTINYINT', :unpacker=>'C' }
77
- USMALLINT = { :name=>'USMALLINT', :unpacker=>'S' }
78
- UINTEGER = { :name=>'UINTEGER', :unpacker=>'I' }
79
- UBIGINT = { :name=>'UBIGINT', :unpacker=>'Q' }
80
-
81
- SIZEOF = {'a'=>1, 'c'=>1, 's'=>1, 'i'=>1, 'f'=>1, 'd'=>1, 'ccs'=>4, 'cccc'=>4, 'A'=>1, 'C'=>1, 'S'=>1, 'I'=>1, 'Q'=>1}
82
-
83
+
83
84
  def self.unpacker(offset, datatype, size)
84
85
  offsetter = "@#{offset}"
85
86
  btrtype = lookup(datatype, size)
@@ -115,9 +116,10 @@ class BtrieveSchema
115
116
  end
116
117
 
117
118
  def cache_system_table(tablename)
118
- @session.cache[tablename] = []
119
- schema_table = BtrieveTable.new(SYS_DDF[tablename][:filename], @session, SYS_DDF[tablename])
120
- schema_table.each_record(ACCELERATED_MODE) {|value| @session.cache[tablename] << value}
119
+ session=BtrieveSession.get_session
120
+ session.cache[tablename] = []
121
+ schema_table = BtrieveTable.new(SYS_DDF[tablename][:filename], SYS_DDF[tablename])
122
+ schema_table.each_record(ACCELERATED_MODE) {|value| session.cache[tablename] << value}
121
123
  end
122
124
  end
123
125
 
@@ -1,48 +1,57 @@
1
+ # Concept of a BTR session. Beware, this implementation is NOT thread safe!
1
2
  class BtrieveSession
2
- SESSIONS = {}
3
3
  include Btrieve
4
- attr_reader :pathname, :client_id, :cache, :model_classes, :btrieve_schema
5
- attr_accessor :mappings, :mapping_functions, :relations
6
-
7
- def self.set_context(pathname)
8
- session = get_session
9
- if session
10
- raise Exception.new("The existing context in the current is set to a different pathname.") if(session.pathname != pathname)
11
- else
12
- SESSIONS[Thread.current] = new(pathname)
13
- end
4
+ attr_reader :client_id, :cache, :btrieve_schema
5
+ attr_accessor :host, :data_share
6
+ private_class_method :new
7
+ @@instance=nil
8
+
9
+ # Factory of BTR sessions. A block can be passed into it, or alternatively the factory returns
10
+ # the session instance to the caller, who then must call 'dispose' on it when done with it.
11
+ # The 'host' argument can be a named server or its IP address.
12
+ # The 'data_share' argument is typically the share name of the data folder.
13
+ # The 'data_share' argument can also be the database name when "IDS" is used on the client.
14
+ def BtrieveSession.create_session(host, data_share)
15
+ raise "Cannot create more than one instance of session." if(@@instance != nil)
16
+ @@instance = new(host, data_share)
17
+ @@instance.set_schema(BtrieveSchema.new())
14
18
  end
15
19
 
16
- def self.get_session
17
- SESSIONS[Thread.current]
20
+ # Returns the session instance created.
21
+ def BtrieveSession.get_session()
22
+ @@instance
23
+ end
24
+
25
+ # Disposes of the session object, releasing any and all resources consumed/locked on the server.
26
+ def BtrieveSession.destroy_session()
27
+ @@instance.btr_op(RESET, NULL_BUFFER, NULL_BUFFER, NULL_BUFFER, NULL_KEY)
28
+ @@instance=nil
18
29
  end
19
30
 
20
- def transaction(&block)
21
- btr_op(self, BEGIN_TRANSACTION, NULL_BUFFER, NULL_BUFFER, NULL_BUFFER, NULL_KEY)
31
+ # Executes a block of BTR directive in a transaction.
32
+ def BtrieveSession.transaction(&block)
22
33
  begin
34
+ @@instance.btr_op(BEGIN_TRANSACTION, NULL_BUFFER, NULL_BUFFER, NULL_BUFFER, NULL_KEY)
23
35
  yield
24
36
  rescue Exception => exception
25
- btr_op(self, ABORT_TRANSACTION, NULL_BUFFER, NULL_BUFFER, NULL_BUFFER, NULL_KEY)
26
- raise Exception.new("PSQL TX ABORTED!!! - #{exception.message}\n#{exception.backtrace.join("\n\t")}")
37
+ # Oops! We must roll back the whole shebang!
38
+ @@instance.btr_op(ABORT_TRANSACTION, NULL_BUFFER, NULL_BUFFER, NULL_BUFFER, NULL_KEY)
39
+ raise "PSQL TX ABORTED!!! - #{exception.message}\n#{exception.backtrace.join("\n\t")}"
40
+ ensure
41
+ @@instance.btr_op(END_TRANSACTION, NULL_BUFFER, NULL_BUFFER, NULL_BUFFER, NULL_KEY)
27
42
  end
28
- btr_op(self, END_TRANSACTION, NULL_BUFFER, NULL_BUFFER, NULL_BUFFER, NULL_KEY)
29
43
  end
30
-
31
- def get_table(tablename)
32
- table=@table_cache[tablename]||=BtrieveTable.new(tablename.to_sym, self)
33
- [table,table.version]
44
+
45
+ def set_schema(schema)
46
+ @btrieve_schema=schema
34
47
  end
35
-
36
- private
37
-
38
- def initialize(pathname)
39
- @cache = {}
40
- @model_classes = {}
41
- @table_cache = {}
42
- @pathname = pathname
48
+
49
+ private
50
+
51
+ def initialize(host, data_share)
52
+ @host = host
53
+ @data_share = data_share
43
54
  @client_id = "#{0.chr*12}#{[0x5257].pack('S')}#{rand(65535)}"
44
- btr_op(self, SET_DIRECTORY, NULL_BUFFER, NULL_BUFFER, @pathname, NULL_KEY)
45
- @btrieve_schema = BtrieveSchema.new(self)
55
+ @cache = {}
46
56
  end
47
57
  end
48
-
@@ -1,78 +1,52 @@
1
1
  require 'digest/md5'
2
2
 
3
+ # Represents a single btrieve table for a particular BTR database.
3
4
  class BtrieveTable
4
5
  include Btrieve
5
- attr_reader :tablename, :session, :pos_buffer, :schema
6
+ attr_reader :tablename, :pos_buffer, :schema
6
7
  attr_accessor :primary_key
7
8
 
8
- def initialize(tablename, session, schema=nil)
9
+ # Initializes a btrieve table.
10
+ def initialize(tablename, schema=nil)
9
11
  @tablename = tablename
10
- @session = session
11
12
  @pos_buffer = Btrieve.create_string_buffer(POS_BLOCK_SIZE)
12
- @schema = schema ? schema : @session.btrieve_schema.load_schema(@tablename)
13
- end
14
-
15
- def open(mode = NORMAL_MODE)
16
- btr_op(@session, OPEN, @pos_buffer, NULL_BUFFER, @schema[:filename], mode)
17
- end
18
-
19
- def mappings()
20
- @session.mappings[@tablename] ||= {}
21
- end
22
-
23
- def add_mapping(attr_name, mapping_name, transform)
24
- mappings[mapping_name.to_sym]={:column=>attr_name.to_sym,:transform=>transform.to_sym}
25
- end
26
-
27
- def relations()
28
- @session.relations[@tablename] ||= {}
29
- end
30
-
31
- def add_relation(name, target_table, index, join)
32
- relations[name.to_sym]={:target=>target_table.to_sym,:index=>index,:join=>join}
13
+ @schema = schema ? schema : session.btrieve_schema.get_table_schema(@tablename)
14
+ end
15
+
16
+ # Opens this btrieve table in preparation for some BTR operation(s).
17
+ # If a block is passed to the call, the table is closed automatically.
18
+ # If a block is NOT passed to the call, the client code has to make sure to close the file.
19
+ def open(mode=NORMAL_MODE, &block)
20
+ file_unc="//#{session.host}/#{session.data_share}/#{@schema[:filename]}"
21
+ btr_op(OPEN, @pos_buffer, NULL_BUFFER, file_unc, mode)
22
+ if block_given?
23
+ yield
24
+ close()
25
+ end
33
26
  end
34
27
 
35
- def find(match, index_number)
36
- unique=schema[:index_flags].map{|f|f&1==1}[index_number]
37
- result=nil
38
- if(unique)
39
- result=find_in_unique_index(match, index_numer)
28
+ # Finds an array of records in this table, using the specified index number and match hash.
29
+ # If a block is passed in, the entries of this set are passed into this block one by one. Otherwise,
30
+ # the set is returned to the caller.
31
+ def find(match, index_number, &block)
32
+ allows_duplicates=schema[:index_flags].map{|f|f&1==1;}[index_number]
33
+ set=nil
34
+ if(allows_duplicates)
35
+ set=find_in_index(match, index_number)
40
36
  else
41
- result=find_in_index(match, index_numer)
42
- end
43
- result
44
- end
45
-
46
- def find_in_unique_index(match, index_number=nil)
47
- finder(match, index_number) do |key_buffer, index|
48
- btr_record = BtrieveRecord.new(self)
49
- batch(){ btr_op(@session, GET_EQUAL, @pos_buffer, btr_record.data_buffer, key_buffer, index) }
50
- btr_record
37
+ rec=find_in_unique_index(match, index_number)
38
+ set=rec.nil? ? [] : [rec]
51
39
  end
52
- end
53
-
54
- def find_in_index(match, index_number=nil)
55
- finder(match, index_number) do |key_buffer, index|
56
- absolute_match = match.keys.inject({}){|vals, key| vals[key] = match[key] if(match[key] != nil); vals}
57
- absolute_match_keys = absolute_match.keys
58
- result = []
59
- batch() do
60
- btr_record = BtrieveRecord.new(self)
61
- ops_result = btr_op(@session, GET_GREATER_THAN_OR_EQUAL, @pos_buffer, btr_record.data_buffer, key_buffer, index, [OK, EOF])
62
- if OK==ops_result
63
- result << btr_record
64
- while(true)
65
- btr_record = BtrieveRecord.new(self)
66
- op_result = btr_op(@session, GET_NEXT, @pos_buffer, btr_record.data_buffer, key_buffer, index_number, [OK, EOF, 21])
67
- break unless btr_record.get_attributes(absolute_match_keys)==absolute_match and op_result!=EOF and op_result!=21
68
- result << btr_record
69
- end
70
- end
71
- end
72
- result
40
+ if(block_given?)
41
+ set.each{|record| yield record}
42
+ else
43
+ set
73
44
  end
74
45
  end
75
46
 
47
+ # Finds an array of records in this table, using the specified index number, a key and a range of values.
48
+ # If a block is passed in, the entries of this set are passed into this block one by one. Otherwise,
49
+ # the set is returned to the caller.
76
50
  def find_in_range(index_num, key, range, &block)
77
51
  index = @schema[:indices][index_num]
78
52
  columns = @schema[:columns]
@@ -84,23 +58,32 @@ class BtrieveTable
84
58
  packer
85
59
  end
86
60
  key_buffer = index_values.pack(key_packer)
87
-
88
61
  btr_record = BtrieveRecord.new(self)
62
+ records = []
89
63
  batch do
90
- btr_op(@session, GET_GREATER_THAN_OR_EQUAL, @pos_buffer, btr_record.data_buffer, key_buffer, index_num, [OK, EOF])
91
- while(range.include?(btr_record[key]))
92
- yield btr_record
64
+ btr_op(GET_GREATER_THAN_OR_EQUAL, @pos_buffer, btr_record.data_buffer, key_buffer, index_num, [OK, EOF])
65
+ while(range.include?(btr_record[key]))
66
+ if(!block.nil?)
67
+ yield btr_record
68
+ else
69
+ records << btr_record
70
+ end
93
71
  btr_record = BtrieveRecord.new(self)
94
- btr_op(@session, GET_NEXT, @pos_buffer, btr_record.data_buffer, key_buffer, index_num, [OK, EOF])
72
+ btr_op(GET_NEXT, @pos_buffer, btr_record.data_buffer, key_buffer, index_num, [OK, EOF])
95
73
  end
96
74
  end
75
+ if(block.nil?)
76
+ records
77
+ end
97
78
  end
98
79
 
80
+ # Closes this btrieve table to conclude a sequence of BTR operation(s).
99
81
  def close
100
- btr_op(@session, CLOSE, @pos_buffer, NULL_BUFFER, NULL_BUFFER, NULL_KEY)
82
+ btr_op(CLOSE, @pos_buffer, NULL_BUFFER, NULL_BUFFER, NULL_KEY)
101
83
  end
102
84
 
103
- def each_record(mode = READ_ONLY_MODE, &block)
85
+ # Loops over the records of this BTR table and passes each record to the block passed in.
86
+ def each_record(mode=NORMAL_MODE, &block)
104
87
  batch(mode) do
105
88
  while(record = step_next) do
106
89
  yield record
@@ -108,34 +91,24 @@ class BtrieveTable
108
91
  end
109
92
  end
110
93
 
111
- def batch(mode = READ_ONLY_MODE, &block)
94
+ # Wraps a sequence of BTR operations between a pair of open and close statements for this table.
95
+ # DEPRECATED - Use the "open" method instead and pass a block to it.
96
+ def batch(mode=NORMAL_MODE, &block)
112
97
  open(mode)
113
98
  yield
114
99
  close
115
100
  end
116
101
 
102
+ # Returns this table's version as a MD5 Digest value.
117
103
  def version()
118
104
  Digest::MD5.hexdigest(BtrieveSchema.sort(schema[:columns]).inject([]){|array,column|array << BtrieveSchema.readable_type(column);array}.to_s)
119
105
  end
120
-
121
- #def self.primary_key_match(pk)
122
- # vals=pk.split('.')
123
- # {PK_KEYS[0]=>vals[0].to_i,PK_KEYS[1]=>vals[1].to_i,PK_KEYS[2]=>vals[2],PK_KEYS[3]=>vals[3].to_i,PK_KEYS[4]=>vals[4].to_i}
124
- #end
125
-
126
- #def self.tablename_to_url(tablename)
127
- # tablename.gsub(' & ','.and.').gsub('a/c ', 'ac.').gsub('es - o','es.o').gsub(' ','.')
128
- #end
129
-
130
- #def self.url_to_tablename(url_tablename)
131
- # url_tablename.gsub('.and.', ' & ').gsub('ac.', 'a/c ').gsub('es.o','es - o').gsub('.',' ')
132
- #end
133
106
 
134
107
  private
135
108
 
136
109
  def step_next
137
110
  btr_record = BtrieveRecord.new(self)
138
- result = btr_op(@session, STEP_NEXT, @pos_buffer, btr_record.data_buffer, NULL_BUFFER, NULL_KEY, [OK, EOF])
111
+ result = btr_op(STEP_NEXT, @pos_buffer, btr_record.data_buffer, NULL_BUFFER, NULL_KEY, [OK, EOF])
139
112
  return false if(result == EOF)
140
113
  btr_record
141
114
  end
@@ -158,6 +131,7 @@ class BtrieveTable
158
131
  value = match[key]
159
132
  value = value.to_f if FLOAT_TYPES.include?(datatype)
160
133
  value = value.to_i if INTEGER_TYPES.include?(datatype)
134
+ value = value.ljust(columns[key][:size], ' ') if datatype=='CHAR'
161
135
  vals << value
162
136
  vals
163
137
  end
@@ -173,5 +147,41 @@ class BtrieveTable
173
147
  key_buffer = key_components.pack(key_packer)
174
148
  yield(key_buffer, index_number)
175
149
  end
150
+
151
+ def find_in_unique_index(match, index_number=nil)
152
+ finder(match, index_number) do |key_buffer, index|
153
+ btr_record = BtrieveRecord.new(self)
154
+ batch(){ btr_op(GET_EQUAL, @pos_buffer, btr_record.data_buffer, key_buffer, index, [KEY_NOT_FOUND, OK, EOF]) }
155
+ btr_record.nil? ? nil : btr_record
156
+ end
157
+ end
158
+
159
+ def find_in_index(match, index_number=nil)
160
+ finder(match, index_number) do |org_key_buffer, index|
161
+ absolute_match = match.keys.inject({}){|vals, key| vals[key] = match[key] if(match[key] != nil); vals}
162
+ absolute_match_keys = absolute_match.keys
163
+ result = []
164
+ batch do
165
+ key_buffer="#{org_key_buffer}"
166
+ ops_result = btr_op(GET_EQUAL_KEY, @pos_buffer, NULL_BUFFER, key_buffer, index, [OK, EOF, KEY_NOT_FOUND])
167
+ ops=GET_EQUAL
168
+ while(ops_result == OK)
169
+ btr_record = BtrieveRecord.new(self)
170
+ ops_result = btr_op(ops, @pos_buffer, btr_record.data_buffer, key_buffer, index, [OK, EOF])
171
+ break if(key_buffer!=org_key_buffer)
172
+ ops=GET_NEXT
173
+ result << btr_record if(ops_result == OK)
174
+ end
175
+ end
176
+ result
177
+ end
178
+ end
179
+
180
+ def session
181
+ s=BtrieveSession.get_session
182
+ raise "Cannot manipulate a BtrieveTable when no BtrieveSession exists." if s.nil?
183
+ s
184
+ end
185
+
176
186
  end
177
187
 
@@ -0,0 +1,133 @@
1
+ require 'helper'
2
+
3
+ class TestBeezwax < Test::Unit::TestCase
4
+ context "when a BtrieveSession is initialized" do
5
+ setup do
6
+ BtrieveSession.create_session(DB_SERVER,"Demodata")
7
+ end
8
+
9
+ teardown do
10
+ BtrieveSession.destroy_session
11
+ end
12
+
13
+ should "not allow the creation of another session" do
14
+ assert_raise(RuntimeError){BtrieveSession.create_session(DB_SERVER,"Demodata")}
15
+ end
16
+
17
+ should "return a handle to the session singleton" do
18
+ session=BtrieveSession.get_session
19
+ assert_not_nil session
20
+ end
21
+
22
+ should "permit the instanciation of a DB table" do
23
+ table=BtrieveTable.new(:course)
24
+ assert_not_nil table
25
+ end
26
+
27
+ should "allow an empty transaction to go through" do
28
+ BtrieveSession.transaction{}
29
+ end
30
+
31
+ context "and an instance of BtrieveTable is created, it" do
32
+ setup do
33
+ @table=BtrieveTable.new(:course)
34
+ end
35
+
36
+ teardown do
37
+ @table=nil
38
+ end
39
+
40
+ should "be possible to open it for operations, then close it" do
41
+ assert_nothing_raised(RuntimeError){@table.open}
42
+ assert_nothing_raised(RuntimeError){@table.close}
43
+ end
44
+
45
+ should "be possible to have the file automatically closed when a block is passed when opening a table" do
46
+ @table.open{}
47
+ assert_raise(RuntimeError){@table.close}
48
+ end
49
+
50
+ should "return a version number for that table" do
51
+ table_version=@table.version
52
+ assert_not_nil table_version
53
+ assert_equal 32, table_version.size
54
+ end
55
+
56
+ should "allow looping over each of its records to count them" do
57
+ counter = 0
58
+ assert_nothing_raised{@table.each_record{|record|counter+=1}}
59
+ assert_equal 145, counter
60
+ end
61
+
62
+ should "be possible to search the table for a given index" do
63
+ assert_nothing_raised {@table.find({:name=>'blah'}, 0)}
64
+ end
65
+
66
+ should "be possible to find a particular record in a unique index" do
67
+ name = 'PHI 101'
68
+ record=@table.find({:name=>name}, 0).first
69
+ assert_not_nil record
70
+ assert_equal record[:name], name
71
+ end
72
+
73
+ should "be possible to fetch a particular record and all its columns should be properly set" do
74
+ name = 'PHI 101'
75
+ record=@table.find({:name=>name}, 0).first
76
+ expected_values={:name=>name, :description=>'Introduction to Ethics', :credit_hours=>3, :dept_name=>'Philosophy'}
77
+ assert_equal expected_values, record.values
78
+ end
79
+
80
+ should "be possible to search for a unique key that doesn't exist and not cause an exception" do
81
+ name = 'FRA 333'
82
+ records=@table.find({:name=>name}, 0)
83
+ assert_not_nil records
84
+ assert records.empty?, "records is NOT empty"
85
+ end
86
+
87
+ should "be possible to find several records in an index that supports duplicates" do
88
+ dept_name = 'Mathematics'
89
+ records=@table.find({:dept_name=>dept_name}, 1)
90
+ assert_not_nil records
91
+ assert !records.empty?, "records is empty"
92
+ assert_equal 9, records.size
93
+ assert records.inject(true){|test, record| test |= record[:dept_name]==dept_name; test}
94
+ end
95
+
96
+ should "support finding records and looping over them if a block is passed in" do
97
+ dept_name = 'Mathematics'
98
+ counter = 0
99
+ @table.find({:dept_name=>dept_name}, 1) do
100
+ counter += 1
101
+ end
102
+ assert_equal 9, counter
103
+ end
104
+
105
+ should "be possible to search for a key that doesn't exit and not cause an exception" do
106
+ dept_name = 'Francais'
107
+ records=@table.find({:dept_name=>dept_name}, 1)
108
+ assert_not_nil records
109
+ assert records.empty?, "records is NOT empty"
110
+ end
111
+
112
+
113
+ end
114
+ end
115
+
116
+ context "A destroyed BtrieveSession" do
117
+ setup do
118
+ BtrieveSession.create_session(DB_SERVER,"Demodata")
119
+ @table = BtrieveTable.new(:course)
120
+ BtrieveSession.destroy_session
121
+ end
122
+
123
+ should "not allow the instanciation of a DB table" do
124
+ assert_raise(RuntimeError){BtrieveTable.new(:course)}
125
+ end
126
+
127
+ should "not allow exsting tables to search against the DB" do
128
+ records=nil
129
+ assert_raise(RuntimeError){records=@table.find({:dept_name=>'Mathematics'}, 1)}
130
+ assert_nil records
131
+ end
132
+ end
133
+ end
@@ -6,5 +6,13 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
6
  $LOAD_PATH.unshift(File.dirname(__FILE__))
7
7
  require 'beezwax'
8
8
 
9
+
9
10
  class Test::Unit::TestCase
11
+ #DB_SERVER=nil
12
+ DB_SERVER="10.211.55.4"
13
+ context "The database server name DB_SERVER" do
14
+ should "be defined to match your environment" do
15
+ assert_not_nil DB_SERVER
16
+ end
17
+ end
10
18
  end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beezwax
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
- - 5
9
- - 2
10
- version: 0.5.2
7
+ - 6
8
+ - 0
9
+ version: 0.6.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Patrick Lardin
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-10-07 00:00:00 -07:00
17
+ date: 2010-12-19 00:00:00 -08:00
19
18
  default_executable:
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
@@ -26,7 +25,6 @@ dependencies:
26
25
  requirements:
27
26
  - - ">="
28
27
  - !ruby/object:Gem::Version
29
- hash: 1
30
28
  segments:
31
29
  - 0
32
30
  - 6
@@ -54,29 +52,19 @@ files:
54
52
  - lib/beezwax.rb
55
53
  - lib/btrieve/btrieve_const.rb
56
54
  - lib/btrieve/btrieve_core.rb
57
- - lib/btrieve/btrieve_model.rb
58
55
  - lib/btrieve/btrieve_record.rb
59
56
  - lib/btrieve/btrieve_schema.rb
60
57
  - lib/btrieve/btrieve_session.rb
61
58
  - lib/btrieve/btrieve_table.rb
62
- - pkg/beezwax-0.0.0.gem
63
- - pkg/beezwax-0.1.0.gem
64
- - pkg/beezwax-0.1.1.gem
65
- - pkg/beezwax-0.1.2.gem
66
- - pkg/beezwax-0.1.3.gem
67
- - pkg/beezwax-0.1.4.gem
68
- - pkg/beezwax-0.2.0.gem
69
- - pkg/beezwax-0.3.0.gem
70
- - pkg/beezwax-0.4.0.gem
59
+ - test/btrieve/test_beezwax.rb
71
60
  - test/helper.rb
72
- - test/test_beezwax.rb
73
61
  has_rdoc: true
74
62
  homepage: http://github.com/plardin/beezwax
75
63
  licenses: []
76
64
 
77
65
  post_install_message:
78
- rdoc_options:
79
- - --charset=UTF-8
66
+ rdoc_options: []
67
+
80
68
  require_paths:
81
69
  - lib
82
70
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -84,7 +72,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
84
72
  requirements:
85
73
  - - ">="
86
74
  - !ruby/object:Gem::Version
87
- hash: 3
88
75
  segments:
89
76
  - 0
90
77
  version: "0"
@@ -93,7 +80,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
80
  requirements:
94
81
  - - ">="
95
82
  - !ruby/object:Gem::Version
96
- hash: 3
97
83
  segments:
98
84
  - 0
99
85
  version: "0"
@@ -105,5 +91,5 @@ signing_key:
105
91
  specification_version: 3
106
92
  summary: Btrieve API wrapper.
107
93
  test_files:
108
- - test/test_beezwax.rb
94
+ - test/btrieve/test_beezwax.rb
109
95
  - test/helper.rb
@@ -1,49 +0,0 @@
1
- class BtrieveModel
2
- include Btrieve
3
- def initialize(classname, tablename)
4
- session = BtrieveSession.get_session()
5
- table = BtrieveTable.new(tablename, session)
6
- session.model_classes[classname] = table
7
- end
8
-
9
- def self.new_record()
10
- BtrieveRecord.new(get_table())
11
- end
12
-
13
- def self.find_in_unique_index(match, index_number)
14
- get_table().find_in_unique_index(match, index_number)
15
- end
16
-
17
- def self.find_in_index(match, index_number)
18
- get_table().find_in_index(match, index_number)
19
- end
20
-
21
- def self.each_record(mode=ACCELERATED_MODE, &block)
22
- get_table().each_record(mode, &block)
23
- end
24
-
25
- def self.batch(mode=ACCELERATED_MODE, &block)
26
- get_table().batch(mode, &block)
27
- end
28
-
29
- def self.one_to_one(association)
30
- get_table().schema[:one_to_one][association[:name]]=association
31
- end
32
-
33
- def self.one_to_many(association)
34
- get_table().schema[:one_to_many][association[:name]]=association
35
- end
36
-
37
- private
38
-
39
- def self.get_table()
40
- session = BtrieveSession.get_session()
41
- session.model_classes[self.name.to_sym]
42
- end
43
- end
44
-
45
- def BtrieveModel(classname, tablename)
46
- raise Exception.new("The context is not set. Call 'Btrieve::Session.set_context( <pathname> )' before declaring model classes.") unless BtrieveSession.get_session() != nil
47
- BtrieveModel.new(classname, tablename)
48
- BtrieveModel
49
- end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,7 +0,0 @@
1
- require 'helper'
2
-
3
- class TestBeezwax < Test::Unit::TestCase
4
- should "probably rename this file and start testing for real" do
5
- flunk "hey buddy, you should probably rename this file and start testing for real"
6
- end
7
- end