Reputation: 3269
I just started with c++, after reading some tutorials I'm trying to create a simple myqsl connection with a database. Keep in mind that I'm mainly a web developer hence this is a new thing for me. My current code (taken from a tutorial) is this:
#include <mysql.h>
#include <stdio.h>
#include <stdlib.h>
//#include <string>
using namespace std;
struct connection_details
{
char *server;
char *user;
char *password;
char *database;
};
MYSQL* mysql_connection_setup(struct connection_details mysql_details) {
MYSQL *connection = mysql_init(NULL);
if (!mysql_real_connect(connection,mysql_details.server, mysql_details.user, mysql_details.password, mysql_details.database, 0, NULL, 0)) {
printf("Conection error : %s\n", mysql_error(connection));
exit(1);
}
return connection;
}
MYSQL_RES* mysql_perform_query(MYSQL *connection, char *sql_query) {
if (mysql_query(connection, sql_query)) {
printf("MySQL query error : %s\n", mysql_error(connection));
exit(1);
}
return mysql_use_result(connection);
}
int main() {
MYSQL *conn; // the connection
MYSQL_RES *res; // the results
MYSQL_ROW row; // the results row (line by line)
struct connection_details mysqlD;
mysqlD.server = "localhost"; // line 46
mysqlD.user = "root"; // line 47
mysqlD.password = "root"; // line 48
mysqlD.database = "backseat"; // line 49
conn = mysql_connection_setup(mysqlD);
res = mysql_perform_query(conn, "show tables"); // line 53
printf("MySQL Tables in mysql database:\n");
while ((row = mysql_fetch_row(res)) !=NULL)
printf("%s\n", row[0]);
mysql_free_result(res);
mysql_close(conn);
return 0;
}
however g++ gives me the followign warning:
main.cpp:46:19: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
main.cpp:47:17: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
main.cpp:48:21: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
main.cpp:49:21: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
main.cpp:53:48: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
Which is beyond my understanding at the time being, although the program works. What I did in order to remove the warning was the following:
char s[] = "localhost";
char u[] = "root";
char p[] = "root";
char d[] = "backseat";
and then
mysqlD.server = s;
mysqlD.user = u;
mysqlD.password = p;
mysqlD.database = d;
That took care of the warning but I assume there must be a better way & explanation on how I should take care of this. Moreover I tried to use:
struct connection_details
{
string *server;
string *user;
string *password;
string *database;
};
But that didn't take care the warning on line 53 plus all hell broke loose after doing this. My question is how should I be approaching simple mysql connection, why did those warnings came up and was it a bad idea to use strings in the struct?
I'm sorry for the long post, but I'm on a learning curve here and there a lot of things to take in.
PS: Any good tutorials / guides will be appreciated. Thank you.
Upvotes: 0
Views: 703
Reputation: 39688
You're missing some basics. I don't know about good tutorials to link to, but I'll explain what you're doing wrong:
First of all, when you're writing C++, you should use string
rather than char*
. You should read up the details of char*
; it's a pointer and handling it is therefore significantly different from handling a string
.
What happens in your code is that you assign the address of a string literal like "localhost"
to a char*
(because it's a pointer). The problem is, gcc converts string literals to constants, which are read-only (as the warning tells you). The type char*
however implies that the contents of the string can be changed. Change the type to const char*
to get rid of the warning.
Here's some code to illustrate the issue:
char* a;
const char* b;
a = "foo";
b = "bar";
a[0] = 'a'; // you're changing the constant string!
b[0] = 'b'; // compiler error; b is const
a = "foz"; // both allowed because you're not changing
b = "baz"; // the string, but only the pointer
The easier option is to use string
:
struct connection_details
{
string server;
string user;
string password;
string database;
}
You shouldn't use pointers here. string
manages the low-level memory stuff internally. Now the problem is that you're using the C-level MySQL binding, which expects char*
rather than string
. To call it when you're using string
s in your code, use c_str()
for conversion:
connection.server.c_str()
and so on.
Alternatively, you might want to use a higher-level C++ API to connect to MySQL. If you're learning C++, you'll be better off avoiding C APIs if possible. There is, for example, MySQL++, but I don't know it and therefore cannot recommend it. A higher-level API is provided by SOCI, which works with multiple database backends (including MySQL).
Upvotes: 1