Mercurial > hg > monetdb-ruby
changeset 20:789e400999dc
Whitespace and spell check.
author | Sjoerd Mullender <sjoerd@acm.org> |
---|---|
date | Tue, 20 Oct 2020 15:31:33 +0200 (2020-10-20) |
parents | 139897304835 |
children | 88e1fdba3669 |
files | lib/MonetDB.rb lib/MonetDBConnection.rb lib/MonetDBData.rb lib/hasher.rb |
diffstat | 4 files changed, 177 insertions(+), 177 deletions(-) [+] |
line wrap: on
line diff
--- a/lib/MonetDB.rb +++ b/lib/MonetDB.rb @@ -16,37 +16,37 @@ # # A database handler (dbh) is and instance of the MonetDB class. # - # = Connection management + # = Connection management # # connect - establish a new connection # * user: username (default is monetdb) # * passwd: password (default is monetdb) - # * lang: language (default is sql) - # * host: server hostanme or ip (default is localhost) + # * lang: language (default is sql) + # * host: server hostname or ip (default is localhost) # * port: server port (default is 50000) # * db_name: name of the database to connect to # * auth_type: hashing function to use during authentication (default is SHA1) # - # is_connected? - returns true if there is an active connection to a server, false otherwise - # reconnect - recconnect to a server + # is_connected? - returns true if there is an active connection to a server, false otherwise + # reconnect - reconnect to a server # close - terminate a connection - # auto_commit? - returns ture if the session is running in auto commit mode, false otherwise + # auto_commit? - returns true if the session is running in auto commit mode, false otherwise # auto_commit - enable/disable auto commit mode. # # query - fire a query # # Currently MAPI protocols 8 and 9 are supported. # - # = Managing record sets + # = Managing record sets # # # A record set is represented as an instance of the MonetDBData class; the class provides methods to manage retrieved data. # # # The following methods allow to iterate over data: - # + # # fetch - iterates over the record set and retrieves one row at a time. Each row is returned as an array. - # each_record - works as ruby each method. The method takes a block as parameter and yields each record to this block. + # each_record - works as ruby each method. The method takes a block as parameter and yields each record to this block. # fetch_hash - iterates over the record set and retrieves one row at a time. Each row is returned as a hash. # each_record_as_hash - works as ruby each method. The method takes a block as parameter and yields each record, as hash, to this block # fetch_all - returns all rows as a two dimensional array @@ -66,15 +66,15 @@ # All values from the database are converted to the closest ruby type, i.e: INTEGER to int, TIME to time, CLOB to string # Some of the more complex datatypes are not recognized, such as INTERVAL, these are converted to strings # - # = Transactions + # = Transactions # # By default monetdb works in auto_commit mode. To turn this feature off MonetDB#auto_commit(flag=false) can be used. # - # Once auto_commit has been disable it is possible to start transactions, create/delete savepoints, rollback and commit with + # Once auto_commit has been disable it is possible to start transactions, create/delete savepoints, rollback and commit with # the usual SQL statements. # # Savepoints IDs can be generated using the MonetDB#save method. To release a savepoint ID use MonetDB#release. - # + # # Savepoints can be accessed (as a stack) with the MonetDB#transactions method. # # demo.rb contains usage example of the above mentioned methods. @@ -91,22 +91,22 @@ class MonetDB DEFAULT_PORT = 50000 DEFAULT_DATABASE = "test" DEFAULT_AUTHTYPE = "SHA1" - + def initalize() - @connection = nil + @connection = nil end # Establish a new connection. # * username: username (default is monetdb) # * password: password (default is monetdb) - # * lang: language (default is sql) - # * host: server hostanme or ip (default is localhost) + # * lang: language (default is sql) + # * host: server hostname or ip (default is localhost) # * port: server port (default is 50000) # * db_name: name of the database to connect to # * auth_type: hashing function to use during authentication (default is SHA1) def connect(username=DEFAULT_USERNAME, password=DEFAULT_PASSWORD, lang=DEFAULT_LANG, host=DEFAULT_HOST, port=DEFAULT_PORT, db_name=DEFAULT_DATABASE, auth_type=DEFAULT_AUTHTYPE) # TODO: handle pools of connections - + @username = username @password = password @lang = lang @@ -114,7 +114,7 @@ class MonetDB @port = port @db_name = db_name @auth_type = auth_type - + @connection = MonetDBConnection.new(user = @username, passwd = @password, lang = @lang, host = @host, port = @port) @connection.connect(@db_name, @auth_type) end @@ -122,7 +122,7 @@ class MonetDB # Establish a new connection using named parameters. # * user: username (default is monetdb) # * passwd: password (default is monetdb) - # * language: lang (default is sql) + # * language: lang (default is sql) # * host: host to connect to (default is localhost) # * port: port to connect to (default is 50000) # * database: name of the database to connect to @@ -135,7 +135,7 @@ class MonetDB # # Ruby 1.9: # MonetDB::conn(user: "username", passwd: "password", database: "database") - def conn(options) + def conn(options) user = options[:user] || DEFAULT_USERNAME passwd = options[:passwd] || DEFAULT_PASSWORD language = options[:language] || DEFAULT_LANG @@ -143,25 +143,25 @@ class MonetDB port = options[:port] || DEFAULT_PORT database = options[:database] || DEFAULT_DATABASE auth_type = options[:auth_type] || DEFAULT_AUTHTYPE - + connect(user, passwd, language, host, port, database, auth_type) end # Send a <b> user submitted </b> query to the server and store the response. # Returns and instance of MonetDBData. def query(q="") - if @connection != nil + if @connection != nil @data = MonetDBData.new(@connection) - @data.execute(q) + @data.execute(q) end return @data end - + # Return true if there exists a "connection" object def is_connected? if @connection == nil return false - else + else return true end end @@ -170,12 +170,12 @@ class MonetDB def reconnect if @connection != nil self.close - + @connection = MonetDBConnection.new(user = @username, passwd = @password, lang = @lang, host = @host, port = @port) @connection.connect(db_name = @db_name, auth_type = @auth_type) end end - + # Turn auto commit on/off def auto_commit(flag=true) @connection.set_auto_commit(flag) @@ -185,22 +185,22 @@ class MonetDB def auto_commit? @connection.auto_commit? end - + # Returns the name of the last savepoint in a transactions pool def transactions @connection.savepoint end - + # Create a new savepoint ID def save @connection.transactions.save end - + # Release a savepoint ID def release @connection.transactions.release end - + # Close an active connection def close() @connection.disconnect
--- a/lib/MonetDBConnection.rb +++ b/lib/MonetDBConnection.rb @@ -31,8 +31,8 @@ class MonetDBConnection REPLY_SIZE = '-1' - MAX_AUTH_ITERATION = 10 # maximum number of atuh iterations (thorough merovingian) allowed - + MAX_AUTH_ITERATION = 10 # maximum number of auth iterations (through merovingian) allowed + MONET_ERROR = -1 LANG_SQL = "sql" @@ -45,7 +45,7 @@ class MonetDBConnection MEROVINGIAN_MAX_ITERATIONS = 10 - + # enable debug output @@DEBUG = false @@ -54,22 +54,22 @@ class MonetDBConnection # maximum size (in bytes) for a monetdb message to be sent @@MAX_MESSAGE_SIZE = 8190 - + # endianness of a message sent to the server @@CLIENT_ENDIANNESS = "BIG" - + # MAPI protocols supported by the driver @@SUPPORTED_PROTOCOLS = [ MonetDBConnection::MAPIv9 ] - + attr_reader :socket, :auto_commit, :transactions, :lang - + # Instantiates a new MonetDBConnection object # * user: username (default is monetdb) # * passwd: password (default is monetdb) - # * lang: language (default is sql) - # * host: server hostanme or ip (default is localhost) + # * lang: language (default is sql) + # * host: server hostname or ip (default is localhost) # * port: server port (default is 50000) - + def initialize(user = "monetdb", passwd = "monetdb", lang = "sql", host="127.0.0.1", port = "50000") @user = user @passwd = passwd @@ -78,12 +78,12 @@ class MonetDBConnection @port = port @client_endianness = @@CLIENT_ENDIANNESS - + @auth_iteration = 0 @connection_established = false - + @transactions = MonetDBTransaction.new # handles a pool of transactions (generates and keeps track of savepoints) - + if @@DEBUG == true require 'logger' end @@ -93,27 +93,27 @@ class MonetDBConnection end end - + # Connect to the database, creates a new socket def connect(db_name = 'demo', auth_type = 'SHA1') @database = db_name @auth_type = auth_type - - @socket = TCPSocket.new(@host, @port.to_i) + + @socket = TCPSocket.new(@host, @port.to_i) if real_connect if @lang == MonetDBConnection::LANG_SQL - set_timezone + set_timezone set_reply_size end true end false end - + # perform a real connection; retrieve challenge, proxy through merovinginan, build challenge and set the timezone def real_connect - + server_challenge = retrieve_server_challenge() if server_challenge != nil salt = server_challenge.split(':')[0] @@ -128,7 +128,7 @@ class MonetDBConnection else raise MonetDBConnectionError, "Error: server returned an empty challenge string." end - + # The server supports only RIPMED160 or crypt as an authentication hash function, but the driver does not. if @supported_auth_types.length == 1 auth = @supported_auth_types[0] @@ -144,32 +144,32 @@ class MonetDBConnection send(reply) monetdb_auth = receive - + if monetdb_auth.length == 0 - # auth succedeed + # auth succeeded true else if monetdb_auth[0].chr == MonetDBConnection::MSG_REDIRECT #redirection - + redirects = [] # store a list of possible redirects - + monetdb_auth.split('\n').each do |m| # strip the trailing ^mapi: # if the redirect string start with something != "^mapi:" or is empty, the redirect is invalid and shall not be included. if m[0..5] == "^mapi:" redir = m[6..m.length] # url parse redir - redirects.push(redir) + redirects.push(redir) else $stderr.print "Warning: Invalid Redirect #{m}" - end + end end - - if redirects.size == 0 + + if redirects.size == 0 raise MonetDBConnectionError, "No valid redirect received" else - begin + begin uri = URI.split(redirects[0]) # Splits the string on following parts and returns array with result: # @@ -190,7 +190,7 @@ class MonetDBConnection raise MonetDBConnectionError, "Invalid redirect: #{redirects[0]}" end end - + if server_name == MonetDBConnection::MONETDB_MEROVINGIAN if @auth_iteration <= MonetDBConnection::MEROVINGIAN_MAX_ITERATIONS @auth_iteration += 1 @@ -207,7 +207,7 @@ class MonetDBConnection # reinitialize a connection @host = host @port = port - + connect(database, @auth_type) else @connection_established = false @@ -228,25 +228,25 @@ class MonetDBConnection def format_command(x) return "X" + x + "\n" end - + # send an 'export' command to the server def set_export(id, idx, offset) send(format_command("export " + id.to_s + " " + idx.to_s + " " + offset.to_s )) end - + # send a 'reply_size' command to the server def set_reply_size send(format_command(("reply_size " + MonetDBConnection::REPLY_SIZE))) - + response = receive - + if response == MonetDBConnection::MSG_PROMPT true elsif response[0] == MonetDBConnection::MSG_INFO raise MonetDBCommandError, "Unable to set reply_size: #{response}" end - + end def set_output_seq @@ -255,7 +255,7 @@ class MonetDBConnection # Disconnect from server def disconnect() - if @connection_established + if @connection_established begin @socket.close rescue => e @@ -265,46 +265,46 @@ class MonetDBConnection raise MonetDBConnectionError, "No connection established." end end - + # send data to a monetdb5 server instance and returns server's response def send(data) encode_message(data).each do |m| @socket.write(m) end end - + # receive data from a monetdb5 server instance def receive is_final, chunk_size = recv_decode_hdr if chunk_size == 0 - return "" # needed on ruby-1.8.6 linux/64bit; recv(0) hangs on this configuration. + return "" # needed on ruby-1.8.6 linux/64bit; recv(0) hangs on this configuration. end - + data = @socket.recv(chunk_size) - - if is_final == false + + if is_final == false while is_final == false is_final, chunk_size = recv_decode_hdr data += @socket.recv(chunk_size) end end - + return data end # # Builds and authentication string given the parameters submitted by the user (MAPI protocol v9). - # + # def build_auth_string_v9(auth_type, salt, db_name) if (auth_type.upcase == "MD5" or auth_type.upcase == "SHA1") and @supported_auth_types.include?(auth_type.upcase) auth_type = auth_type.upcase # Hash the password pwhash = Hasher.new(@pwhash, @passwd) - + digest = Hasher.new(auth_type, pwhash.hashsum + salt) hashsum = digest.hashsum - + elsif auth_type.downcase == "plain" # or not @supported_auth_types.include?(auth_type.upcase) # Keep it for compatibility with merovingian auth_type = 'plain' @@ -316,61 +316,61 @@ class MonetDBConnection end # Hash the password pwhash = Hasher.new(@pwhash, @passwd) - + digest = Hasher.new(auth_type, pwhash.hashsum + salt) - hashsum = digest.hashsum + hashsum = digest.hashsum else # The user selected an auth type not supported by the server. raise MonetDBConnectionError, "#{auth_type} not supported by the server. Please choose one from #{@supported_auth_types}" - end + end # Build the reply message with header reply = @client_endianness + ":" + @user + ":{" + auth_type + "}" + hashsum + ":" + @lang + ":" + db_name + ":" end # builds a message to be sent to the server - def encode_message(msg = "") + def encode_message(msg = "") message = Array.new data = "" - + hdr = 0 # package header pos = 0 is_final = false # last package in the stream - + while (! is_final) data = msg[pos..pos+[@@MAX_MESSAGE_SIZE.to_i, (msg.length - pos).to_i].min] - pos += data.length - + pos += data.length + if (msg.length - pos) == 0 last_bit = 1 is_final = true else last_bit = 0 end - + hdr = [(data.length << 1) | last_bit].pack('v') - - message << hdr + data.to_s # Short Little Endian Encoding + + message << hdr + data.to_s # Short Little Endian Encoding end - + message.freeze # freeze and return the encode message end - # Used as the first step in the authentication phase; retrives a challenge string from the server. + # Used as the first step in the authentication phase; retrieves a challenge string from the server. def retrieve_server_challenge() server_challenge = receive end - + # reads and decodes the header of a server message def recv_decode_hdr() if @socket != nil fb = @socket.recv(1) sb = @socket.recv(1) - - # Use execeptions handling to keep compatibility between different ruby + + # Use exceptions handling to keep compatibility between different ruby # versions. # # Chars are treated differently in ruby 1.8 and 1.9 - # try do to ascii to int conversion using ord (ruby 1.9) + # try do to ASCII to int conversion using ord (ruby 1.9) # and if it fail fallback to character.to_i (ruby 1.8) begin fb = fb[0].ord @@ -379,21 +379,21 @@ class MonetDBConnection fb = fb[0].to_i sb = sb[0].to_i end - + chunk_size = (sb << 7) | (fb >> 1) - + is_final = false if ( (fb & 1) == 1 ) is_final = true - + end # return the size of the chunk (in bytes) - return is_final, chunk_size - else + return is_final, chunk_size + else raise MonetDBSocketError, "Error while receiving data\n" - end + end end - + # Sets the time zone according to the Operating System settings def set_timezone() tz = Time.new @@ -411,43 +411,43 @@ class MonetDBConnection tz_offset = "'+" + tz_offset.to_s + ":00'" end query_tz = "sSET TIME ZONE INTERVAL " + tz_offset + " HOUR TO MINUTE;" - + # Perform the query directly within the method send(query_tz) response = receive - + if response == MonetDBConnection::MSG_PROMPT true elsif response[0].chr == MonetDBConnection::MSG_INFO raise MonetDBQueryError, response end end - + # Turns auto commit on/off def set_auto_commit(flag=true) - if flag == false + if flag == false ac = " 0" - else + else ac = " 1" end send(format_command("auto_commit " + ac)) - + response = receive if response == MonetDBConnection::MSG_PROMPT @auto_commit = flag elsif response[0].chr == MonetDBConnection::MSG_INFO raise MonetDBCommandError, response - return + return end - + end - + # Check the auto commit status (on/off) def auto_commit? @auto_commit end - + # Check if monetdb is running behind the merovingian proxy and forward the connection in case def merovingian? if @server_name.downcase == MonetDBConnection::MONETDB_MEROVINGIAN @@ -456,7 +456,7 @@ class MonetDBConnection false end end - + def mserver? if @server_name.downcase == MonetDBConnection::MONETDB_MSERVER true @@ -467,33 +467,33 @@ class MonetDBConnection end # handles transactions and savepoints. Can be used to simulate nested transactions. -class MonetDBTransaction +class MonetDBTransaction SAVEPOINT_STRING = "monetdbsp" - + def initialize @id = 0 @savepoint = "" end - + def savepoint @savepoint = SAVEPOINT_STRING + @id.to_s end - + def release prev_id end - + def save next_id end - + private def next_id @id += 1 end - + def prev_id @id -= 1 end - + end
--- a/lib/MonetDBData.rb +++ b/lib/MonetDBData.rb @@ -15,35 +15,35 @@ require_relative 'MonetDBConnection' require 'logger' -class MonetDBData +class MonetDBData @@DEBUG = false - + def initialize(connection) @connection = connection @lang = @connection.lang - # Structure containing the header+results set for a fired Q_TABLE query + # Structure containing the header+results set for a fired Q_TABLE query @header = [] @query = {} - + @record_set = [] @index = 0 # Position of the last returned record - - + + @row_count = 0 @row_offset = 10 @row_index = Integer(MonetDBConnection::REPLY_SIZE) end - + # Fire a query and return the server response def execute(q) - # fire a query and get ready to receive the data + # fire a query and get ready to receive the data @connection.send(format_query(q)) data = @connection.receive - + return if data == nil - - record_set = "" # temporarly store retrieved rows + + record_set = "" # temporarily store retrieved rows record_set = receive_record_set(data) if (@lang == MonetDBConnection::LANG_SQL) @@ -52,7 +52,7 @@ class MonetDBData if @action == MonetDBConnection::Q_TABLE @header = parse_header_table(@header) @header.freeze - + if @row_index.to_i < @row_count.to_i block_rows = "" while next_block @@ -66,15 +66,15 @@ class MonetDBData # ruby string management seems to not properly understand the MSG_PROMPT escape character. # In order to avoid data loss the @record_set array is built once that all tuples have been retrieved @record_set = record_set.split("\t]\n") - + if @record_set.length != @query['rows'].to_i raise MonetDBQueryError, "Warning: Query #{@query['id']} declared to result in #{@query['rows']} but #{@record_set.length} returned instead" end end - @record_set.freeze + @record_set.freeze end - - # Returns the record set entries hashed by column name orderd by column position + + # Returns the record set entries hashed by column name ordered by column position def fetch_all_as_column_hash columns = {} @header["columns_name"].each do |col_name| @@ -86,7 +86,7 @@ class MonetDBData # returns a record hash (i.e: { id: 1, name: "John Doe", age: 42 } ) def fetch_hash - return false if @index >= @query['rows'].to_i + return false if @index >= @query['rows'].to_i record_hash = record_hash(parse_tuple(@record_set[@index])) @index += 1 @@ -95,7 +95,7 @@ class MonetDBData # loops through all the hashes of the records and yields them to a given block def each_record_as_hash - @record_set.each do |record| + @record_set.each do |record| parsed_record = parse_tuple(record) yield(record_hash(parsed_record)) end @@ -128,9 +128,9 @@ class MonetDBData @index = 0 end - # loops through all records and yields to a given block paramter + # loops through all records and yields to a given block parameter def each_record - raise MonetDBDataError, "There is no record set currently available" unless @query['type'] == MonetDBConnection::Q_TABLE + raise MonetDBDataError, "There is no record set currently available" unless @query['type'] == MonetDBConnection::Q_TABLE @record_set.each { |record| yield(parse_tuple(record)) } end @@ -142,7 +142,7 @@ class MonetDBData end return result end - + # Returns the number of rows in the record set def num_rows return @query['rows'].to_i @@ -162,16 +162,16 @@ class MonetDBData def name_fields return @header['columns_name'] end - + # Returns the (ordered) name of the columns in the record set def type_fields return @header['columns_type'] end - + # =================== private # =================== - + # store block of data, parse it and store it. def receive_record_set(response) rows = "" @@ -193,17 +193,17 @@ class MonetDBData @action = MonetDBConnection::Q_TABLE @query = parse_header_query(row) @query.freeze - @row_count = @query['rows'].to_i #total number of rows in table + @row_count = @query['rows'].to_i #total number of rows in table when MonetDBConnection::Q_BLOCK @action = MonetDBConnection::Q_BLOCK # strip the block header from data - @block = parse_header_query(row) + @block = parse_header_query(row) when MonetDBConnection::Q_TRANSACTION @action = MonetDBConnection::Q_TRANSACTION when MonetDBConnection::Q_CREATE @action = MonetDBConnection::Q_CREATE end end - + def record_hash(record) result = {} @@ -223,16 +223,16 @@ class MonetDBData # For larger values of the step performance drop; # @row_offset = [@row_offset, (@row_count - @row_index)].min - + # export offset amount - @connection.set_export(@query['id'], @row_index.to_s, @row_offset.to_s) - @row_index += @row_offset + @connection.set_export(@query['id'], @row_index.to_s, @row_offset.to_s) + @row_index += @row_offset @row_offset += 1 - end + end return true - + end - + # Formats a query <i>string</i> so that it can be parsed by the server def format_query(q) if @lang == MonetDBConnection::LANG_SQL @@ -241,7 +241,7 @@ class MonetDBData raise LanguageNotSupported, @lang end end - + # parse one tuple as returned from the server def parse_tuple(tuple) fields = [] @@ -251,7 +251,7 @@ class MonetDBData field_value = convert_type(field, index) fields << field_value end - + return fields.freeze end @@ -269,34 +269,34 @@ class MonetDBData else value.gsub(/\\/, '').gsub(/^"/,'').gsub(/"$/,'').gsub(/\"/, '') end end - + # Parses a query header and returns information about the query. def parse_header_query(row) type = row[1].chr if type == MonetDBConnection::Q_TABLE - # Performing a SELECT: store informations about the table size, query id, total number of records and returned. + # Performing a SELECT: store information about the table size, query id, total number of records and returned. id = row.split(' ')[1] rows = row.split(' ')[2] columns = row.split(' ')[3] returned = row.split(' ')[4] - + header = { "id" => id, "type" => type, "rows" => rows, "columns" => columns, "returned" => returned } elsif type == MonetDBConnection::Q_BLOCK # processing block header - + id = row.split(' ')[1] columns = row.split(' ')[2] remains = row.split(' ')[3] offset = row.split(' ')[4] - + header = { "id" => id, "type" => type, "remains" => remains, "columns" => columns, "offset" => offset } else header = {"type" => type} end - + return header.freeze end - + # Parse escaped strings between double quotes def parse_header_table_values(line, start, stop, results) i = start @@ -312,11 +312,11 @@ class MonetDBData inString = true elsif !escaped inString = false - end + end escaped = false when ',' if !inString # && line[i + 1] == '\t' - if line[start] == '"' # Don't include the leading " in the column atribute + if line[start] == '"' # Don't include the leading " in the column attribute start += 1 end if line[i - 1] == '"' @@ -334,7 +334,7 @@ class MonetDBData end i += 1 end - if line[start] == '"' # Don't include the leading " in the column atribute + if line[start] == '"' # Don't include the leading " in the column attribute start += 1 end if line[stop] == '"' @@ -344,38 +344,38 @@ class MonetDBData end results.push(line[start..stop - next_end]) end - + # Parses a Q_TABLE header and returns information about the schema. def parse_header_table(header_t) if @query["type"] == MonetDBConnection::Q_TABLE if header_t != nil - + name_t = Array.new parse_header_table_values(header_t[0], 2, header_t[0].length - 15, name_t) - + name_cols = Array.new parse_header_table_values(header_t[1], 2, header_t[1].length - 9, name_cols) - + type_cols = { } type_cols_array = Array.new parse_header_table_values(header_t[2], 2, header_t[2].length - 9, type_cols_array) type_cols_array.each_with_index do |col, i| type_cols[name_cols[i]] = col end - + length_cols = { } length_cols_array = Array.new parse_header_table_values(header_t[3], 2, header_t[3].length - 11, length_cols_array) length_cols_array.each_with_index do |col, i| length_cols[name_cols[i]] = col end - + columns_order = {} name_cols.each_with_index do |col, i| columns_order[col] = i end - - return {"table_name" => name_t, "columns_name" => name_cols, "columns_type" => type_cols, + + return {"table_name" => name_t, "columns_name" => name_cols, "columns_type" => type_cols, "columns_length" => length_cols, "columns_order" => columns_order}.freeze end end
--- a/lib/hasher.rb +++ b/lib/hasher.rb @@ -6,7 +6,7 @@ require 'digest/md5' require 'digest/sha1' -require 'digest/sha2' +require 'digest/sha2' class Hasher # Constructor @@ -16,7 +16,7 @@ class Hasher if (method.upcase == "SHA1") @hashfunc = Digest::SHA1.new @hashname = method.upcase - elsif (method.upcase == "SHA256") + elsif (method.upcase == "SHA256") @hashfunc = Digest::SHA256.new @hashname = method.upcase elsif (method.upcase == "SHA384") @@ -32,7 +32,7 @@ class Hasher end @pwd = pwd end - + def hashname @hashname