/************************************************************************* * * Function: sql_finish_query * * Purpose: As a single SQL statement may return multiple results * sets, (for example stored procedures) it is necessary to check * whether more results exist and process them in turn if so. * *************************************************************************/ static int sql_finish_query(rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t *config) { #if (MYSQL_VERSION_ID >= 40100) rlm_sql_mysql_conn_t *conn = handle->conn; int status; skip_next_result: status = sql_store_result(handle, config); if (status != 0) { return status; } else if (conn->result != NULL) { radlog(L_DBG, "rlm_sql_mysql: SQL statement returned unexpected result"); sql_free_result(handle, config); } status = mysql_next_result(conn->sock); if (status == 0) { /* there are more results */ goto skip_next_result; } else if (status > 0) { radlog(L_ERR, "rlm_sql_mysql: Cannot get next result"); radlog(L_ERR, "rlm_sql_mysql: MySQL error '%s'", mysql_error(conn->sock)); return sql_check_error(status); } #endif return 0; }
/************************************************************************* * * Function: sql_finish_query * * Purpose: As a single SQL statement may return multiple results * sets, (for example stored procedures) it is necessary to check * whether more results exist and process them in turn if so. * *************************************************************************/ static int sql_finish_query(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) { #if (MYSQL_VERSION_ID >= 40100) rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn; int status; skip_next_result: status = sql_store_result(sqlsocket, config); if (status != 0) { return status; } else if (mysql_sock->result != NULL) { radlog(L_DBG, "rlm_sql_mysql: SQL statement returned unexpected result"); sql_free_result(sqlsocket, config); } status = mysql_next_result(mysql_sock->sock); if (status == 0) { /* there are more results */ goto skip_next_result; } else if (status > 0) { radlog(L_ERR, "rlm_sql_mysql: Cannot get next result"); radlog(L_ERR, "rlm_sql_mysql: MySQL error '%s'", mysql_error(mysql_sock->sock)); return sql_check_error(status); } #endif return 0; }
int get_users(const char *where, struct user **users, size_t *ucount){ if(!instance_exist()){ return DBE_NOINSTANCE; } size_t _t = 200 + strlen(where); char sql[_t]; sprintf(sql, "select * from user %s", where); int flag = sql_query(mysql, sql); if(flag>0){ return DBE_STATEMENT; } MYSQL_RES *result = sql_store_result(mysql); if(result == NULL){ return DBE_RESULT; } my_ulonglong item_count = mysql_num_rows(result); if(item_count<=0){ *ucount = 0; return 1; } size_t user_il = sizeof(struct user); *users = (struct user *)malloc(item_count*user_il); struct user _u; MYSQL_ROW row; int i=0; while((row = mysql_fetch_row(result))){ memset(&_u, '\0', user_il); _u.id = atoi(row[0]); strncpy(_u.account, row[1], sizeof(_u.account)-1); strncpy(_u.pwd, row[2], sizeof(_u.pwd)-1); strncpy(_u.name, row[3], sizeof(_u.name)-1); strncpy(_u.avatar, row[4], sizeof(_u.avatar)-1); getAvatarFull( _u.avatar ); memcpy(*users+i, &_u, user_il); i++; } *ucount = i; return 1; }
/************************************************************************* * * Function: sql_query * * Purpose: Issue a query to the database * *************************************************************************/ static int sql_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr) { rlm_sql_postgres_sock *pg_sock = sqlsocket->conn; if (config->sqltrace) radlog(L_DBG,"rlm_sql_postgresql: query:\n%s", querystr); if (pg_sock->conn == NULL) { radlog(L_ERR, "rlm_sql_postgresql: Socket not connected"); return SQL_DOWN; } pg_sock->result = PQexec(pg_sock->conn, querystr); /* Returns a result pointer or possibly a NULL pointer. * A non-NULL pointer will generally be returned except in * out-of-memory conditions or serious errors such as inability * to send the command to the backend. If a NULL is returned, * it should be treated like a PGRES_FATAL_ERROR result. * Use PQerrorMessage to get more information about the error. */ if (!pg_sock->result) { radlog(L_ERR, "rlm_sql_postgresql: PostgreSQL Query failed Error: %s", PQerrorMessage(pg_sock->conn)); return SQL_DOWN; } else { ExecStatusType status = PQresultStatus(pg_sock->result); radlog(L_DBG, "rlm_sql_postgresql: Status: %s", PQresStatus(status)); radlog(L_DBG, "rlm_sql_postgresql: affected rows = %s", PQcmdTuples(pg_sock->result)); if (!status_is_ok(status)) return sql_check_error(status); if (strncasecmp("select", querystr, 6) != 0) { /* store the number of affected rows because the sql module * calls finish_query before it retrieves the number of affected * rows from the driver */ pg_sock->affected_rows = affected_rows(pg_sock->result); return 0; } else { if ((sql_store_result(sqlsocket, config) == 0) && (sql_num_fields(sqlsocket, config) >= 0)) return 0; else return -1; } } }
/************************************************************************* * * Function: sql_num_fields * * Purpose: database specific num_fields function. Returns number * of columns from query * *************************************************************************/ static int sql_num_fields(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) { int num = 0; rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn; #if MYSQL_VERSION_ID >= 32224 if (!(num = mysql_field_count(mysql_sock->sock))) { #else if (!(num = mysql_num_fields(mysql_sock->sock))) { #endif radlog(L_ERR, "rlm_sql_mysql: MYSQL Error: No Fields"); radlog(L_ERR, "rlm_sql_mysql: MYSQL error: %s", mysql_error(mysql_sock->sock)); } return num; } /************************************************************************* * * Function: sql_select_query * * Purpose: Issue a select query to the database * *************************************************************************/ static int sql_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querystr) { int ret; ret = sql_query(sqlsocket, config, querystr); if(ret) return ret; ret = sql_store_result(sqlsocket, config); if (ret) { return ret; } /* Why? Per http://www.mysql.com/doc/n/o/node_591.html, * this cannot return an error. Perhaps just to complain if no * fields are found? */ sql_num_fields(sqlsocket, config); return ret; }
/************************************************************************* * * Function: sql_num_fields * * Purpose: database specific num_fields function. Returns number * of columns from query * *************************************************************************/ static int sql_num_fields(rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t *config) { int num = 0; rlm_sql_mysql_conn_t *conn = handle->conn; #if MYSQL_VERSION_ID >= 32224 if (!(num = mysql_field_count(conn->sock))) { #else if (!(num = mysql_num_fields(conn->sock))) { #endif ERROR("rlm_sql_mysql: MYSQL Error: No Fields"); ERROR("rlm_sql_mysql: MYSQL error: %s", mysql_error(conn->sock)); } return num; } /************************************************************************* * * Function: sql_select_query * * Purpose: Issue a select query to the database * *************************************************************************/ static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config, char const *query) { int ret; ret = sql_query(handle, config, query); if(ret) return ret; ret = sql_store_result(handle, config); if (ret) { return ret; } /* Why? Per http://www.mysql.com/doc/n/o/node_591.html, * this cannot return an error. Perhaps just to complain if no * fields are found? */ sql_num_fields(handle, config); return ret; }
/************************************************************************* * * Function: sql_fetch_row * * Purpose: database specific fetch_row. Returns a SQL_ROW struct * with all the data for the query in 'sqlsocket->row'. Returns * 0 on success, -1 on failure, SQL_DOWN if database is down. * *************************************************************************/ static int sql_fetch_row(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) { rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn; int status; /* * Check pointer before de-referencing it. */ if (!mysql_sock->result) { return SQL_DOWN; } retry_fetch_row: sqlsocket->row = mysql_fetch_row(mysql_sock->result); if (sqlsocket->row == NULL) { status = sql_check_error(mysql_errno(mysql_sock->sock)); if (status != 0) { radlog(L_ERR, "rlm_sql_mysql: Cannot fetch row"); radlog(L_ERR, "rlm_sql_mysql: MySQL error '%s'", mysql_error(mysql_sock->sock)); return status; } #if (MYSQL_VERSION_ID >= 40100) sql_free_result(sqlsocket, config); status = mysql_next_result(mysql_sock->sock); if (status == 0) { /* there are more results */ if ((sql_store_result(sqlsocket, config) == 0) && (mysql_sock->result != NULL)) goto retry_fetch_row; } else if (status > 0) { radlog(L_ERR, "rlm_sql_mysql: Cannot get next result"); radlog(L_ERR, "rlm_sql_mysql: MySQL error '%s'", mysql_error(mysql_sock->sock)); return sql_check_error(status); } #endif } return 0; }
/************************************************************************* * * Function: sql_fetch_row * * Purpose: database specific fetch_row. Returns a rlm_sql_row_t struct * with all the data for the query in 'handle->row'. Returns * 0 on success, -1 on failure, SQL_DOWN if database is down. * *************************************************************************/ static int sql_fetch_row(rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t *config) { rlm_sql_mysql_conn_t *conn = handle->conn; int status; /* * Check pointer before de-referencing it. */ if (!conn->result) { return SQL_DOWN; } retry_fetch_row: handle->row = mysql_fetch_row(conn->result); if (handle->row == NULL) { status = sql_check_error(mysql_errno(conn->sock)); if (status != 0) { radlog(L_ERR, "rlm_sql_mysql: Cannot fetch row"); radlog(L_ERR, "rlm_sql_mysql: MySQL error '%s'", mysql_error(conn->sock)); return status; } #if (MYSQL_VERSION_ID >= 40100) sql_free_result(handle, config); status = mysql_next_result(conn->sock); if (status == 0) { /* there are more results */ if ((sql_store_result(handle, config) == 0) && (conn->result != NULL)) goto retry_fetch_row; } else if (status > 0) { radlog(L_ERR, "rlm_sql_mysql: Cannot get next result"); radlog(L_ERR, "rlm_sql_mysql: MySQL error '%s'", mysql_error(conn->sock)); return sql_check_error(status); } #endif } return 0; }
int get_user(int id, struct user *_u) { if(!instance_exist()){ return DBE_NOINSTANCE; } size_t _t = 200; char sql[_t]; sprintf(sql, "select * from user where id=%d", id); int flag = sql_query(mysql, sql); if(flag>0){ return DBE_STATEMENT; } MYSQL_RES *result = sql_store_result(mysql); if(result == NULL){ return DBE_RESULT; } my_ulonglong count = mysql_num_rows(result); if(count==0){ return 0; } MYSQL_ROW row = mysql_fetch_row(result); _u->id = atoi(row[0]); strncpy(_u->account, row[1], sizeof(_u->account)); strncpy(_u->pwd, row[2], sizeof(_u->pwd)); strncpy(_u->name, row[3], sizeof(_u->name)); strncpy(_u->avatar, row[4], sizeof(_u->avatar)); getAvatarFull( _u->avatar ); return 1; }