How to init MYSQL correctly - c++

I wrote a server using cpp to connect mysql with libmysqlclient.a, codes are like this:
#ifndef __IVC_MYSQLAPI_H__
#define __IVC_MYSQLAPI_H__
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <mysql.h>
#include <string.h>
#include <vector>
using namespace std;
class ConnMysql {
public:
ConnMysql();
~ConnMysql();
int connInit(const char* host,int port,const char* user,const char* password,const char* database);
int executeSql(const char* sql, std::vector<std::string> &v);
void close();
private:
MYSQL *sock;
MYSQL *my_sql;
};
ConnMysql::ConnMysql(){
}
ConnMysql::~ConnMysql(){
}
int ConnMysql::connInit(const char* host,int port,const char* user,const char* password,const char* database){
my_sql = mysql_init(NULL);
if (my_sql == NULL) {
fprintf(stderr, "Init failed\n");
return -1;
}
sock = mysql_real_connect(my_sql, host,
user, password, database, port, NULL, CLIENT_MULTI_STATEMENTS);
if (sock < 0) {
return -1;
}
}
int ConnMysql::executeSql(const char* sql, std::vector<std::string> &v) {
mysql_query(sock, sql);
MYSQL_RES *res_ptr;
res_ptr = mysql_store_result(sock);
if(res_ptr == nullptr) {
printf("Get data from mysql failed\n");
return -1;
}
MYSQL_ROW sqlrow;
int j = mysql_num_fields(res_ptr);
while((sqlrow = mysql_fetch_row(res_ptr))) {
v.push_back(std::string(sqlrow[0]));
}
return 0;
}
void ConnMysql::close() {
mysql_close(sock);
sock=NULL;
my_sql = NULL;
}
#endif //__IVC_MYSQLAPI_H__
The method called like this:
ConnMysql connsql = ConnMysql{};
fprintf(stderr, "begin to init\n");
if (connsql.connInit(ip, port, username, pwd, database) < 0) {
fprintf(stderr, "mysql init return failed\n");
return -1;
}
std::string sql = "select env_code from env_codes where env_type = 1";
connsql.executeSql(sql.c_str(), v);
for (int len=0; len < v.size(); len++) {
fprintf(stderr, "get: %s\n", v[len].c_str());
}
connsql.close();
I will get error suchInit failed occasionally, not always. My questions are
Is there any wrong with my codes? Forget to release something?
How can get the reason why mysql init failed?

I changed mysql_real_connect like this
if(mysql_real_connect(my_sql, host,
user, password, database, port, NULL, CLIENT_MULTI_STATEMENTS) == NULL)
{
return -1;
}
and delete MYSQL *sock parameter, and changed sock to my_sql, such as mysql_query(sock, sql) to mysql_query(my_sql, sql). It seems workable.

Related

Code::Blocks returns -10737741819 (0xC0000005) when executing MySQL loop insert c++

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();
}

Cout doesn't display all fields (C++, MySQL)

