mysteries of : mysql_fetch_row(res) - mysql

If we know there are 3 results. Can we replace the while loop below:
res = mysql_use_result(co);
row = mysql_fetch_row(res);
while ((row = mysql_fetch_row(res)) != NULL)
printf("%s \n", row[0]);
With the following code?:
row = mysql_fetch_row(res)
printf("%s \n", row[0]);
row = mysql_fetch_row(res)
printf("%s \n", row[0]);
row = mysql_fetch_row(res)
printf("%s \n", row[0]);
How does it know which result to fetch?

It keeps track of an index in the result data structure. When you call fetch_row, it will return the next row, then increase the index by 1. Once there are no more rows that can be returned, it will return null (which is what terminates the while loop in the first case).

Related

Csv conversion with go

I am still a noob at golang, but I will try to explain what I want to create.
I have this:
I want to convert this same table into a csv file like
This is the code I have:
func maakCSVBestand() {
rapportage := haalRapportage()
opdrachten := rapportage.Opdrachten
csvFile, err := os.Create("Rapportage Urenverantwoording.csv")
if err != nil {
fmt.Println(err)
}
defer csvFile.Close()
writer := csv.NewWriter(csvFile)
writer.Comma = ';'
writer.Write([]string{"Datum", "Naam", "Aantal uren gewerkt", "Aantal deuren gemaakt", "Informatie"})
for i := 0; i < len(opdrachten); i++ {
var row []string
persoon := opdrachten[i].Persoon
row = append(row, opdrachten[i].Datum.String())
for j := 0; j < len(persoon); j++ {
row = append(row, persoon[j].Naam+" "+persoon[j].Achternaam)
row = append(row, strconv.FormatFloat(persoon[j].UrenGewerkt, 'g', 2, 64))
row = append(row, strconv.Itoa(persoon[j].AantalDeurenGemaakt))
row = append(row, persoon[j].Informatie)
}
writer.Write(row)
}
writer.Flush()
}
But this creates
What am i doing wrong?
Write one row for each iteration of the inner loop. Clear the first column after the first iteration:
for i := 0; i < len(opdrachten); i++ {
var row []string
persoon := opdrachten[i].Persoon
row = append(row, opdrachten[i].Datum.String())
for j := 0; j < len(persoon); j++ {
row = append(row, persoon[j].Naam+" "+persoon[j].Achternaam)
row = append(row, strconv.FormatFloat(persoon[j].UrenGewerkt, 'g', 2, 64))
row = append(row, strconv.Itoa(persoon[j].AantalDeurenGemaakt))
row = append(row, persoon[j].Informatie)
writer.Write(row)
row[0] = "" // clear Datum field
row = row[1:] // collect new values after blank datum
}
}

Storing data from mysql

