I have recently learned MySQL and I want to implement the knowledge on how to build a C Program using MySQL database on windows. Can anyone provide me with a detailed description on which files to download and whether I need XAMPP running or not?
I have tried to read the documentation here : https://dev.mysql.com/doc/refman/8.0/en/c-api-implementations.html . However , I couldn't figure out for my life how to do it on Windows.(Seems pretty easy for Linux, unfortunately I do not have a Linux machine)
It would be great if someone would provide me with a detailed and step by step explanation. Thanks in advance.
I know how the code would look like.
#include <stdio.h>
#include <stdlib.h>
#include <my_global.h>
#include <mysql.h>
typedef struct
{
char host[20];
char user[25];
char pass[50];
}DB_CONN_PARAMS;
MYSQL * connect_db(DB_CONN_PARAMS *params)
{
MYSQL *connection = mysql_init(NULL);//init connection
if (connection == NULL)
{//check init worked
fprintf(stderr, "%s\n", mysql_error(connection));
exit(EXIT_FAILURE):
}
//connect:
if (mysql_real_connect(
connection,
params->host,
params->user,
params->pass,
NULL,0,NULL,0)
==NULL)
{//connection failed?
fprintf(stderr, "%s\n", mysql_error(connection));
mysql_close(connection);
exit(EXIT_FAILURE):
}
return connection;
}
int main()
{
MYSQL *db;
DB_CONN_PARAMS *params = calloc(1,sizeof(DB_CONN_PARAMS));
//just an alternative way of passing connection params, find a struct easier
params->host = "127.0.0.1";
params->user = "root";
params->pass = "mySuperSecretPass";
MYSQL * connect_db(DB_CONN_PARAMS *params);
db = connect_db(params);
//we don't need the struct anymore
free(params);
params = NULL;
//do stuff
mysql_close(db);//close connection, of course!
return EXIT_SUCCESS;
}
I just need help with the setup.
When I am trying to use C mysql-connector from official web-site Connector/C I got an error which is hard to resolve for a person who is just learning C.
#Here is CMakeList.txt
cmake_minimum_required(VERSION 3.10)
set(MYSQL_CONNECTOR C:/mysql-connector-c)
include_directories(${MYSQL_CONNECTOR}/include)
set(SOURCE_FILES main.c)
add_executable(untitled ${SOURCE_FILES})
target_link_libraries(untitled ${MYSQL_CONNECTOR}/lib/libmysql.lib)
#Dummy code
#include <stdio.h>
#include <mysql.h>
int main (void) {
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
char *server = "localhost";
char *user = "root";
char *password = "";
char *database = "core_loc";
/*****/
/*some dummy query*/
return 1
}
#Error
This may happen e.g. when you mix architectures between app and libs (32bit <-> 64bit). MinGW bundled with Qt is 32-bit i.e. you have to download 'mysql-connector-c-6.1.11-win32.zip' from dev.mysql.com host.
We have a C code as below. This is how we have compiled it gcc -o get1Receive $(mysql_config --cflags) get1ReceiveSource.c $(mysql_config --libs) -lrt. I works fine when we run from the terminal. Then we tried to run it using cron job and when we review this two line printf("\nNumf of fields : %d",num_fields); and printf("\nNof of row : %lu",mysql_num_rows(localRes1));. The first line shows 4 as the value and second line never give any values and is always 0. We have took the same select query and run on the db and confirm there is value but it is just not delivering when running via cron job.The script is given executable permission too.
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <time.h>
#include <signal.h>
#include <mysql.h>
#include <string.h>
int flag = 0;
int main () {
MYSQL *localConn;
MYSQL_RES *localRes1;
MYSQL_ROW localRow1;
char *server = "localhost";
char *user = "user1";
char *password = "*****";
char *database = "test1";
localConn = mysql_init(NULL);
if (!mysql_real_connect(localConn, server,
user, password, database, 0, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(localConn));
exit(1);
}
struct timeval tv;
char queryBuf1[500],queryBuf2[500];
char buff1[20] = {0};
char buff2[20] = {0};
gettimeofday (&tv, NULL);
//fprintf (stderr, "[%d.%06d] Flag set to 1 on ", tv.tv_sec, tv.tv_usec);
//tv.tv_sec -= 5;
strftime(buff1, 20, "%Y-%m-%d %H:%M:00", localtime(&tv.tv_sec));
strftime(buff2, 20, "%Y-%m-%d %H:%M:59", localtime(&tv.tv_sec));
printf("\nTime from %s", buff1);
printf("\nTime to %s", buff2);
sprintf(queryBuf1,"SELECT ipDest, macDest,portDest, sum(totalBits) FROM dataReceive WHERE timeStampID between '%s' And '%s' GROUP BY ipDest, macDest, portDest ",buff1,buff2);
printf("\nQuery receive %s",queryBuf1);
if(mysql_query(localConn, queryBuf1))
{
printf("Error in first query of select %s\n",mysql_error(localConn));
exit(1);
}
localRes1 = mysql_store_result(localConn);
int num_fields = mysql_num_fields(localRes1);
printf("\nNumf of fields : %d",num_fields);
printf("\nNof of row : %lu",mysql_num_rows(localRes1));
while((localRow1 = mysql_fetch_row(localRes1)) !=NULL)
{
int totalBits = atoi(localRow1[3]);
printf("totalBits %d\n", totalBits);
printf("RECEIVE %s,%s\n", localRow1[0], localRow1[1]);
if(totalBits>5000)
{
sprintf(queryBuf1,"INSERT INTO alertReceive1 (timeStampID,ipDest, macDest, portDest, totalBits)VALUES ('%s','%s','%s','%s',%s)",buff1, localRow1[0],localRow1[1],localRow1[2],localRow1[3]);
printf("Query 1 before executing %s\n",queryBuf1);
if (mysql_real_query(localConn,queryBuf1,strlen(queryBuf1))) {
printf("Error in first insert %s\n",mysql_error(localConn));
fprintf(stderr, "%s\n", mysql_error(localConn));
exit(1);
}
//printf("Query 1 after executing %s\n",queryBuf1);*/
}
}
mysql_free_result(localRes1);
mysql_close(localConn);
}
We have run this command file get1Receive and resulting to
file get1Receive
get1Receive.c: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
We have also run this command * * * * * set > /tmp/myvars and below is the results.
GROUPS=()
HOME=/root
HOSTNAME=capture
HOSTTYPE=x86_64
IFS='
'
LOGNAME=root
MACHTYPE=x86_64-redhat-linux-gnu
OPTERR=1
OPTIND=1
OSTYPE=linux-gnu
PATH=/usr/bin:/bin
POSIXLY_CORRECT=y
PPID=11086
PS4='+ '
PWD=/root
SHELL=/bin/sh
SHELLOPTS=braceexpand:hashall:interactive-comments:posix
SHLVL=1
TERM=dumb
UID=0
USER=root
_=/bin/sh
Generic hints (see also my comments):
Take time to read documentation notably from Advanced Linux Programming, man pages (which you can also get by typing man man or man 2 intro on the terminal, etc etc...), and MySQL 5.5 reference. Be sure to understand what GIYF or STFW means.
Put the \n at the end of printf format strings, not the beginning.
Also, call fflush(NULL) if appropriate, notably before any MySQL queries e.g. before your mysql_real_query calls, and at the end of your while loops
Compile with gcc -Wall -g e.g. with the following command in your terminal
gcc -Wall -g $(mysql_config --cflags) get1ReceiveSource.c \
$(mysql_config --libs) -lrt -o get1Receive
Improve the code till no warnings are given. (You may even want to have -Wall -Wextra instead of just -Wall). Don't forget to use a version control system like git.
use the gdb debugger (you need to learn how to use it).
(only once you are sure there is no more bugs in your code replace -g by -O2 -g in your compilation command)
use sizeof; most occurrences of 20 should be a sizeof, or at the very least use #define SMALLSIZE 20 and then only SMALLSIZE not 20.
Use snprintf not sprintf (and test its result size, which should fit!). snprintf(3) takes an extra size argument, e.g.
if (snprintf(querybuf, sizeof querybuf,
"SELECT ipDest, macDest, portDest, sum(totalBits)"
" FROM dataReceive"
" WHERE timeStampID between '%s' And '%s' "
" GROUP BY ipDest, macDest, portDest ",
buff1, buff2) >= (int) (sizeof querybuf))
abort();
consider using syslog(3) with openlog, and look into your system logs.
I don't see how is queryBuf1 declared. (Your code, as posted, probably don't even compile!). You might want something like char querybuf[512]; ...
And most importantly, calling mysql_real_query inside a mysql_fetch_row loop is wrong: you should have fetched all the rows before issuing the next MySQL query. Read more about MySQL C API.
You also forgot to test the result localRes1 of mysql_store_result(localConn); show somehow (perhaps thru syslog) the mysql_error(localConn) when localRes1 is NULL ....
hello all i have write a c program which connects to a mysql server and executes a sql query from a text file which has only one query.
#include <mysql.h>
#include <stdio.h>
main() {
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
char *server = "127.0.0.1";
char *user = "root";
char *password = "PASSWORD"; /* set me first */
char *database = "har";
conn = mysql_init(NULL);
char ch, file_name[25];
char *ch1;
FILE *fp;
printf("Enter the name of file you wish to see ");
gets(file_name);
fp = fopen(file_name,"r"); // read mode
if( fp == NULL )
{
perror("Error while opening the file.\n");
exit(0);
}
while( ( ch = fgetc(fp) ) != EOF )
printf("%c",ch);
ch1=ch;
/* Connect to database */
if (!mysql_real_connect(conn, server,
NULL , NULL, database, 0, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(0);
}
printf("%c",ch);
/* send SQL query */
if (mysql_query(conn, ch1)) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(0);
}
res = mysql_use_result(conn);
/* output table name */
printf("MySQL Tables in mysql database:\n");
while ((row = mysql_fetch_row(res)) != NULL)
printf("%s \n", row[0]);
/* close connection */
mysql_free_result(res);
mysql_close(conn);
fclose(fp);
}
i am unable to understand where i have gone wrong....
thanks in advance...
This is the line causing problem:
ch1=ch;
ch1 is a pointer to a character, whereas ch is a character.
Do you intend to store the bytes read from fp in a char array pointed by ch1? What you are doing is, every time in the while loop you are reading a character using fgetc storing it in ch and printing it.
Then, when while loop gets over, you are assigning a char to a char pointer. I am not sure what you are trying to do with this. But this definitely causes the problem.
You're going wrong in a lot of ways:
You don't declare the return type or arguments for main.
You're using gets. Never ever use gets, don't even think about. Use fgets instead.
fgetc returns an int, not a char so your ch should be an int. You won't be able to recognize EOF until you fix this.
You're declaring char ch and char *ch1 but assigning ch to ch1. That's where the error in your title is coming from.
Your code appears to be trying feed your SQL to MySQL one byte at a time and that's not going to do anything useful. I think you're meaning to use fgets to read the SQL file one line a time so that you can feed each line to MySQL as a single SQL statement.
You should spend some time reading about your compiler's warning switches
I tried to create a very simple application using the MySQL embedded server.
I basically took the simple example from the MySQL documentation and modified it a bit.
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "mysql.h"
MYSQL *mysql;
static char *server_options[] = { "mysql_test", "--datadir=/Users/admin/libmysqldtest", "--language=/Users/admin/libmysqldtest/german", NULL };
int num_elements = (sizeof(server_options) / sizeof(char *)) - 1;
static char *server_groups[] = { "libmysqld_server", "libmysqld_client", NULL };
int main(void)
{
mysql_library_init(num_elements, server_options, server_groups);
mysql = mysql_init(NULL);
mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, "libmysqld_client");
mysql_options(mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
//Do some queries here...
mysql_close(mysql);
mysql_library_end();
return 0;
}
On start-up
mysql_embedded: Unknown error 1146
is logged and InnoDB initializes.
Afterwards the app crashes at mysql_init.
Linking against libmysqld-debug I get the following error message:
Assertion failed: (argc && *argc >= 1), function handle_options, file
/Volumes/hd2/pb2/build/sb_0-3198286-1302522144.5/mysql-5.5.12/mysys/my_getopt.c, line 167
I use the static libmysqld(-debug) library distributed with the community server TAR-Archive for Mac OS X from the MySQL website (64 bit).