I have a function:
int main()
{
MySQL::Connect("127.0.0.1", 3306, "root", "", "player");
MySQL::ExecuteQuery("select * from player");
while (row = mysql_fetch_row(res))
{
std::cout << row[2] << "\n";
MySQL::SetDatabase("account");
MySQL::ExecuteQuery("select * from account"); // This function causes a problem.
// while (row = mysql_fetch_row(res))
// break;
}
return 0;
}
Which should get everything of player names from player table what it does and what it display in console (I'm posting a screenshot of table in Navicat):
https://i.stack.imgur.com/n6HJQ.png
However, when MySQL::ExecuteQuery("select * from account"); function is used which selects everything in account table, the earlier std::cout display only one player name instead of two:
https://i.stack.imgur.com/q9ZkP.png
What can I do in this situation? Or is there another simple way to connect to MySQL in C++? Please help.
I attach files such as MySQL_Func.cpp and MySQL_Func.h which include problematic function:
.cpp:
#include "MySQL_Func.h"
#include "../Log.hpp"
MYSQL* conn;
MYSQL_ROW row;
MYSQL_RES* res;
std::string conf_ip;
unsigned int conf_port;
std::string conf_db;
std::string conf_login;
std::string conf_password;
std::string error = mysql_error(conn);
int err = 0;
namespace MySQL
{
void Connect(std::string ip, unsigned int port, std::string login, std::string password, std::string db)
{
conf_ip = ip;
conf_port = port;
conf_login = login;
conf_password = password;
conf_db = db;
if (conn != 0)
{
SendLog(0, "MySQL has been restared.");
mysql_close(conn);
}
conn = mysql_init(0);
if (!mysql_real_connect(conn, ip.c_str(), login.c_str(), password.c_str(), db.c_str(), port, NULL, 0))
{
error = mysql_error(conn);
SendLog(1, "Connection with database was failed: " + error + ".");
exit(1);
}
else
{
SendLog(0, "Successfully connected with database!");
}
}
void ExecuteQuery(std::string query)
{
err = mysql_query(conn, query.c_str());
res = mysql_store_result(conn);
if (res != 0) // Protection against NullPointer.
{
int total_rows = mysql_num_fields(res);
if (total_rows != 0) // If total rows isn't 0.
{
if (err)
{
error = mysql_error(conn);
SendLog(1, "Query execute failed:" + error + ".");
mysql_free_result(res);
exit(1);
}
else
{
SendLog(0, "Query has been sent (" + query + ")!");
}
}
else
{
SendLog(1, "Query has been sent: (" + query + ") but its value is 0.");
exit(0);
}
}
else
{
exit(1);
}
}
void SetDatabase(std::string current_db)
{
if (current_db != conf_db) // If current_db isn't conf_db.
MySQL::Connect(conf_ip, conf_port, conf_login, conf_password, current_db);
}
}
.h:
#pragma once
#include <iostream>
#include <mysql.h>
#include <string>
extern MYSQL* conn;
extern MYSQL_ROW row;
extern MYSQL_RES* res;
extern std::string conf_ip;
extern unsigned int conf_port;
extern std::string conf_db;
extern std::string conf_login;
extern std::string conf_password;
namespace MySQL
{
void Connect(std::string ip, unsigned int port, std::string login, std::string password, std::string db);
void ExecuteQuery(std::string query);
void SetDatabase(std::string database);
}
Your two calls to ExecuteQuery share state, namely the "currently active query" and the buffered resultset you downloaded with mysql_result_row.
This is called a non-reentrant function.
Some options:
have a dedicated connection for each query
Do a single query that somehow combines the results (ie JOIN the players and accounts table)
Fetch all the players first into a dedicated datastructure (eg std::vector or std::map), then do the query for accounts later.

config.h: No such file or directory in ssh_client from libssh's example

When I compile ssh_client code from example folder of libssh source directory( I have wrote about building process of this library in this link : libssh's functions couldn't be found on qt):
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_PTY_H
#include <pty.h>
#endif
#include <sys/ioctl.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <libssh/callbacks.h>
#include <libssh/libssh.h>
#include <libssh/sftp.h>
#include "examples_common.h"
#define MAXCMD 10
static char *host = NULL;
static char *user = NULL;
static char *cmds[MAXCMD];
static char *config_file = NULL;
static struct termios terminal;
static char *pcap_file = NULL;
static char *proxycommand;
static int auth_callback(const char *prompt,
char *buf,
size_t len,
int echo,
int verify,
void *userdata)
{
(void) verify;
(void) userdata;
return ssh_getpass(prompt, buf, len, echo, verify);
}
struct ssh_callbacks_struct cb = {
.auth_function = auth_callback,
.userdata = NULL,
};
static void add_cmd(char *cmd)
{
int n;
for (n = 0; (n < MAXCMD) && cmds[n] != NULL; n++);
if (n == MAXCMD) {
return;
}
cmds[n] = strdup(cmd);
}
static void usage(void)
{
fprintf(stderr,
"Usage : ssh [options] [login#]hostname\n"
"sample client - libssh-%s\n"
"Options :\n"
" -l user : log in as user\n"
" -p port : connect to port\n"
" -d : use DSS to verify host public key\n"
" -r : use RSA to verify host public key\n"
" -F file : parse configuration file instead of default one\n"
#ifdef WITH_PCAP
" -P file : create a pcap debugging file\n"
#endif
#ifndef _WIN32
" -T proxycommand : command to execute as a socket proxy\n"
#endif
"\n",
ssh_version(0));
exit(0);
}
static int opts(int argc, char **argv)
{
int i;
while((i = getopt(argc,argv,"T:P:F:")) != -1) {
switch(i){
case 'P':
pcap_file = optarg;
break;
case 'F':
config_file = optarg;
break;
#ifndef _WIN32
case 'T':
proxycommand = optarg;
break;
#endif
default:
fprintf(stderr, "Unknown option %c\n", optopt);
usage();
}
}
if (optind < argc) {
host = argv[optind++];
}
while(optind < argc) {
add_cmd(argv[optind++]);
}
if (host == NULL) {
usage();
}
return 0;
}
#ifndef HAVE_CFMAKERAW
static void cfmakeraw(struct termios *termios_p)
{
termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
termios_p->c_oflag &= ~OPOST;
termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
termios_p->c_cflag &= ~(CSIZE|PARENB);
termios_p->c_cflag |= CS8;
}
#endif
static void do_cleanup(int i)
{
/* unused variable */
(void) i;
tcsetattr(0, TCSANOW, &terminal);
}
static void do_exit(int i)
{
/* unused variable */
(void) i;
do_cleanup(0);
exit(0);
}
static ssh_channel chan;
static int signal_delayed = 0;
static void sigwindowchanged(int i)
{
(void) i;
signal_delayed = 1;
}
static void setsignal(void)
{
signal(SIGWINCH, sigwindowchanged);
signal_delayed = 0;
}
static void sizechanged(void)
{
struct winsize win = {
.ws_row = 0,
};
ioctl(1, TIOCGWINSZ, &win);
ssh_channel_change_pty_size(chan,win.ws_col, win.ws_row);
setsignal();
}
static void select_loop(ssh_session session,ssh_channel channel)
{
ssh_connector connector_in, connector_out, connector_err;
int rc;
ssh_event event = ssh_event_new();
/* stdin */
connector_in = ssh_connector_new(session);
ssh_connector_set_out_channel(connector_in, channel, SSH_CONNECTOR_STDINOUT);
ssh_connector_set_in_fd(connector_in, 0);
ssh_event_add_connector(event, connector_in);
/* stdout */
connector_out = ssh_connector_new(session);
ssh_connector_set_out_fd(connector_out, 1);
ssh_connector_set_in_channel(connector_out, channel, SSH_CONNECTOR_STDINOUT);
ssh_event_add_connector(event, connector_out);
/* stderr */
connector_err = ssh_connector_new(session);
ssh_connector_set_out_fd(connector_err, 2);
ssh_connector_set_in_channel(connector_err, channel, SSH_CONNECTOR_STDERR);
ssh_event_add_connector(event, connector_err);
while (ssh_channel_is_open(channel)) {
if (signal_delayed) {
sizechanged();
}
rc = ssh_event_dopoll(event, 60000);
if (rc == SSH_ERROR) {
fprintf(stderr, "Error in ssh_event_dopoll()\n");
break;
}
}
ssh_event_remove_connector(event, connector_in);
ssh_event_remove_connector(event, connector_out);
ssh_event_remove_connector(event, connector_err);
ssh_connector_free(connector_in);
ssh_connector_free(connector_out);
ssh_connector_free(connector_err);
ssh_event_free(event);
}
static void shell(ssh_session session)
{
ssh_channel channel;
struct termios terminal_local;
int interactive=isatty(0);
channel = ssh_channel_new(session);
if (channel == NULL) {
return;
}
if (interactive) {
tcgetattr(0, &terminal_local);
memcpy(&terminal, &terminal_local, sizeof(struct termios));
}
if (ssh_channel_open_session(channel)) {
printf("Error opening channel : %s\n", ssh_get_error(session));
ssh_channel_free(channel);
return;
}
chan = channel;
if (interactive) {
ssh_channel_request_pty(channel);
sizechanged();
}
if (ssh_channel_request_shell(channel)) {
printf("Requesting shell : %s\n", ssh_get_error(session));
ssh_channel_free(channel);
return;
}
if (interactive) {
cfmakeraw(&terminal_local);
tcsetattr(0, TCSANOW, &terminal_local);
setsignal();
}
signal(SIGTERM, do_cleanup);
select_loop(session, channel);
if (interactive) {
do_cleanup(0);
}
ssh_channel_free(channel);
}
static void batch_shell(ssh_session session)
{
ssh_channel channel;
char buffer[1024];
size_t i;
int s = 0;
for (i = 0; i < MAXCMD && cmds[i]; ++i) {
s += snprintf(buffer + s, sizeof(buffer) - s, "%s ", cmds[i]);
free(cmds[i]);
cmds[i] = NULL;
}
channel = ssh_channel_new(session);
if (channel == NULL) {
return;
}
ssh_channel_open_session(channel);
if (ssh_channel_request_exec(channel, buffer)) {
printf("Error executing '%s' : %s\n", buffer, ssh_get_error(session));
ssh_channel_free(channel);
return;
}
select_loop(session, channel);
ssh_channel_free(channel);
}
static int client(ssh_session session)
{
int auth = 0;
char *banner;
int state;
if (user) {
if (ssh_options_set(session, SSH_OPTIONS_USER, user) < 0) {
return -1;
}
}
if (ssh_options_set(session, SSH_OPTIONS_HOST, host) < 0) {
return -1;
}
if (proxycommand != NULL) {
if (ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, proxycommand)) {
return -1;
}
}
/* Parse configuration file if specified: The command-line options will
* overwrite items loaded from configuration file */
if (config_file != NULL) {
ssh_options_parse_config(session, config_file);
} else {
ssh_options_parse_config(session, NULL);
}
if (ssh_connect(session)) {
fprintf(stderr, "Connection failed : %s\n", ssh_get_error(session));
return -1;
}
state = verify_knownhost(session);
if (state != 0) {
return -1;
}
ssh_userauth_none(session, NULL);
banner = ssh_get_issue_banner(session);
if (banner) {
printf("%s\n", banner);
free(banner);
}
auth = authenticate_console(session);
if (auth != SSH_AUTH_SUCCESS) {
return -1;
}
if (cmds[0] == NULL) {
shell(session);
} else {
batch_shell(session);
}
return 0;
}
static ssh_pcap_file pcap;
static void set_pcap(ssh_session session)
{
if (pcap_file == NULL) {
return;
}
pcap = ssh_pcap_file_new();
if (pcap == NULL) {
return;
}
if (ssh_pcap_file_open(pcap, pcap_file) == SSH_ERROR) {
printf("Error opening pcap file\n");
ssh_pcap_file_free(pcap);
pcap = NULL;
return;
}
ssh_set_pcap_file(session, pcap);
}
static void cleanup_pcap(void)
{
if (pcap != NULL) {
ssh_pcap_file_free(pcap);
}
pcap = NULL;
}
int main(int argc, char **argv)
{
ssh_session session;
session = ssh_new();
ssh_callbacks_init(&cb);
ssh_set_callbacks(session,&cb);
if (ssh_options_getopt(session, &argc, argv)) {
fprintf(stderr,
"Error parsing command line: %s\n",
ssh_get_error(session));
usage();
}
opts(argc, argv);
signal(SIGTERM, do_exit);
set_pcap(session);
client(session);
ssh_disconnect(session);
ssh_free(session);
cleanup_pcap();
ssh_finalize();
return 0;
}
I got the following error:
/home/heydari.f/projects/ssh_client/ssh_client/main.c:100: error: config.h: No such file or directory
#include "config.h"
^~~~~~~~~~
Is there anything to do with configure or what?
I use Qt and my os is ubuntu 18.04.
Config headers as config.h normally aren't needed to compile a program against a library. Those are generated to compile the library, not the programs that link against them. If not, there will be lot of trouble as lots of software use them and there would be lots of collisions between them.
Being an example, it may be that it uses the config.h, but in that case I'm pretty sure you should compile with the system libssh uses to compile. (You may need to specify an option to compile examples when calling configure or specify something in DefineOptions.cmake or something in the same line.)
If you copied the sources (as it seems as the error states projects/ssh_client/) to build with Qt, you probably can remove that include unless it is a config from Qt itself.
Also, if you are compiling with Qt you surely need to install the lib and follow #Dmitry advice about -I, -L and -l flags to compiler.

String Vector showing duplicates C++

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.

How to read data from SQLite database?

I decided to use SQLite as it allows to store database into a single file. I think I have managed to do a database with SQLite Database Browser.
How can I read that data in a C/C++ program?
A example using sqlite read:
#include <stdio.h>
#include <sqlite3.h>
#include <string.h>
int main(int argc, char** argv)
{
const char* username = "satyam";
char q[999];
sqlite3* db;
sqlite3_stmt* stmt;
int row = 0;
int bytes;
const unsigned char* text;
if (2 == argc) {
username = argv[1];
}
q[sizeof q - 1] = '\0';
snprintf(
q,
sizeof q - 1,
"SELECT ipaddr FROM items WHERE username = '%s'",
username
);
if (sqlite3_open ("test.db", &db) != SQLITE_OK) {
fprintf(stderr, "Error opening database.\n");
return 2;
}
printf("Query: %s\n", q);
sqlite3_prepare(db, q, sizeof q, &stmt, NULL);
bool done = false;
while (!done) {
printf("In select while\n");
switch (sqlite3_step (stmt)) {
case SQLITE_ROW:
bytes = sqlite3_column_bytes(stmt, 0);
text = sqlite3_column_text(stmt, 1);
printf ("count %d: %s (%d bytes)\n", row, text, bytes);
row++;
break;
case SQLITE_DONE:
done = true;
break;
default:
fprintf(stderr, "Failed.\n");
return 1;
}
}
sqlite3_finalize(stmt);
return 0;
}
How about the 'An Introduction to Sqlite C/C++ Interface', and there is a whole C++ example here on CodeProject.
This is bits of the more full sample,
#include "CppSQLite.h"
#include <ctime>
#include <iostream>
using namespace std;
const char* gszFile = "C:\\test.db";
int main(int argc, char** argv)
{
try
{
int i, fld;
time_t tmStart, tmEnd;
CppSQLiteDB db;
cout << "SQLite Version: " << db.SQLiteVersion() << endl;
db.open(gszFile);
cout << db.execScalar("select count(*) from emp;")
<< " rows in emp table in ";
db.Close();
}
catch (CppSQLiteException& e)
{
cerr << e.errorCode() << ":" << e.errorMessage() << endl;
}
}
One way to do it without additional wrappers
#include <stdio.h>
#include <string>
using std::string;
#include <sstream>
using std::stringstream;
#include "sqlite3.h"
bool find_employee(int _id)
{
bool found = false;
sqlite3* db;
sqlite3_stmt* stmt;
stringstream ss;
// create sql statement string
// if _id is not 0, search for id, otherwise print all IDs
// this can also be achieved with the default sqlite3_bind* utilities
if(_id) { ss << "select * from employees where id = " << _id << ";"; }
else { ss << "select * from employees;"; }
string sql(ss.str());
//the resulting sql statement
printf("sql: %s\n", sql.c_str());
//get link to database object
if(sqlite3_open("data/test.db", &db) != SQLITE_OK) {
printf("ERROR: can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return found;
}
// compile sql statement to binary
if(sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, NULL) != SQLITE_OK) {
printf("ERROR: while compiling sql: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
sqlite3_finalize(stmt);
return found;
}
// execute sql statement, and while there are rows returned, print ID
int ret_code = 0;
while((ret_code = sqlite3_step(stmt)) == SQLITE_ROW) {
printf("TEST: ID = %d\n", sqlite3_column_int(stmt, 0));
found = true;
}
if(ret_code != SQLITE_DONE) {
//this error handling could be done better, but it works
printf("ERROR: while performing sql: %s\n", sqlite3_errmsg(db));
printf("ret_code = %d\n", ret_code);
}
printf("entry %s\n", found ? "found" : "not found");
//release resources
sqlite3_finalize(stmt);
sqlite3_close(db);
return found;
}