DBD-MariaDB

 view release on metacpan or  search on metacpan

dbdimp.c  view on Meta::CPAN

	      }
    #else
	      mariadb_dr_do_error(dbh, CR_SSL_CONNECTION_ERROR, "SSL connection error: mariadb_ssl_verify_server_cert=1 is not supported", "HY000");
	      mariadb_db_disconnect(dbh, imp_dbh);
	      return FALSE;
    #endif
	    }

  #endif
	  }
	else
	  {
#ifdef HAVE_SSL_MODE
	    unsigned int ssl_mode = SSL_MODE_DISABLED;
	    mysql_options(sock, MYSQL_OPT_SSL_MODE, &ssl_mode);
#endif
	  }
        (void)hv_stores(processed, "mariadb_local_infile", &PL_sv_yes);
     if ((svp = hv_fetchs(hv, "mariadb_local_infile", FALSE)) && *svp)
     {
	  unsigned int flag = SvTRUE(*svp);
    if (DBIc_TRACE_LEVEL(imp_xxh) >= 2)
	    PerlIO_printf(DBIc_LOGPIO(imp_xxh),
        "imp_dbh->mariadb_dr_connect: Using"
        " local infile %u.\n", flag);
	  mysql_options(sock, MYSQL_OPT_LOCAL_INFILE, (const char *) &flag);
	}

        hv_iterinit(hv);
        while ((he = hv_iternext(hv)) != NULL)
        {
          I32 len;
          const char *key;
          key = hv_iterkey(he, &len);
          if (skip_attribute(key) || hv_exists(processed, key, len))
            continue;
          error_unknown_attribute(dbh, key);
          mariadb_db_disconnect(dbh, imp_dbh);
          return FALSE;
        }
      }

    if (DBIc_TRACE_LEVEL(imp_xxh) >= 2)
      PerlIO_printf(DBIc_LOGPIO(imp_xxh), "imp_dbh->mariadb_dr_connect: client_flags = %d\n",
		    client_flag);

    /*
      MySQL's "utf8mb4" charset is capable of handling 4-byte UTF-8 characters.
      MySQL's "utf8" charset is capable of handling only up to 3-byte UTF-8 characters.
      MySQL's "utf8mb4" charset was introduced in MySQL server version 5.5.3.
      If MySQL's "utf8mb4" is not supported by server, fallback to MySQL's "utf8".
      If MySQL's "utf8mb4" is not supported by client, connect with "utf8" and issue SET NAMES 'utf8mb4'.
      MYSQL_SET_CHARSET_NAME option (prior to establishing connection) sets client's charset.
      Some clients think that they were connected with MYSQL_SET_CHARSET_NAME, but reality can be different.
      This problem was reported in MariaDB bug tracker https://jira.mariadb.org/browse/CONC-342
      but problem is not going to be fixed. So always manually issue SET NAMES to prevent misbehave.
      To enable UTF-8 storage on server it is needed to configure it via session variable character_set_server.
      Some clients provides function get_charset_number() to check if charset is supported.
      If MySQL client does not support specified charset it used to print error message to stdout or stderr.
      DBD::MariaDB expects that whole communication with server is encoded in UTF-8.
      By default broken utf8mb4_general_ci collation is used. So change it to utf8mb4_unicode_ci which is according to the Unicode 4.0.0.
    */
#ifdef HAVE_GET_CHARSET_NUMBER
    client_supports_utf8mb4 = get_charset_number("utf8mb4", MY_CS_PRIMARY) ? TRUE : FALSE;
#elif MYSQL_VERSION_ID < 50503
    client_supports_utf8mb4 = FALSE;
#else
    client_supports_utf8mb4 = TRUE;
