changeset 23:838f38eb7de4

Added .editorconfig + indented.
author Sjoerd Mullender <sjoerd@acm.org>
date Tue, 20 Oct 2020 16:24:05 +0200 (2020-10-20)
parents de7332f6911e
children a4a96e70ee13
files .editorconfig lib/MonetDB.rb lib/MonetDBConnection.rb lib/MonetDBData.rb lib/MonetDBExceptions.rb lib/hasher.rb monetdb-sql.gemspec
diffstat 7 files changed, 926 insertions(+), 917 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,9 @@
+[*]
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+charset = utf-8
+max_line_length = 120
+indent_style = tab
+tab_width = 4
+indent_size = tab
--- a/lib/MonetDB.rb
+++ b/lib/MonetDB.rb
@@ -5,205 +5,205 @@
 # Copyright 1997 - July 2008 CWI, August 2008 - 2020 MonetDB B.V.
 
 # = Introduction
-    #
-    # A typical sequence of events is as follows:
-    # Create a database instance (handle), invoke query using the database handle to send the statement to the server and get back a result set object.
-    #
-    # A result set object  has methods for fetching rows, moving around in the result set, obtaining column metadata, and releasing the result set.
-    # A result set object is an instance of the MonetDBData class.
-    #
-    # Records can be returned as arrays and iterators over the set.
-    #
-    # A database handler (dbh) is and instance of the MonetDB class.
-    #
-    # = Connection management
-    #
-    #  connect    -  establish a new connection
-    #                * user: username (default is monetdb)
-    #                * passwd: password (default is monetdb)
-    #                * 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     - reconnect to a server
-    #  close         - terminate a connection
-    #  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
-    #
-    #
-    # 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.
-    # 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
-    # fetch_all_as_column_hash - returns all records as a hash with the column name as the keys and an array with all column values as values
-    #
-    # Information about the retrieved record set can be obtained via the following methods:
-    #
-    # num_rows       - returns the number of rows present in the record set
-    # num_fields     - returns the number of fields (columns) that compose the schema
-    # name_fields    - returns the (ordered) name of the schema's columns
-    # type_fields    - returns the (ordered) types list of the schema's columns
-    #
-    # To release a record set MonetDBData#free can be used.
-    #
-    # = Type conversion
-    #
-    # 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
-    #
-    # 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
-    # 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.
+#
+# A typical sequence of events is as follows:
+# Create a database instance (handle), invoke query using the database handle to send the statement to the server and get back a result set object.
+#
+# A result set object  has methods for fetching rows, moving around in the result set, obtaining column metadata, and releasing the result set.
+# A result set object is an instance of the MonetDBData class.
+#
+# Records can be returned as arrays and iterators over the set.
+#
+# A database handler (dbh) is and instance of the MonetDB class.
+#
+# = Connection management
+#
+#  connect    -  establish a new connection
+#                * user: username (default is monetdb)
+#                * passwd: password (default is monetdb)
+#                * 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     - reconnect to a server
+#  close         - terminate a connection
+#  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
+#
+#
+# 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.
+# 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
+# fetch_all_as_column_hash - returns all records as a hash with the column name as the keys and an array with all column values as values
+#
+# Information about the retrieved record set can be obtained via the following methods:
+#
+# num_rows       - returns the number of rows present in the record set
+# num_fields     - returns the number of fields (columns) that compose the schema
+# name_fields    - returns the (ordered) name of the schema's columns
+# type_fields    - returns the (ordered) types list of the schema's columns
+#
+# To release a record set MonetDBData#free can be used.
+#
+# = Type conversion
+#
+# 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
+#
+# 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
+# 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.
 
 require_relative 'MonetDBConnection'
 require_relative 'MonetDBData'
 require_relative 'MonetDBExceptions'
 
 class MonetDB
-  DEFAULT_USERNAME = "monetdb"
-  DEFAULT_PASSWORD = "monetdb"
-  DEFAULT_LANG     = MonetDBConnection::LANG_SQL
-  DEFAULT_HOST     = "127.0.0.1"
-  DEFAULT_PORT     = 50000
-  DEFAULT_DATABASE = "test"
-  DEFAULT_AUTHTYPE = "SHA1"
+	DEFAULT_USERNAME = "monetdb"
+	DEFAULT_PASSWORD = "monetdb"
+	DEFAULT_LANG     = MonetDBConnection::LANG_SQL
+	DEFAULT_HOST     = "127.0.0.1"
+	DEFAULT_PORT     = 50000
+	DEFAULT_DATABASE = "test"
+	DEFAULT_AUTHTYPE = "SHA1"
 
-  def initalize()
-    @connection = nil
-  end
+	def initalize()
+		@connection = nil
+	end
 
-  # Establish a new connection.
-  #                * username: username (default is monetdb)
-  #                * password: password (default is monetdb)
-  #                * 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
+	# Establish a new connection.
+	#                * username: username (default is monetdb)
+	#                * password: password (default is monetdb)
+	#                * 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
-    @host = host
-    @port = port
-    @db_name = db_name
-    @auth_type = auth_type
+		@username = username
+		@password = password
+		@lang = lang
+		@host = host
+		@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
+		@connection = MonetDBConnection.new(user = @username, passwd = @password, lang = @lang, host = @host, port = @port)
+		@connection.connect(@db_name, @auth_type)
+	end
 
