I'm facing a very strange issue while interacting with mysql db through my c++ app.
environment:
docker-compose.yml
version: '3.1'
services:
db:
image: mysql:8.0.21 #libmysqlcppconn8-2_8.0.21-1ubuntu18.04_amd64.deb connector
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
security_opt:
- seccomp:unconfined
client:
build: .
ports:
- "2890:2890"
Client container is ubuntu18.04, here a simple code to test connection and a minimum result:
#include <cstdio>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include "mysql_connection.h"
#include <array>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/prepared_statement.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
int main() {
sql::Driver *driver = get_driver_instance();
sql::Connection *con =
driver->connect("tcp://remote_backup_db_1", "root", "example");
con->setSchema("db_test");
sql::PreparedStatement *stmt;
sql::ResultSet *res;
stmt = con->prepareStatement("SELECT test from t;");
res = stmt->executeQuery();
if (res->rowsCount() > 0) {
if (res->next()) {
std::string text = res->getString("test");
std::clog << "text: " << text << "\n";
}
}
return 0;
}
here is a describe of the table:
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| test | varchar(128) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
issue: when I try to retrieve a text that is less than 64 bytes everything works properly, but when I try to execute the same code with a text greater than 64 bytes it retrieves the firts 64 bytes followed by random characters. The problem seems not to be related to the column type (same problem with blob for example). It seems to be related with encoding because when i try to get the result length, it is set properly (e.g with a 70 character text long it gives me 70).
I've already tried to change table encoding and I don't know how to solve this. (ps I'm not using strange characters only ASCII basically).
Related
I am doing kind of password manager, when I try to delete some entry ids are placed wrong
For instance, ids are place like ...19,20,21... >> deleted 20 >> ...19,21,22...
The only way to fix it, that I found was deleting and creating back id column.
The part of deleting a column works fine, but creating it back though doesn't work.
Here is my code
#include <iostream>
#include <mysql/mysql.h>
#include <mysql_connection.h>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
using namespace std;
int main(){
sql::Driver *myDriver; //connecting an SQL
sql::Connection *myConn;
sql::Statement *myStmt;
sql::ResultSet *myRes;
myDriver = get_driver_instance(); // connecting to db
myConn = myDriver->connect("localhost", "root", "password");
myConn->setSchema("passwords");
myStmt = myConn->createStatement(); // deleting id column
myRes = myStmt->executeQuery("ALTER TABLE password_table DROP id;");
myStmt = myConn->createStatement(); // creating id column, creates an error
myRes = myStmt->executeQuery("ALTER TABLE password_table ADD id INT(200) NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY(id);");
return 0;
}
It should be noted that, if I do the same command in mysql itself, it will work, but not in code.
First, I thought that it's because of quotation marks, but that it did not work. Than I tried to reinstall mysql connector, but it did not work either.
The issue is that you are calling:
myRes = myStmt->executeQuery("ALTER TABLE password_table DROP id;");
for a query that doesn't produce results.
Instead, call
myStmt->execute("ALTER TABLE password_table DROP id;");
which returns bool to check if the command has results.
PS: and don't forget to add a try catch block on this code otherwise your program will crash and you never know why something is failing.
I am trying to make a CIFS connection between my Ubuntu client desktop and my Windows 10 server Desktop, so I can share folders and files though a local network.
My code is the following:
#include <sys/mount.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <string>
using namespace std;
int main()
{
string src = "//xxx.xxx.x.xxx/shared_folder"; //xxx.xxx.x.xxx should be replaced by the server IP. shared_folder is my folder shared on the server side
string dst = "/opt/share";//My shared folder on Linux
string fstype = "cifs";
printf("src: %s\n", src.c_str());
if( -1 == mount(src.c_str(), dst.c_str(), fstype.c_str(), MS_MGC_VAL | MS_SILENT , "username=myemail#hotmail.com,password=mypassword") )
{
printf("mount failed with error: %s\n",strerror(errno));
}
else
printf("mount success!\n");
return 0;
}
But it always returns:
src: //xxx.xxx.x.xxx/shared_folder
mount failed with error: Operation not permitted
[1] + Done "/usr/bin/gdb" --interpreter=mi --tty=${DbgTerm} 0<"/tmp/Microsoft-MIEngine-In-fmryivr5.02p" 1>"/tmp/Microsoft-MIEngine-Out-zfdhv3x2.zc5"
Any clue, please?
I have a C++ project running on Linux and gcc/g++ 4.8. I am using MySql database version 5.7 and MySql C++ connector API 1.1.12. I am trying to execute two insert statements (each for a different table) separated by a semicolon. I got this working for Statements but not for PreparedStatements. See code sample below:
#include "mysql_connection.h"
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
....
sql::Driver* driver;
sql::Connection *con;
sql::Statement *stmt;
sql::ResultSet *res;
sql::ConnectOptionsMap options;
options["hostName"] = "tcp://127.0.0.1";
options["userName"] = "user";
options["password"] = "password";
options["schema"] = "test_db";
options["port"] = 3306;
options["CLIENT_MULTI_STATEMENTS"] = true;
driver = get_driver_instance();
con = driver->connect(options);
Against that setup, I tried to run either of the following options:
//option 1: works
stmt = con->createStatement();
stmt -> execute("INSERT INTO T_TEST1(TEST1) VALUES ('VALUE1');INSERT INTO T_TEST2(TEST2) VALUES ('VALUE2')");
//option 2: does not work
sql::PreparedStatement *pstmt = con->prepareStatement("INSERT INTO T_TEST1(TEST1) VALUES ('VALUE1');INSERT INTO T_TEST2(TEST2) VALUES ('VALUE2')");
pstmt->executeUpdate();
Option 1 works. Option 2 but throws the following error:
# ERR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO T_TEST2(TEST2) VALUES ('TEST9')' at line 1 (MySQL error code: 1064, SQLState: 42000 )
Is there any way to make option 2 work?
I'm trying to insert data in a .txt file into MySQL.
Following is the code, I tried so far
#include <stdlib.h>
#include <iostream>
#include <chrono>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#define HOST "localhost"
#define USER "root"
#define PASS "admin"
#define DB "test_index"
using namespace std;
int main(int argc, const char **argv)
{
const string url = HOST;
const string user = USER;
const string pass = PASS;
const string database = DB;
sql::Driver *driver = NULL;
sql::Connection *con = NULL;
//sql::Statement *stmt;
sql::ResultSet *res = NULL;
/* Create a connection */
driver = get_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "root", "admin");
/* Connect to the MySQL test database */
con->setSchema("test_index");
sql::PreparedStatement *prep_stmt = NULL;
prep_stmt = con->prepareStatement("LOAD DATA INFILE 'C:\ProgramData\MySQL\MySQL Server 8.0\Data\test_index\data.txt' INTO TABLE dataload_file_raw fields terminated by '\t'");
bool ret = prep_stmt->execute();
cout << "The data is inserted" << ret << endl;
delete res;
delete prep_stmt;
con->close();
return 0;
}
The program is failing when it is trying to execute prep_stmt->execute(). Is there any extra configuration I need to do here?
I'm guessing you need to escape the backslashes in your SQL string.
So instead of
"LOAD DATA INFILE 'C:\ProgramData\MySQL..."
You should have
"LOAD DATA INFILE 'C:\\ProgramData\\MySQL..."
Otherwise the C++ compiler will be turning your the '\P' (at the start of ProgramData) into something and '\M' (at the start of MySQL) into something else, which means it'll be trying to hit the wrong path and probably failing because of that. Every backslash in your string will need to be escaped.
You may also want to look into setting up try/catch for the MySQL error reporting, then it'll tell you straightforwardly what went wrong.
My simple mysql c++ connector program is throwing error 15. What does this mean? The code was taken directly from the online documentation. I can't find the error codes documented anywhere. It's strange because the data ends up getting inserted into the table . Yes i know my statements should be parameterized to avoid SQL injection , this is just a simple test program.
#include <stdlib.h>
#include <iostream>
/*
Include directly the different
headers from cppconn/ and mysql_driver.h + mysql_util.h
(and mysql_connection.h). This will reduce your build time!
*/
#include "mysql_connection.h"
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
using namespace std;
int main(void)
{
try {
sql::Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
sql::ResultSet *res;
/* Create a connection */
driver = get_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "root", "1092Wilda");
/* Connect to the MySQL test database */
con->setSchema("test");
stmt = con->createStatement();
res = stmt->executeQuery("INSERT INTO bung VALUES ('39', 'TestVal')");
delete res;
delete stmt;
delete con;
} catch (sql::SQLException &e) {
cout << e.getErrorCode();
}
cout << endl;
return EXIT_SUCCESS;
}
after digging around in the header file statement.h i found out that there was a function called executeUpdate (function header below)
virtual int executeUpdate(const sql::SQLString& sql) = 0;
this ended up doing what i wanted to do. program added values into database without throwing any exceptions.
i wish the mySQL C++ connector library wasn't so poorly documented.