|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2163
|
[C++] SQLite - inserire/estrarre jpg
Sono 3 giorni che studio come fare in C++, ho trovato MOLTI articoli ma non ne vengo a capo. Ho trovato esempi come QUESTO, QUESTO e QUESTO, mi sono letto molte cose su http://www.sqlite.org e mille commenti di altre persone.
L'inserimento sono riuscito, ma non riesco a fare ad estrarre il jpg e poi poterlo usare come variabile in una classe C++. Provengo da Java, e il C/C++ mi da ancora molte grane.
__________________
Vendo...nulla. Cerco...la felicità. |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Dovresti postare un pò di codice, nei link che hai indicato c'è la soluzione al tuo problema.
|
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2163
|
Ho notato che l'insertion da me scritto non funzionava.
Si lo so che negli esempi c'è la soluzione, ma io dovrei modificarli in base alle mie classi e non ci riesco. In pratica nel DB ho un TABLE con 4 colonne. Ogni colonna è un attributo della mia classe Item: Codice:
#include "Item.h"
using namespace Tamagotchi;
using namespace std;
Item::Item(string aName, int aPrice, int anHappiness, FILE aPicture){
name=aName;
price=aPrice;
happiness=anHappiness;
picture = aPicture;
}
int Item::getPrice(){
return price;
}
int Item::getHappiness(){
return happiness;
}
string Item::getName(){
return name;
}
FILE Item:: getPicture(){
return picture;
}
__________________
Vendo...nulla. Cerco...la felicità. |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Si ma serve il codice che hai scritto per interrogare sqlite
|
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2163
|
...è proprio quello che mi manca e serve.
__________________
Vendo...nulla. Cerco...la felicità. |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Potresti cominciare copiando quello che hai trovato no?
Ad esempio questo è un esempio funzionanate: http://www.yolinux.com/TUTORIALS/SQLite.html#BLOB |
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2163
|
Quote:
__________________
Vendo...nulla. Cerco...la felicità. |
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2163
|
Allora, l'insertion che avevo fatto (ora cancellato perchè non mi serve più) era sbagliato perchè, se non erro, il quarto parametro di sqlite3_bind_blob() deve essere la dimensione del file in bytes. Forse se avessi cambiato quello, punzionava.
Comunque dato che l'insertion non serviva per la funzionalità del mio programma, ho optato per creare il DB a mano usando sqliteman di Linux. Ora però mi serve l'algoritmo di interrogazione. Partiamo dall'inizio. Se i valori restituiti fossero semplici valori (int o string) potrei usare semplicemente sqlite3_exec(). Dato che il dato estratto è un blob, non so come muovermi. Mi stavo orientando sul "readBlob()" dell'altro ESEMPIO.
__________________
Vendo...nulla. Cerco...la felicità. |
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2163
|
Bene, me lo sono studiato e ho scritto del codice:
Codice:
ostringstream oss;
int aNumber = getItemRandomNumber();
oss << aNumber;
string number = oss.str();
string aQuery = "SELECT image FROM items WHERE number = " + number + ";";
unsigned char** ptrPicture;
int* ptrPictureSize;
const char* bQuery = &aQuery[0];
sqlite3_stmt* pStmt;
int rc;
const char* ptrValue = &oss.str()[0];
do {
rc = sqlite3_prepare(databaseConnection, bQuery, -1, &pStmt, 0);
if (rc != SQLITE_OK) {
cerr << "error by sqlite3_prepare";
}
sqlite3_bind_text(pStmt, 1, ptrValue, -1, SQLITE_STATIC);
rc = sqlite3_step(pStmt);
if (rc == SQLITE_ROW) {
*ptrPictureSize = sqlite3_column_bytes(pStmt, 0);
*ptrPicture = (unsigned char *) malloc(*ptrPictureSize);
memcpy(*ptrPicture, sqlite3_column_blob(pStmt, 0), *ptrPictureSize);
}
rc = sqlite3_finalize(pStmt);
} while (rc == SQLITE_SCHEMA);
Idee?
__________________
Vendo...nulla. Cerco...la felicità. |
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2163
|
Dopo altre 3 ore sono arrivato a fare qualche modifica:
Codice:
ostringstream oss;
int aNumber = getItemRandomNumber();
oss << aNumber;
string number = oss.str();
string aQuery = "SELECT image FROM items WHERE number = " + number + ";";
FILE* ptrPicture;
int* ptrPictureSize;
const char* bQuery = &aQuery[0];
sqlite3_stmt* pStmt;
int rc;
const char* ptrValue = "newfile.jpg";
do {
rc = sqlite3_prepare(databaseConnection, bQuery, -1, &pStmt, 0);
if (rc != SQLITE_OK) {
cerr << "error by sqlite3_prepare in getRandomItem";
}
sqlite3_bind_blob(pStmt, 1, ptrValue, -1, SQLITE_STATIC);
rc = sqlite3_step(pStmt);
if (rc == SQLITE_ROW) {
*ptrPictureSize = sqlite3_column_bytes(pStmt, 0);
ptrPicture = (FILE*) malloc(*ptrPictureSize);
memcpy(ptrPicture, sqlite3_column_blob(pStmt, 0), *ptrPictureSize);
}
rc = sqlite3_finalize(pStmt);
} while (rc == SQLITE_SCHEMA);
Ora se lancio, non da errori e non va in crash. La mia domanda... Come faccio a vedere se veramente mi prende l'immagine dal DB e mi crea l'oggetto di tipo FILE?
__________________
Vendo...nulla. Cerco...la felicità. |
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2163
|
FINALMENTE penso di aver capito. Ho scritto il seguente metodo:
Codice:
Item* Database::getRandomItem() { //TODO
//getting a random number from the table items
int aNumber = getRandomNumber("items");
string number;
//converting the random number to a string
{
ostringstream oss;
oss << aNumber;
number = oss.str();
}
//getting the name price and happiness value from
//the table itemns, accordingly to the random number
//and converting the price and hapiness to int
string aQuery =
"SELECT name, price, happiness, image, filename FROM items WHERE number = "
+ number + ";";
sqlite3_stmt *pStmt;
char* ptAQuery = &aQuery[0];
if (sqlite3_prepare_v2(databaseConnection, ptAQuery, -1, &pStmt, 0)
!= SQLITE_OK) {
cerr << "db error (preparev2 in getRandomItem): " << sqlite3_errmsg(
databaseConnection) << endl;
}
if (sqlite3_step(pStmt) != SQLITE_ROW) {
cerr << "db error (step in getRandomItem): " << sqlite3_errmsg(
databaseConnection) << endl;
}
const unsigned char* ptName = sqlite3_column_text(pStmt, 0);
char* ptNameChar = (char*) ptName;
string nameString = ptNameChar;
int price = sqlite3_column_int(pStmt, 1);
int happiness = sqlite3_column_int(pStmt, 2);
int imageSize = sqlite3_column_bytes(pStmt, 3);
FILE* ptImage = (FILE*) malloc(imageSize);
memcpy(ptImage, sqlite3_column_blob(pStmt, 3), imageSize);
const unsigned char* ptFilename = sqlite3_column_text(pStmt, 4);
char* ptFilenameChar = (char*) ptFilename;
string filenameString = ptFilenameChar;
sqlite3_finalize(pStmt);
return new Item(filenameString, price, happiness, ptImage);
}
Ora ho due dubbi: 1. dato che ptImage è un puntatore, una volta che uso sqlite3_finalize(pStmt); il puntatore perde il valore, o grazie a malloc e memcpy resta? 2. come faccio a testare se fuzniona? Chiedo "gentilmente" due risposte
__________________
Vendo...nulla. Cerco...la felicità. |
|
|
|
|
|
#12 | |
|
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Quote:
1) Non funzionerà certamente perchè stai cercando di allocare tramite malloc un FILE, operazione che è destinata miseramente a fallire, dovresti invece allocare un buffer. 2)Un debugger? Una osservazione: quando copi il risultato di sqlite3_column_text in una stringa non hai bisogno di effettuare tutti quei passaggi: Codice:
string nameString((const char*)sqlite3_column_text(pStmt, 0)); |
|
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2163
|
che potevo scrivere direttamente string non lo sapevo, pensavo di dover fare le conversioni. Grazie per l'osservazione.
Che dovevo "liberare" dopo malloc lo sapevo, ma me ne sono scordato. Per il fatto del buffer...non ho idea di come fare. Hai voglia si spiegarmi?
__________________
Vendo...nulla. Cerco...la felicità. |
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Quote:
Codice:
vector<unsinged char>ptImage(imageSize); memcpy(&ptImage[0], sqlite3_column_blob(pStmt, 3), imageSize); |
|
|
|
|
|
|
#15 | |
|
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2163
|
Quote:
Non manca qualcosa? Codice:
vector<unsinged char>ptImage(imageSize);
__________________
Vendo...nulla. Cerco...la felicità. Ultima modifica di Emaborsa : 21-04-2011 alle 11:38. |
|
|
|
|
|
|
#16 | |
|
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2163
|
Quote:
__________________
Vendo...nulla. Cerco...la felicità. |
|
|
|
|
|
|
#17 | |
|
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Quote:
Forse il namespace std se non hai dichiarato lo using prima e ovviamente l'include dell'header vector: Codice:
#include <vector> ... std::vector<unsinged char>ptImage(imageSize); |
|
|
|
|
|
|
#18 | |
|
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Quote:
Contiene informazioni riguardanti uno stream di dati e deve essere istanziato ed elaborato da funzioni presenti in cstdio.h. Non hai modo programmaticamente di istanziare correttamente tutte le strutture dati interne all' "oggetto" FILE, nè tanto meno può farlo malloc, che semplicemente riserva un'area di memoria. |
|
|
|
|
|
|
#19 | ||
|
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2163
|
Quote:
Quote:
Codice:
char* ptImage = (char*) malloc(imageSize); memcpy(ptImage, sqlite3_column_blob(pStmt, 3), imageSize); const unsigned char* ptFilename = sqlite3_column_text(pStmt, 4); const char* ptFilenameChar = (const char*) ptFilename; ofstream outfile (ptFilenameChar,ofstream::binary); outfile.write (ptImage,imageSize);
__________________
Vendo...nulla. Cerco...la felicità. Ultima modifica di Emaborsa : 21-04-2011 alle 22:24. |
||
|
|
|
|
|
#20 | ||
|
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Quote:
Il vantaggio di vector è che è compatibile con gli array del C. Quote:
In tal caso devi usare le funzioni di io su file del C al posto di ofstream tipo: Codice:
FILE * fp = fopen(ptFilenameChar, "wb"); fwrite (ptImage, 1 , imageSize , fp ); ... fclose(fp); |
||
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 08:02.




















