All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.twitter.finagle.mysql.Handshake.scala Maven / Gradle / Ivy

package com.twitter.finagle.exp.mysql

import com.twitter.util.{Return, StorageUnit, Throw, Try}
import com.twitter.conversions.storage._

class IncompatibleServerError(msg: String)
  extends Exception(msg)

case object IncompatibleVersion
  extends IncompatibleServerError(
    "This client is only compatible with MySQL version 4.1 and later"
  )

case object IncompatibleCharset
  extends IncompatibleServerError(
    "This client is only compatible with UTF-8 and Latin-1 charset encoding"
  )

/**
 * Bridges a server handshake (HandshakeInit) with a
 * client handshake (HandshakeResponse) using the given
 * parameters. This facilitates the connection phase of
 * the mysql protocol.
 *
 * @param username MySQL username used to login.
 *
 * @param password MySQL password used to login.
 *
 * @param database initial database to use for the session.
 *
 * @param clientCap The capability this client has.
 *
 * @param charset default character established with the server.
 *
 * @param maxPacketSize max size of a command packet that the
 * client intends to send to the server. The largest possible
 * packet that can be transmitted to or from a MySQL 5.5 server or
 * client is 1GB.
 *
 * @return A Try[HandshakeResponse] that encodes incompatibility
 * with the server.
 */
case class Handshake(
  username: Option[String] = None,
  password: Option[String] = None,
  database: Option[String] = None,
  clientCap: Capability = Capability.baseCap,
  charset: Short = Charset.Utf8_general_ci,
  maxPacketSize: StorageUnit = 1.gigabyte
) extends (HandshakeInit => Try[HandshakeResponse]) {
  import Capability._
  require(maxPacketSize <= 1.gigabyte, "max packet size can't exceed 1 gigabyte")

  private[this] val newClientCap =
    if (database.isDefined) clientCap + ConnectWithDB
    else clientCap - ConnectWithDB

  private[this] def isCompatibleVersion(init: HandshakeInit) =
    if (init.serverCap.has(Capability.Protocol41)) Return(true)
    else Throw(IncompatibleVersion)

  private[this] def isCompatibleCharset(init: HandshakeInit) =
    if (Charset.isCompatible(init.charset)) Return(true)
    else Throw(IncompatibleCharset)

  def apply(init: HandshakeInit) = {
    for {
      _ <- isCompatibleVersion(init)
      _ <- isCompatibleCharset(init)
    } yield HandshakeResponse(
      username,
      password,
      database,
      newClientCap,
      init.salt,
      init.serverCap,
      charset,
      maxPacketSize.inBytes.toInt
    )
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy