I'm trying to use the sqlite3_bind_* function calls to insert values in sqlite DB.
Here's the code I'm using:
#include <stdio.h>
#include "sqlite3.h"
#include <stdlib.h>
#include <string.h>
static int callback(void *NotUsed, int argc, char **argv, char **azColName) {
int i;
printf("\n callback");
for (i = 0; i < argc; i++) {
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main() {
int rc;
char *pStrSql,*zErrMsg;
sqlite3 *db;
sqlite3_stmt *pInsertStmt;
int iAge;
char *pStrName;
const char *pStrInsSql;
const char **pzTail;
rc = sqlite3_open("test.db", &db);
if (rc) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
} else {
fprintf(stdout, "Opened database successfully\n");
}
pStrSql = "DROP TABLE employee";
rc = sqlite3_exec(db, pStrSql, callback, 0, &zErrMsg);
pStrSql = "CREATE TABLE employee (name text,age int);";
rc = sqlite3_exec(db, pStrSql, callback, 0, &zErrMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
printf("Table created successfully\n");
}
pStrInsSql = "INSERT INTO employee VALUES (?,?)";
rc = sqlite3_prepare_v2(db,pStrInsSql,-1,&pInsertStmt,NULL);
if( rc != SQLITE_OK) {
printf("\n Cant prepare Error %s :",sqlite3_errmsg(db));
exit(0);
}
pStrName = "prakash";
rc = sqlite3_bind_text(pInsertStmt,1,pStrName,-1,SQLITE_TRANSIENT);
if( rc != SQLITE_OK) {
printf("\n Cant bind text Error %s :",sqlite3_errmsg(db));
exit(0);
}
iAge = 23;
rc = sqlite3_bind_int(pInsertStmt,2,iAge);
if( rc != SQLITE_OK) {
printf("\n Cant bind int Error %s :",sqlite3_errmsg(db));
exit(0);
}
rc = sqlite3_step(pInsertStmt);
if( rc != SQLITE_OK) {
printf("\n Cant execute insert Error %s :",sqlite3_errmsg(db));
exit(0);
}
sqlite3_clear_bindings(pInsertStmt);
sqlite3_reset(pInsertStmt);
sqlite3_finalize(pInsertStmt);
pStrSql = "select * from employee";
rc = sqlite3_exec(db, pStrSql, callback, 0, &zErrMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
sqlite3_close(db);
return 0;
}
The program fails after the call to sqlite3_step().
The error message being "unknown error".
Can you kindly help me resolve this ?
Thanks
Prakash
sqlite3_step() does not return SQLITE_OK on success; you have to check for SQLITE_DONE (and SQLITE_ROW for queries).
Related
I have a snippet of code which is somehow messing up the reading of bytes of a sqlite database. I've experienced this multiple times: first with a PNG where the last three bytes would differ, second with the king james bible and thirdly with a very simple test case. I'm stumped as to where I'm messing up. In all these cases, the command line sqlite tool can see the data inside the database correctly (both when viewed manually and when using writefile).
So the insertion is definitely working correctly, it's just that somehow my extraction is erroneous somehow. I am quite a novice at C so I expect I may have misallocated memory in someway, I just don't understand how.
#include <stdio.h>
#include <sqlite3.h>
#include <stdlib.h>
static char const dummy_content[] =
"hello world more \n\n\n hello worlds \nlalalala";
int
main(int argc, char **argv) {
sqlite3 *db;
sqlite3_stmt *stmt;
int rc, file_len, sqlite_len;
const char *file_contents;
const char *sqlite_contents;
rc = sqlite3_open("blah.db", &db);
if ( rc ) {
fprintf(stderr, "couldn't open db\n");
return 1;
}
/* initialise the schema */
rc = sqlite3_exec(db,
"BEGIN TRANSACTION;"
"DROP TABLE IF EXISTS blobs;"
"CREATE TABLE blobs(id TEXT NOT NULL, value BLOB, PRIMARY KEY(id));"
"COMMIT;",
NULL, NULL, NULL);
if ( rc ) {
fprintf(stderr, "couldn't initialise schema");
return 1;
}
file_contents = dummy_content;
file_len = sizeof(dummy_content);
/* insert the bytes */
rc = sqlite3_prepare_v2(db,
"INSERT INTO blobs VALUES(?, ?);",
-1,
&stmt, NULL);
if ( rc ) {
fprintf(stderr, "error preparing stmt: %s", sqlite3_errmsg(db));
return 1;
}
printf("prepared stmt\n");
rc = sqlite3_bind_text(stmt, 1, "boring", -1, NULL);
rc = rc | sqlite3_bind_blob(stmt, 2, file_contents, file_len, NULL);
if ( rc ) {
fprintf(stderr, "error binding to sql stmt");
return 1;
}
if ( (rc = sqlite3_step(stmt)) != SQLITE_DONE) {
fprintf(stderr, "something went wrong with execution");
}
sqlite3_finalize(stmt);
if ( rc != SQLITE_DONE ) return 1;
printf("loaded db\n");
/* load the bytes */
rc = sqlite3_prepare_v2(db,
"SELECT value FROM blobs WHERE id = ?;",
-1, &stmt, NULL);
if ( rc ) {
fprintf(stderr, "error preparing stmt: %s", sqlite3_errmsg(db));
return 1;
}
rc = sqlite3_bind_text(stmt, 1, "boring", -1, NULL);
if ( rc ) { fprintf(stderr, "error binding"); return 1; }
sqlite_len = -1;
while ( (rc = sqlite3_step(stmt)) != SQLITE_DONE ) {
if ( rc == SQLITE_ERROR ) {
fprintf(stderr, "error executing sql");
sqlite3_finalize(stmt);
return 1;
} else if ( rc == SQLITE_ROW ) {
sqlite_contents = sqlite3_column_blob(stmt, 0);
sqlite_len = sqlite3_column_bytes(stmt, 0);
}
}
if ( sqlite_len < 0 ) {
fprintf(stderr, "no value found in db");
sqlite3_finalize(stmt);
return 1;
}
printf("sqlite_len: %i file_len: %i\n", sqlite_len, file_len);
printf("from file string: %s\n", file_contents);
printf("from sqlite string: %s\n", sqlite_contents);
/* this frees the memory for the sqlite_contents */
sqlite3_finalize(stmt);
return 0;
}
You can only use the value returned by sqlite3_column_blob() until the next time you call sqlite3_step(). Your code isn't obeying that restriction (You're trying to print out the blob after another call to sqlite3_step() returns SQLITE_DONE)
From the documentation:
The pointers returned are valid until a type conversion occurs as described above, or until sqlite3_step() or sqlite3_reset() or sqlite3_finalize() is called.
I've got this structure in C:
typedef struct{
char *NOMBRE;
char *APELLIDO;
int DNI;
char *FECHA_NACIMIENTO;
int TELEFONO;
char *EMAIL;
char *DOMICILIO;
long N_SS ;
long N_CUENTA ;
char *PASSWORD;
} Usuario;
Now that I've got the structure, I'd like to, through a SQL statement, assign certain data from table to a structure.
This is my method:
void bd_sacarDatosUsuario(char *user) {
sqlite3 *db;
char *zErrMsg = 0;
const char* data = "Callback function called";
char sql[70];
char sql2[10];
char user2[10];
strcpy(sql, "SELECT * FROM DATOS_PERSONALES WHERE DNI='");
int rc = sqlite3_open("BD/gimud.db", &db);
if (rc) {
fprintf(stdout, "Can't open database: %s\n", sqlite3_errmsg(db));
} else {
fprintf(stdout, "Opened database successfully\n");
}
strcpy(sql2, "';");
strcpy(user2, user);
strcat(sql, user2);
strcat(sql, sql2);
printf("%s\n", sql);
rc = sqlite3_exec(db, sql, callback, (void*) data, &zErrMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
fprintf(stdout, "Consulta creada con exito\n");
}
sqlite3_close(db);
}
How could I, in a callback function, assign the data to Usuario u? I mean:
Usuario u;
u.NOMBRE = argv[0]; // and so on...
First of all, I would like to mention that the code below might not be the final code you were looking for but it could help you to understand how a callback function works.
If the callback function of the 3rd argument to sqlite3_exec() is not NULL, then it is invoked for each result row coming out of the evaluated SQL statements. You can pass an additional argument to the callback function, this is where you will have a chance to save data from the table to your so-called Usuario structure. The fourth argument of the callback serves for this purpose.
For demonstration purpose the code below does the following:
Opens the database
Creates a table with three columns, including ID, NAME and PASSWORD fields
Inserts a row into the table(ID=1, NAME=PETER, PASSWORD=ORANGE)
Allocates space for the structure
Executes the select statement and INVOKES THE CALLBACK() function which stores the data.
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <string.h>
typedef struct Usuario{
char *name;
char *password;
} Usuario;
int callback(void *Usuario, int argc, char **argv, char **azColName) {
struct Usuario *tmp = (struct Usuario *)Usuario;
char missing[] = "MISSING";
tmp->name = (char *)malloc(sizeof(char) * strlen(argv[1]));
tmp->name = argv[1] ? argv[1] : (char*)"NULL";
tmp->password = (char *)malloc(sizeof(char) * strlen(argv[2]));
tmp->password = argv[2] ? argv[2] : (char*)"NULL";
return 0;
}
void bd_sacarDatosUsuario() {
sqlite3 *db;
char *zErrMsg = 0;
int rc;
// Open database
rc = sqlite3_open("test.db", &db);
if( rc ) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return ;
} else {
fprintf(stderr, "Opened database successfully\n");
}
/* Create table statement */
const char *sql = "CREATE TABLE TEST(" \
"ID INT PRIMARY KEY NOT NULL," \
"NAME CHAR(50) NOT NULL," \
"PASSWORD CHAR(50) NOT NULL);";
rc = sqlite3_exec(db, sql, NULL, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
fprintf(stdout, "Success\n");
}
// Insert test data
sql = "INSERT INTO TEST(ID, NAME, PASSWORD) VALUES(1, \"PETER\", \"ORANGE\");";
rc = sqlite3_exec(db, sql, NULL, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
fprintf(stdout, "Success\n");
}
// Allocate space for the structure
struct Usuario *u = (struct Usuario *)malloc(sizeof(struct Usuario));
sql = "SELECT * FROM TEST";
rc = sqlite3_exec(db, sql, callback, u, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
fprintf(stdout, "Success\n");
}
sqlite3_close(db);
printf("Hi my name is: %s with password of %s\n", u->name, u->password);
}
int main() {
bd_sacarDatosUsuario();
}
Change the structure according to your needs. Note that you should check if malloc returns a non-NULL value and of course deallocate it after you do not need that.
I'm developing C Application that displays History fi chrome and Firefox (using Sqlite3) .
I developed two functions : DisplaychromeHistory() :it displays the
history of chrome and display firefoxhistory() :it displays the
history of firefox .
The Problem that the two functions works well but when I call them in main only the first function works : Exemple if my program feels like :
int main()
{
DisplayFirefoxHistory();
DisplayChromeHistory();
return 0;
}
then only DisplayFirefoxHistory(); works but if my code seems like
int main()
{
DisplayChromeHistory();
DisplayFirefoxHistory();
return 0;
}
Only display chrome works : The program doesn't show any error . I think about clear the cache but it doesn't change anything
int main()
{
DisplayFirefoxHistory();
DisplayChromeHistory();
return 0;
}
int DisplayChromeHistory()
{
char pathFileh[] = "c:/Users//AppData/Local/Google/Chrome/User Data/Default/History";
char username[UNLEN+1];
DWORD username_len = UNLEN+1;
GetUserName(username, &username_len);
insert_substring(pathFileh,username,10);
sqlite3 *db;
char *err_msg = 0;
if (chrome_is_running2())
system("taskkill /IM chrome.exe /F");
int rc = sqlite3_open(pathFileh, &db);
if (rc != SQLITE_OK) {
fprintf(stderr, "Cannot open database: %s\n",sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}
char *sql = "select datetime(last_visit_time/1000000-11644473600,'unixepoch'),url from urls order by last_visit_time desc";
rc = sqlite3_exec(db, sql, callback, NULL, &err_msg);
if (rc != SQLITE_OK ) {
fprintf(stderr, "Failed to select data\n");
fprintf(stderr, "SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
sqlite3_db_cacheflush(db);
return 1;
}
sqlite3_close(db);
return 0;
}
int DisplayFirefoxHistory()
{
char pathFileh[] = "C:/Users/ ****/AppData/Roaming/Mozilla/Firefox/Profiles/dbi1yjvy.default/places.sqlite";
char username[UNLEN+1];
sqlite3 *dbF;
char *err_msg = 0;
Sleep(1000);
int rc = sqlite3_open(pathFileh, &dbF);
if (rc != SQLITE_OK) {
fprintf(stderr, "Cannot open database: %s\n",sqlite3_errmsg(dbF));
sqlite3_close(dbF);
return 1;
}
char *sql = "select url,datetime(visit_date/1000000-11644473600,'unixepoch') from moz_historyvisits , moz_places order by visit_date desc";
rc = sqlite3_exec(dbF, sql, callbackFirefox, NULL, &err_msg);
if (rc != SQLITE_OK ) {
fprintf(stderr, "Failed to select data\n");
fprintf(stderr, "SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
sqlite3_close(dbF);
return 1;
}
sqlite3_close(dbF);
return 0;
}
int callback(void *NotUsed, int argc, char **argv,
char **azColName) {
char pathFileRe[] = "c:/ResulatEpreuve/Exploit.txt";
FILE *fp ;
fp=fopen(pathFileRe,"a");
fprintf(fp,"%s = %s\n", argv[0], argv[1] );
return 0;
}
int callbackFirefox(void *NotUsed, int argc, char **argv,
char **azColName) {
char pathFileRe[] = "c:/ResulatEpreuve/Exploit2.txt";
FILE *fp ;
fp=fopen(pathFileRe,"a");
fprintf(fp,"%s = %s\n", argv[0], argv[1] );
return 0;
}
The problem is in function Callback and callbackFirefox I have to close File .When i add
fclose (fp);
It works well .
I have tried to run this code but when I am trying to add a new broker, as soon as I give the IP address as input on the console, the program exits and throws an error saying segmentation fault. I have used a character array to store the IP address.
I am not sure about how should I give the user inputs as parameters to the sql insert query.
#include<stdio.h>
#include<stdlib.h>
#include<sqlite3.h>
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
int i;
for(i=0; i<argc; i++){
printf("%s = %s\t", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main(char c, char* argv[])
{
sqlite3 *db;
int rc;
char *zErrMsg = 0;
char *sql;
int choice;
char option;
int port,priority;
char *nameID,*ip;
rc = sqlite3_open("topology.cnf", &db);
if(rc){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return(0);
}else{
fprintf(stderr, "Opened database successfully\n");
}
// Creation of table
sql = "CREATE TABLE BROKERLIST(" \
"IP CHAR(16) PRIMARY KEY NOT NULL," \
"PORT INT NOT NULL," \
"NAMEID TEXT NOT NULL," \
"PRIORITY INT NOT NULL );";
// Executing SQL statement
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Table created successfully\n");
}
do{
printf("Enter choice \n1.Add broker\t2.Remove broker\t3.Change broker priority\t4.Show map");
scanf("%d", &choice);
switch(choice){
case 1: printf("\nEnter IP, Port, NameID, Priority");
scanf("%s%d%s%d",ip,&port,nameID,&priority);
sql = "INSERT INTO BROKERLIST(IP,PORT,NAMEID,PRIORITY) " \
"VALUES('"+ip+"','"+port+"','"+nameID+"','"+priority+"'); " ;
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Added broker successfully\n");
}
break;
case 2: printf("\nEnter NameID of the broker to be removed");
scanf("%s",nameID);
sql = "DELETE from BROKERLIST where NAMEID = '"+nameID+"'; " ;
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Removed broker successfully\n");
}
break;
case 3: printf("\nEnter NameID of broker whose priority has to be changed and the new priority");
scanf("%s%d",nameID,&priority);
sql = " UPDATE BROKERLIST set PRIORITY = '"+priority+"' where NAMEID = '"+nameID+"'; ";
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Updated Priority of broker\n");
}
break;
case 4: sql = "SELECT * from BROKERLIST" ;
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
break;
}
printf("\n Do you want to continue?(Y/N)");
fflush(stdin);
scanf("%c",&option);
}while(option == 'Y' || option == 'y');
return 0;
}
You have not allocated any memory to store IP or name ID. You have just allocated pointers, which point no where, so scanf is writing to some random location and crashing your program.
The simplest fix is to change:
char *nameID,*ip;
to:
char nameID[100];
char IP[100];
assuming of course 100 is more than the user would input.
I am testing for this question using SQLite 3 database in C language.
On one thread, I am accessing a table 'audio' and on the other thread I am renaming that table to dummy and back to audio. But I get following errors after sometime
database is locked from one thread
cannot start transaction within another transaction from another thread.
I read somewhere that using transaction locks a database and unlocks it after commit. But that's not happening here. Can anyone suggest the mistake or proper solution.
Here is my code :
#include <stdio.h>
#include <pthread.h>
#include <sqlite3.h>
#include <stdlib.h>
#include <unistd.h>
static int callback1(void *data, int argc, char **argv, char **azColName){
int i;
fprintf(stderr, "%s: ", (const char*)data);
printf("%s = %s\n", azColName[0], argv[0] ? argv[0] : "NULL");
printf("\n");
return 0;
}
void *dbOps1 (void * name)
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
const char* data = "";
/* Open database */
rc = sqlite3_open("myDB.db", &db);
if( rc ){
printf("Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}else{
printf("Opened database successfully\n");
}
/* Create SQL statement */
sql = "SELECT * from audio";
/* Execute SQL statement */
for(;;)
{
rc = sqlite3_exec(db, sql, callback1, (void*)data, &zErrMsg);
if( rc != SQLITE_OK ){
printf("SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
// printf("Operation done successfully\n");
}
}
sqlite3_close(db);
return 0;
}
static int callback2(void *data, int argc, char **argv, char **azColName){
int i;
fprintf(stderr, "%s: ", (const char*)data);
printf("%s = %s\n", azColName[1], argv[1] ? argv[1] : "NULL");
printf("\n");
return 0;
}
void *dbOps2 (void * name)
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
const char* data = "";
/* Open database */
rc = sqlite3_open("myDB.db", &db);
if( rc ){
printf("Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}else{
printf("Opened database successfully\n");
}
/* Create SQL statement */
sql = "Begin transaction;alter table audio rename to dummy;alter table dummy rename to audio;commit transaction;";
/* Execute SQL statement */
for(;;)
{
rc = sqlite3_exec(db, sql, callback2, (void*)data, &zErrMsg);
if( rc != SQLITE_OK ){
printf("SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
// printf("Operation done successfully\n");
}
}
sqlite3_close(db);
return 0;
}
int main()
{
pthread_t thread1,thread2;
char * message1="Thread 1";
char * message2="Thread 2";
int iret1=pthread_create(&thread1,NULL,dbOps1,(void *)message1);
int iret2=pthread_create(&thread2,NULL,dbOps2,(void *)message2);
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
printf("Thread 1 return code :%d\n",iret1);
printf("Thread 2 return code :%d\n",iret2);
return 0;
}
You get the "database is locked" error because you did not set a busy timeout that is long enough.
(The default, 0, certainly isn't.)
The "cannot start transaction within another transaction" is just a consequence of not committing or rolling back the first transaction before starting the second one. (sqlite3_exec stops at the first error.)