require 'digest/md5' # Represents a single btrieve record for a particular BTR table. class BtrieveRecord include Btrieve attr_reader :data_buffer, :btrieve_table # Initializes a btrieve record. def initialize(btrieve_table, data_buffer=nil) @btrieve_table = btrieve_table @data_buffer = data_buffer.nil? ? Btrieve.create_string_buffer(@btrieve_table.schema[:record_size]) : data_buffer end # Inserts a new btrieve record through the transactional BTR engine. def insert btr_op(@btrieve_table.session, INSERT, @btrieve_table.pos_buffer, @data_buffer, NULL_BUFFER, NO_CURRENCY_CHANGE) end # Updates an existing btrieve record through the transactional BTR engine. def update btr_op(@btrieve_table.session, UPDATE, @btrieve_table.pos_buffer, @data_buffer, NULL_BUFFER, NO_CURRENCY_CHANGE) end # Deletes an existing btrieve record through the transactional BTR engine. def delete btr_op(@btrieve_table.session, DELETE, @btrieve_table.pos_buffer, NULL_BUFFER, NULL_BUFFER, NULL_KEY) end # Returns hash of column-value pairs for this btrieve record, given an array of named columns. # If the array is nil, the hash will contain ALL the column-value pairs defined by the schema. def values(column_names=nil) if(column_names.nil?) column_names=@btrieve_table.schema[:columns].keys.sort.inject([]){|array,column|array<< column;array} end column_names.inject({}){|vals, key| vals[key]=self[key]; vals} end # Returns this record's primary key value. Supports composite keys. def primary_key() values(@btrieve_table.primary_key) end # Returns this record's value of the column passed in. def [](key_name) column_info = get_column_info(key_name) return nil if(column_info.nil?) @data_buffer.unpack(column_info[:unpacker])[0] end # Sets this record's value for a particular column. def []=(key_name, value) schema_key = get_schema_key(key_name) packer_string = schema_key[:unpacker] match = packer_string.match(/@(\d+)([a-zA-Z]+)(\d*)/) offset = match[1].to_i datatype = match[2] thesizeof = BtrieveSchema.sizeof(datatype) thesizeof *= match[3].empty? ? 1 : match[3].to_i packer = "#{datatype}#{thesizeof}" array = [value] packed_value = array.pack(packer) range = (offset..offset+packed_value.size-1) @data_buffer[range] = packed_value end def nil?() data_buffer.gsub("\x00", "").size==0 end # Returns a string representation of this record. def to_s() @btrieve_table.schema[:columns].keys.inject(''){|pretty_print, key| pretty_print = "#{pretty_print} #{key}=>#{self[key]}"; pretty_print} end # Returns this record's version as a MD5 Digest value. def version() Digest::MD5.hexdigest(@data_buffer) end private def get_column_info(column_name) @btrieve_table.schema[:columns][column_name] end end