-  # Establish a new connection using named parameters.
-  #                * user: username (default is monetdb)
-  #                * passwd: password (default is monetdb)
-  #                * 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
-  #                * auth_type: hashing function to use during authentication (default is SHA1)
-  #
-  # Conventionally named parameters are passed as an hash.
-  #
-  # Ruby 1.8:
-  # MonetDB::conn({ :user => "username", :passwd => "password", :database => "database"})
-  #
-  # Ruby 1.9:
-  # MonetDB::conn(user: "username", passwd: "password", database: "database")
-  def conn(options)
-    user        = options[:user] || DEFAULT_USERNAME
-    passwd      = options[:passwd] || DEFAULT_PASSWORD
-    language    = options[:language] || DEFAULT_LANG
-    host        = options[:host] || DEFAULT_HOST
-    port        = options[:port] || DEFAULT_PORT
-    database    = options[:database] || DEFAULT_DATABASE
-    auth_type   = options[:auth_type] || DEFAULT_AUTHTYPE
+	# Establish a new connection using named parameters.
+	#                * user: username (default is monetdb)
+	#                * passwd: password (default is monetdb)
+	#                * 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
+	#                * auth_type: hashing function to use during authentication (default is SHA1)
+	#
+	# Conventionally named parameters are passed as an hash.
+	#
+	# Ruby 1.8:
+	# MonetDB::conn({ :user => "username", :passwd => "password", :database => "database"})
+	#
+	# Ruby 1.9:
+	# MonetDB::conn(user: "username", passwd: "password", database: "database")
+	def conn(options)
+		user        = options[:user] || DEFAULT_USERNAME
+		passwd      = options[:passwd] || DEFAULT_PASSWORD
+		language    = options[:language] || DEFAULT_LANG
+		host        = options[:host] || DEFAULT_HOST
+		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
+		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
-      @data = MonetDBData.new(@connection)
-      @data.execute(q)
-    end
-    return @data
-  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
+			@data = MonetDBData.new(@connection)
+			@data.execute(q)
+		end
+		return @data
+	end
 
-  # Return true if there exists a "connection" object
-  def is_connected?
-    if @connection == nil
-      return false
-    else
-      return true
-    end
-  end
+	# Return true if there exists a "connection" object
+	def is_connected?
+		if @connection == nil
+			return false
+		else
+			return true
+		end
+	end
 
-  # Reconnect to the server
-  def reconnect
-    if @connection != nil
-      self.close
+	# Reconnect to the server
+	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
+			@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)
-  end
+	# Turn auto commit on/off
+	def auto_commit(flag=true)
+		@connection.set_auto_commit(flag)
+	end
 
-  # Returns the current auto commit  (on/off) settings.
-  def auto_commit?
-    @connection.auto_commit?
-  end
+	# Returns the current auto commit  (on/off) settings.
+	def auto_commit?
+		@connection.auto_commit?
+	end
 
-  # Returns the name of the last savepoint in a transactions pool
-  def transactions
-    @connection.savepoint
-  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
+	# Create a new savepoint ID
+	def save
+		@connection.transactions.save
+	end
 
-  # Release a savepoint ID
-  def release
-    @connection.transactions.release
-  end
+	# Release a savepoint ID
+	def release
+		@connection.transactions.release
+	end
 
-  # Close an active connection
-  def close()
-    @connection.disconnect
-    @connection = nil
-  end
+	# Close an active connection
+	def close()
+		@connection.disconnect
+		@connection = nil
+	end
 end
--- a/lib/MonetDBConnection.rb
+++ b/lib/MonetDBConnection.rb
@@ -14,486 +14,486 @@ require_relative 'MonetDBExceptions'
 require 'uri'   # parse merovingian redirects
 
 class MonetDBConnection
-  Q_TABLE               = "1" # SELECT operation
-  Q_UPDATE              = "2" # INSERT/UPDATE operations
-  Q_CREATE              = "3" # CREATE/DROP TABLE operations
-  Q_TRANSACTION         = "4" # TRANSACTION
-  Q_PREPARE             = "5"
-  Q_BLOCK               = "6" # QBLOCK message
+	Q_TABLE               = "1" # SELECT operation
+	Q_UPDATE              = "2" # INSERT/UPDATE operations
+	Q_CREATE              = "3" # CREATE/DROP TABLE operations
+	Q_TRANSACTION         = "4" # TRANSACTION
+	Q_PREPARE             = "5"
+	Q_BLOCK               = "6" # QBLOCK message
 
-  MSG_REDIRECT          = '^' # auth redirection through merovingian
-  MSG_QUERY             = '&'
-  MSG_SCHEMA_HEADER     = '%'
-  MSG_INFO              = '!' # info response from mserver
-  MSG_TUPLE             = '['
-  MSG_PROMPT            =  ""
+	MSG_REDIRECT          = '^' # auth redirection through merovingian
+	MSG_QUERY             = '&'
+	MSG_SCHEMA_HEADER     = '%'
+	MSG_INFO              = '!' # info response from mserver
+	MSG_TUPLE             = '['
+	MSG_PROMPT            =  ""
 
 
-  REPLY_SIZE            = '-1'
+	REPLY_SIZE            = '-1'
 
-  MAX_AUTH_ITERATION    = 10  # maximum number of auth iterations (through merovingian) allowed
+	MAX_AUTH_ITERATION    = 10  # maximum number of auth iterations (through merovingian) allowed
 
-  MONET_ERROR           = -1
+	MONET_ERROR           = -1
 
-  LANG_SQL = "sql"
+	LANG_SQL = "sql"
 
-  # Protocols
-  MAPIv9 = 9
+	# Protocols
+	MAPIv9 = 9
 
-  MONETDB_MEROVINGIAN = "merovingian"
-  MONETDB_MSERVER     = "monetdb"
+	MONETDB_MEROVINGIAN = "merovingian"
+	MONETDB_MSERVER     = "monetdb"
 
-  MEROVINGIAN_MAX_ITERATIONS = 10
+	MEROVINGIAN_MAX_ITERATIONS = 10
 
 
-  # enable debug output
-  @@DEBUG               = false
+	# enable debug output
+	@@DEBUG               = false
 
-  # hour in seconds, used for timezone calculation
-  @@HOUR                = 3600
+	# hour in seconds, used for timezone calculation
+	@@HOUR                = 3600
 
-  # maximum size (in bytes) for a monetdb message to be sent
-  @@MAX_MESSAGE_SIZE    = 8190
+	# 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"
+	# endianness of a message sent to the server
+	@@CLIENT_ENDIANNESS   = "BIG"
 
-  # MAPI protocols supported by the driver
-  @@SUPPORTED_PROTOCOLS = [ MonetDBConnection::MAPIv9 ]
+	# MAPI protocols supported by the driver
+	@@SUPPORTED_PROTOCOLS = [ MonetDBConnection::MAPIv9 ]
 
