DBD-MariaDB

 view release on metacpan or  search on metacpan

dbdimp.h  view on Meta::CPAN

 * This is the versions of libmysql that supports MySQL Fabric.
 * We need to check for special macro LIBMYSQL_VERSION_ID.
 */
#ifdef LIBMYSQL_VERSION_ID
#if LIBMYSQL_VERSION_ID >= 60200 && LIBMYSQL_VERSION_ID < 70000
#define HAVE_FABRIC
#endif
#endif

#if !defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 80001
#define my_bool bool
#endif

/*
 * MariaDB Connector/C 3.1.10 changed API of mysql_get_client_version()
 * function. Before that release it returned client version. With that release
 * it started returning Connector/C package version.
 *
 * So when compiling with MariaDB Connector/C client library, redefine
 * mysql_get_client_version() to always returns client version via function
 * mariadb_get_infov(MARIADB_CLIENT_VERSION_ID) call.
 *
 * Driver code expects for a long time that mysql_get_client_version() call
 * returns client version and not something different.
 *
 * Function mariadb_get_infov() is supported since MariaDB Connector/C 3.0+.
 */
#if defined(MARIADB_PACKAGE_VERSION) && defined(MARIADB_PACKAGE_VERSION_ID) && MARIADB_PACKAGE_VERSION_ID >= 30000
PERL_STATIC_INLINE unsigned long mariadb_get_client_version(void)
{
  /* MARIADB_CLIENT_VERSION_ID really expects size_t type, documentation is wrong and says unsigned int. */
  size_t version;
  if (mariadb_get_infov(NULL, MARIADB_CLIENT_VERSION_ID, &version) != 0)
    version = mysql_get_client_version(); /* On error fallback to mysql_get_client_version() */
  return version;
}
#define mysql_get_client_version() mariadb_get_client_version()
#endif

/* mysql_commit() and mysql_rollback() are broken in MariaDB Connector/C prior to version 3.1.3, see: https://jira.mariadb.org/browse/CONC-400 */
#if defined(MARIADB_PACKAGE_VERSION) && MARIADB_PACKAGE_VERSION_ID < 30103
#define mysql_commit(mysql) ((my_bool)(mysql_real_query((mysql), "COMMIT", 6)))
#define mysql_rollback(mysql) ((my_bool)(mysql_real_query((mysql), "ROLLBACK", 8)))
#endif

/* MYSQL_SECURE_AUTH became a no-op from MySQL 5.7.5 and is removed from MySQL 8.0.3 */
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID <= 50704
#define HAVE_SECURE_AUTH
#endif

/* mysql_error(NULL) returns last error message, needs MySQL 5.0.60+ or 5.1.24+; does not work with MariaDB Connector/C yet: https://jira.mariadb.org/browse/CONC-374 */
#if ((MYSQL_VERSION_ID >= 50060 && MYSQL_VERSION_ID < 50100) || MYSQL_VERSION_ID >= 50124) && !defined(MARIADB_PACKAGE_VERSION)
#define HAVE_LAST_ERROR
#endif

/*
 * MySQL and MariaDB Embedded are affected by https://jira.mariadb.org/browse/MDEV-16578
 * MariaDB 10.2.2+ prior to 10.2.19 and 10.3.9 and MariaDB Connector/C prior to 3.0.5 are affected by https://jira.mariadb.org/browse/CONC-336
 * MySQL 8.0.4+ prior to 8.0.20 is affected too by https://bugs.mysql.com/bug.php?id=93276
 */
#if defined(HAVE_EMBEDDED) || (!defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 80004 && MYSQL_VERSION_ID < 80020) || (defined(MARIADB_PACKAGE_VERSION) && (!defined(MARIADB_PACKAGE_VERSION_ID) || MARIADB_PACKAGE_VERSION_ID < 30005)) || (defined(...
#define HAVE_BROKEN_INIT
#endif

/*
 * Check which SSL settings are supported by API at compile time
 */

