beezwax 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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