# encoding: utf-8 require "moped/connection/manager" require "moped/connection/sockets" module Moped # This class contains behaviour of database socket connections. # # @since 2.0.0 class Connection include Authenticatable # The default connection timeout, in seconds. # # @since 2.0.0 TIMEOUT = 5 REPLY_DECODE_STR = 'l<5q ] operations The query or get more ops. # # @return [ Array ] The returned deserialized documents. # # @since 1.0.0 def receive_replies(operations) operations.map do |operation| operation.receive_replies(self) end end # Write to the connection. # # @example Write to the connection. # connection.write(data) # # @param [ Array ] operations The database operations. # # @return [ Integer ] The number of bytes written. # # @since 1.0.0 def write(operations) buf = "" operations.each do |operation| operation.request_id = (@request_id += 1) operation.serialize(buf) end with_connection do |socket| socket.write(buf) end end private # Read data from the socket until we get back the number of bytes that we # are expecting. # # @api private # # @example Read the number of bytes. # connection.read_data(socket, 36) # # @param [ TCPSocket ] socket The socket to read from. # @param [ Integer ] length The number of bytes to read. # # @return [ String ] The read data. # # @since 1.2.9 def read_data(socket, length) data = socket.read(length) unless data raise Errors::ConnectionFailure.new( "Attempted to read #{length} bytes from the socket but nothing was returned." ) end if data.length < length data << read_data(socket, length - data.length) end data end # Yields a connected socket to the calling back. It will attempt to reconnect # the socket if it is not connected. # # @api private # # @example Write to the connection. # with_connection do |socket| # socket.write(buf) # end # # @return The yielded block # # @since 1.3.0 def with_connection if @sock.nil? || !@sock.alive? connect apply_credentials(@original_credentials || {}) end yield @sock end end end