Using mysql in c programming - mysql

I installed ubuntu on a virtual machine. There, I installed mysql server sudo apt-get install mysql-server .This worked, because I could acces mysql-u root -p password
After that, I did : sudo apt-get install libmysqlclient-dev
#include <my_global.h>
#include <mysql.h>
int main(int argc, char **argv)
{
printf("MySQL client version: %s\n", mysql_get_client_info());
exit(0);
}
When I compile this with
gcc version.c -o version `mysql_config --cflags --libs`
it works.
But when I compile this one from below
gcc createdb.c -o createdb -std=c99 `mysql_config --cflags --libs`
I get some errors.
#include <my_global.h>
#include <mysql.h>
int main(int argc, char **argv)
{
MYSQL *con = mysql_init(NULL);
if (con == NULL)
{
fprintf(stderr, "%s\n", mysql_error(con));
exit(1);
}
if (mysql_real_connect(con, "localhost", "root", "root_pswd",
NULL, 0, NULL, 0) == NULL)
{
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(1);
}
if (mysql_query(con, "CREATE DATABASE testdb"))
{
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(1);
}
mysql_close(con);
exit(0);
}
Errors:
"Usage:: No such file or directory
[OPTIONS]: No such file or directory
Options:: No such file or directory
[-I/usr/include/mysql: No such file or directory
[-L/user/lib/x86_64-linux-gnu: No such file or directory
.
.
.
unrecognized command line option '--cflags'
unrecognized command line option '--libs'
.
.
unrecognized command line option '--socket'
unrecognized command line option '--port' "
Can someone explain me what I did wrong,and how to fix it?
I just want to get some data from tables in a C program.

I suspect you actually ran
gcc createdb.c -o createdb -std=c99 `mysql_config` --cflags --libs
rather than
gcc createdb.c -o createdb -std=c99 `mysql_config --cflags --libs`
That’s not going to work; mysql_config, if it doesn’t get any arguments, is going to print out a bunch of usage instructions, which will be passed to gcc, and then you’ll follow that with --cflags --libs, which gcc also doesn’t understand. gcc is severely confused and complains.
If you make sure those arguments get to mysql_config rather than gcc, everyone will be happy.

Related

mysql.h compile, but not its functions

I am trying to see how to embed sql code in a C program, but I have an issue I am not able to understand when I compile this code :
#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>
MYSQL *mysql;
MYSQL_RES *results;
MYSQL_ROW record;
int main() {
mysql = mysql_init(NULL);
if (mysql == NULL) {
fprintf(stderr, "%s\n", mysql_error(mysql));
return 1;
}
if (mysql_real_connect(mysql, "localhost", "root", "PassWord",
NULL, 0, NULL, 0) == NULL) {
fprintf(stderr, "%s\n", mysql_error(mysql));
mysql_close(mysql);
return 1;
}
mysql_query(mysql, "SHOW DATABASES");
return 0;
}
this is what the compiler tell me when I compile it :
clang++ -g -c testSql.cc
clang++ testSql.o -o testSql
/usr/bin/ld: testSql.o: in function `main':
/home/antoine/Documenti/L3/Information Management II/code/testSql.cc:12: undefined reference to `mysql_init'
/usr/bin/ld: /home/antoine/Documenti/L3/Information Management II/code/testSql.cc:15: undefined reference to `mysql_error'
/usr/bin/ld: /home/antoine/Documenti/L3/Information Management II/code/testSql.cc:19: undefined reference to `mysql_real_connect'
/usr/bin/ld: /home/antoine/Documenti/L3/Information Management II/code/testSql.cc:21: undefined reference to `mysql_error'
/usr/bin/ld: /home/antoine/Documenti/L3/Information Management II/code/testSql.cc:22: undefined reference to `mysql_close'
/usr/bin/ld: /home/antoine/Documenti/L3/Information Management II/code/testSql.cc:26: undefined reference to `mysql_query'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Makefile:25: testSql] Errore 1
I have check in the mysql.h file, those function are implemented, so I do not understand why I have this "undifined reference" error, do any onehave an idea on the origin of this error ?
Thank you all for the answer. I had to provide a linker in my compilation.
I am now compiling with
clang++ -g -c testSql.cc
clang++ testSql.o -o testSql `mysql_config --cflags --libs`
instead of
clang++ -g -c testSql.cc
clang++ testSql.o -o testSql
and it compile correctly.
Thank you !

cannot link to static mysqlclient library, though shared library works

I have a sample program to familiarize myself with mysqlclient APIs. However when I compile and link it to the mysqlclient library statically (.a file), the linker complains it cannot find the file, although it exists in my path. Linking to the shared library (.dylib file on my Mac) works.
Please help me get my head around this behaviour. Much appreciated!
Here's my driver program client.c that calls mysqlclient library.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <mysql.h>
int main(int argc, char **argv)
{
MYSQL *mysql = NULL;
if (mysql_library_init(argc, argv, NULL)) {
fprintf(stderr, "could not initialize MySQL client library\n");
exit(1);
}
mysql = mysql_init(mysql);
if (!mysql) {
puts("Init faild, out of memory?");
return EXIT_FAILURE;
}
if (!mysql_real_connect(mysql, /* MYSQL structure to use */
NULL, /* server hostname or IP address */
NULL, /* mysql user */
NULL, /* password */
NULL, /* default database to use, NULL for none */
0, /* port number, 0 for default */
NULL, /* socket file or named pipe name */
CLIENT_FOUND_ROWS /* connection flags */ )) {
puts("Connect failed\n");
} else {
const char *query = "SELECT VERSION()";
if (mysql_real_query(mysql, query, strlen(query))) {
printf("Query failed: %s\n", mysql_error(mysql));
} else {
puts("Query OK");
}
}
mysql_close(mysql);
mysql_library_end();
return EXIT_SUCCESS;
}
Here's how I compile it
gcc -I /usr/local/Cellar/mysql/8.0.16/include/mysql client.c -L /usr/local/Cellar/mysql/8.0.16/lib/ -l mysqlclient.a
ld: library not found for -lmysqlclient.a
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Compiling without the .a succeeds, as it links to the shared library, not static one.
Lastly, here's my library files:
ls /usr/local/Cellar/mysql/8.0.16/lib/libmysqlclient*
/usr/local/Cellar/mysql/8.0.16/lib/libmysqlclient.21.dylib /usr/local/Cellar/mysql/8.0.16/lib/libmysqlclient.a /usr/local/Cellar/mysql/8.0.16/lib/libmysqlclient.dylib
This argument:
-l mysqlclient.a
causes the linker to look for a file named libmysqlclient.a.a. Instead, you want something like:
gcc -I /usr/local/Cellar/mysql/8.0.16/include/mysql client.c /usr/local/Cellar/mysql/8.0.16/lib/mysqlclient.a
-lmysqlclient should work. The extension .a does not need.
When you want to use static link, --static should be used.
You may also need to link other libraries
gcc client.c -o client --static -lmysqlclient -lssl -lcrypto -ldl -lpthread

Embedded MariaDB C/C++ API

I'm trying to get an embedded MariaDB (i.e. not connecting to running server) setup going but I'm failing to get any of the examples I find to work.
The most recent example I have is from this post https://stackoverflow.com/a/24548826/400048
When the app runs it produces:
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
The docs https://mariadb.com/kb/en/library/embedded-mariadb-interface/ isn't much help on this.
For convenience the code from that StackOverflow post is:
#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);
}
I had a cursory look at https://github.com/MariaDB/server but didn't know where to really look...or in fact what I was looking for.
How does one go about getting an embedded mariadb going?
I'm running on Mac OS High Sierra, MariaDB was installed with brew install mariadb --with-embedded.
UPDATE:
I'm fairly certain I'm linking to the correct lib.
ls /usr/local/lib | grep maria
FIND_LIBRARY(mariadb mariadb)
MESSAGE(FATAL_ERROR "BOOM ${mariadb}")
Output of which is:
BOOM /usr/local/lib/libmariadb.dylib
UPDATE 2
I'm now linking to the following. Note that I started with just libmysqld and added libraries until all link errors went away. The trouble here is I may not have all the correct libs or versions.
TARGET_LINK_LIBRARIES(sql_fn /usr/local/lib/libmysqld.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/opt/openssl/lib/libcrypto.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/opt/openssl/lib/libssl.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/opt/bzip2/lib/libbz2.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/lib/liblz4.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/opt/zlib/lib/libz.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/opt/xz/lib/liblzma.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/lib/libsnappy.a)
It now compiles but exits with code 6
Process finished with exit code 6
Looking at https://stackoverflow.com/a/7495907/400048 if it's points to the same thing/is still true then exit code 6 means EX_ILLEGAL_TABLE 6, unfortunately I don't know what table that would be. The mysql_test and datadir strings passed in are valid identifiers/path.
Ok first a little explanation about your example. The user is using gcc to compile and I can see you are using cmake.
First what does -lz and mysql_config --include --libmysqld-libs means. The first is link zlib to link zlib in cmake you can refer to this answer, but long story short:
find_package( ZLIB REQUIRED )
if ( ZLIB_FOUND )
include_directories( ${ZLIB_INCLUDE_DIRS} )
target_link_libraries( sql_fn ${ZLIB_LIBRARIES} )
endif( ZLIB_FOUND )
Then you need the mariaDB library and that is the second part. mysql_config --include --libmysqld-libs this means execute the command mysql_config --include --libmysqld-libs which will return a string with the link options so execute the command:
$mysql_config --include --libmysqld-libs
-I/usr/local/mysql/include
-L/usr/local/mysql/lib -lmysqld
And you should get an output like the one above. The -I is to look for headers in a given directory and the -L is to search a library in a directory, the -l is to link a given library it serves the same purpose as -lz only you are adding -lmysqld.
Well now that all is explained you need only include the -I -L and -l options with mysql however this is not such a standard library so you need to include directories and libraries through a script as explained in this anwer. So again long story short there is no bullet proof for this for example my library is in /usr/local/mysql/lib and yours is in /usr/local/lib. Since that is the case it will be easier to use the second method.
execute_process(COMMAND mysql_config --include
OUTPUT_VARIABLE MYSQL_INCLUDE)
execute_process(COMMAND mysql_config --libmysqld-libs
OUTPUT_VARIABLE MYSQL_LIBS)
target_compile_options(sql_fn PUBLIC ${MYSQL_INCLUDE})
target_link_libraries(sql_fn ${MYSQL_LIBS})
And that is all the required information you need. Now we are glad we have Cmake to make things easier for us don't we. ;)
Here is my CMakeLists.txt
cmake_minimum_required(VERSION 3.6)
project(embedded_mysql)
set(CMAKE_CXX_STANDARD 14)
set(SOURCE_FILES main.cpp)
add_executable(embedded_mysql ${SOURCE_FILES})
find_package( ZLIB REQUIRED )
if ( ZLIB_FOUND )
include_directories( ${ZLIB_INCLUDE_DIRS} )
target_link_libraries( embedded_mysql ${ZLIB_LIBRARIES} )
endif( ZLIB_FOUND )
execute_process(COMMAND mysql_config --include
OUTPUT_VARIABLE MYSQL_INCLUDE)
execute_process(COMMAND mysql_config --libmysqld-libs
OUTPUT_VARIABLE MYSQL_LIBS)
string(STRIP ${MYSQL_LIBS} MYSQL_LIBS)
target_compile_options(embedded_mysql PUBLIC ${MYSQL_INCLUDE})
target_link_libraries(embedded_mysql ${MYSQL_LIBS})
You can see the code in github here

Can not compile simple mysql program

cblog.c:
#include "html.h"
#include "config.h"
#include <mysql/mysql.h>
//#include <my_global.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
conn = mysql_init(NULL);
// Connect to database
if (!msyql_real_connect(conn, server, username, password, database, 0, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
// Query the DB
if (mysql_query(conn, "show tables")) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
res = mysql_use_result(conn);
htmlf("MySQL Tables in mysql database:\n");
while ((row = mysql_fetch_row(res)) != NULL)
htmlf("%s \n", row[0]);
mysql_free_result(res);
mysql_close(conn);
html("Hello World!");
return 0;
}
Makefile:
all:
# gcc -Wall cblog.c html.c -o cblog `mysql_config --cflags --libs`
# gcc -Wall cblog.c html.c -L/usr/lib -lmysqlclient -o cblog
gcc cblog.c html.c -Wall $(shell mysql_config --cflags) -o cblog $(shell mysql_config --libs)
test: all
./cblog
Output:
ttouch cblog$ make
gcc cblog.c html.c -g -Wall -I/usr/include/mysql -fPIC -pipe -fstack-protector --param=ssp-buffer-size=4 -fno-strict-aliasing -DBIG_JOINS=1 -fomit-frame-pointer -g -DNDEBUG -o cblog -L/usr/lib -lmysqlclient -lpthread -lz -lm -lssl -lcrypto -ldl
cblog.c: In function ‘main’:
cblog.c:16:2: warning: implicit declaration of function ‘msyql_real_connect’ [-Wimplicit-function-declaration]
if (!msyql_real_connect(conn, server, username, password, database, 0, NULL, 0)) {
^
/tmp/ccs1WQsi.o: In function `main':
/media/files/Lab/cblog/cblog.c:16: undefined reference to `msyql_real_connect'
collect2: error: ld returned 1 exit status
make: *** [all] Error 1
I know this question has been answered over a thousand times, I've searched all over the internet, I've tested putting mysql_config at the beginning or at the end. I know that it gives the right paths (checked)
ls /usr/lib/ | grep mysql:
libmysqlclient.a
libmysqlclient_r.a
libmysqlclient_r.so
libmysqlclient_r.so.18
libmysqlclient_r.so.18.0.0
libmysqlclient.so
libmysqlclient.so.18
libmysqlclient.so.18.0.0
libmysqld.a
libmysqld.so
libmysqld.so.18
libmysqlservices.a
mysql
tdbcmysql1.0.0
ls /usr/include/mysql | grep mysql:
mysql_com.h
mysqld_ername.h
mysqld_error.h
mysql_embed.h
mysql.h
mysql_time.h
mysql_version.h
Sorry for the noobish question, but I've been banging my head for about 4-5 hours
You have a typo in the function name, msyql_real_connect should be mysql_real_connect

Connecting C to mysql

I am connecting C to mysql and then creating a database .
My code is:
#include <mysql.h>
#include <my_global.h>
int main(int argc, char **argv)
{MYSQL *conn;
conn = mysql_init(NULL);
if (conn == NULL) {
printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
exit(1);}
if (mysql_real_connect(conn, "localhost", "zetcode", "passwd", NULL, 0, NULL, 0) == NULL)
{printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
exit(1);}
if (mysql_query(conn, "create database testdb")) {
printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
exit(1);
}
mysql_close(conn);}
But i don't have the headers mysql.h and my_global.h
How can i get them??Thanks
In ubuntu/debian
$sudo apt-get install libmysqlclient libmysqlclient-dev
in centos/fedora/RHEL
$yum install mysql-devel
Once you have installed the Client....you should be able to just link them? Or at least add the include/libs to your compiler?
http://www.mysql.com/downloads/
You have to install the library:
http://dev.mysql.com/downloads/connector/c/
Insufficient. You need all the files for development. You need the header and proper libraries or you won't get anywhere. So if you are one some linux check out something like libmysql or search on the proposed download pages.