I work on a C tool, in which I need to manipulate and query process-internal data intensively.
Hence, I've decided to use the MySQL C API on Embedded mode, so I can have an embedded DB for each running process of my tool, and use all the SQL features on it.
All the MySQL C API tutorials I've found over the web, deal with connecting to a running server, which is not my case.
There are some examples for working with Embedded mode in Oracle's MySQL website, but they are not simple, and it's hard to make them work.
Q: Can someone please point me or write me a short example for initiating a DB using MySQL C API on Embedded mode?
Thanks!
After a lot of tries, finally answering to myself and sharing it with you:
Create a central data directory that would be used for storing DBs. In this example, I'll use /tmp/mysql_embedded_data
> mkdir /tmp/mysql_embedded_data
Create a C file, as in the following example:
#include <my_global.h>
#include <mysql.h>
int main(int argc, char **argv) {
static char *server_options[] = {
"mysql_test", // An unused string
"--datadir=/tmp/mysql_embedded_data", // Your data dir
NULL };
int num_elements = (sizeof(server_options) / sizeof(char *)) - 1;
static char *server_groups[] = { "libmysqld_server",
"libmysqld_client", NULL };
// Init MySQL lib and connection
mysql_library_init(num_elements, server_options, server_groups);
MYSQL *con = mysql_init(NULL);
if (con == NULL) {
fprintf(stderr, "%s\n", mysql_error(con));
exit(1);
}
mysql_options(con, MYSQL_READ_DEFAULT_GROUP, "libmysqld_client");
mysql_options(con, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
// Connect to no host/port -> Embedded mode
if (mysql_real_connect(con, NULL, NULL, NULL, NULL, 0, NULL, 0) == NULL) {
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(1);
}
// Create a sample empty DB, named "aNewDatabase"
if (mysql_query(con, "CREATE DATABASE aNewDatabase")) {
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(1);
}
// Close connection
mysql_close(con);
exit(0);
}
Compile your file (I assume in this example that my C filename is /tmp/mysql_try.c)
gcc /tmp/mysql_try.c -o /tmp/mysql_try -lz `mysql_config --include --libmysqld-libs`
Run your compiled program:
> /tmp/mysql_try
When your program returnes, ensure that the DB creation succeeded. We named our sample DB aNewDatabase, so we'll check if it now has a directory inside the data directory we created -> We'll check if the directory /tmp/mysql_embedded_data/aNewDatabase was created:
> ls /tmp/mysql_embedded_data/aNewDatabase
db.opt
Enjoy!
Related
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.
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 ....
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to make #include <mysql.h> work?
I need to connect C and mysql
This is my program
#include <stdio.h>
#include <mysql.h>
#define host "localhost"
#define username "root"
#define password "viswa"
#define database "dbase"
MYSQL *conn;
int main()
{
MYSQL_RES *res_set;
MYSQL_ROW row;
conn = mysql_init(NULL);
if( conn == NULL )
{ `
printf("Failed to initate MySQL\n");
return 1;
}
if( ! mysql_real_connect(conn,host,username,password,database,0,NULL,0) )
{
printf( "Error connecting to database: %s\n", mysql_error(conn));
return 1;
}
unsigned int i;
mysql_query(conn,"SELECT name, email, password FROM users");
res_set = mysql_store_result(conn);
unsigned int numrows = mysql_num_rows(res_set);
unsigned int num_fields = mysql_num_fields(res_set);
while ((row = mysql_fetch_row(res_set)) != NULL)
{
for(i = 0; i < num_fields; i++)
{
printf("%s\t", row[i] ? row[i] : "NULL");
}
printf("\n");
}
mysql_close(conn);
return 0;
}
I got the error "unable to include mysql.h".
I am using windows 7, Turbo C, mysql and I downloaded mysql-connector-c-noinstall-6.0.2-win32-vs2005, but I don't know how to include it.
Wrong syntax. The #include is a C preprocessor directive, not a statement (so should not end with a semi-colon). You should use
#include <mysql.h>
and you may need instead to have
#include <mysql/mysql.h>
or to pass -I /some/dir options to your compiler (with /some/dir replaced by the directory containing the mysql.h header).
Likewise, your #define should very probably not be ended with a semi-colon, you may need
#define username "root"
#define password "viswa"
#define database "dbase"
I strongly suggest reading a good book on C programming. You may want to examine the preprocessed form of your source code; when using gcc you could invoke it as gcc -C -E
yoursource.c to get the preprocessed form.
I also strongly recommend enabling warnings and debugging info (e.g. gcc -Wall -g for GCC). Find out how your specific compiler should be used. Learn also how to use your debugger (e.g. gdb). Study also existing C programs (notably free software).
You should learn how to configure your compiler to use extra include directories, and to link extra libraries.
N.B. With a linux distribution, you'll just have to install the appropriate packages and perhaps use mysql_config inside our Makefile (of course you'll need appropriate compiler and linker flags), perhaps with lines like
CFLAGS += -g -Wall $(shell mysql_config --cflags)
LIBES += $(shell mysql_config --libs)
added to your Makefile.
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).