#endif
    connected = FALSE;
    if (client_supports_utf8mb4)
    {
      mysql_options(sock, MYSQL_SET_CHARSET_NAME, "utf8mb4");
      connected = mysql_real_connect(sock, host, user, password, dbname, port, mysql_socket, client_flag | CLIENT_REMEMBER_OPTIONS) ? TRUE : FALSE;
      if (!connected && mysql_errno(sock) != CR_CANT_READ_CHARSET)
      {
        mariadb_dr_do_error(dbh, mysql_errno(sock), mysql_error(sock), mysql_sqlstate(sock));
        mariadb_db_disconnect(dbh, imp_dbh);
        return FALSE;
      }
      if (connected && mysql_get_server_version(sock) < 40100)
      {
        mariadb_dr_do_error(dbh, CR_CONNECTION_ERROR, "Connection error: MariaDB or MySQL server version is older than 4.1.0", "HY000");
        mariadb_db_disconnect(dbh, imp_dbh);
        return FALSE;
      }
    }
    if (!connected)
    {
      mysql_options(sock, MYSQL_SET_CHARSET_NAME, "utf8");
      connected = mysql_real_connect(sock, host, user, password, dbname, port, mysql_socket, client_flag) ? TRUE : FALSE;
      if (!connected)
      {
        mariadb_dr_do_error(dbh, mysql_errno(sock), mysql_error(sock), mysql_sqlstate(sock));
        mariadb_db_disconnect(dbh, imp_dbh);
        return FALSE;
      }
      if (mysql_get_server_version(sock) < 40100)
      {
        mariadb_dr_do_error(dbh, CR_CONNECTION_ERROR, "Connection error: MariaDB or MySQL server version is older than 4.1.0", "HY000");
        mariadb_db_disconnect(dbh, imp_dbh);
        return FALSE;
      }
    }
    if (mysql_query(sock, "SET NAMES 'utf8mb4'") != 0 ||
        mysql_query(sock, "SET character_set_server = 'utf8mb4'") != 0)
    {
      if (mysql_errno(sock) != ER_UNKNOWN_CHARACTER_SET)
      {
        mariadb_dr_do_error(dbh, mysql_errno(sock), mysql_error(sock), mysql_sqlstate(sock));
        mariadb_db_disconnect(dbh, imp_dbh);
        return FALSE;
      }
      if (mysql_query(sock, "SET NAMES 'utf8'") != 0 ||
          mysql_query(sock, "SET character_set_server = 'utf8'") != 0 ||
          mysql_query(sock, "SET collation_connection = 'utf8_unicode_ci'") != 0 ||
          mysql_query(sock, "SET collation_server = 'utf8_unicode_ci'") != 0)
      {
        mariadb_dr_do_error(dbh, mysql_errno(sock), mysql_error(sock), mysql_sqlstate(sock));
        mariadb_db_disconnect(dbh, imp_dbh);
        return FALSE;
      }
    }
    else
    {
      if (mysql_query(sock, "SET collation_connection = 'utf8mb4_unicode_ci'") != 0 ||
          mysql_query(sock, "SET collation_server = 'utf8mb4_unicode_ci'") != 0)
      {
        mariadb_dr_do_error(dbh, mysql_errno(sock), mysql_error(sock), mysql_sqlstate(sock));
        mariadb_db_disconnect(dbh, imp_dbh);
        return FALSE;
      }
    }

      /*
        we turn off Mysql's auto reconnect and handle re-connecting ourselves
        so that we can keep track of when this happens.
      */
#if MYSQL_VERSION_ID >= 50013
    /* Beginning with MySQL 8.0.34, the automatic reconnection feature is deprecated and disabled by default. */
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 80034
    {
      my_bool reconnect = FALSE;
      mysql_options(sock, MYSQL_OPT_RECONNECT, &reconnect);
    }
#endif
#else
      sock->reconnect = FALSE;
#endif

    /* Connection to Embedded server does not have socket */
    if (imp_dbh->is_embedded)
    {
      imp_dbh->sock_fd = -1;
    }
    else
    {
      my_socket sock_os;
      int retval;

      /*
        mysql_get_socket() is not available:
        - in all MySQL clients
        - MariaDB clients prior to 5.5.38 and 10.0.11
        - MariaDB Connector/C clients prior to 2.2.1
        NOTE: MARIADB_PACKAGE_VERSION_ID is set since MariaDB Connector/C 2.3.5+
      */
#if defined(MARIADB_BASE_VERSION) && ((MYSQL_VERSION_ID >= 50538 && MYSQL_VERSION_ID < 100000) || MYSQL_VERSION_ID >= 100011 || (defined(MARIADB_PACKAGE_VERSION_ID) && MARIADB_PACKAGE_VERSION_ID >= 20201))
      sock_os = mysql_get_socket(sock);
#else
      sock_os = sock->net.fd;
#endif
      /*
        Client library returns socket in my_socket type, which is C file
        descriptor on Linux or Windows native socket type on Windows.
        On Windows it can be zero in case connection type is not socket.
        Perl requires sockets to always be in C file descriptor type,
        so on Windows associate it with C file descriptor via Perl's
        win32_open_osfhandle() function.
      */
#ifdef _WIN32
      imp_dbh->sock_fd = sock_os != 0 ? win32_open_osfhandle(sock_os, O_RDWR|O_BINARY) : -1;
#else
      imp_dbh->sock_fd = sock_os;
#endif

#ifdef _WIN32



( run in 0.527 second using v1.01-cache-2.11-cpan-39bf76dae61 )