/* Use mysql_options with MYSQL_OPT_SSL_VERIFY_SERVER_CERT */
#if ((MYSQL_VERSION_ID >= 50023 && MYSQL_VERSION_ID < 50100) || MYSQL_VERSION_ID >= 50111) && (MYSQL_VERSION_ID < 80000 || defined(MARIADB_BASE_VERSION))
#define HAVE_SSL_VERIFY
#endif

/* Use mysql_options with MYSQL_OPT_SSL_ENFORCE (CVE-2015-3152, fix for MySQL) */
#if !defined(MARIADB_BASE_VERSION) && !defined(HAVE_EMBEDDED) && MYSQL_VERSION_ID >= 50703 && MYSQL_VERSION_ID < 80000 && MYSQL_VERSION_ID != 60000
#define HAVE_SSL_ENFORCE
#endif

/* Use mysql_options with MYSQL_OPT_SSL_MODE (CVE-2015-3152, fix for MySQL) */
#if !defined(MARIADB_BASE_VERSION) && !defined(HAVE_EMBEDDED) && MYSQL_VERSION_ID >= 50711 && MYSQL_VERSION_ID != 60000
#define HAVE_SSL_MODE
#endif

/* Use mysql_options with MYSQL_OPT_SSL_MODE, but only SSL_MODE_REQUIRED is supported (CVE-2017-3305, fix for MySQL) */
#if !defined(MARIADB_BASE_VERSION) && !defined(HAVE_EMBEDDED) && ((MYSQL_VERSION_ID >= 50636 && MYSQL_VERSION_ID < 50700) || (MYSQL_VERSION_ID >= 50555 && MYSQL_VERSION_ID < 50600))
#define HAVE_SSL_MODE_ONLY_REQUIRED
#endif

/*
 * Check which SSL settings are supported by API at runtime
 */

/* MYSQL_OPT_SSL_VERIFY_SERVER_CERT automatically enforce SSL mode (CVE-2015-3152 and CVE-2017-3305 and CVE-2018-2767, fix for MariaDB) */
PERL_STATIC_INLINE bool ssl_verify_also_enforce_ssl(void) {
#ifdef MARIADB_BASE_VERSION
	unsigned long version = mysql_get_client_version();
 #ifdef HAVE_EMBEDDED
	return ((version >= 50560 && version < 50600) || (version >= 100035 && version < 100100) || (version >= 100133 && version < 100200) || (version >= 100215 && version < 100300) || version >= 100307);
 #else
	return ((version >= 50556 && version < 50600) || (version >= 100031 && version < 100100) || (version >= 100123 && version < 100200) || (version >= 100206 && version < 100300) || version >= 100301);
 #endif
#else
	return FALSE;
#endif
}

/* MYSQL_OPT_SSL_VERIFY_SERVER_CERT is not vulnerable (CVE-2016-2047) and can be used */
PERL_STATIC_INLINE bool ssl_verify_usable(void) {
	unsigned long version = mysql_get_client_version();
#ifdef MARIADB_BASE_VERSION
	return ((version >= 50547 && version < 50600) || (version >= 100023 && version < 100100) || version >= 100110);
#else
	return ((version >= 50549 && version < 50600) || (version >= 50630 && version < 50700) || version >= 50712);
#endif
}

/*
 *  Internal constants, used for fetching array attributes
 */
enum av_attribs {
    AV_ATTRIB_NAME = 0,
    AV_ATTRIB_TABLE,
    AV_ATTRIB_TYPE,
    AV_ATTRIB_SQL_TYPE,
    AV_ATTRIB_IS_PRI_KEY,
    AV_ATTRIB_IS_NOT_NULL,
    AV_ATTRIB_NULLABLE,
    AV_ATTRIB_LENGTH,
    AV_ATTRIB_IS_NUM,
    AV_ATTRIB_TYPE_NAME,
    AV_ATTRIB_PRECISION,
    AV_ATTRIB_SCALE,
    AV_ATTRIB_MAX_LENGTH,
    AV_ATTRIB_IS_KEY,
    AV_ATTRIB_IS_BLOB,
    AV_ATTRIB_IS_AUTO_INCREMENT,
    AV_ATTRIB_LAST         /*  Dummy attribute, never used, for allocation  */
};                         /*  purposes only                                */