-  attr_reader :socket, :auto_commit, :transactions, :lang
+	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 hostname or ip  (default is localhost)
-  # * port: server port (default is 50000)
+	# Instantiates a new MonetDBConnection object
+	# * user: username (default is monetdb)
+	# * passwd: password (default is monetdb)
+	# * 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
-    @lang = lang.downcase
-    @host = host
-    @port = port
+	def initialize(user = "monetdb", passwd = "monetdb", lang = "sql", host="127.0.0.1", port = "50000")
+		@user = user
+		@passwd = passwd
+		@lang = lang.downcase
+		@host = host
+		@port = port
 
-    @client_endianness = @@CLIENT_ENDIANNESS
+		@client_endianness = @@CLIENT_ENDIANNESS
 
-    @auth_iteration = 0
-    @connection_established = false
+		@auth_iteration = 0
+		@connection_established = false
 
-    @transactions = MonetDBTransaction.new # handles a pool of transactions (generates and keeps track of savepoints)
+		@transactions = MonetDBTransaction.new # handles a pool of transactions (generates and keeps track of savepoints)
 
-    if @@DEBUG == true
-      require 'logger'
-    end
+		if @@DEBUG == true
+			require 'logger'
+		end
 
-    if @lang[0, 3] == 'sql'
-      @lang = "sql"
-    end
+		if @lang[0, 3] == 'sql'
+			@lang = "sql"
+		end
 
-  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
+	# 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)
-    if real_connect
-      if @lang == MonetDBConnection::LANG_SQL
-        set_timezone
-        set_reply_size
-      end
-      true
-    end
-    false
-  end
+		@socket = TCPSocket.new(@host, @port.to_i)
+		if real_connect
+			if @lang == MonetDBConnection::LANG_SQL
+				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
+	# 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]
-      @server_name = server_challenge.split(':')[1]
-      @protocol = server_challenge.split(':')[2].to_i
-      @supported_auth_types = server_challenge.split(':')[3].split(',')
-      @server_endianness = server_challenge.split(':')[4]
-      if @@SUPPORTED_PROTOCOLS.include?(@protocol) == false
-        raise MonetDBProtocolError, "Protocol not supported. The current implementation of ruby-monetdb works with MAPI protocols #{@@SUPPORTED_PROTOCOLS} only."
-      end
-      @pwhash = server_challenge.split(':')[5]
-    else
-      raise MonetDBConnectionError, "Error: server returned an empty challenge string."
-    end
+		server_challenge = retrieve_server_challenge()
+		if server_challenge != nil
+			salt = server_challenge.split(':')[0]
+			@server_name = server_challenge.split(':')[1]
+			@protocol = server_challenge.split(':')[2].to_i
+			@supported_auth_types = server_challenge.split(':')[3].split(',')
+			@server_endianness = server_challenge.split(':')[4]
+			if @@SUPPORTED_PROTOCOLS.include?(@protocol) == false
+				raise MonetDBProtocolError, "Protocol not supported. The current implementation of ruby-monetdb works with MAPI protocols #{@@SUPPORTED_PROTOCOLS} only."
+			end
+			@pwhash = server_challenge.split(':')[5]
+		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]
-      if auth.upcase == "RIPEMD160"
-        raise MonetDBConnectionError, auth.upcase + " " + ": algorithm not supported by ruby-monetdb."
-      end
-    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]
+			if auth.upcase == "RIPEMD160"
+				raise MonetDBConnectionError, auth.upcase + " " + ": algorithm not supported by ruby-monetdb."
+			end
+		end
 
-    reply = build_auth_string_v9(@auth_type, salt, @database)
+		reply = build_auth_string_v9(@auth_type, salt, @database)
 
-    if @socket != nil
-      @connection_established = true
+		if @socket != nil
+			@connection_established = true
 
-      send(reply)
-      monetdb_auth = receive
+			send(reply)
+			monetdb_auth = receive
 
-      if monetdb_auth.length == 0
-        # auth succeeded
-        true
-      else
-        if monetdb_auth[0].chr == MonetDBConnection::MSG_REDIRECT
-        #redirection
+			if monetdb_auth.length == 0
+				# auth succeeded
+				true
+			else
+				if monetdb_auth[0].chr == MonetDBConnection::MSG_REDIRECT
+					#redirection
 
-          redirects = [] # store a list of possible redirects
+					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)
-            else
-              $stderr.print "Warning: Invalid Redirect #{m}"
-            end
-          end
+					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)
+						else
+							$stderr.print "Warning: Invalid Redirect #{m}"
+						end
+					end
 
