Mst137 Mst137 - 3 months ago 14
C Question

Unable to read from SQLite database

Im trying to read from a database row-by-row. I am getting a warning that states "assignment makes integer from pointer without a cast [enabled by default" for all the rows containing the sqlite3_column_text() function. However no such error occurs on the row in which I try to get an integer, although this line still only returns 0 from the database.

rc handling is removed for compactness.

typedef struct {
char InstrumentType[32];
char Protocol[16];
int RegNum;
char RW[4];
char RegisterType[32];
char Signed[8];
char Inverted[8];
char DataType[16];
} Register;

typedef struct {
char InstrumentType[32];
int Bus;
int Address;
int Port;
int Sampling;
char Sync[2];
Register Reg[];
} Instrument;

int main(void) {
sqlite3 *db;
Register Register[8];
sqlite3_stmt* SQL;
char SQL2[128];
int i;
int MPTotalReg;

int rc;

rc = sqlite3_open("/root/BBBTest/Instruments.db", &db);

for (i=0; i<4; i++){

rc = sqlite3_prepare_v2(db, "SELECT * from instrumentsdefinition WHERE Type='Magprobe' AND Register=?;", -1, &SQL, 0);

rc = sqlite3_bind_int(SQL, 1, i);

*Register[i].InstrumentType=(const char*) sqlite3_column_text(SQL,2);
*Register[i].Protocol=(const char*) sqlite3_column_text(SQL,3);
Register[i].RegNum= sqlite3_column_int(SQL,5);
*Register[i].RW=(const char*) sqlite3_column_text(SQL,5);
*Register[i].RegisterType=(const char*) sqlite3_column_text(SQL,6);
*Register[i].Signed=(const char*) sqlite3_column_text(SQL,7);
*Register[i].Inverted=(const char*) sqlite3_column_text(SQL,8);
*Register[i].DataType=(const char*) sqlite3_column_text(SQL,9);
printf("Magprobe %d\n", i);
printf("Instrument Type: ");
printf("%s\n", Register[i].InstrumentType);
printf("Protocol: ");
printf("%s\n", Register[i].Protocol);
printf("Register: ");
printf("%d\n", Register[i].RegNum);
printf("R/W?: ");
printf("%s\n", Register[i].RW);
printf("Register Type: ");
printf("%s\n", Register[i].RegisterType);
printf("Signed?: ");
printf("%s\n", Register[i].Signed);
printf("Inverted?: ");
printf("%s\n", Register[i].Inverted);
printf("Data Type: ");
printf("%s\n", Register[i].DataType);


I know the error is something related to char arrays and chars however I've tried numerous methods to fix this. Also the fact that the int returned is always 0 leads me to believe there is an error with my prepare or bind statement also.


Using you cannot assign an array to another, you have to copy source array content to destination array, eg using strcpy

unsigned char *value = sqlite3_column_text(SQL,2);
if ((value != NULL) && (strlen(value) < sizeof(Register[i].InstrumentType)))
    strcpy(Register[i].InstrumentType, value);

In your specific case you can also use pointers to do that refactoring your struct.

Register[i].InstrumentType=(const char*) sqlite3_column_text(SQL,2);
if (Register[i].InstrumentType != NULL)

I wrote your specific case due to the fact that as soon as you call sqlite3_finalize, the return values from sqlite3_column_text become invalid.

Another thing is the query execution, after bind you must call

rc = sqlite3_step(stmt);

to retrieve result of query execution. You should loop until returned value is == SQLITE_ROW

 for (i=0; i<4; i++)
    rc = sqlite3_prepare_v2(db, "SELECT * from instrumentsdefinition WHERE Type='Magprobe' AND Register=?;", -1, &SQL, 0);

    rc = sqlite3_bind_int(SQL, 1, i);

    rc = sqlite3_step(stmt);

    if (rc == SQLITE_ROW)
       // QUERY retrieve a record from DB

Last thing It would be better to change name of array. Not has the same name of defined struct type. Something like Register registers[8];