/* Double linked list */
struct mariadb_list_entry {
    void *data;
    struct mariadb_list_entry *prev;
    struct mariadb_list_entry *next;
};
#define mariadb_list_add(list, entry, ptr)           \
  STMT_START {                                       \
    Newz(0, (entry), 1, struct mariadb_list_entry);  \
    (entry)->data = (ptr);                           \
    (entry)->prev = NULL;                            \
    (entry)->next = (list);                          \
    if ((list))                                      \
      (list)->prev = (entry);                        \
    (list) = (entry);                                \
  } STMT_END
#define mariadb_list_remove(list, entry)             \
  STMT_START {                                       \
    if ((entry)->prev)                               \
      (entry)->prev->next = (entry)->next;           \
    if ((entry)->next)                               \
      (entry)->next->prev = (entry)->prev;           \
    if ((list) == (entry))                           \
      (list) = (entry)->next;                        \
    Safefree((entry));                               \
    (entry) = NULL;                                  \
  } STMT_END


/*
 *  This is our part of the driver handle. We receive the handle as
 *  an "SV*", say "drh", and receive a pointer to the structure below
 *  by declaring
 *
 *    D_imp_drh(drh);
 *
 *  This declares a variable called "imp_drh" of type
 *  "struct imp_drh_st *".
 */
struct imp_drh_st {
    dbih_drc_t com;         /* MUST be first element in structure   */

    struct mariadb_list_entry *active_imp_dbhs; /* List of imp_dbh structures with active MYSQL* */
    struct mariadb_list_entry *taken_pmysqls;   /* List of active MYSQL* from take_imp_data() */
    unsigned long int instances;
    bool non_embedded_started;
#if !defined(HAVE_EMBEDDED) && defined(HAVE_BROKEN_INIT)
    bool non_embedded_finished;
#endif
    bool embedded_started;
    SV *embedded_args;
    SV *embedded_groups;
};


/*
 *  Likewise, this is our part of the database handle, as returned
 *  by DBI->connect. We receive the handle as an "SV*", say "dbh",
 *  and receive a pointer to the structure below by declaring
 *
 *    D_imp_dbh(dbh);
 *
 *  This declares a variable called "imp_dbh" of type
 *  "struct imp_dbh_st *".
 */
struct imp_dbh_st {
    dbih_dbc_t com;         /*  MUST be first element in structure   */

    struct mariadb_list_entry *list_entry; /* Entry of imp_drh->active_imp_dbhs list */
    MYSQL *pmysql;
    int sock_fd;
    bool connected;          /* Set to true after DBI->connect finished */
    bool is_embedded;
    bool auto_reconnect;
    bool bind_type_guessing;
    bool bind_comment_placeholders;
    bool no_autocommit_cmd;
    bool use_mysql_use_result; /* TRUE if execute should use
                               * mysql_use_result rather than
                               * mysql_store_result
                               */
    bool use_server_side_prepare;
    bool disable_fallback_for_server_prepare;
    bool use_multi_statements;
    void* async_query_in_flight;
    my_ulonglong insertid;
    struct {
	    unsigned int auto_reconnects_ok;
	    unsigned int auto_reconnects_failed;
    } stats;
};


/*
 *  The bind_param method internally uses this structure for storing
 *  parameters.
 */
typedef struct imp_sth_ph_st {
    char* value;
    STRLEN len;
    int type;
    bool bound;
} imp_sth_ph_t;

/*
 *  Storage for numeric value in prepared statement
 */



( run in 1.212 second using v1.01-cache-2.11-cpan-71847e10f99 )