-          if redirects.size == 0
-            raise MonetDBConnectionError, "No valid redirect received"
-          else
-            begin
-              uri = URI.split(redirects[0])
-              # Splits the string on following parts and returns array with result:
-              #
-              #  * Scheme
-              #  * Userinfo
-              #  * Host
-              #  * Port
-              #  * Registry
-              #  * Path
-              #  * Opaque
-              #  * Query
-              #  * Fragment
-              server_name = uri[0]
-              host   = uri[2]
-              port   = uri[3]
-              database   = uri[5].gsub(/^\//, '') if uri[5] != nil
-            rescue URI::InvalidURIError
-              raise MonetDBConnectionError, "Invalid redirect: #{redirects[0]}"
-            end
-          end
+					if redirects.size == 0
+						raise MonetDBConnectionError, "No valid redirect received"
+					else
+						begin
+							uri = URI.split(redirects[0])
+							# Splits the string on following parts and returns array with result:
+							#
+							#  * Scheme
+							#  * Userinfo
+							#  * Host
+							#  * Port
+							#  * Registry
+							#  * Path
+							#  * Opaque
+							#  * Query
+							#  * Fragment
+							server_name = uri[0]
+							host   = uri[2]
+							port   = uri[3]
+							database   = uri[5].gsub(/^\//, '') if uri[5] != nil
+						rescue URI::InvalidURIError
+							raise MonetDBConnectionError, "Invalid redirect: #{redirects[0]}"
+						end
+					end
 
-          if server_name == MonetDBConnection::MONETDB_MEROVINGIAN
-            if @auth_iteration <= MonetDBConnection::MEROVINGIAN_MAX_ITERATIONS
-              @auth_iteration += 1
-              real_connect
-            else
-              raise MonetDBConnectionError, "Merovingian: too many iterations while proxying."
-            end
-          elsif server_name == MonetDBConnection::MONETDB_MSERVER
-            begin
-              @socket.close
-            rescue
-              raise MonetDBConnectionError, "I/O error while closing connection to #{@socket}"
-            end
-            # reinitialize a connection
-            @host = host
-            @port = port
+					if server_name == MonetDBConnection::MONETDB_MEROVINGIAN
+						if @auth_iteration <= MonetDBConnection::MEROVINGIAN_MAX_ITERATIONS
+							@auth_iteration += 1
+							real_connect
+						else
+							raise MonetDBConnectionError, "Merovingian: too many iterations while proxying."
+						end
+					elsif server_name == MonetDBConnection::MONETDB_MSERVER
+						begin
+							@socket.close
+						rescue
+							raise MonetDBConnectionError, "I/O error while closing connection to #{@socket}"
+						end
+						# reinitialize a connection
+						@host = host
+						@port = port
 
-            connect(database, @auth_type)
-          else
-            @connection_established = false
-            raise MonetDBConnectionError, monetdb_auth
-          end
-        elsif monetdb_auth[0].chr == MonetDBConnection::MSG_INFO
-          raise MonetDBConnectionError, monetdb_auth
-        end
-      end
-    end
-  end
+						connect(database, @auth_type)
+					else
+						@connection_established = false
+						raise MonetDBConnectionError, monetdb_auth
+					end
+				elsif monetdb_auth[0].chr == MonetDBConnection::MSG_INFO
+					raise MonetDBConnectionError, monetdb_auth
+				end
+			end
+		end
+	end
 
-  def savepoint
-    @transactions.savepoint
-  end
+	def savepoint
+		@transactions.savepoint
+	end
 
-  # Formats a <i>command</i> string so that it can be parsed by the server
-  def format_command(x)
-      return "X" + x + "\n"
-  end
+	# Formats a <i>command</i> string so that it can be parsed by the server
+	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 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)))
+	# send a 'reply_size' command to the server
+	def set_reply_size
+		send(format_command(("reply_size " + MonetDBConnection::REPLY_SIZE)))
 
-    response = receive
+		response = receive
 
-    if response == MonetDBConnection::MSG_PROMPT
-      true
-    elsif response[0] == MonetDBConnection::MSG_INFO
-      raise MonetDBCommandError, "Unable to set reply_size: #{response}"
-    end
+		if response == MonetDBConnection::MSG_PROMPT
+			true
+		elsif response[0] == MonetDBConnection::MSG_INFO
+			raise MonetDBCommandError, "Unable to set reply_size: #{response}"
+		end
 
-  end
+	end
 
-  def set_output_seq
-    send(format_command("output seq"))
-  end
+	def set_output_seq
+		send(format_command("output seq"))
+	end
 
-  # Disconnect from server
-  def disconnect()
-    if  @connection_established
-      begin
-        @socket.close
-      rescue => e
-        $stderr.print e
-      end
-    else
-      raise MonetDBConnectionError, "No connection established."
-    end
-  end
+	# Disconnect from server
+	def disconnect()
+		if  @connection_established
+			begin
+				@socket.close
+			rescue => e
+				$stderr.print e
+			end
+		else
+			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
+	# 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
+	# 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.
-    end
+		if chunk_size == 0
+			return ""  # needed on ruby-1.8.6 linux/64bit; recv(0) hangs on this configuration.
+		end
 
-    data = @socket.recv(chunk_size)
+		data = @socket.recv(chunk_size)
 
-    if is_final == false
-      while is_final == false
-        is_final, chunk_size = recv_decode_hdr
-        data +=  @socket.recv(chunk_size)
-      end
-    end
+		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
+		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)
+	#
+	# 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
+			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'
-      hashsum = @passwd + salt
-    elsif @supported_auth_types.include?(auth_type.upcase)
-      if auth_type.upcase == "RIPEMD160"
-        auth_type =  @supported_auth_types[@supported_auth_types.index(auth_type)+1]
-        $stderr.print "The selected hashing algorithm is not supported by the Ruby driver. #{auth_type} will be used instead."
-      end
-      # Hash the password
-      pwhash = Hasher.new(@pwhash, @passwd)
+		elsif auth_type.downcase == "plain" # or not  @supported_auth_types.include?(auth_type.upcase)
+			# Keep it for compatibility with merovingian
+			auth_type = 'plain'
+			hashsum = @passwd + salt
+		elsif @supported_auth_types.include?(auth_type.upcase)
+			if auth_type.upcase == "RIPEMD160"
+				auth_type =  @supported_auth_types[@supported_auth_types.index(auth_type)+1]
+				$stderr.print "The selected hashing algorithm is not supported by the Ruby driver. #{auth_type} will be used instead."
+			end
+			# Hash the password
+			pwhash = Hasher.new(@pwhash, @passwd)
 
-      digest = Hasher.new(auth_type, pwhash.hashsum + salt)
-      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
-    # Build the reply message with header
-    reply = @client_endianness + ":" + @user + ":{" + auth_type + "}" + hashsum + ":" + @lang + ":" + db_name + ":"
-  end
+			digest = Hasher.new(auth_type, pwhash.hashsum + salt)
+			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
+		# 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 = "")
-    message = Array.new
-    data = ""
+	# builds a message to be sent to the server
+	def encode_message(msg = "")
+		message = Array.new
+		data = ""
 
-    hdr = 0 # package header
-    pos = 0
-    is_final = false # last package in the stream
+		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
+		while (! is_final)
+			data = msg[pos..pos+[@@MAX_MESSAGE_SIZE.to_i, (msg.length - pos).to_i].min]
+			pos += data.length
 