I need an advice from community. I need to store somewhere data from mysql so later I could compare data. I tried to put everything to struct, but I realized that struct was gone after loop, and that i cannot create that struct name would be variable. Like this:
struct Columns (variable);
So basically I need to store columns information like field, type, key etc.. I don't know how much there will be tables.
My struct:
struct Columns {
char field[1000];
char type[50];
char null[10];
char key[20];
char defaul[50];
char extra[50];
};
Code part:
if (mysql_query(conn, "Show tables;")){
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
res = mysql_store_result(conn);
printf("MySQL Tables in mysql database:\n");
while ((row = mysql_fetch_row(res)) != NULL){
printf("%s\n", row[0]);
sprintf(str, "Show columns from %s;", row[0]); //row[0]-is table names
sprintf(str1, "lentele_%s", row[0]);
printf("%s\n", str1);
struct Columns str1;
if (mysql_query(conn, str)){
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
res2 = mysql_use_result(conn);
while ((row2 = mysql_fetch_row(res2)) != NULL){
strcpy(str1.field, row2[0]);
printf("Belekas Column field %s\n", str1.field);
}
There are 6 columns on each table: field || type || null || key || default || extra
As I said, i will need that data for later comparison.

How can I get a variable in C to be used in a MySQL Query

I have a temperature sensor hooked up to a Raspberry Pi, I am able to read and printf the temperature. What I am trying to do next is to get the values from the sensor and have them get logged into a MySQL database.
Everything works, except, I can not figure out how to format the MySQL insert Query to use the f variable and the h variable that is generated by the read_dht_data() function and pass it to the MIA_temp_insert(float f, float h).
#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>
#include <wiringPi.h>
#include <stdint.h>
#define MAX_TIMINGS 85
#define DHT_PIN 3 /* GPIO-22 */
int data[5] = { 0, 0, 0, 0, 0 };
float temp_f;
static char *host = "XXX.XXX.XXX.XXX";
static char *user = "XXX";
static char *password = "XXX";
static char *dbname = "XXX";
unsigned int port = 3306;
static char *unix_socket = NULL;
unsigned int flag = 0;
static MYSQL *conn; //Needed to be static so all of the functions can draw from it
void MIA_mysql_connection()
{
// Connecting to the Database
conn = mysql_init(NULL);
if (!(mysql_real_connect(conn, host, user, password, dbname, port, unix_socket, flag)))
{
fprintf(stderr, "\n Error: %s [%d] \n", mysql_error(conn),mysql_errno(conn));
exit (1);
}
//Connected
printf ("We Are Connected \n");
}
void MIA_mysql_close()
{
//Closing Connection
mysql_close(conn);
}
void MIA_temp_insert(float f, float h)
{
//Inserting into MySQL Table
if(mysql_query(conn, "INSERT INTO `temperature` (`id`, `Date`,`Time`, `Temperature`, `Humidity`) VALUES (NULL, CURRENT_DATE(), CURRENT_TIME(), '%f' , '%f')") !=0)
{
fprintf(stderr, "%s\n", mysql_error(conn));
exit (-1);
} else {
printf("Rows were insert \n");
}
}
void read_dht_data()
{
uint8_t laststate = HIGH;
uint8_t counter = 0;
uint8_t j = 0, i;
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
/* pull pin down for 18 milliseconds */
pinMode( DHT_PIN, OUTPUT );
digitalWrite( DHT_PIN, LOW );
delay( 18 );
/* prepare to read the pin */
pinMode( DHT_PIN, INPUT );
/* detect change and read data */
for ( i = 0; i < MAX_TIMINGS; i++ )
{
counter = 0;
while ( digitalRead( DHT_PIN ) == laststate )
{
counter++;
delayMicroseconds( 1 );
if ( counter == 255 )
{
break;
}
}
laststate = digitalRead( DHT_PIN );
if ( counter == 255 )
break;
/* ignore first 3 transitions */
if ( (i >= 4) && (i % 2 == 0) )
{
/* shove each bit into the storage bytes */
data[j / 8] <<= 1;
if ( counter > 16 )
data[j / 8] |= 1;
j++;
}
}
/*
* check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
* print it out if data is good
*/
if ( (j >= 40) &&
(data[4] == ( (data[0] + data[1] + data[2] + data[3]) & 0xFF) ) )
{
float h = (float)((data[0] << 8) + data[1]) / 10;
if ( h > 100 )
{
h = data[0]; // for DHT11
}
float c = (float)(((data[2] & 0x7F) << 8) + data[3]) / 10;
if ( c > 125 )
{
c = data[2]; // for DHT11
}
if ( data[2] & 0x80 )
{
c = -c;
}
float f = c * 1.8f + 32;
//printf( "Humidity = %.1f %% Temperature = %.1f *C (%.1f *F)\n", h, c, f );
printf ("Temp of the room is : %.1f \n",f);
//Insert Data into MIA Temperature Table
MIA_temp_insert(10.0,11.1);
}else {
//printf( "Data not good, skip\n" );
}
}
int main ()
{
printf( "Raspberry Pi DHT11/DHT22 temperature/humidity test\n" );
if ( wiringPiSetup() == -1 )
exit( 1 );
while ( 1 )
{
MIA_mysql_connection();
read_dht_data();
delay (1000);
MIA_mysql_close();
printf("End of program \n");
}
return(0);
}
You cannot use printf()-style format specifiers in mysql_query() directly as you have above. Instead, you can use sprintf() or snprintf() to write the format string -- with the formatted numbers instead of format specifiers -- into a buffer... then pass that as your query string.
So in MIA_temp_insert(), instead of the following:
if(mysql_query(conn, "INSERT INTO `temperature` (`id`, `Date`,`Time`, `Temperature`, `Humidity`) VALUES (NULL, CURRENT_DATE(), CURRENT_TIME(), '%f' , '%f')") !=0)
{
fprintf(stderr, "%s\n", mysql_error(conn));
exit (-1);
/* ...etc... */
...you could try this:
/* Your original query string, with the %f specifiers */
const char *formatstring = "INSERT INTO `temperature` (`id`, `Date`,`Time`, `Temperature`, `Humidity`) VALUES (NULL, CURRENT_DATE(), CURRENT_TIME(), '%f' , '%f')";
/* snprintf() the query into a buffer, to fill in the numbers */
char buf[256]; // should be large enough for the query with the numbers filled in
if (snprintf(buf, sizeof(buf), formatstring, f, h) >= sizeof(buf))
{
exit(-1); // if snprintf() returned sizeof(buf) or more, buf was too short
}
/* call mysql_query() with the formatted query from the buffer */
if (mysql_query(conn, buf) != 0)
{
fprintf(stderr, "%s\n", mysql_error(conn));
exit (-1);
/* ...etc... */

MySQL C API: check if a field exists

I'm new to mysql programming on c. I need to check if a certain user exists in a table. How can I do this using the C API?
Here's what I've got, but it isn't working:
if (mysql_query(con, "SELECT * FROM Users WHERE UserName='user3'"))
{
finish_with_error(con);
}
MYSQL_RES *result = mysql_store_result(con);
if (result == NULL)
{
finish_with_error(con);
}
int count = mysql_field_count(con);
printf("%d\n", count );
For anyone interested, this is something I wrote using the comments, and finally ended up using.
if (mysql_query(con, "SELECT field FROM table WHERE userName='user1'"))
{
finish_with_error(con);
}
MYSQL_RES *result = mysql_store_result(con);
if (result == NULL)
{
finish_with_error(con);
}
MYSQL_ROW row;
MYSQL_FIELD *field;
if (row = mysql_fetch_row(result))
{
printf("%s\n", row[0]);
db_pwd = row[0];
}

How to separate result values in different rows using Mysql query

I created this table (results) in my sql database (test)
CREATE DATABASE `test`;
USE `test`;
CREATE TABLE `results` (
`number` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`id_machine` int(10) unsigned NOT NULL,
`value` float NOT NULL,
`datetime` datetime NOT NULL,
PRIMARY KEY (`number`),
UNIQUE KEY `indice_UNIQUE` (`number`)
) ENGINE=InnoDB AUTO_INCREMENT=100;
My external device gives me these results:
+DATA: 43 BYTES FROM 0000:0000 (045)
Machine_8: (T=22.22, HR=42.56, Dw=8.95, VCC=3.64V)
and with the usage of strtok I get some values of these results to save them in the database:
Results: 8, 22.22, 42.56, 8.95, 3.64
I would like to save my data in my table in this way:
101, 8, 22.22, 2013-06-05 14:03:00
102, 8, 42.56, 2013-06-05 14:03:00
103, 8, 8.95, 2013-06-05 14:03:00
104, 8, 3.64, 2013-06-05 14:03:00
This is my code in my function until now
int learn_port2(int fd)
{
MYSQL *conn;
MYSQL_RES *res;
MYSQL_RES *res1;
MYSQL_ROW row;
char *server = "127.0.0.1";
char *user = "root";
char *password = "***"; // got tot keep my data secret
char *database = "test";
conn = mysql_init(NULL);
if(!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0))
{
fprintf(stderr, "%s\n", mysql_error(conn));
return -1;
//finish_with_error(conn);
}
int n, i;
char buff[300];
memset(buff, 0, sizeof(buff));
for (int x = 0; x<1; x++)
//for (;;)
{
char id_machine[35] = "";
char temp[35] = "";
char hum[35] = "";
char dw[35] = "";
char vol[45] = "";
char* ptr;
int i,nodo,nodo1;
float temp, hum, dw, vcc;
n=read(fd,buff,sizeof(buff));
sleep(1);
printf("%s", buff);
printf("\n");
if (buff[37] == 'N' || buff[38] == 'N' || buff[39] == 'N' || buff[40] == 'N' )
{
ptr = strtok(buff, "Machine_,=T:HR:DW:Vcc()");
i = 0;
while (ptr != NULL)
{
if (i == 9)
strcat(id_machine, ptr); // copies Nodo
if (i == 10)
strcat(temp, ptr); // copies T
if (i == 11)
strcat(hum, ptr); // copies HR
if (i == 13)
strcat(dw, ptr); // copies DW
if (i == 15)
strcat(vol, ptr); // copies Vcc
ptr = strtok(NULL, "Machine_,=T:HR:DW:Vcc()");
i++;
}
printf("Results: %s, %s, %s, %s, %s\n", id_machine, temp, hum, dw, vol);
}
char query[]="INSERT INTO results(`id_machine`,`value`,`valor`) VALUES(id_machine,'14',value)";
if(mysql_query(conn, query))
{
fprintf(stderr, "%s\n", mysql_error(conn));
return -1;
}
res = mysql_use_result(conn);
}
}
How can I modify the char query[] to have the results which I want? Or if there are some examples like this.
To make a parameterized query you could use something like the following...
The example uses vsnprintf() to take a printf like format string and a variable number of arguments after it to print the query into a temporary buffer and then pass the buffer to the MYSQL query. In this way you can get a paramaterized query...
vsnprintf() accepts a variable parameter list, va_list and also is buffer-overflow safe.
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#define BUFSTRLEN 255
/* Returns -1 if the internal buffer was not large enough to hold the formatted
* string, or a format error occurred. If neither condition occurred then the
* result of the MYSQL query is returned... */
int DoMysqlQuery(MYSQL *conn, char const *printfstring, ...)
{
int len;
va_list args;
char buffer[BUFSTRLEN + 1];
memset(buffer, '\0', sizeof(buffer));
va_start(args, printfstring);
len = vsnprintf(buffer, BUFSTRLEN, printfstring, args);
va_end(args);
/* Did the buffer print work ? */
if( len < 0 || len >= BUFSTRLEN + 1 )
return -1;
return mysql_query(conn, buffer);
}
int main(int argc, char const *argv[])
{
int result;
MYSQL mysqlConn = ...;
/* Example stuff to send to the function.... */
char *id_machine= "8";
char *value= "1234";
char *valor= "1";
/* Send the query */
result = DoMysqlQuery(
&mysqlConn,
"INSERT INTO results(`id_machine`,`value`,`valor`) VALUES(%s,'%s',%s);",
id_machine, value, valor);
if( result )
{
/* handle error etc... *.
}
}
In this example, the query string that will be sent to mysql_query() is:
INSERT INTO results(id_machine,value,valor) VALUES(8,'1234',1);
Hope this helps :)