static void SMSDDBI_LogError(GSM_SMSDConfig * Config) { int rc; const char *msg; rc = dbi_conn_error(Config->conn.dbi, &msg); if (rc == -1) { SMSD_Log(DEBUG_ERROR, Config, "Unknown DBI error!"); } else { SMSD_Log(DEBUG_ERROR, Config, "DBI error %d: %s", rc, msg); } }
// MySQL: 1062: Duplicate entry '1' for key 1 // PostgreSQL: ERROR: duplicate key violates unique constraint ... int dbi_duplicate_entry(dbi_conn conn) { const char *errmsg; if (dbi_conn_error(conn, &errmsg) == DBI_ERROR_NONE) { return FALSE; } if (strcasestr(errmsg, "duplicate")) { return TRUE; } return FALSE; }
template <> void error_handler<DbType::DBI_MYSQL> (dbi_conn conn, void* user_data) { GncDbiBackend<DbType::DBI_MYSQL>* dbi_be = static_cast<decltype(dbi_be)>(user_data); const char* msg; auto err_num = dbi_conn_error (conn, &msg); /* Note: the sql connection may not have been initialized yet * so let's be careful with using it */ /* Database doesn't exist. When this error is triggered the * GncDbiSqlConnection may not exist yet either, so don't use it here */ if (err_num == 1049) // Database doesn't exist { PINFO ("DBI error: %s\n", msg); dbi_be->set_exists(false); return; } /* All the other error handling code assumes the GncDbiSqlConnection * has been initialized. So let's assert it exits here, otherwise * simply return. */ if (!dbi_be->connected()) { PINFO ("DBI error: %s\n", msg); PINFO ("Note: GbcDbiSqlConnection not yet initialized. Skipping further error processing."); return; } /* Test for other errors */ if (err_num == 2006) // Server has gone away { PINFO ("DBI error: %s - Reconnecting...\n", msg); dbi_be->set_dbi_error (ERR_BACKEND_CONN_LOST, 1, true); dbi_be->retry_connection(msg); } else if (err_num == 2003) // Unable to connect { dbi_be->set_dbi_error (ERR_BACKEND_CANT_CONNECT, 1, true); dbi_be->retry_connection (msg); } else // Any other error { PERR ("DBI error: %s\n", msg); dbi_be->set_dbi_error (ERR_BACKEND_MISC, 0, FALSE); } }
/** @brief Load a stored query. @param state Pointer to the query-building context. @param query_id ID of the query in query.stored_query. @return A pointer to the newly loaded StoredQ if successful, or NULL if not. The calling code is responsible for freeing the StoredQ by calling storedQFree(). */ StoredQ* getStoredQuery( BuildSQLState* state, int query_id ) { if( !state ) return NULL; // Check the stack to see if the current query is nested inside itself. If it is, then // abort in order to avoid infinite recursion. If it isn't, then add it to the stack. // (Make sure to pop it off the stack before returning.) if( searchIdStack( state->query_stack, query_id, NULL )) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Infinite recursion detected; query # %d is nested within itself", query_id )); state->error = 1; return NULL; } else push_id( &state->query_stack, query_id, NULL ); StoredQ* sq = NULL; dbi_result result = dbi_conn_queryf( state->dbhandle, "SELECT id, type, use_all, use_distinct, from_clause, where_clause, having_clause " "FROM query.stored_query WHERE id = %d;", query_id ); if( result ) { if( dbi_result_first_row( result ) ) { sq = constructStoredQ( state, result ); if( sq ) { PRINT( "Got a query row\n" ); PRINT( "\tid: %d\n", sq->id ); PRINT( "\ttype: %d\n", (int) sq->type ); PRINT( "\tuse_all: %s\n", sq->use_all ? "true" : "false" ); PRINT( "\tuse_distinct: %s\n", sq->use_distinct ? "true" : "false" ); } else osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to build a query for id = %d", query_id )); } else { sqlAddMsg( state, "Stored query not found for id %d", query_id ); } dbi_result_free( result ); } else { const char* msg; int errnum = dbi_conn_error( state->dbhandle, &msg ); osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to query query.stored_query table: #%d %s", errnum, msg ? msg : "No description available" )); } pop_id( &state->query_stack ); return sq; }
/* Connect to the MYSQL database */ static logsql_opendb_ret log_sql_dbi_connect(server_rec *s, logsql_dbconnection *db) { const char *driver = apr_table_get(db->parms,"driver"); const char *host = apr_table_get(db->parms,"hostname"); const char *user = apr_table_get(db->parms,"username"); const char *passwd = apr_table_get(db->parms,"password"); const char *database = apr_table_get(db->parms,"database"); const char *s_tcpport = apr_table_get(db->parms,"port"); unsigned int tcpport = (s_tcpport)?atoi(s_tcpport):0; const char *socketfile = apr_table_get(db->parms,"socketfile"); //dbi_result result; dbi_conn_rec *dblink = db->handle; if (!dblink) { dblink = apr_pcalloc(db->p, sizeof(*dblink)); db->handle = (void *)dblink; } dblink->conn = dbi_conn_new(driver); dbi_conn_set_option(dblink->conn, "host", host); dbi_conn_set_option(dblink->conn, "username", user); dbi_conn_set_option(dblink->conn, "password", passwd); dbi_conn_set_option(dblink->conn, "dbname", database); if (tcpport) { dbi_conn_set_option_numeric(dblink->conn, "port", tcpport); } if (socketfile && !strcmp(driver,"mysql")) { dbi_conn_set_option(dblink->conn, "mysql_unix_socket", socketfile); } if (!dbi_conn_connect(dblink->conn)) { log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "HOST: '%s' PORT: '%d' DB: '%s' USER: '******' SOCKET: '%s'", host, tcpport, database, user, socketfile); return LOGSQL_OPENDB_SUCCESS; } else { const char *error; dbi_conn_error(dblink->conn, &error); log_error(APLOG_MARK, APLOG_ERR, 0, s, "DBI Error: %s", error); log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "HOST: '%s' PORT: '%d' DB: '%s' USER: '******' SOCKET: '%s'", host, tcpport, database, user, socketfile); return LOGSQL_OPENDB_FAIL; } }
static void set_options(dbi_conn conn, const PairVec& options) { for (auto option : options) { auto opt = option.first.c_str(); auto val = option.second.c_str(); auto result = dbi_conn_set_option(conn, opt, val); if (result < 0) { const char *msg = nullptr; int err = dbi_conn_error(conn, &msg); PERR("Error setting %s option to %s: %s", opt, val, msg); throw std::runtime_error(msg); } } }
template<> void error_handler<DbType::DBI_PGSQL> (dbi_conn conn, void* user_data) { GncDbiBackend<DbType::DBI_PGSQL>* dbi_be = static_cast<decltype(dbi_be)>(user_data); const char* msg; (void)dbi_conn_error (conn, &msg); if (g_str_has_prefix (msg, "FATAL: database") && g_str_has_suffix (msg, "does not exist\n")) { PINFO ("DBI error: %s\n", msg); dbi_be->set_exists(false); } else if (g_strrstr (msg, "server closed the connection unexpectedly")) // Connection lost { if (!dbi_be->connected()) { PWARN ("DBI Error: Connection lost, connection pointer invalid"); return; } PINFO ("DBI error: %s - Reconnecting...\n", msg); dbi_be->set_dbi_error (ERR_BACKEND_CONN_LOST, 1, true); dbi_be->retry_connection(msg); } else if (g_str_has_prefix (msg, "connection pointer is NULL") || g_str_has_prefix (msg, "could not connect to server")) // No connection { if (!dbi_be->connected()) qof_backend_set_error(reinterpret_cast<QofBackend*>(dbi_be), ERR_BACKEND_CANT_CONNECT); else { dbi_be->set_dbi_error(ERR_BACKEND_CANT_CONNECT, 1, true); dbi_be->retry_connection (msg); } } else { PERR ("DBI error: %s\n", msg); if (dbi_be->connected()) dbi_be->set_dbi_error (ERR_BACKEND_MISC, 0, false); } }
static GSM_Error SMSDDBI_Query(GSM_SMSDConfig * Config, const char *query, SQL_result * res) { const char *msg; int rc; res->dbi = NULL; SMSD_Log(DEBUG_SQL, Config, "Execute SQL: %s", query); res->dbi = dbi_conn_query(Config->conn.dbi, query); if (res->dbi != NULL) return ERR_NONE; SMSD_Log(DEBUG_INFO, Config, "SQL failed: %s", query); /* Black magic to decide whether we should bail out or attempt to retry */ rc = dbi_conn_error(Config->conn.dbi, &msg); if (rc != -1) { SMSD_Log(DEBUG_INFO, Config, "SQL failure: %s", msg); if (strstr(msg, "syntax") != NULL) { return ERR_SQL; } if (strstr(msg, "violation") != NULL) { return ERR_SQL; } if (strstr(msg, "violates") != NULL) { return ERR_SQL; } if (strstr(msg, "SQL error") != NULL) { return ERR_SQL; } if (strstr(msg, "duplicate") != NULL) { return ERR_SQL; } if (strstr(msg, "unique") != NULL) { return ERR_SQL; } if (strstr(msg, "need to rewrite") != NULL) { return ERR_SQL; } if (strstr(msg, "locked") != NULL) { return ERR_DB_TIMEOUT; } } return ERR_DB_TIMEOUT; }
static SelectItem* getSelectList( BuildSQLState* state, int query_id ) { SelectItem* select_list = NULL; // The ORDER BY is in descending order so that we can build the list by adding to // the head, and it will wind up in the right order. dbi_result result = dbi_conn_queryf( state->dbhandle, "SELECT id, stored_query, seq_no, expression, column_alias, grouped_by " "FROM query.select_item WHERE stored_query = %d ORDER BY seq_no DESC", query_id ); if( result ) { if( dbi_result_first_row( result ) ) { while( 1 ) { SelectItem* item = constructSelectItem( state, result ); if( item ) { PRINT( "Found a SELECT item\n" ); PRINT( "\tid: %d\n", item->id ); PRINT( "\tstored_query_id: %d\n", item->stored_query_id ); PRINT( "\tseq_no: %d\n", item->seq_no ); PRINT( "\tcolumn_alias: %s\n", item->column_alias ? item->column_alias : "(none)" ); PRINT( "\tgrouped_by: %d\n", item->grouped_by ); item->next = select_list; select_list = item; } else { osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to build select list for query id #%d", query_id )); selectListFree( select_list ); select_list = NULL; break; } if( !dbi_result_next_row( result ) ) break; }; } } else { const char* msg; int errnum = dbi_conn_error( state->dbhandle, &msg ); osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to query query.select_list table: #%d %s", errnum, msg ? msg : "No description available" )); } return select_list; }
/** * Safely resave a database by renaming all of its tables, recreating * everything, and then dropping the backup tables only if there were * no errors. If there are errors, drop the new tables and restore the * originals. * * @param qbe: QofBackend for the session. * @param book: QofBook to be saved in the database. */ void gnc_dbi_safe_sync_all (QofBackend* qbe, QofBook* book) { GncDbiBackend* be = (GncDbiBackend*)qbe; auto conn = dynamic_cast<GncDbiSqlConnection*>(be->m_conn); g_return_if_fail (conn != nullptr); g_return_if_fail (be != nullptr); g_return_if_fail (book != nullptr); ENTER ("book=%p, primary=%p", book, be->m_book); auto table_list = conn->m_provider->get_table_list (conn->conn(), ""); if (!conn->table_operation (table_list, backup)) { qof_backend_set_error (qbe, ERR_BACKEND_SERVER_ERR); conn->table_operation (table_list, rollback); LEAVE ("Failed to rename tables"); return; } auto index_list = conn->m_provider->get_index_list (conn->m_conn); for (auto index : index_list) { const char* errmsg; conn->m_provider->drop_index (conn->m_conn, index); if (DBI_ERROR_NONE != dbi_conn_error (conn->m_conn, &errmsg)) { qof_backend_set_error (qbe, ERR_BACKEND_SERVER_ERR); conn->table_operation (table_list, rollback); LEAVE ("Failed to drop indexes %s", errmsg); return; } } gnc_sql_sync_all (be, book); if (qof_backend_check_error (qbe)) { conn->table_operation (table_list, rollback); LEAVE ("Failed to create new database tables"); return; } conn->table_operation (table_list, drop_backup); LEAVE ("book=%p", book); }
static Expression* getExpression( BuildSQLState* state, int id ) { // Check the stack to see if the current expression is nested inside itself. If it is, // then abort in order to avoid infinite recursion. If it isn't, then add it to the // stack. (Make sure to pop it off the stack before returning.) if( searchIdStack( state->expr_stack, id, NULL )) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Infinite recursion detected; expression # %d is nested within itself", id )); state->error = 1; return NULL; } else push_id( &state->expr_stack, id, NULL ); Expression* exp = NULL; dbi_result result = dbi_conn_queryf( state->dbhandle, "SELECT id, type, parenthesize, parent_expr, seq_no, literal, table_alias, " "column_name, left_operand, operator, right_operand, function_id, subquery, cast_type " "FROM query.expression WHERE id = %d;", id ); if( result ) { if( dbi_result_first_row( result ) ) { exp = constructExpression( state, result ); if( exp ) { PRINT( "Got an expression\n" ); PRINT( "\tid = %d\n", exp->id ); PRINT( "\ttype = %d\n", exp->type ); PRINT( "\tparenthesize = %d\n", exp->parenthesize ); PRINT( "\tcolumn_name = %s\n", exp->column_name ? exp->column_name : "(none)" ); } else osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to construct an Expression for id = %d", id )); } } else { const char* msg; int errnum = dbi_conn_error( state->dbhandle, &msg ); osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to query query.expression table: #%d %s", errnum, msg ? msg : "No description available" )); } pop_id( &state->expr_stack ); return exp; }
template<> StrVec GncDbiProviderImpl<DbType::DBI_SQLITE>::get_index_list (dbi_conn conn) { StrVec retval; const char* errmsg; dbi_result result = dbi_conn_query (conn, "SELECT name FROM sqlite_master WHERE type = 'index' AND name NOT LIKE 'sqlite_autoindex%'"); if (dbi_conn_error (conn, &errmsg) != DBI_ERROR_NONE) { PWARN ("Index Table Retrieval Error: %s\n", errmsg); return retval; } while (dbi_result_next_row (result) != 0) { std::string index_name {dbi_result_get_string_idx (result, 1)}; retval.push_back(index_name); } dbi_result_free (result); return retval; }
/** @brief Build a list of joined relations. @param state Pointer to the query-building context. @param id ID of the parent relation. @return A pointer to the first in a linked list of FromRelations, if there are any; or NULL if there aren't any, or in case of an error. Look for relations joined directly to the parent relation, and make a list of them. */ static FromRelation* getJoinList( BuildSQLState* state, int id ) { FromRelation* join_list = NULL; // The ORDER BY is in descending order so that we can build the list by adding to // the head, and it will wind up in the right order. dbi_result result = dbi_conn_queryf( state->dbhandle, "SELECT id, type, table_name, class_name, subquery, function_call, " "table_alias, parent_relation, seq_no, join_type, on_clause " "FROM query.from_relation WHERE parent_relation = %d ORDER BY seq_no DESC", id ); if( result ) { if( dbi_result_first_row( result ) ) { while( 1 ) { FromRelation* relation = constructFromRelation( state, result ); if( relation ) { PRINT( "Found a joined relation\n" ); PRINT( "\tjoin_type: %d\n", relation->join_type ); PRINT( "\ttable_name: %s\n", relation->table_name ); relation->next = join_list; join_list = relation; } else { osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to build join list for from relation id #%d", id )); joinListFree( join_list ); join_list = NULL; break; } if( !dbi_result_next_row( result ) ) break; }; } } else { const char* msg; int errnum = dbi_conn_error( state->dbhandle, &msg ); osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to query query.from_relation table for join list: #%d %s", errnum, msg ? msg : "No description available" )); } return join_list; }
static int _sql_setparam(struct sql_table_helper* th,char* key, char* value) { char* dbi_errstr=NULL; dbi_driver driver; /* if not connected */ if (! th->conn) { /* initialize some stuff */ th->table_next=th->table_start; th->result=NULL; th->connected=0; /* initialize db */ if (getenv("RRDDEBUGSQL")) { fprintf(stderr,"RRDDEBUGSQL: %li: initialize libDBI\n",time(NULL) ); } dbi_initialize(NULL); /* load the driver */ driver=dbi_driver_open(th->dbdriver); if (! driver) { rrd_set_error( "libdbi - no such driver: %s (possibly a dynamic link problem of the driver being linked without -ldbi)",th->dbdriver); return -1; } /* and connect to driver */ th->conn=dbi_conn_open(driver); /* and handle errors */ if (! th->conn) { rrd_set_error( "libdbi - could not open connection to driver %s",th->dbdriver); dbi_shutdown(); return -1; } } if (th->connected) { rrd_set_error( "we are already connected - can not set parameter %s=%s",key,value); _sql_close(th); return -1; } if (getenv("RRDDEBUGSQL")) { fprintf(stderr,"RRDDEBUGSQL: %li: setting option %s to %s\n",time(NULL),key,value ); } if (dbi_conn_set_option(th->conn,key,value)) { dbi_conn_error(th->conn,(const char**)&dbi_errstr); rrd_set_error( "libdbi: problems setting %s to %s - %s",key,value,dbi_errstr); _sql_close(th); return -1; } return 0; }
template<> StrVec GncDbiProviderImpl<DbType::DBI_PGSQL>::get_index_list (dbi_conn conn) { StrVec retval; const char* errmsg; PINFO ("Retrieving postgres index list\n"); auto result = dbi_conn_query (conn, "SELECT relname FROM pg_class AS a INNER JOIN pg_index AS b ON (b.indexrelid = a.oid) INNER JOIN pg_namespace AS c ON (a.relnamespace = c.oid) WHERE reltype = '0' AND indisprimary = 'f' AND nspname = 'public'"); if (dbi_conn_error (conn, &errmsg) != DBI_ERROR_NONE) { PWARN("Index Table Retrieval Error: %s\n", errmsg); return retval; } while (dbi_result_next_row (result) != 0) { std::string index_name {dbi_result_get_string_idx (result, 1)}; retval.push_back(index_name); } dbi_result_free (result); return retval; }
ENDfreeInstance BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo /* nothing special here */ ENDdbgPrintInstInfo /* log a database error with descriptive message. * We check if we have a valid database handle. If not, we simply * report an error, but can not be specific. RGerhards, 2007-01-30 */ static void reportDBError(instanceData *pData, int bSilent) { unsigned uDBErrno; char errMsg[1024]; const char *pszDbiErr; BEGINfunc ASSERT(pData != NULL); /* output log message */ errno = 0; if(pData->conn == NULL) { errmsg.LogError(0, NO_ERRCODE, "unknown DB error occured - could not obtain connection handle"); } else { /* we can ask dbi for the error description... */ uDBErrno = dbi_conn_error(pData->conn, &pszDbiErr); snprintf(errMsg, sizeof(errMsg)/sizeof(char), "db error (%d): %s\n", uDBErrno, pszDbiErr); if(bSilent || uDBErrno == pData->uLastDBErrno) dbgprintf("libdbi, DBError(silent): %s\n", errMsg); else { pData->uLastDBErrno = uDBErrno; errmsg.LogError(0, NO_ERRCODE, "%s", errMsg); } } ENDfunc }
int main() { dbi_conn conn; dbi_result result; int v; dbi_initialize(NULL); conn = dbi_conn_new("pgsql"); dbi_conn_set_option(conn, "host", "localhost"); dbi_conn_set_option(conn, "username", "mud"); dbi_conn_set_option(conn, "dbname", "mud"); if ( (v = dbi_conn_connect(conn)) < 0 ) { const char* p; dbi_conn_error(conn, &p); printf(" :: %s\n", p); return 0; } else printf("%d\n", v); result = dbi_conn_query(conn, "select * from account"); }
/* * Functions */ static const char *cdbi_strerror (dbi_conn conn, /* {{{ */ char *buffer, size_t buffer_size) { const char *msg; int status; if (conn == NULL) { sstrncpy (buffer, "connection is NULL", buffer_size); return (buffer); } msg = NULL; status = dbi_conn_error (conn, &msg); if ((status >= 0) && (msg != NULL)) ssnprintf (buffer, buffer_size, "%s (status %i)", msg, status); else ssnprintf (buffer, buffer_size, "dbi_conn_error failed with status %i", status); return (buffer); } /* }}} const char *cdbi_conn_error */
static OrderItem* getOrderByList( BuildSQLState* state, int query_id ) { OrderItem* ord_list = NULL; // The ORDER BY is in descending order so that we can build the list by adding to // the head, and it will wind up in the right order. dbi_result result = dbi_conn_queryf( state->dbhandle, "SELECT id, stored_query, seq_no, expression " "FROM query.order_by_item WHERE stored_query = %d ORDER BY seq_no DESC", query_id ); if( result ) { if( dbi_result_first_row( result ) ) { while( 1 ) { OrderItem* item = constructOrderItem( state, result ); if( item ) { PRINT( "Found an ORDER BY item\n" ); item->next = ord_list; ord_list = item; } else { osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to build ORDER BY item for query id #%d", query_id )); orderItemListFree( ord_list ); ord_list = NULL; break; } if( !dbi_result_next_row( result ) ) break; }; } } else { const char* msg; int errnum = dbi_conn_error( state->dbhandle, &msg ); osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to query query.order_by_list table: #%d %s", errnum, msg ? msg : "No description available" )); } return ord_list; }
//******************************************************************* // STORE RAW RESULTS //******************************************************************* static gint mysqlstats_store_raw_result(trx *t) { dbi_result result; struct mysqlstats_result *res = (struct mysqlstats_result *)t->res; struct probe_def *def = (struct probe_def *)t->def; char *escmsg; const char *errmsg; if (t->res->color == STAT_PURPLE) return 1; t->seen_before = FALSE; if (res->message) { dbi_conn_quote_string_copy(t->probe->db->conn, t->res->message, &escmsg); } else { escmsg = strdup(""); } result = db_query(t->probe->db, 0, "insert into pr_mysqlstats_raw (probe, yellow, red, stattime, color, selectq, insertq, " " updateq, deleteq, message) " " values ('%u', '%f', '%f', '%u', '%u', '%u', '%u', " " '%u', '%u', '%s')", def->probeid, def->yellow, def->red, res->stattime, res->color, res->selectq, res->insertq, res->updateq, res->deleteq,escmsg); g_free(escmsg); if (result) { dbi_result_free(result); return 1; // success } if (dbi_duplicate_entry(t->probe->db->conn)) { t->seen_before = TRUE; return 1; // success } if (dbi_conn_error(t->probe->db->conn, &errmsg) == DBI_ERROR_NONE) { return 1; // success } LOG(LOG_ERR, "%s", errmsg); return 0; // Failure }
static inline gboolean afsql_dd_handle_insert_row_error_depending_on_connection_availability(AFSqlDestDriver *self, LogMessage *msg, LogPathOptions *path_options) { const gchar *dbi_error, *error_message; if (dbi_conn_ping(self->dbi_ctx) == 1) { log_queue_push_head(self->queue, msg, path_options); return TRUE; } if (afsql_dd_is_transaction_handling_enabled(self)) { error_message = "SQL connection lost in the middle of a transaction," " rewinding backlog and starting again"; afsql_dd_handle_transaction_error(self); } else { error_message = "Error, no SQL connection after failed query attempt"; log_queue_push_head(self->queue, msg, path_options); } dbi_conn_error(self->dbi_ctx, &dbi_error); msg_error(error_message, evt_tag_str("type", self->type), evt_tag_str("host", self->host), evt_tag_str("port", self->port), evt_tag_str("username", self->user), evt_tag_str("database", self->database), evt_tag_str("error", dbi_error), NULL); return FALSE; }
static gboolean afsql_dd_insert_fail_handler(AFSqlDestDriver *self, LogMessage *msg, LogPathOptions *path_options) { if (self->failed_message_counter < self->num_retries - 1) { log_queue_push_head(self->queue, msg, path_options); /* database connection status sanity check after failed query */ if (dbi_conn_ping(self->dbi_ctx) != 1) { const gchar *dbi_error; dbi_conn_error(self->dbi_ctx, &dbi_error); msg_error("Error, no SQL connection after failed query attempt", evt_tag_str("type", self->type), evt_tag_str("host", self->host), evt_tag_str("port", self->port), evt_tag_str("username", self->user), evt_tag_str("database", self->database), evt_tag_str("error", dbi_error), NULL); return FALSE; } self->failed_message_counter++; return FALSE; } msg_error("Multiple failures while inserting this record into the database, message dropped", evt_tag_int("attempts", self->num_retries), NULL); stats_counter_inc(self->dropped_messages); log_msg_drop(msg, path_options); self->failed_message_counter = 0; return TRUE; }
dbi_conn open_database(const char *dbtype, const char *dbhost, const char *dbport, const char *dbname, const char *dbuser, const char *dbpasswd) { dbi_conn conn; dbi_initialize(NULL); conn = dbi_conn_new(dbtype); if ( ! conn ) { LOG(LOG_ERR, "Cannot start a connection with driver %s", dbtype); } dbi_conn_set_option(conn, "host", dbhost); dbi_conn_set_option(conn, "port", dbport); dbi_conn_set_option(conn, "username", dbuser); dbi_conn_set_option(conn, "password", dbpasswd); dbi_conn_set_option(conn, "dbname", dbname); dbi_conn_set_option(conn, "encoding", "UTF-8"); if (dbi_conn_connect(conn) < 0) { const char *errmsg; dbi_conn_error(conn, &errmsg); LOG(LOG_ERR, "%s dbhost=%s,dbport=%d,dbname=%s,dbuser=%s,dbpasswd=%s", errmsg, dbhost, dbport, dbname, dbuser, dbpasswd); return(NULL); } return(conn); }
//******************************************************************* // STORE RAW RESULTS //******************************************************************* static gint bb_cpu_store_raw_result(trx *t) { dbi_result result; struct bb_cpu_result *res = (struct bb_cpu_result *)t->res; struct probe_def *def = (struct probe_def *)t->def; char *escmsg; const char *errmsg; if (t->res->color == STAT_PURPLE) return 1; t->seen_before = FALSE; if (res->message) { dbi_conn_quote_string_copy(t->probe->db->conn, t->res->message, &escmsg); } else { escmsg = strdup(""); } result = db_query(t->probe->db, 0, "insert into pr_bb_cpu_raw (probe, stattime, color, loadavg, user, idle, free, used, message)" " values ('%u', '%u', '%u', '%f', '%u', '%u', '%u', '%u', '%s')", def->probeid, res->stattime, res->color, res->loadavg, res->user, res->idle, res->free, res->used, escmsg); g_free(escmsg); if (result) { dbi_result_free(result); return 1; // success } if (dbi_duplicate_entry(t->probe->db->conn)) { t->seen_before = TRUE; return 1; // success } if (dbi_conn_error(t->probe->db->conn, &errmsg) == DBI_ERROR_NONE) { return 1; // success } LOG(LOG_ERR, "%s", errmsg); return 0; // Failure }
void refresh_database(dbi_conn conn) { dbi_result result; char qry[1024]; sprintf(qry, "SELECT pr_mysql_def.id, pr_mysql_def.domid, pr_mysql_def.tblid, pr_realm.name, " " pr_mysql_def.ipaddress, pr_mysql_def.dbname, " " pr_mysql_def.dbuser, pr_mysql_def.dbpasswd," " pr_mysql_def.query, " " pr_mysql_def.yellow, pr_mysql_def.red " "FROM pr_mysql_def, pr_realm " "WHERE pr_mysql_def.id > 1 and pr_mysql_def.disable <> 'yes'" " and pr_mysql_def.pgroup = '%d' and pr_realm.id = pr_mysql_def.domid", (unsigned)OPT_VALUE_GROUPID); result = db_query(conn, 1, qry); if (!result) { return; } while (dbi_result_next_row(result)) { int id; struct probedef *probe; id = dbi_result_get_uint(result, "id"); probe = g_hash_table_lookup(cache, &id); if (!probe) { probe = g_malloc0(sizeof(struct probedef)); if (dbi_result_get_uint(result, "domid") > 1) { probe->probeid = dbi_result_get_uint(result, "tblid"); probe->realm=strdup(dbi_result_get_string(result, "name")); } else { probe->probeid = probe->id; } g_hash_table_insert(cache, guintdup(id), probe); } if (probe->ipaddress) g_free(probe->ipaddress); probe->ipaddress = dbi_result_get_string_copy(result, "ipaddress"); if (probe->dbname) g_free(probe->dbname); probe->dbname = dbi_result_get_string_copy(result, "dbname"); if (probe->dbuser) g_free(probe->dbuser); probe->dbuser = dbi_result_get_string_copy(result, "dbuser"); if (probe->dbpasswd) g_free(probe->dbpasswd); probe->dbpasswd = dbi_result_get_string_copy(result, "dbpasswd"); if (probe->query) g_free(probe->query); probe->query = dbi_result_get_string_copy(result, "query"); probe->yellow = dbi_result_get_float(result, "yellow"); probe->red = dbi_result_get_float(result, "red"); if (probe->msg) g_free(probe->msg); probe->msg = NULL; probe->seen = 1; } if (dbi_conn_error_flag(conn)) { const char *errmsg; dbi_conn_error(conn, &errmsg); LOG(LOG_ERR, "%s", errmsg); g_hash_table_foreach(cache, reset_seen, NULL); } else { g_hash_table_foreach_remove(cache, return_seen, NULL); } dbi_result_free(result); }
static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */ udb_query_t *q, udb_query_preparation_area_t *prep_area) { const char *statement; dbi_result res; size_t column_num; char **column_names; char **column_values; int status; size_t i; /* Macro that cleans up dynamically allocated memory and returns the * specified status. */ #define BAIL_OUT(status) \ if (column_names != NULL) { sfree (column_names[0]); sfree (column_names); } \ if (column_values != NULL) { sfree (column_values[0]); sfree (column_values); } \ if (res != NULL) { dbi_result_free (res); res = NULL; } \ return (status) column_names = NULL; column_values = NULL; statement = udb_query_get_statement (q); assert (statement != NULL); res = dbi_conn_query (db->connection, statement); if (res == NULL) { char errbuf[1024]; ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " "dbi_conn_query failed: %s", db->name, udb_query_get_name (q), cdbi_strerror (db->connection, errbuf, sizeof (errbuf))); BAIL_OUT (-1); } else /* Get the number of columns */ { unsigned int db_status; db_status = dbi_result_get_numfields (res); if (db_status == DBI_FIELD_ERROR) { char errbuf[1024]; ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " "dbi_result_get_numfields failed: %s", db->name, udb_query_get_name (q), cdbi_strerror (db->connection, errbuf, sizeof (errbuf))); BAIL_OUT (-1); } column_num = (size_t) db_status; DEBUG ("cdbi_read_database_query (%s, %s): There are %zu columns.", db->name, udb_query_get_name (q), column_num); } /* Allocate `column_names' and `column_values'. {{{ */ column_names = calloc (column_num, sizeof (*column_names)); if (column_names == NULL) { ERROR ("dbi plugin: calloc failed."); BAIL_OUT (-1); } column_names[0] = calloc (column_num, DATA_MAX_NAME_LEN); if (column_names[0] == NULL) { ERROR ("dbi plugin: calloc failed."); BAIL_OUT (-1); } for (i = 1; i < column_num; i++) column_names[i] = column_names[i - 1] + DATA_MAX_NAME_LEN; column_values = calloc (column_num, sizeof (*column_values)); if (column_values == NULL) { ERROR ("dbi plugin: calloc failed."); BAIL_OUT (-1); } column_values[0] = calloc (column_num, DATA_MAX_NAME_LEN); if (column_values[0] == NULL) { ERROR ("dbi plugin: calloc failed."); BAIL_OUT (-1); } for (i = 1; i < column_num; i++) column_values[i] = column_values[i - 1] + DATA_MAX_NAME_LEN; /* }}} */ /* Copy the field names to `column_names' */ for (i = 0; i < column_num; i++) /* {{{ */ { const char *column_name; column_name = dbi_result_get_field_name (res, (unsigned int) (i + 1)); if (column_name == NULL) { ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " "Cannot retrieve name of field %zu.", db->name, udb_query_get_name (q), i + 1); BAIL_OUT (-1); } sstrncpy (column_names[i], column_name, DATA_MAX_NAME_LEN); } /* }}} for (i = 0; i < column_num; i++) */ udb_query_prepare_result (q, prep_area, (db->host ? db->host : hostname_g), /* plugin = */ "dbi", db->name, column_names, column_num, /* interval = */ (db->interval > 0) ? db->interval : 0); /* 0 = error; 1 = success; */ status = dbi_result_first_row (res); /* {{{ */ if (status != 1) { char errbuf[1024]; ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " "dbi_result_first_row failed: %s. Maybe the statement didn't " "return any rows?", db->name, udb_query_get_name (q), cdbi_strerror (db->connection, errbuf, sizeof (errbuf))); udb_query_finish_result (q, prep_area); BAIL_OUT (-1); } /* }}} */ /* Iterate over all rows and call `udb_query_handle_result' with each list of * values. */ while (42) /* {{{ */ { status = 0; /* Copy the value of the columns to `column_values' */ for (i = 0; i < column_num; i++) /* {{{ */ { status = cdbi_result_get_field (res, (unsigned int) (i + 1), column_values[i], DATA_MAX_NAME_LEN); if (status != 0) { ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " "cdbi_result_get_field (%zu) failed.", db->name, udb_query_get_name (q), i + 1); status = -1; break; } } /* }}} for (i = 0; i < column_num; i++) */ /* If all values were copied successfully, call `udb_query_handle_result' * to dispatch the row to the daemon. */ if (status == 0) /* {{{ */ { status = udb_query_handle_result (q, prep_area, column_values); if (status != 0) { ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " "udb_query_handle_result failed.", db->name, udb_query_get_name (q)); } } /* }}} */ /* Get the next row from the database. */ status = dbi_result_next_row (res); /* {{{ */ if (status != 1) { if (dbi_conn_error (db->connection, NULL) != 0) { char errbuf[1024]; WARNING ("dbi plugin: cdbi_read_database_query (%s, %s): " "dbi_result_next_row failed: %s.", db->name, udb_query_get_name (q), cdbi_strerror (db->connection, errbuf, sizeof (errbuf))); } break; } /* }}} */ } /* }}} while (42) */ /* Tell the db query interface that we're done with this query. */ udb_query_finish_result (q, prep_area); /* Clean up and return `status = 0' (success) */ BAIL_OUT (0); #undef BAIL_OUT } /* }}} int cdbi_read_database_query */
static gboolean afsql_dd_ensure_initialized_connection(AFSqlDestDriver *self) { if (self->dbi_ctx) return TRUE; self->dbi_ctx = dbi_conn_new(self->type); if (!self->dbi_ctx) { msg_error("No such DBI driver", evt_tag_str("type", self->type), NULL); return FALSE; } dbi_conn_set_option(self->dbi_ctx, "host", self->host); if (strcmp(self->type, "mysql")) dbi_conn_set_option(self->dbi_ctx, "port", self->port); else dbi_conn_set_option_numeric(self->dbi_ctx, "port", atoi(self->port)); dbi_conn_set_option(self->dbi_ctx, "username", self->user); dbi_conn_set_option(self->dbi_ctx, "password", self->password); dbi_conn_set_option(self->dbi_ctx, "dbname", self->database); dbi_conn_set_option(self->dbi_ctx, "encoding", self->encoding); dbi_conn_set_option(self->dbi_ctx, "auto-commit", self->flags & AFSQL_DDF_EXPLICIT_COMMITS ? "false" : "true"); /* database specific hacks */ dbi_conn_set_option(self->dbi_ctx, "sqlite_dbdir", ""); dbi_conn_set_option(self->dbi_ctx, "sqlite3_dbdir", ""); /* Set user-specified options */ g_hash_table_foreach(self->dbd_options, afsql_dd_set_dbd_opt, self->dbi_ctx); g_hash_table_foreach(self->dbd_options_numeric, afsql_dd_set_dbd_opt_numeric, self->dbi_ctx); if (dbi_conn_connect(self->dbi_ctx) < 0) { const gchar *dbi_error; dbi_conn_error(self->dbi_ctx, &dbi_error); msg_error("Error establishing SQL connection", evt_tag_str("type", self->type), evt_tag_str("host", self->host), evt_tag_str("port", self->port), evt_tag_str("username", self->user), evt_tag_str("database", self->database), evt_tag_str("error", dbi_error), NULL); return FALSE; } if (self->session_statements != NULL) { GList *l; for (l = self->session_statements; l; l = l->next) { if (!afsql_dd_run_query(self, (gchar *) l->data, FALSE, NULL)) { msg_error("Error executing SQL connection statement", evt_tag_str("statement", (gchar *) l->data), NULL); return FALSE; } } } return TRUE; }
int dberror() const noexcept override { return dbi_conn_error(m_conn, nullptr); }
dbi_result _db_rawquery(const char *file, int line, database *db, int log_dupes, char *qry) { dbi_result result; const char *errmsg; int tries = 0; if (debug > 4) { LOGRAW(LOG_DEBUG, qry); } if (!dbi_conn_ping(db->conn)) { if (db->conn) dbi_conn_close(db->conn); db->conn = dbi_conn_new(db->driver); if (db->conn == NULL) { perror(db->driver); exit(1); } dbi_conn_set_option(db->conn, "host", db->host); dbi_conn_set_option(db->conn, "port", db->port); dbi_conn_set_option(db->conn, "username", db->username); dbi_conn_set_option(db->conn, "password", db->password); dbi_conn_set_option(db->conn, "dbname", db->name); retry: if (++tries == 3) exit(1); if (dbi_conn_connect(db->conn) < 0) { dbi_conn_error(db->conn, &errmsg); _logsrce = file; _logline = line; _LOG(LOG_ERR, "%s connection failed to %s:%s:%s %s", db->driver, db->host, db->port, db->name, errmsg); sleep(3); goto retry; } { char versionstring[VERSIONSTRING_LENGTH]; dbi_driver driver; driver = dbi_conn_get_driver(db->conn); dbi_conn_get_engine_version_string(db->conn, versionstring); LOG(LOG_INFO, "using driver: %s, version %s, compiled %s", dbi_driver_get_filename(driver), dbi_driver_get_version(driver), dbi_driver_get_date_compiled(driver)); LOG(LOG_INFO, "connected to %s:%s:%s, server version %s", db->host, db->port, db->name, versionstring); } } if (debug > 2) { char *src, *dst, buf[4096]; for (dst = buf, src = qry; *src; src++, dst++) { if (*src == '%') *dst++ = '%'; *dst = *src; } *dst = 0; LOG(LOG_INFO, buf); } result = dbi_conn_query(db->conn, qry); if (result == NULL) { int ret = dbi_conn_error(db->conn, &errmsg); _logsrce = file; _logline = line; _LOG(LOG_ERR, "query failed: %s (%s)", errmsg, qry); if (ret == DBI_ERROR_NOCONN) { dbi_conn_close(db->conn); db->conn = NULL; sleep(3); goto retry; } } return(result); }
static int _sql_fetchrow(struct sql_table_helper* th,time_t *timestamp, rrd_value_t *value,int ordered) { char* dbi_errstr=NULL; char sql[10240]; time_t startt=0,endt=0; /*connect to the database if needed */ if (! th->conn) { rrd_set_error( "libdbi no parameters set for libdbi",th->filename,dbi_errstr); return -1; } if (! th->connected) { /* and now connect */ if (getenv("RRDDEBUGSQL")) { fprintf(stderr,"RRDDEBUGSQL: %li: connect to DB\n",time(NULL) ); } if (dbi_conn_connect(th->conn) <0) { dbi_conn_error(th->conn,(const char**)&dbi_errstr); rrd_set_error( "libdbi: problems connecting to db with connect string %s - error: %s",th->filename,dbi_errstr); _sql_close(th); return -1; } th->connected=1; } /* now find out regarding an existing result-set */ if (! th->result) { /* return if table_next is NULL */ if (th->table_next==NULL) { if (getenv("RRDDEBUGSQL")) { fprintf(stderr,"RRDDEBUGSQL: %li: reached last table to connect to\n",time(NULL) ); } /* but first close connection */ _sql_close(th); /* and return with end of data */ return 0; } /* calculate the table to use next */ th->table_start=th->table_next; th->table_next=_find_next_separator(th->table_start,'+'); _inline_unescape(th->table_start); /* and prepare FULL SQL Statement */ if (ordered) { snprintf(sql,sizeof(sql)-1,"SELECT %s as rrd_time, %s as rrd_value FROM %s WHERE %s ORDER BY %s", th->timestamp,th->value,th->table_start,th->where,th->timestamp); } else { snprintf(sql,sizeof(sql)-1,"SELECT %s as rrd_time, %s as rrd_value FROM %s WHERE %s", th->timestamp,th->value,th->table_start,th->where); } /* and execute sql */ if (getenv("RRDDEBUGSQL")) { startt=time(NULL); fprintf(stderr,"RRDDEBUGSQL: %li: executing %s\n",startt,sql); } th->result=dbi_conn_query(th->conn,sql); if (startt) { endt=time(NULL);fprintf(stderr,"RRDDEBUGSQL: %li: timing %li\n",endt,endt-startt); } /* handle error case */ if (! th->result) { dbi_conn_error(th->conn,(const char**)&dbi_errstr); if (startt) { fprintf(stderr,"RRDDEBUGSQL: %li: error %s\n",endt,dbi_errstr); } rrd_set_error("libdbi: problems with query: %s - errormessage: %s",sql,dbi_errstr); _sql_close(th); return -1; } } /* and now fetch key and value */ if (! dbi_result_next_row(th->result)) { /* free result */ dbi_result_free(th->result); th->result=NULL; /* and call recursively - this will open the next table or close connection as a whole*/ return _sql_fetchrow(th,timestamp,value,ordered); } /* and return with flag for one value */ *timestamp=rrd_fetch_dbi_long(th->result,1); *value=rrd_fetch_dbi_double(th->result,2); return 1; }