using sqlite3 C++ bindings with GCC(MINGW) 4.6.2
the following code does not work i.e the callback function does not print anything to the screen.
Any suggestions?
#include <iostream>
#include "sqlite3.h"
using namespace std;
static int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
for (int i=0; i<argc; i++)
{
cout << azColName[i] << "=" << argv[i] << endl;
cout << "\n" << endl;
}
return 0;
}
class db
{
public:
sqlite3* mydb;
char database;
char* mysql;
char* zErrMsg;
db()
{
zErrMsg = 0;
}
void open(string mydatabase)
{
sqlite3_open(mydatabase.c_str(), &mydb);
}
void exec(char* mysql)
{
int rc = sqlite3_exec(mydb, mysql, callback, 0, &zErrMsg);
}
void close()
{
sqlite3_close(mydb);
}
};
int main()
{
db* mystorage;
string s_var = "test.db";
char* sql = "SELECT * FROM COMPANY;";
mystorage -> open(s_var);
mystorage -> exec(sql);
mystorage -> close();
return 0;
}
Related
I've been making program that need to continuously insert data to a database. I'm new to C++.
I'm using xampp for my database. I want to make insert loop inside one of my function.
my code looks like this
#include "stdio.h"
#include "fstream"
#include "iostream"
#include "mysql.h"
#include "sstream"
void loop();
void print();
int i;
const char* hostname = "localhost";
const char* username = "root";
const char* password = "";
const char* database = "testinsertdb";
unsigned int port = 3306;
const char* unixsocket = NULL;
unsigned long clientflag = 0;
insertion(){
MYSQL* conn;
conn = mysql_init(0);
conn = mysql_real_connect(conn, hostname, username, password, database, port, unixsocket, clientflag);
int qstate=0;
using namespace std;
stringstream ss;
ss << " INSERT INTO test (number) values ('" <<i<<"')";
string query = ss.str ();
const char * q = query.c_str();
qstate = mysql_query(conn, q);
if (qstate == 0)
{
cout <<" Record inserted successfully ..."<<endl;
}
else
{
cout <<" Error, data not inserted..."<<endl;
}
}
int main()
{
print();
return 0;
}
void print()
{
for (int j = 0; j < 1000000; j++) {
loop();
}
}
void loop()
{
i=1;
insertion();
}
When I run the program, I managed to insert some data to the database, but after several seconds the program stopped with code -10737741819 (0xC0000005). On my build log Process the terminated with status -1073741510
How can i solve this?
Preferablly try this one.
Your code is trying to connect database as many times as the loop proceeds.
There is the description of that error from this link
#include "stdio.h"
#include "fstream"
#include "iostream"
#include "mysql.h"
#include "sstream"
void loop();
void print();
MYSQL* conn;
const char* hostname = "localhost";
const char* username = "root";
const char* password = "";
const char* database = "testinsertdb";
unsigned int port = 3306;
const char* unixsocket = NULL;
unsigned long clientflag = 0;
void insertion() {
int qstate=0, i;
using namespace std;
stringstream ss;
ss << " INSERT INTO test (number) values ('" <<i<<"')";
string query = ss.str ();
const char * q = query.c_str();
qstate = mysql_query(conn, q);
if (qstate == 0)
{
cout <<" Record inserted successfully ..."<<endl;
}
else
{
cout <<" Error, data not inserted..."<<endl;
}
}
int main()
{
print();
return 0;
}
void print()
{
conn = mysql_init(0);
conn = mysql_real_connect(conn, hostname, username, password, database, port, unixsocket, clientflag);
for (int j = 0; j < 1000000; j++) {
loop();
mysql_close(conn);
}
void loop()
{
i=1;
insertion();
}
I try to create 2 matrices: 1 of char* and 1 of THAR*. But for TCHAR* matrix instead of strings I get addresses of some kind. What's wrong?
Code:
#include <tchar.h>
#include <iostream>
using namespace std;
int main(int argc, _TCHAR* argv[])
{
//char
const char* items1[2][2] = {
{"one", "two"},
{"three", "four"},
};
for (size_t i = 0; i < 2; ++i)
{
cout << items1[i][0] << "," << items1[i][1] <<endl;
}
/*
Correct output:
one,two
three,four
*/
//TCHAR attempt
const TCHAR* items2[2][2] = {
{_T("one"), _T("two")},
{_T("three"), _T("four")},
};
for (size_t i = 0; i < 2; ++i)
{
cout << items2[i][0] << "," << items2[i][1] <<endl;
}
/*
Incorrect output:
0046AB14,0046AB1C
0046AB50,0046D8B0
*/
return 0;
}
To fix the issue we need to use wcout for Unicode strings. Using How to cout the std::basic_string<TCHAR> we can create flexible tcout:
#include <tchar.h>
#include <iostream>
using namespace std;
#ifdef UNICODE
wostream& tcout = wcout;
#else
ostream& tcout = cout;
#endif // UNICODE
int main(int argc, _TCHAR* argv[])
{
//char
const char* items1[2][2] = {
{"one", "two"},
{"three", "four"},
};
for (size_t i = 0; i < 2; ++i)
{
tcout << items1[i][0] << "," << items1[i][1] <<endl;
}
/*
Correct output:
one,two
three,four
*/
//TCHAR attempt
const TCHAR* items2[2][2] = {
{_T("one"), _T("two")},
{_T("three"), _T("four")},
};
for (size_t i = 0; i < 2; ++i)
{
tcout << items2[i][0] << "," << items2[i][1] <<endl;
}
/*
Correct output:
one,two
three,four
*/
return 0;
}
I'm trying to work with a database in C++. I made a program that opens the database and then creates the tables in procedural programming.
When trying to make it in OOP, sqlite3_exec() != SQLITE_OK
I am new at this, so be gentle.
Here is main.cpp:
#include <iostream>
#include "sqlite3.h"
#include "Table.h"
using namespace std;
int openDatabase(sqlite3 *db);
int main() {
sqlite3 *db;
string columnValues, rowValues; // these are for query
Table Personal;
Personal.SettableName("PERSONAL");
columnValues = "NUME TEXT, ID TEXT"; // this is just an example
openDatabase(db);
Personal.createTable(db, columnValues);
sqlite3_close(db);
return 0;
}
Table.cpp
#include <string>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "Table.h"
#include "sqlite3.h"
using namespace std;
static int callback(void *data, int argc, char **argv, char **azColName) {
int i;
fprintf(stderr, "%s: ", (const char*)data);
for(i = 0; i < argc; i++) {
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
void executeSqlStatement(sqlite3 *db,const char* sql) {
int rc = 0 ;
char *zErrMsg = 0;
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); // Here it doesn't work, rc=21;
if( rc != SQLITE_OK ) {
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
else {
fprintf(stdout, "Operation done successfully\n");
}
}
void Table::createTable(sqlite3 *db, string columnDetails) {
this->sqlCommand = "CREATE TABLE ";
this->sqlCommand += (this->tableName + " (" + columnDetails + ");");
executeSqlStatement(db, this->sqlCommand.c_str());
printf(sqlCommand.c_str());
}
And Table.h
#include "sqlite3.h"
using namespace std;
void executeSqlStatement(sqlite3 *db);
static int callback(void *data, int argc, char **argv, char **azColName);
class Table
{
public:
void SettableName(string val){tableName = val;}
void createTable(sqlite3 *db, string columnDetails);
string tableName;
string sqlCommand;
};
Including the sqlite3.h file in all three files is not necessary, as Table.h was included by both the cpp files, so you only needed to have it in that file.
The sqlite3.h file is also a system file, so using include <sqlite3.h> instead of include "sqlite3.h" makes it clearer where the file is coming from.
I would recommend compiling with the -Wall and -Wextra flags - at first they appear to make loads of complaints but it is worth paying attention to the problems reported and working out how to fix them.
Table.h
#include <sqlite3.h>
using namespace std;
void executeSqlStatement(sqlite3 *db);
int callback(void *data, int argc, char **argv, char **azColName);
class Table
{
public:
void SettableName(string val){tableName = val;}
void createTable(sqlite3 *db, string columnDetails);
string tableName;
string sqlCommand;
};
Table.cpp
#include <string>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "Table.h"
using namespace std;
int callback(void *data, int argc, char **argv, char **azColName) {
int i;
fprintf(stderr, "%s: ", (const char*)data);
for(i = 0; i < argc; i++) {
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
void executeSqlStatement(sqlite3 *db,const char* sql) {
int rc = 0 ;
char *zErrMsg = 0;
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); // Here it doesn't work, rc=21;
if( rc != SQLITE_OK ) {
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
else {
fprintf(stdout, "Operation done successfully\n");
}
}
void Table::createTable(sqlite3 *db, string columnDetails) {
this->sqlCommand = "CREATE TABLE ";
this->sqlCommand += (this->tableName + " (" + columnDetails + ");");
executeSqlStatement(db, this->sqlCommand.c_str());
printf(sqlCommand.c_str());
}
main.cpp
#include <iostream>
#include "Table.h"
using namespace std;
int main() {
sqlite3 *db;
sqlite3_open_v2("test.db", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
string columnValues, rowValues; // these are for query
Table Personal;
Personal.SettableName("PERSONAL");
columnValues = "NUME TEXT, ID TEXT"; // this is just an example
Personal.createTable(db, columnValues);
sqlite3_close(db);
return 0;
}
On my github I have a working version of your code, with a (borrowed) makefile to pull the files together so I just have to type make debug to compile the code.
make debug && bin/debug/hello
will build the file, and if the compilation was successful run the executable.
I am writing mosquitto code for consuming the message after subscribing to a particular topic. Now I want to set different configuration for mosquitto like
autosave_interval 100
persistence true
persistence_location /var/lib/mosquitto/
persistence_file mosquitto.db
But I have no idea how to set this configuration in c++. I tried to google it but could not found any result. Plz, help. Below is c++ code for mosquito
myMosq.h
/*
* myMosq.h
*
* Created on: Jul 28, 2016
* Author: nilav
*/
#include <iostream>
#ifndef MYMOSQ_H_
#define MYMOSQ_H_
#include <mosquittopp.h>
#include <mosquitto.h>
using namespace std;
class myMosq : public mosqpp::mosquittopp
{
private:
const char * host;
const char * id;
const char * topic;
int port;
int keepalive;
void on_connect(int rc);
void on_message(const struct mosquitto_message *message);
void on_disconnect(int rc);
void on_subscribe(int mid, int qos_count, const int *granted_qos);
void on_publish(int mid);
void on_unsubscribe(int mid);
public:
myMosq(const char *id, const char * _topic, const char *host, int port);
~myMosq();
bool send_message(string responseMessage);
bool receive_message();
void writeToDatabase(string query);
};
#endif
myMosq.cpp
#include <cstdio>
#include <cstring>
#include <iostream>
#include "myMosq.h"
#include <mosquittopp.h>
#include "Configuration.h"
#include "Databases.h"
using namespace std;
Configuration configuration;
myMosq::myMosq(const char * _id,const char * _topic, const char * _host, int _port) : mosquittopp(_id)
{
mosqpp::lib_init(); // Mandatory initialization for mosquitto library
this->keepalive = 60; // Basic configuration setup for myMosq class
this->id = _id;
this->port = _port;
this->host = _host;
this->topic = _topic;
connect_async(host, // non blocking connection to broker request
port,
keepalive);
loop_start(); // Start thread managing connection / publish / subscribe
};
myMosq::~myMosq() {
loop_stop(); // Kill the thread
mosqpp::lib_cleanup(); // Mosquitto library cleanup
}
bool myMosq::receive_message()
{
int set = subscribe(NULL, configuration.subscriptionTopic.c_str(),2);
return set;
}
bool myMosq::send_message(string responseMessage) {
int ret = publish(NULL,configuration.producerTopic.c_str(),strlen(responseMessage.c_str()),responseMessage.c_str(),1,false);
return (ret = MOSQ_ERR_SUCCESS);
}
void myMosq::on_disconnect(int rc) {
std::cout << ">> myMosq - disconnection(" << rc << ")" << std::endl;
}
void myMosq::on_connect(int rc)
{
if ( rc == 0 ) {
std::cout << ">> myMosq - connected with server" << std::endl;
} else {
std::cout << ">> myMosq - Impossible to connect with server(" << rc << ")" << std::endl;
}
}
void myMosq::on_message(const struct mosquitto_message *message) {
char * pchar = (char*)(message->payload);
string str(pchar);
writeToDatabase(str);
}
void myMosq::on_subscribe(int mid, int qos_count, const int *granted_qos)
{
std::cout << ">> subscription succeeded (" << mid << ") " << std::endl;
}
void myMosq::on_publish(int mid) {
std::cout << ">> myMosq - Message (" << mid << ") succeed to be published " << std::endl;
}
void myMosq::writeToDatabase(string query) {
Databases* database = new Databases(configuration.db,
configuration.dbPort, configuration.username, configuration.password,
configuration.schema);
database->writeDatabase(query);
if(database->responseMessage == "") {
database->responseMessage = "SUCCESS";
}
this->send_message(database->responseMessage);
}
void myMosq::on_unsubscribe(int mid) {
cout<<"unscubscribed";
};
The options you are seeing are for mosquitto broker which acts almost like a server.
Mosquitto C++ library is a client library and those options(e.g. autosave_interval) are not valid for a client. Regarding persistance, mosquitto C/C++ client library doesn't offer file persistance currently.
Not working Code:
#include "stdafx.h"
#include <stdio.h>
#include "sqlite3.h"
#include <Windows.h>
#include <string>
#include <iostream>
#include <vector>
using namespace std;
std::vector<string> emailsfound;
static int callback(void *data, int argc, char **argv, char **azColName)
{
int i;
string thefile;
for(i=0; i<argc; i++)
{
thefile = string(argv[i]);
size_t found = thefile.find(":");
if(found != std::string::npos)
{
thefile.erase(thefile.begin(), thefile.begin()+1);
emailsfound.push_back(thefile);
//here's the problem
cout << emailsfound[i] << endl; //here it only couts emailsfound[0] over and over until the loop's work is done.
}
else
{
}
}
return 0;
}
int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
const char* data = "Callback function called"; //I am not printing this
/* Open database */
rc = sqlite3_open("C:\\Users\\main.db", &db);
if( rc )
{
return 0;
}
else
{
}
/* Create SQL statement */
sql = "SELECT emails from People";
/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if( rc != SQLITE_OK )
{
sqlite3_free(zErrMsg);
return 0;
}
else
{
}
sqlite3_close(db);
system("PAUSE");
return 0;
}
Working Code:
#include "stdafx.h"
#include <stdio.h>
#include "sqlite3.h"
#include <Windows.h>
#include <string>
#include <iostream>
#include <vector>
using namespace std;
std::vector<string> emailsfound;
static int callback(void *data, int argc, char **argv, char **azColName)
{
int i;
string thefile;
for(i=0; i<argc; i++)
{
thefile = string(argv[i]);
size_t found = thefile.find(":");
if(found != std::string::npos)
{
thefile.erase(thefile.begin(), thefile.begin()+1);
emailsfound.push_back(thefile);
//Doing this makes it works great.
printthevector();
}
else
{
}
}
return 0;
}
void printthevector()
{
int sizeofthevector;
int i = 0;
sizeofthevector = emailsfound.size();
while (i < sizeofthevector)
{
cout << emailsfound[i].c_str() << endl; //print everything / it works great
}
}
int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
const char* data = "Callback function called"; //I am not printing this
/* Open database */
rc = sqlite3_open("C:\\Users\\main.db", &db);
if( rc )
{
return 0;
}
else
{
}
/* Create SQL statement */
sql = "SELECT emails from People";
/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if( rc != SQLITE_OK )
{
sqlite3_free(zErrMsg);
return 0;
}
else
{
}
sqlite3_close(db);
system("PAUSE");
return 0;
}
As you can see, in the first code it only counts emailsfound[0] over and over for some reason so I had to create a proper void to cout all the emails found properly.
Please explain this to me, I know I fixed it but I am not sure why the first code was not working.