-      if (msg.length - pos) == 0
-        last_bit = 1
-        is_final = true
-      else
-        last_bit = 0
-      end
+			if (msg.length - pos) == 0
+				last_bit = 1
+				is_final = true
+			else
+				last_bit = 0
+			end
 
-      hdr = [(data.length << 1) | last_bit].pack('v')
+			hdr = [(data.length << 1) | last_bit].pack('v')
 
-      message << hdr + data.to_s # Short Little Endian Encoding
-    end
+			message << hdr + data.to_s # Short Little Endian Encoding
+		end
 
-    message.freeze # freeze and return the encode message
-  end
+		message.freeze # freeze and return the encode message
+	end
 
-  # Used as the first step in the authentication phase; retrieves a challenge string from the server.
-  def retrieve_server_challenge()
-    server_challenge = receive
-  end
+	# 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)
+	# 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 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)
-      # and if it fail fallback to character.to_i (ruby 1.8)
-      begin
-        fb = fb[0].ord
-        sb = sb[0].ord
-      rescue NoMethodError => one_eight
-        fb = fb[0].to_i
-        sb = sb[0].to_i
-      end
+			# 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)
+			# and if it fail fallback to character.to_i (ruby 1.8)
+			begin
+				fb = fb[0].ord
+				sb = sb[0].ord
+			rescue NoMethodError => one_eight
+				fb = fb[0].to_i
+				sb = sb[0].to_i
+			end
 
-      chunk_size = (sb << 7) | (fb >> 1)
+			chunk_size = (sb << 7) | (fb >> 1)
 
-      is_final = false
-      if ( (fb & 1) == 1 )
-        is_final = true
+			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
-        raise MonetDBSocketError, "Error while receiving data\n"
-    end
-  end
+			end
+			# return the size of the chunk (in bytes)
+			return is_final, chunk_size
+		else
+			raise MonetDBSocketError, "Error while receiving data\n"
+		end
+	end
 
-  # Sets the time zone according to the Operating System settings
-  def set_timezone()
-    tz = Time.new
-    tz_offset = tz.gmt_offset / @@HOUR
+	# Sets the time zone according to the Operating System settings
+	def set_timezone()
+		tz = Time.new
+		tz_offset = tz.gmt_offset / @@HOUR
 
-    # verify minute count!
-    if tz_offset <= -10
-      tz_offset = "'" + tz_offset.to_s + ":00'"
-    elsif tz_offset < 0
-      tz_offset = -tz_offset
-      tz_offset = "'-0" + tz_offset.to_s + ":00'"
-    elsif tz_offset <= 9
-      tz_offset = "'+0" + tz_offset.to_s + ":00'"
-    else
-      tz_offset = "'+" + tz_offset.to_s + ":00'"
-    end
-    query_tz = "sSET TIME ZONE INTERVAL " + tz_offset + " HOUR TO MINUTE;"
+		# verify minute count!
+		if tz_offset <= -10
+			tz_offset = "'" + tz_offset.to_s + ":00'"
+		elsif tz_offset < 0
+			tz_offset = -tz_offset
+			tz_offset = "'-0" + tz_offset.to_s + ":00'"
+		elsif tz_offset <= 9
+			tz_offset = "'+0" + tz_offset.to_s + ":00'"
+		else
+			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
+		# 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
+		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
-      ac = " 0"
-    else
-      ac = " 1"
-    end
+	# Turns auto commit on/off
+	def set_auto_commit(flag=true)
+		if flag == false
+			ac = " 0"
+		else
+			ac = " 1"
+		end
 
-    send(format_command("auto_commit " + ac))
+		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
-    end
+		response = receive
+		if response == MonetDBConnection::MSG_PROMPT
+			@auto_commit = flag
+		elsif response[0].chr == MonetDBConnection::MSG_INFO
+			raise MonetDBCommandError, response
+			return
+		end
 
-  end
+	end
 
-  # Check the auto commit status (on/off)
-  def auto_commit?
-    @auto_commit
-  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
-      true
-    else
-      false
-    end
-  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
+			true
+		else
+			false
+		end
+	end
 
-  def mserver?
-    if @server_name.downcase == MonetDBConnection::MONETDB_MSERVER
-      true
-    else
-      false
-    end
-  end
+	def mserver?
+		if @server_name.downcase == MonetDBConnection::MONETDB_MSERVER
+			true
+		else
+			false
+		end
+	end
 end
 
 # handles transactions and savepoints. Can be used to simulate nested transactions.
 class MonetDBTransaction
-  SAVEPOINT_STRING = "monetdbsp"
+	SAVEPOINT_STRING = "monetdbsp"
 
-  def initialize
-    @id = 0
-    @savepoint = ""
-  end
+	def initialize
+		@id = 0
+		@savepoint = ""
+	end
 
-  def savepoint
-    @savepoint = SAVEPOINT_STRING + @id.to_s
-  end
+	def savepoint
+		@savepoint = SAVEPOINT_STRING + @id.to_s
+	end
 
-  def release
-    prev_id
-  end
+	def release
+		prev_id
+	end
 
-  def save
-    next_id
-  end
+	def save
+		next_id
+	end
 
-  private
-  def next_id
-    @id += 1
-  end
+	private
+	def next_id
+		@id += 1
+	end
 
-  def prev_id
-    @id -= 1
-  end
+	def prev_id
+		@id -= 1
+	end
 
 end
--- a/lib/MonetDBData.rb
+++ b/lib/MonetDBData.rb
@@ -16,368 +16,368 @@ require_relative 'MonetDBConnection'
 require 'logger'
 
 class MonetDBData
-  @@DEBUG               = false
+	@@DEBUG               = false
 
-  def initialize(connection)
-    @connection = connection
-    @lang = @connection.lang
+	def initialize(connection)
+		@connection = connection
+		@lang = @connection.lang
 
