Firefox - Chronik - SQLite
-
Hallo,
Habe mir vorgenommen ein Programm zu schreiben, das mir alle besuchten Seiten und dazugehörige Uhrzeiten aus dem Firefox-Browser zusammenfasst bzw in ne Datei schreibt.Mir geht es eigentlich nur darum, wie die places.sqlite mit Hilfe von C++ und einer Datenbankprogrammierschnittstelle zu lesen ist und wie ich da inhalte in Strings umwandle, um sie irgendwohin zu schreiben.
Würde mich auch gern etwas mehr mit "C++ & Datenbanken" befassen.
Habt ihr eine Ahnung, wo ich anfangen kann, bzw. wie ich überhaupt Datenbanken mit Hilfe von C/C++ lesen kann, bzw. Inhalte herausfiltern kann?MfG
QuellcodeEdit:
Oh... ich war mal wieder zu schnell. Habe hier viel Nützliches gefunden. Würde mich dennoch freuen zu erfahren, wie man aus der Datenbank gewisse Daten filtern kann. Kann ich so etwas "SELECT-FROM-WHERE" benutzen?
-
(Ja das geht mit SELECT)
-
Gut, danke für die Hilfe.
Ich habe es geschafft die Datenbank zu öffnen und die gewünschten Informationen zu erhalten bzw. sie in ein Textdokument zu speichern.Habe zwar von SQL nicht so viel Ahnung, da ich die Vorlesungen versäumt habe. Aber mit den Tutorials von Google bin ich selbst darauf gekommen, was zu tun ist.
EDIT:
Jetzt habe ich glatt noch etwas vergessen.
Es wird jedes Mal eine AccessViolation-Exception geworfen, wenn mein Programm am Ende des Tables mit den urls ist. Woran das liegt wei ich leider nicht, un d damit ihr nicht lange rästeln müsst was falsch sein kann hier einfach mal der Quelltext://--------------------------------------------------------------------------- #pragma hdrstop #include <tchar.h> #include <iostream.h> #include <string.h> #include "sqlite3.h" //--------------------------------------------------------------------------- #pragma argsused int count = 0; FILE *fp = fopen("C:\\log.txt", "w+"); // Die Callback-Funktion ist aus der Dokumentation geklaut static int callback(void *NotUsed, int argc, char **argv, char **azColName) { int i; for(i=0; i<argc; i++){ printf("%s: %d = %s\n", azColName[i], count, argv[i] ? argv[i] : "NULL"); count++; fprintf(fp, "%s\n", argv[i] ? argv[i] : "NULL"); } printf("\n"); return 0; } int _tmain(int argc, _TCHAR* argv[]) { sqlite3* Database; const char* path = "C:\\places.sqlite"; char **err; if(sqlite3_open(path, &Database) != SQLITE_OK) { cout << "Fehler beim Öffnen: " << sqlite3_errmsg(Database) << endl; return 1; } cout << "Datenbank erfolgreich geöffnet!" << endl; if(sqlite3_exec(Database, "SELECT url FROM moz_places;", callback, 0 ,err) != SQLITE_OK) { cout << "Fehler beim Ausführen der QUERY" << endl; return 1; } sqlite3_close(Database); cout << "Datenbank geschlossen!" << endl; fclose(fp); getchar(); return 0; }
Bin das ganze mal mit dem Debugger Step-By-Step durchgegangen und der Fehler tritt genau dann auf, wenn er mit der For-Schleife fertig ist und das return 0 ausgeführt hat. Wo genau liegt mein Fehler?
-
ich entschuldige mich gleich vorweg für den Doppelpost, habe aber die Lösung des Problems gefunden!
vorher:char **err; if(sqlite3_exec(Database, "SELECT url FROM moz_places;", callback, 0, err) != SQLITE_OK) {...}
nachher:
char *err; if(sqlite3_exec(Database, "SELECT url FROM moz_places;", callback, 0, &err) != SQLITE_OK) {...}
Kann mir das jemand erklären?
Ist doch genau dasselbe, oder liege ich da falsch?
-
Nein. Es ist nicht das selbe. Im Ersten Fall erstellst du einen Pointer auf einen Pointer, dieser Pointer zeigt aber nicht auf einen Pointer, da er nicht initialisiert wird.
Im zweiten Fall erstellst du einen Pointer. Und du übergibst einen Pointer auf diesen Pointer der Funktion. Das klappt dann, denn jetzt zeigt der Pointer den du übergibst auf einen gültigen Speicherbereich, der einen Pointer aufnehmen kann.
Zweiteres ist äquivalent zu ersterem, wenn du folgendes schreibst.
char *inhalt; char **err = &inhalt;
-
Noch eine Kleinigkeiten: err erhält von der Funktion sqlite3_exec mit malloc()
Speicherplatz zugewiesen wenn ein Fehler auftritt (und nur dann). Denke daran,
den bei einem Fehler nach dem anzeigen wieder freizugeben.zB
if(sqlite3_exec(Database, "SELECT url FROM moz_places;", callback, 0 ,err) != SQLITE_OK) { printf( "\nFehler: %s", err); free( err); return 1; }
-
Danke für die Hinweise.
Habe sqlite3_free(); zur Speicherplatzfreigabe genommen und
jetzt habe ich das mit den Pointern verstanden.Werde jetzt noch ein bisschen SQL üben müssen, weil ich die Uhrzeit/Datum dazu noch herausfiltern will, die sich in einer anderen Tabelle befindet.
Wie ich das bewerkstellige weiß ich noch nicht genau, entweder zweiter sqlite3_exec() - Aufruf oder alles mit einmal(was ich aber schwieriger finde), was so aussehen könnte:Variante 1:
1. urls:sqlite3_exec(Database, "SELECT url FROM moz_places;", callback, 0, &err);
2. datum:
sqlite3_exec(Database, "SELECT visit_date FROM moz_historyvisits;", callback, 0, &err);
Variante 2:
sqlite3_exec(Database, "SELECT url, visit_date FROM moz_places, moz_historyvisits, WHERE (in den beiden tabellen gibt es id's)id1=id2;", callback, 0, &err)
-
Variante 2 nennt sich Join und ist der Weg, wie man es normalerweise macht.
-
ja, sorry, dass ich davon keine ahnung hab...
-
Wenn Du SQLite sauber laufen hast dann besorge Dir mal Literatur.
Zu empfehlen wäre: Einführung in SQL, O'Reilly, ISBN 3-89721-443-1.
-
Danke für den Buchhinweis, jedoch versteh ich den Satz davor nicht.