-    # Structure containing the header+results set for a fired Q_TABLE query
-    @header = []
-    @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
+		@record_set = []
+		@index = 0 # Position of the last returned record
 
 
-    @row_count = 0
-    @row_offset = 10
-    @row_index = Integer(MonetDBConnection::REPLY_SIZE)
-  end
+		@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
-    @connection.send(format_query(q))
-    data = @connection.receive
+	# Fire a query and return the server response
+	def execute(q)
+		# fire a query and get ready to receive the data
+		@connection.send(format_query(q))
+		data = @connection.receive
 
-    return if data == nil
+		return if data == nil
 
-    record_set = "" # temporarily store retrieved rows
-    record_set = receive_record_set(data)
+		record_set = "" # temporarily store retrieved rows
+		record_set = receive_record_set(data)
 
-    if (@lang == MonetDBConnection::LANG_SQL)
-      rows = receive_record_set(data)
-      # the fired query is a SELECT; store and return the whole record set
-      if @action == MonetDBConnection::Q_TABLE
-        @header = parse_header_table(@header)
-        @header.freeze
+		if (@lang == MonetDBConnection::LANG_SQL)
+			rows = receive_record_set(data)
+			# the fired query is a SELECT; store and return the whole record set
+			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
-            data = @connection.receive
-            block_rows += receive_record_set(data)
-          end
-          record_set += block_rows
-        end
-      end
+				if @row_index.to_i < @row_count.to_i
+					block_rows = ""
+					while next_block
+						data = @connection.receive
+						block_rows += receive_record_set(data)
+					end
+					record_set += block_rows
+				end
+			end
 
-      # 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")
+			# 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
-  end
+			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
+	end
 
-  # 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|
-       columns[col_name] = fetch_by_column_name(col_name)
-     end
+	# 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|
+			columns[col_name] = fetch_by_column_name(col_name)
+		end
 
-     return columns
-   end
+		return columns
+	end
 
-  # returns a record hash (i.e: { id: 1, name: "John Doe", age: 42 } )
-  def fetch_hash
-    return false if @index >= @query['rows'].to_i
+	# returns a record hash (i.e: { id: 1, name: "John Doe", age: 42 } )
+	def fetch_hash
+		return false if @index >= @query['rows'].to_i
 
-    record_hash = record_hash(parse_tuple(@record_set[@index]))
-    @index += 1
-    return record_hash
-  end
+		record_hash = record_hash(parse_tuple(@record_set[@index]))
+		@index += 1
+		return record_hash
+	end
 
-  # 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|
-      parsed_record = parse_tuple(record)
-      yield(record_hash(parsed_record))
-    end
-  end
+	# 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|
+			parsed_record = parse_tuple(record)
+			yield(record_hash(parsed_record))
+		end
+	end
 
-  # Returns the values for the column 'field'
-  def fetch_by_column_name(column_name="")
-    position = @header["columns_order"].fetch(column_name)
+	# Returns the values for the column 'field'
+	def fetch_by_column_name(column_name="")
+		position = @header["columns_order"].fetch(column_name)
 
-    column_values = []
-    @record_set.each do |row|
-      column_values << parse_tuple(row)[position]
-    end
+		column_values = []
+		@record_set.each do |row|
+			column_values << parse_tuple(row)[position]
+		end
 
-    return column_values
-  end
+		return column_values
+	end
 
-  # fetches a single record, updates the iterator index
-  def fetch
-    return false if @index >= @query['rows'].to_i
+	# fetches a single record, updates the iterator index
+	def fetch
+		return false if @index >= @query['rows'].to_i
 
-    result = parse_tuple(@record_set[@index])
-    @index += 1
+		result = parse_tuple(@record_set[@index])
+		@index += 1
 
-    return result
-  end
+		return result
+	end
 
-  # resets the internal iterator index used by fetch and fetch_hash
-  def reset_index
-    @index = 0
-  end
+	# resets the internal iterator index used by fetch and fetch_hash
+	def reset_index
+		@index = 0
+	end
 
-  # 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
-    @record_set.each { |record| yield(parse_tuple(record)) }
-  end
+	# 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
+		@record_set.each { |record| yield(parse_tuple(record)) }
+	end
 
-  # Cursor method that returns all the records
-  def fetch_all
-    result = []
-    each_record do |record|
-      result.push(record)
-    end
-    return result
-  end
+	# Cursor method that returns all the records
+	def fetch_all
+		result = []
+		each_record do |record|
+			result.push(record)
+		end
+		return result
+	end
 
-  # Returns the number of rows in the record set
-  def num_rows
-      return @query['rows'].to_i
-   end
+	# Returns the number of rows in the record set
+	def num_rows
+		return @query['rows'].to_i
+	end
 
-  # Returns the number of fields in the record set
-  def num_fields
-     return @query['columns'].to_i
-   end
+	# Returns the number of fields in the record set
+	def num_fields
+		return @query['columns'].to_i
+	end
 
-  # Returns the (ordered) name of the columns' tables in the record set
-  def table_name_fields
-    return @header['table_name']
-  end
+	# Returns the (ordered) name of the columns' tables in the record set
+	def table_name_fields
+		return @header['table_name']
+	end
 
-  # Returns the (ordered) name of the columns in the record set
-  def name_fields
-    return @header['columns_name']
-  end
+	# Returns the (ordered) name of the columns in the record set
+	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
+	# Returns the (ordered) name of the columns in the record set
+	def type_fields
+		return @header['columns_type']
+	end
 
-  # ===================
-          private
-  # ===================
+	# ===================
+    private
+	# ===================
 
-  # store block of data, parse it and store it.
-  def receive_record_set(response)
-    rows = ""
-    response.each_line do |row|
-      case row[0]
-      when MonetDBConnection::MSG_QUERY then parse_query(row)
-      when MonetDBConnection::MSG_INFO then raise MonetDBQueryError, row
-      when MonetDBConnection::MSG_SCHEMA_HEADER then @header << row
-      when MonetDBConnection::MSG_TUPLE then rows += row
-      when MonetDBConnection::MSG_PROMPT then return rows
-      end
-    end
-    return rows # return an array of unparsed tuples
-  end
+	# store block of data, parse it and store it.
+	def receive_record_set(response)
+		rows = ""
+		response.each_line do |row|
+			case row[0]
+			when MonetDBConnection::MSG_QUERY then parse_query(row)
+			when MonetDBConnection::MSG_INFO then raise MonetDBQueryError, row
+			when MonetDBConnection::MSG_SCHEMA_HEADER then @header << row
+			when MonetDBConnection::MSG_TUPLE then rows += row
+			when MonetDBConnection::MSG_PROMPT then return rows
+			end
+		end
+		return rows # return an array of unparsed tuples
+	end
 
-  def parse_query(row)
-    case row[1]
-      when MonetDBConnection::Q_TABLE
-        @action = MonetDBConnection::Q_TABLE
-        @query = parse_header_query(row)
-        @query.freeze
-        @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)
-      when MonetDBConnection::Q_TRANSACTION
-        @action = MonetDBConnection::Q_TRANSACTION
-      when MonetDBConnection::Q_CREATE
-        @action = MonetDBConnection::Q_CREATE
-    end
-  end
+	def parse_query(row)
+		case row[1]
+		when MonetDBConnection::Q_TABLE
+			@action = MonetDBConnection::Q_TABLE
+			@query = parse_header_query(row)
+			@query.freeze
+			@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)
+		when MonetDBConnection::Q_TRANSACTION
+			@action = MonetDBConnection::Q_TRANSACTION
+		when MonetDBConnection::Q_CREATE
+			@action = MonetDBConnection::Q_CREATE
+		end
+	end
 
-  def record_hash(record)
-    result = {}
+	def record_hash(record)
+		result = {}
 
-    @header["columns_name"].each do |column_name|
-       position = @header["columns_order"].fetch(column_name)
-       result[column_name] = record[position]
-     end
+		@header["columns_name"].each do |column_name|
+			position = @header["columns_order"].fetch(column_name)
+			result[column_name] = record[position]
+		end
 
-    return result
-  end
+		return result
+	end
 
-  def next_block
-    if @row_index == @row_count
-      return false
-    else
-      # The increment step is small to better deal with ruby socket's performance.
-      # For larger values of the step performance drop;
-      #
-      @row_offset = [@row_offset, (@row_count - @row_index)].min
+	def next_block
+		if @row_index == @row_count
+			return false
+		else
+			# The increment step is small to better deal with ruby socket's performance.
+			# 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
-      @row_offset += 1
-    end
-      return true
+			# export offset amount
+			@connection.set_export(@query['id'], @row_index.to_s, @row_offset.to_s)
+			@row_index += @row_offset
+			@row_offset += 1
+		end
+		return true
 
-  end
+	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
-        return "s" + q + "\n;"
-    else
-      raise LanguageNotSupported, @lang
-    end
-  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
+			return "s" + q + "\n;"
+		else
+			raise LanguageNotSupported, @lang
+		end
+	end
 
-  # parse one tuple as returned from the server
-  def parse_tuple(tuple)
-    fields = []
-    # remove trailing  "["
-    tuple = tuple.gsub(/^\[\s+/,'')
-    tuple.split(/,\t/).each_with_index do |field, index|
-      field_value = convert_type(field, index)
-      fields << field_value
-    end
+	# parse one tuple as returned from the server
+	def parse_tuple(tuple)
+		fields = []
+		# remove trailing  "["
+		tuple = tuple.gsub(/^\[\s+/,'')
+		tuple.split(/,\t/).each_with_index do |field, index|
+			field_value = convert_type(field, index)
+			fields << field_value
+		end
 
-    return fields.freeze
-  end
+		return fields.freeze
+	end
 
-  # converts the given value the correct type
-  def convert_type(value, index)
-    return nil if "NULL" == value.upcase
-    return case type_fields.values[index]
-        when "int", "tinyint", "smallint", "bigint", "hugeint" then value.to_i
-        when "double", "real", "decimal" then value.to_f
-        when "boolean" then value.downcase == true
-        when "date" then Date.parse(value)
-        when "time" then Time.parse(value, Time.new("2000-01-01"))
-        when "timestamp" then DateTime.parse(value)
-        when "timestamptz" then DateTime.parse(value)
-        else value.gsub(/\\/, '').gsub(/^"/,'').gsub(/"$/,'').gsub(/\"/, '')
-      end
-  end
+	# converts the given value the correct type
+	def convert_type(value, index)
+		return nil if "NULL" == value.upcase
+		return case type_fields.values[index]
+			   when "int", "tinyint", "smallint", "bigint", "hugeint" then value.to_i
+			   when "double", "real", "decimal" then value.to_f
+			   when "boolean" then value.downcase == true
+			   when "date" then Date.parse(value)
+			   when "time" then Time.parse(value, Time.new("2000-01-01"))
+			   when "timestamp" then DateTime.parse(value)
+			   when "timestamptz" then DateTime.parse(value)
+			   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 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]
+	# 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 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
+			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]
+			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
+			header = { "id" => id, "type" => type, "remains" => remains, "columns" => columns, "offset" => offset }
+		else
+			header = {"type" => type}
+		end
 
-    return header.freeze
-  end
+		return header.freeze
+	end
 
-  # Parse escaped strings between double quotes
-  def parse_header_table_values(line, start, stop, results)
-    i = start
-    inString = false
-    escaped = false
+	# Parse escaped strings between double quotes
+	def parse_header_table_values(line, start, stop, results)
+		i = start
+		inString = false
+		escaped = false
 
-    until i == stop do
-      case line[i]
-        when '\\'
-          escaped = !escaped
-        when '"'
-          if !inString
-            inString = true
-          elsif !escaped
-            inString = false
-          end
-          escaped = false
-        when ','
-          if !inString # && line[i + 1] == '\t'
-            if line[start] == '"' # Don't include the leading " in the column attribute
-              start += 1
-            end
-            if line[i - 1] == '"'
-              next_end = 2
-            else
-              next_end = 1
-            end
-            results.push(line[start..i - next_end])
-            i += 1
-            start = i + 1
-          end
-          escaped = false
-        else
-          escaped = false
-      end
-      i += 1
-    end
-    if line[start] == '"' # Don't include the leading " in the column attribute
-      start += 1
-    end
-    if line[stop] == '"'
-      next_end = 1
-    else
-      next_end = 0
-    end
-    results.push(line[start..stop - next_end])
-  end
+		until i == stop do
+			case line[i]
+			when '\\'
+				escaped = !escaped
+			when '"'
+				if !inString
+					inString = true
+				elsif !escaped
+					inString = false
+				end
+				escaped = false
+			when ','
+				if !inString # && line[i + 1] == '\t'
+					if line[start] == '"' # Don't include the leading " in the column attribute
+						start += 1
+					end
+					if line[i - 1] == '"'
+						next_end = 2
+					else
+						next_end = 1
+					end
+					results.push(line[start..i - next_end])
+					i += 1
+					start = i + 1
+				end
+				escaped = false
+			else
+				escaped = false
+			end
+			i += 1
+		end
+		if line[start] == '"' # Don't include the leading " in the column attribute
+			start += 1
+		end
+		if line[stop] == '"'
+			next_end = 1
+		else
+			next_end = 0
+		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
+	# 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_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)
+				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
+				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
+				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
+				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,
-          "columns_length" => length_cols, "columns_order" => columns_order}.freeze
-      end
-    end
-  end
+				return {"table_name" => name_t, "columns_name" => name_cols, "columns_type" => type_cols,
+						"columns_length" => length_cols, "columns_order" => columns_order}.freeze
+			end
+		end
+	end
 end
--- a/lib/MonetDBExceptions.rb
+++ b/lib/MonetDBExceptions.rb
@@ -7,38 +7,38 @@
 # Exception classes for the ruby-monetdb driver
 
 class MonetDBQueryError < StandardError
-  def initialize(e)
-    $stderr.puts e
-  end
+	def initialize(e)
+		$stderr.puts e
+	end
 end
 
 class MonetDBDataError < StandardError
-  def initialize(e)
-    $stderr.puts e
-  end
+	def initialize(e)
+		$stderr.puts e
+	end
 end
 
 class MonetDBCommandError < StandardError
-  def initialize(e)
-    $stderr.puts e
-  end
+	def initialize(e)
+		$stderr.puts e
+	end
 end
 
 class MonetDBConnectionError < StandardError
-  def initialize(e)
-    $stderr.puts e
-  end
+	def initialize(e)
+		$stderr.puts e
+	end
 end
 
 
 class MonetDBSocketError < StandardError
-  def initialize(e)
-    $stderr.puts e
-  end
+	def initialize(e)
+		$stderr.puts e
+	end
 end
 
 class MonetDBProtocolError < StandardError
-   def initialize(e)
-     $stderr.puts e
-   end
+	def initialize(e)
+		$stderr.puts e
+	end
 end
--- a/lib/hasher.rb
+++ b/lib/hasher.rb
@@ -13,25 +13,25 @@ class Hasher
 	# method = "SHA1" or "MD5"
 	# pwd = Password
 	def initialize(method, pwd)
-          if (method.upcase == "SHA1")
-                  @hashfunc = Digest::SHA1.new
-                  @hashname = method.upcase
-          elsif (method.upcase == "SHA256")
+        if (method.upcase == "SHA1")
+            @hashfunc = Digest::SHA1.new
+            @hashname = method.upcase
+        elsif (method.upcase == "SHA256")
             @hashfunc = Digest::SHA256.new
             @hashname = method.upcase
-          elsif (method.upcase == "SHA384")
+        elsif (method.upcase == "SHA384")
             @hashfunc = Digest::SHA384.new
             @hashname = method.upcase
-          elsif (method.upcase == "SHA512")
+        elsif (method.upcase == "SHA512")
             @hashfunc = Digest::SHA512.new
             @hashname = method.upcase
-          else
+        else
             # default to MD5
-                  @hashfunc = Digest::MD5.new
-                  @hashname = "MD5"
-          end
-          @pwd = pwd
-  end
+            @hashfunc = Digest::MD5.new
+            @hashname = "MD5"
+        end
+        @pwd = pwd
+	end
 
 
 	def hashname
--- a/monetdb-sql.gemspec
+++ b/monetdb-sql.gemspec
@@ -1,17 +1,17 @@
 
 Gem::Specification.new do |s|
-   s.required_ruby_version = '>= 1.8.0'
-   s.name = %q{monetdb-sql}
-   s.version = "1.2"
-   s.date = %q{2020-10-20}
-   s.authors = ["G Modena", "R Koopmanschap"]
-   s.email = "info@monetdb.org"
-   s.license = "MPL-2.0"
-   s.summary = %q{Pure Ruby database driver for MonetDB/SQL}
-   s.homepage = %q{http://www.monetdb.org/}
-   s.description = %q{Pure Ruby database driver for the MonetDB/SQL columnar database management system}
-   s.files = ["lib/MonetDB.rb", "lib/MonetDBConnection.rb", "lib/MonetDBData.rb", "lib/MonetDBExceptions.rb", "lib/hasher.rb"]
-   s.require_path = './lib'
-   # placeholder project to avoid warning about not having a rubyforge_project
-   s.rubyforge_project = "nowarning"
+	s.required_ruby_version = '>= 1.8.0'
+	s.name = %q{monetdb-sql}
+	s.version = "1.2"
+	s.date = %q{2020-10-20}
+	s.authors = ["G Modena", "R Koopmanschap"]
+	s.email = "info@monetdb.org"
+	s.license = "MPL-2.0"
+	s.summary = %q{Pure Ruby database driver for MonetDB/SQL}
+	s.homepage = %q{http://www.monetdb.org/}
+	s.description = %q{Pure Ruby database driver for the MonetDB/SQL columnar database management system}
+	s.files = ["lib/MonetDB.rb", "lib/MonetDBConnection.rb", "lib/MonetDBData.rb", "lib/MonetDBExceptions.rb", "lib/hasher.rb"]
+	s.require_path = './lib'
+	# placeholder project to avoid warning about not having a rubyforge_project
+	s.rubyforge_project = "nowarning"
 end