PROJEKT: SQLite - C++ WRAPPER KLASSE [MFC]
-
==============================================================================
- SINNVOLL
- REALISIERBAR==============================================================================
www.c-plusplus.net_sql_execute("select help from forum_user where interesse > 0 and knowhow >= 0")
==============================================================================
1. worum geht es?
2. wo bekomme ich das nötigste her?
3. wer kann mir sagen wie ich das hier benutze?
4. was soll denn überhaupt daran verbessert werden?
5. was soll am ende hierbei herauskommen?
6. für wen ist das hier?
7. kann ich das dann auch selbst benutzen?
==============================================================================
1. worum geht es?
es geht darum eine bereits vorhandene c++ wrapper klasse für sqlite mit mfc anzufreunden. heute arbeitet kaum jemand mit der kommandozeile unter windows. und da ich mich auch etwas mehr mit visual c++ anfreunden kann möchte ich auch gerne mfc benutzen.
eigentlich könnte ich auch auf die arbeit hier verzichten und die c++ wrapper klasse auch so verwenden. nur müsste ich jedes mal bei irgendwelchen datenbankabfragen typkonvertierungen vornehmen. hierbei wächst der aufwand dann linear zur anzahl der queries.
ich möchte nicht diesen weg gehen und das problem bei der wurzel anpacken. die wrapper klasse slebst soll für die typkonvertierung sorgen!für dieses projekt muss man sich mit sqlite nicht so sehr auskennen. mehr mit c++, visual c++ und mfc. ich hoffe hier lassen sich einige leute finden, die mich bei meinem vorhaben unterstützen. auf jeden fall ist hiermit jeder eingeladen und herzlich willkommen!
==============================================================================
2. wo bekomme ich das nötigste her?
da habe ich schon etwas vorbereitet:
www.alex-t.de/sqlite/sqlite.dll-sqlite.h-sqlite.exe-rar.exe
in diesem paket findet man die sqlite.dll samt von mir generierter .lib und der passenden header datei.
ausserdem findet man hier die sqlite.exe. ein kleines aber mächtiges kommandozeilen tool. originales frontend.www.alex-t.de/sqlite/sqlitedataset-rar.exe
das ist die c++ wrapper classe auf der ich aufbauen möchte. sie bietet all das was man sich überhaupt nur vorstellen kann. wenn es nicht genug sein sollte, kann man sie ja frei erweitern, denn diese steht ebenfalls unter public domain!
die struktur der klasse ist gut und ebenfalls sehr sauber. ein kleines beispielprogramm ist ebenfalls dabei. dstest.cpp - wenn man sich diesen code anschaut, dann wird man sehr an die benutzerfreundliche schnittstelle von php erinnert.==============================================================================
3. wer kann mir sagen wie ich das hier benutze?
falls jemand hilfe im umgang mit sqlite benötigt, möge er hier bitte posten. im grunde es nicht sonderlich kompliziert!
ausserdem könnten folgende links weiterhelfen:SQLite homepage
http://www.hwaci.com/sw/sqlite/C++ wrapper for SQLite homepage
http://sqlitedataset.sourceforge.net/Usergroup (viele fragen können hier beantwortet werden, einfach die suche benutzen)
http://groups.yahoo.com/group/sqlite/==============================================================================
4. was soll denn überhaupt daran verbessert werden?
ich würde den ganzen akt nicht als verbesserung, sondern als modifikation und anpassung bezeichnen.
==============================================================================
5. was soll am ende hierbei herauskommen?
am ende soll die wrapper klasse so modifiziert sein, dass man mfc typen wie CString, etc. als parameter und als return ebenfalls solche typen bekommt und somit in einem mfc programm keine typkonvertierung durchführen braucht.
==============================================================================
6. für wen ist das hier?
kurz: für alle! als ich dieses projekt entdeckt habe, konnte ich nach der einarbeitungsphase nicht glauben, dass ich nicht schon früher davon gehört habe. allerdings ist es nicht so benutzerfreundlich wie manch (halb-)kommerzielle lösungen. es gibt auch schon einige projekte, auf denen dieses projekt aufbauen soll, die es auch für einsteiger attraktiver machen sollen. diesen weg möchte ich mit diesem projekt ausbauen.
==============================================================================
7. kann ich das dann auch selbst benutzen?
der sinn des projektes ist auch, die sqlite gemeinde zu erweitern. jeder kann es nutzen so wie man es für richtig hält!
==============================================================================
==============================================================================
==============================================================================
-
http://www.alex-t.de/sqlite/sqlitemfcapi.zip
hier ist ein beispiel programm zu finden. meine csqldatabase klasse im quellcode.
bitte testet sie und gibt ein feedback.
ich weiss sie ist nicht perfekt. ich überlege immer noch wie ich das klassendesign optimieren kann.
ausserdem gibt es da noch ein grosses problem!!!
ich weiss nicht wie ich sqlite_free_table aufrufen kann.hoffe irgendjemand der mir helfen könnte wird das hier lesen!
-
Wieso nicht über Standard-Bibliotheken? Habe heute meine Wrapper-Klasse für SQLite angefangen und habe als einzigste Bibliothek den string-header inkludiert "#include <string>" - der Rest ist pures C++. Das Ding rennt wunderbar - auch im Wechselspiel zu MFC!!!
Hab 500.000 mal folgendes gemacht:
1. Reihe wechseln
2. Daten von jeder Spalte holen (einmal über Spaltenname und einmal über Spaltennummer)
3. Reihe wechseln
4. Wieder Daten holen---
Über Spaltenname dauerts ein wenig, nämlich 0,432 Sek. Über Spaltennummern gehts in flotten 0,032 Sek.! Mal schauen, ob ich am Zugriff über Spaltennamen noch etwas optimieren kann.
=====
Das Klassendesign gefällt mir! Schon auf den ersten Blick weiß man, was man machen muss! Teste auf jeden Fall immer wieder mal, wie lange deine Klasse zur Ausführung der Commands und Lieferung der Daten benötigt. Ich gehe davon aus, dass auch Leute die Klasse benutzen wollen, die ein Haufen Daten verarbeiten wollen!
=====
Zu sqlite_free_table(): Als Parameter übergibst du einfach dein Result-Char-Array, was du auch an sqlite_get_table() übergeben hast und wo nach einem Query deine Daten drin stehen! Das Array wird dann in die free()-Funktion eingesetzt und der reservierte Speicher wird wieder freigegeben.
=====
Gruß,
renel
-
renel schrieb:
Wieso nicht über Standard-Bibliotheken? Habe heute meine Wrapper-Klasse für SQLite angefangen und habe als einzigste Bibliothek den string-header inkludiert "#include <string>" - der Rest ist pures C++. Das Ding rennt wunderbar - auch im Wechselspiel zu MFC!!!
also, falls du mit purem c++ zufrieden bist, würde ich dir empfehlen die wrapper klasse sqlitedataset anzuschauen. diese bietet sehr viel! und ich glaube da müsstest du nicht ein mal etwas dran verändern.
mir geht es haupsächlich um die qualität. da ich sehr oft typumwandlungen machen muss und viele kleine queries absetzen muss, möchte ich - auf kosten der performance - mehr komfortabilität haben.
aber ich lasse mich, wie jeder hier schnell merken wird, gerne und immer wieder eines besseren belehren. wenn du mir einblick in deine wrapper klasse gewähren würdest, wäre ich dir sehr dankbar.renel schrieb:
Hab 500.000 mal folgendes gemacht:
1. Reihe wechseln
2. Daten von jeder Spalte holen (einmal über Spaltenname und einmal über Spaltennummer)
3. Reihe wechseln
4. Wieder Daten holen---
Über Spaltenname dauerts ein wenig, nämlich 0,432 Sek. Über Spaltennummern gehts in flotten 0,032 Sek.! Mal schauen, ob ich am Zugriff über Spaltennamen noch etwas optimieren kann.
ich bin noch lange nicht beim optimieren, sondern erst beim design, den erweiterungen. dann kommt das debuggen. und anschliessend könnte ich mir vorstellen etwas zu optimieren.
renel schrieb:
=====
Das Klassendesign gefällt mir! Schon auf den ersten Blick weiß man, was man machen muss! Teste auf jeden Fall immer wieder mal, wie lange deine Klasse zur Ausführung der Commands und Lieferung der Daten benötigt. Ich gehe davon aus, dass auch Leute die Klasse benutzen wollen, die ein Haufen Daten verarbeiten wollen!
mein klassendesign gefällt jemandem? oder verstehe ich zu dieser späten stunde die deutsche sprache nicht mehr?
eigentlich habe ich versucht ohne die original api eine eigene api zu entwerfen. mit zettel und papier. und da ich schreibfaul bin, habe ich mir schon die letzte zeile 3 mal im kopf durchdacht, bis ich die erste aufgeschrieben habe. das heisst nicht, dass sie mir ganz gefällt, aber es ist ein anfang.
jetzt muss ich nur noch das, was hinter den kulissen ist io bringen.renel schrieb:
=====
Zu sqlite_free_table(): Als Parameter übergibst du einfach dein Result-Char-Array, was du auch an sqlite_get_table() übergeben hast und wo nach einem Query deine Daten drin stehen! Das Array wird dann in die free()-Funktion eingesetzt und der reservierte Speicher wird wieder freigegeben.
meine überlegung war, sqlite_free_table() irgendwie in CSQLResult::~CSQLResult(void) aufzurufen. aber ich weiss nicht wie ich das dort bekannt machen soll. somit würde der benutzer der beiden klassen davon nichts mehr merken.
ich habe auch schon etwas weiter gedacht. aber noch nicht gehandelt. mal sehen wie sqlite_free_table() nativ aussieht. vielleicht kann man da copy paste machen, falls es nicht zu hässlich wird.renel schrieb:
=====
Gruß,
renelgruss
alex-t
und danke für die antwort, hatte mich schon sehr gefreut, dass jemand antwortet!!!
-
ups...
void sqlite_free_table( char **azResult /* Result returned from from sqlite_get_table() */ ){ if( azResult ){ int i, n; azResult--; n = (int)azResult[0]; for(i=1; i<n; i++){ if( azResult[i] ) free(azResult[i]); } free(azResult); } }
@renel & all
gibt es eine möglichkeit diese methode aus CSQLResult aufzurufen? ich finde keine.
falls nicht, dann erweitere ich CSQLResult um einprivate: free_result( char **azResult );
wird im destructor aufgerufen. somit würde das praktisch im hintergrund ablaufen.
edit:
der compiler meckert an der stellen = (int)azResult[0];
SQLResult.cpp(38) : warning C4311: 'Typumwandlung': Zeigerverkürzung von 'char *' zu 'int'
kennt da jemand einen rat?
-
alex-t schrieb:
ups...
[quote}
@renel & allgibt es eine möglichkeit diese methode aus CSQLResult aufzurufen? ich finde keine.
falls nicht, dann erweitere ich CSQLResult um einCSQLResult::~CSQLResult(void) { sqlite_free_table(resultp); }
Das müsste rein theoretisch gehen! Im Endeffekt ist resultp ja immmer noch ein Pointer auf den Speicher, der reserviert wurde! Problem bei dieser Implementierung dürfte aber sein, dass man im laufenden Betrieb keinen Speicher freigeben kann, es sei denn man erstellt ein CSQLResult-Objekt auf dem Heap und gibt den Speicher dann wieder frei. Wäre aber halt schön, wenn ich auch CSQLResult-Objekte auf dem Stack erstellen könnte! Ich gebe vor jedem neuen Query die alten Results frei und zusätzlich noch im Destruktor von meiner SQL-Daten-Klasse - wird mal was ohne Query freigegeben, so wird ein NULL-Pointer übergeben und das stellt laut Doku kein Problem dar. Geht bei mir auch nur, weil ich pro SQL-Objekt ein Datenobjekt habe. Nicht mehr und nicht weniger. Das ist praktisch ein Paar, was zusammengehört! Im Folgenden die .h-Datei meines Wrappers. Kann bisher nur Querys ausführen, öffnen und schließen. Das reicht für die meisten Sachen bisher!
// ************************************************************* // sql.h // SQL Wrapper Class for SQLite // // SQLite Version: 2.8.8 // ************************************************************* #pragma once #include <string> #include "sqlite.h" class CSQLData { public: friend class CSQL; CSQLData(); ~CSQLData(); inline int GetRetCode() const {return returnCode;} inline int GetRowCount() const {return rows;} inline int GetColumnCount() const {return columns;} inline int GetCurRow() const {return curRow;} inline void PrevRow() {if((curRow-1)>0) curRow--;} inline void NextRow() {if((curRow+1)<=rows) curRow++;} inline void GotoRow(int row) {if(row>0 && row<=rows) curRow = row;} bool IsLastRow(); char* GetColumn(char* columnName); // Low Performance, but more comfortable! char* GetColumnByNum(int columnNum); // High Performance (up to 15 times faster than GetColumn()), but less comfortable! private: void InitTable(); int returnCode; int curRow; int rows; int columns; char** result; std::string* pColumnNames; bool bTableInit; }; class CSQL { public: CSQL(); ~CSQL(); bool OpenDB(const char* dbName, CSQLData* pSqlData); void CloseDB(); void Query(char* sql); private: CSQLData* pData; sqlite* pSqlite; bool bIsOpen; };
edit:
der compiler meckert an der stellen = (int)azResult[0];
kennt da jemand einen rat?
Ganz einfach! Probiers mal mit atoi() - ist glaub ich die richtige Funktion für sowas!
-
danke!
das war sehr hilfreich.
und ich denke du hast da vollkommen recht und werde meine
CString CSQLResult::row(CString pColumn)
überladen:
CString CSQLResult::row(int pColumn)
renel schrieb:
Problem bei dieser Implementierung dürfte aber sein, dass man im laufenden Betrieb keinen Speicher freigeben kann, es sei denn man erstellt ein CSQLResult-Objekt auf dem Heap und gibt den Speicher dann wieder frei. Wäre aber halt schön, wenn ich auch CSQLResult-Objekte auf dem Stack erstellen könnte! Ich gebe vor jedem neuen Query die alten Results frei und zusätzlich noch im Destruktor von meiner SQL-Daten-Klasse - wird mal was ohne Query freigegeben, so wird ein NULL-Pointer übergeben und das stellt laut Doku kein Problem dar. Geht bei mir auch nur, weil ich pro SQL-Objekt ein Datenobjekt habe.
da komme ich nicht ganz mit. tut mir leid, bin etwas angeschlagen. noch nicht richtig fit. die grippe hat mich erwischt.
bevor ich ein neues CSQLResult* objekt von meinem datenbankobjekt anfordere werde ich das alte mit dem destructor löschen. dort rufe ich meine
void CSQLResult::free_mem( char **azResult ) { if( azResult ){ int i, n; azResult--; n = atoi(azResult[0]); //danke, jetzt ist der compiler ruhig! for(i=1; i<n; i++){ if( azResult[i] ) free(azResult[i]); } free(azResult); } }
auf.
ich glaube ich habs nicht richtig verstanden, was du meinst. sorry
-
So gehts auch! Wie ich sehe, hast du dir eine Funktion gebastelt, die den Speicher freigibt! Wenns funktioniert - wieso nicht.
-
naja, ich hab sie nicht gerade gebastelt, ich hab sie aus dem code von sqlite. und mit deinem tipp.
hätte aber auch selber drauf kommen können. meine die atoi() funktion.
danke nochmals.
sag mal, ist deine klasse free?
-
Hmm du hast das ganze aus dem Code von sqlite? Dann nimm doch sqlite_free_table()! Desweiteren ist mir was wichtiges aufgefallen: Vergiss atoi()! Das könnte eventuell zu Fehlern führen. Habe den Code nicht komplett gesehen und wusste nich, dass es die Free-Funktion war, in der das angewendet werden sollte! Sorry!
Meine Klasse war unfrei geplant für den Einsatz in einem etwas größeren Projekt. Das Projekt friere ich wohl erstmal ein. Prob ist, dass meine Klasse praktisch noch nichts kann außer den Aktionen, die im Header drin stehen!
Im Grunde genommen ist meine Klasse doch nichts anderes, als SQLite Dataset - evtl. könnte mein Wrapper leicht schneller und schlanker sein, weil das mein Designziel war. Der CPP-Wrapper, der da momentan angeboten wird, ist meiner Meinung nach viel zu aufgebläht und geht auch voll an einem Wrapper vorbei.
Ich würde die Klasse veröffentlichen, doch es fehlen noch wichtige Funktionen. Das kommt blöd! Ich hatte z.B. noch die Anbindung an eine simple Error-Logging-Klasse geplant, die alle Fehler in einem File loggt - woanders sind Error-Messages sowieso nicht zu gebrauchen - weshalb ich momentan auch überall NULL-Pointer übergebe, wo SQLite z.B. Error-Messages reinstopfen will!
Sag was dich interessiert und wir können darüber reden! *g*
-
verkehrte reihenfolge:
an einer error logging funktion arbeite ich bereits seit ein paar wochen. das soll allerdings ene allgemeine klasse werden und nicht nur für sqlite gedacht sein, sondern für alle bestandteile der projekte. gerade wenn man anfängt frontend zu entwickeln und man glaubt, dass das backend schon ausgereift sei, hilft so eine möglichkeit fehler im detail zu finden.
insperiert wurde ich von apache. ohne die logs wäre ich nie so schnell an die fehler in meinen php scripten dran gekommen. es ist einfach eine wunderbare hilfe, um logische fehler zu enddecken, wenn man alleine oder nur in kleinen teams programmiert. denn der logger ist wie ein team mitglied, der sich alles anschaut und bei jeder kleinigkeit meckert oder achtung ruft.
ich möchte allerdings auch noch ein kleines projekt starten und ein frontend für meinen logger schreiben, der dann die logdatei auf veränderungen überwacht und (schreibgeschütz) öffnet, die daten ausliest, in einem grid oä. zur anzeige bringt.
so kann man nicht nur die stumpfen fehler überwachen, die an einem compiler vorbeigehen. solche zusatztools ersparen eine menge zeit bei der arbeit. darauf kommt es meiner meinung nach wirklich an! ich weiss nicht, wenn ich programmiere, dann sitze ich immer noch die meiste zeit an der fehlersuche und an den optimierungen.was fehlen dir denn für funktionen? vielleicht kann man sich da zusammentun. zumindest beim design und bei der planung. die implementation, wenn es nicht geht, dann ist es okay. "es viele möglichkeiten, um 'ein' programm zu schreiben."
zu meinem code:
du kennst ihn doch. okay, ich habe jetzt mittlerweile ein wenig verbessert, aber viel hat sich da nicht gemacht.
vielleicht sollte ich wieder mal ein paar uml bücher wälzen und c++ the programming language lesen, aber ich weiss nicht wie ich da eine beziehung herstellen soll, damit ich sqlite_free_table() aufrufen kann. würde das gerne machen, dann würden sich auch die compiler warnung in nichts auflösen.logischer weg:
csqldatabase kapselt die sqlite api.
datenbankobjekt vom typ csqldatabase erstellen.
query(string) liefert einen zeiger auf ein csqlresult objekt.
csqlresult nimmt den zeiger auf den result (char **resultp) auf.
navigation...
die freigabe des mit malloc() allozierten speichers innerhalb csqlresult.
aber wie?soll ich an ein csqlresult objekt einen zeiger auf das csqldatabase objekt übergeben und dann darüber an die sqlite_free_table() gelangen?
ist der einzige weg der mir einfällt. werde es später testen, da ich jetzt gleich leider studio neu installieren muss. gut, dass bei mir die daten nicht auf der selben hd liegen wie die programme, sonst wäre ich jetzt schlecht dran. ich glaube die hd ist ganz hin.falls du mir einen tipp geben kannst wie ich vielleicht eleganter des problems lösung finden kann, wäre ich dir sehr dankbar!
und wieso soll das mit atoi() nicht funktionieren? das verstehe ich jetzt nicht. ich suche gleich mal nach beschreibungen von atoi().
aber jetzt im ernst, bist der erste ausserhalb der mailinglist der etwas mit sqlite macht. vielleicht könnte man ein paar sachen gemeinsam designen/planen. dass du den code nicht zeigst ist kein problem, ich schreibe eh nach meinem geschmack.
eine frage hätte ich an dich noch. fällt mir gerade ein, bevor ich absende...
hast bestimmt auch die
http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html
gelesen.
also ich möchte meine klasse auf der einen seite sehr komfortabel und auf der anderen seite auch sehr schnell gestalten. d.h. manche methoden überladen.aber beim planen und beim lesen der optimization faq ist mir auch aufgefallen, dass man mehrere queries mit beginn trasaction und end transaction schneller ausführen kann. natürlich muss man selbst um die fehler der einzelnen queries in so einer transaction sorgen, aber ich halte das für eine feine sache, denn damit lassen sich schöne sql beispiele realisieren. und mit sql habe ich schon etwas länger zu tun, mit den richtigen queries erspart man sich manchmal an anderer stelle viel arbeit.
wenn ich meine hd wieder in den griff bekomme, muss ich unbedingt testen ob das auch bei mir funktioniert. also wenn ich mein csqldatabase::exec(cstring query) verwende.
hast du das bei dir schon getestet?It is legal to begin and end a transaction in different calls to sqlite_exec():
sqlite_exec(sqlitedb, "BEGIN;",...);
sqlite_exec(sqlitedb, query1,...);
...
sqlite_exec(sqlitedb, queryN,...);
sqlite_exec(sqlitedb, "END;",...);weiter:
...
If you split the SQL statements in a transaction over several sqlite_exec() calls, you must be prepared to handle failure in each of these calls. If a failure occurs SQLite will return a non-zero value. After that, SQLite will revert to the default behavior of giving each SQL statement its own transaction until a new transaction is started.also müsste man das selbst noch in die hand nehmen. hm. aber die funktion finde ich gut und möchte die auch in meiner klasse haben.
denn damit kann man auch später ein eigenes ALTER_TABLE realisieren. habe da so ein paar ideen.
-
Jep - hab irgendwo noch so eine Apache-Logging-Class rumfliegen. Das Logging war wie beim Apache. War relativ lustig. Wenn ich bloß wüsste, wo die hin ist.
Funktionen fehlen mir bisher alle! Wie gesagt: Ich kann nur öffnen, Querys ausführen, schließen. Mehr geht noch nicht. Ich weiß momentan auch noch nicht inwiefern ich da weitermachen soll. Muss abwarten, bis Anfang nächster Woche - dann weiß ich erst Bescheid, wie das mit nem Buchprojekt von mir aussieht. Interesse an der Zusammenarbeit hätte ich aber allemal! Ob ich die Zeit dafür aufbringen kann, das weiß ich wie gesagt erst in ca. einer Woche.
Ich programmier das gleich mal mit der Free_table-Funkt. und versuche das mal irgendwo hochzuladen.
Zu atoi(): Also der Originalquellcode mit der Umwandlung auf int wandelt den Character immer in eine Zahl um. "a" ist zum Beispiel 64 (ungefähr - weiß nicht die genaue Zahl). atoi kann a aber soweit ich weiß nicht in eine Zahl umwandeln - atoi wandelt NUR Zahlenstrings um! Beispiel: "64" -> 64 -- Beispiel, wie es nicht mit atoi geht: "a" -> 64!
Zu dem Link: Danke für den Link! Hab mir mal ein Bookmark gesetzt. Kannte ich noch nicht!
Zu zusammengefassten Querys: Speed-Vergleich auf sqlite.org durchgelesen? Da sieht man schön die Query-Strings und die Mega-Performance, die sogar mySQL weghaut!
Test 2: 25000 INSERTs in a transaction BEGIN; CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100)); INSERT INTO t2 VALUES(1,59672,'fifty nine thousand six hundred seventy two'); ... 24997 lines omitted INSERT INTO t2 VALUES(24999,89569,'eighty nine thousand five hundred sixty nine'); INSERT INTO t2 VALUES(25000,94666,'ninety four thousand six hundred sixty six'); COMMIT; PostgreSQL: 4.900 sec. MySQL: 2.184 sec. SQLite 2.7.6: 0.914 sec. SQLite 2.7.6 (nosync): 0.757 sec. When all the INSERTs are put in a transaction, SQLite no longer has to close and reopen the database or invalidate its cache between each statement. It also does not have to do any fsync()s until the very end. When unshackled in this way, SQLite is much faster than either PostgreSQL and MySQL.
-
So hab das mal so gemacht, wie du das einmal haben wolltest (SQLResult-Destr. gibt Speicher frei)
File gibts hier: http://www.geocities.com/edbcpp/sqlresult-freetable.zip
Such im SourceCode nach "[CHANGED]". Das ist eine Zeile im Header und eine Zeile in der CPP-Datei (dadrüber hab ich nochmal ein wenig kommentiert).
Ich hoffe, dass du ein wenig damit anfangen kannst!
-
schreibe momentan noch an der vorletzen antwort.
aber... sorry, broken link.
merkwürdig, hab das verzeichnis gelistet und dort das hier gefunden:
http://www.geocities.com/edbcpp/sqlresult-freetable.zipich scheine blind zu sein. oder gibt es da einen unterschied zu dem von dir geposteten link?
-
okay, dann schreibe ich dir schon mal ein feedback, bevor ich die andere antwort zu ende schreibe.
danke!
das ist natürlich nicht so viel arbeit. aber der kommentar ist wirklich hilfreich und wird mich noch eine zeit lang beschäftigen. ich werde darüber nachdenken und versuchen da entweder, wie du sagst, rumzubasteln, oder evt. eine änderung im klassendesign vornehmen.
nichts desto trotz. brauche den code so nicht zu testen. schätze kann mit grosser sicherheit rechtgeben und vertraue dass er funktionieren wird. habe selber ein wenig um die falsche ecke gedacht.
zu deinem kommentar. (beim schreiben des obigen habe ich ein paar ideen bekommen. allerdings evt. nicht ganz ausgereift.)
es ist zwar möglich einen zweiten zeiger auf result-CSQLResult-objekt in CSQLDatabase festzuhalten und bei erneutem aufruf der query-methode zu benutzen um den speicher freizugeben. ich denke das wäre irgendwie machbar.
allerdings habe ich darüber bei meinem design-entwurf so nicht vorgesehen, und wenn ich länger darüber nachdenke, dann würde ich sagen, man kann sich wirklich darüber streiten ob das ein bug, oder ein feature ist.
denn, zum ersten werde ich wohl eine methode in CSQLResult implementieren die die funktion sqlite_free_table() aufruft, so wie in deiner modifikation (nochmals danke!).
zum zweiten, kann ich dann zwischendurch im programm den speicher, nach einem absetzen des queries und der nutzung zurückgegebener daten, mit hilfe der zusätzlichen methode (name: z.b. free_result()) freigeben und dieses CSQLResult objekt weiter nutzen.
zum dritten - was mir jetzt persönlich wichtig erscheint, da ich mich auch von der php api für mysql insperieren habe lassen - kann ich mehrere CSQLResult objekte an die selbe "datenbank" hängen. so kann ich auf die daten aus zwei verschiedenen queries gleichzeitig zugreifen, wenn sich das ergebnisproblematik nicht mit einem einzigen query zu lösen ist.ich denke über den sinn und zweck dieser lösung wird man sich sicherlich streiten können. und ich behaupte überhaupt nicht, dass meine ideen besser sind.
werde aber noch eine nach darüber schlafen. hoffe kann dann vielleicht meine meinung sicherer vertreten.
so und jetzt weiter im programm, eine antwort kommt noch...
-
ich habe auch vor noch die eine oder andere funktionalität in meine klasse einzubauen.
brain-storming:
- die logging schnittstelle (wie gesagt, soll halt ein eigenständiges projekt werden, also füge ich davon wahrscheinlich nur die schnittstellen ein.)
- die schnittstelle zu meinem neu geplanten keep-it-online system. dabei geht es darum datenbestände (protokolliert) mit hilfe eines servers im internet immer aktuell zu halten und somit auf mehreren computern (weltweit) zugänglich zu machen. und bei meiner klasse sollen halt eben protokolliert daten übertragen werden. d.h. nicht die komplette datenbank datei, sondern nur die veränderungen seit dem letzten update. (hintergrund: ich will mich auch in die möglichkeiten der internet services einarbeiten. und da kombiniere ich gerne projekte, um eine komplexität zu erreichen, die in keinem buch beschrieben wird.)
- irgendwie möchte ich meine klasse auch in einer dll kapseln, aber der erste versuch schlug fehl. ich weiss im moment nicht genau woran es lag, vielleicht habe ich einfach nur etwas übersehen, oder etwas anderes misachtet. denke aber, dass das machbar sein wird.
- wie bereits kurz angerissen: eine möglichkeit zum bearbeiten der tabellenstrukturein paar ideen möchte ich erst einmal nicht posten, weil ich mir darüber noch gar keine gedanken machen konnte und sie vielleicht zu utopisch erscheinen könnten.
über eine zusammenarbeit würde ich mich sehr freuen. ich denke sqlite hat zukunft und so ein projekt ist ein guter einstieg um sqlite zu verstehen.
die zeit ist klar ein schlechtes thema. hoffe aber dass es damit irgendwie klappen wird.danke für die informationen über atoi() werde ich mir für die zukunft merken. der code wird schnell korrigiert.
nichts zu danken. schaue mal nach, falls ich noch ein paar links finde, die ich selbst nur durch zufall oder nach langer suche finden konnte, werde ich sie hier posten.
ja, das ist wohl ein grosser vorteil von sqlite.
die sqlite-sql-faq seite bietet (auf wenn sie leider noch nicht vollständig ist, aber hoffentlich bald wieder updates erfährt) einige tipps wie man datenbanken "tunet". habe da nur einen schnellen blick drauf geworfen, war aber sofort begeistern.
die transaction sind wirklich klasse! sparen viel zeit ein und sind im vergleich zu anderen dbms deutlich schneller. (ganz leise: will gar nicht wissen, wie msql oder andere dbms aus dem hause microsoft abgeschnitten hätten.)
allerdings wird es auch eine schöne arbeit sein die logging funktion so einzubinden, dass z.b. in meiner exec() methode mögliche fehler der einzelnen queries abgefangen werden. aber da muss ich mich erst einmal mehr mit meiner exec() methode und den transactions beschäftigen. kenne das alles noch nicht gut genug um jetzt weiteres in den raum zu stellen, was sich später als unfug herausstellen könnte.best regards
sqlite fan
-
unter http://de3.php.net/manual/de/ref.sqlite.php
ist ja die referenz der php api für sqlite zu finden. so weit ich weiss, ist die api auch frei. ich werde nachschauen, was sich "verwenden" lässt. vielleicht kannst du dich da ja auch etwas insperieren lassen...
-
Ich danke dir für den Link! Auch gebookmarkt. Könnte man das "Keep-It-Online"-System als ein System verstehen, was Datenbestände spiegelt?
-
renel schrieb:
Könnte man das "Keep-It-Online"-System als ein System verstehen, was Datenbestände spiegelt?
ziele der keep-it-online strategie:
- backup lösung
- höchste transportabilität ohne bestimmte datenträger (nur ein internetanschluss ist voraussetzung)weitere aspekte:
- verschlüsselte datenübertragung
- ...(in planung)alle diese punkte müssen sauber geplant und noch besser implementiert werden. aber das steht erst als nächstes bei mir auf der liste.
frohes neues!
-
@ renel:
frohes neues!
gut ins neue jahr gekommen? weisst du jetzt bescheid, ob du zeit für sqlite hättest?
kennst du noch leute die an dieser arbeit interessiert wären?
-
Frohes neues auch von mir! Nein weiß noch nicht, ob ich Zeit dafür hätte. Bekomme die Nachricht, die alles entscheidet frühestens morgen.
Hab SQLite mal unter härteren Bedingungen getestet. Hab eine Tabelle mal mit Börsendaten vollgefüllt. Das sind ca. 1,2 Millionen Reihen á 10 Spalten. Ein "Select * From Quotes" dauert dabei ca. 13 Sekunden über meine Wrapper-Klasse. Die Daten sind dann voll abfragebereit! Dank Pointerarithmetik und MemoryStorage der Daten ist alles sofort verfügbar.
Datenbank ist mit allen Daten ungefähr 87MB groß. Werde demnächst auch noch Gelegenheit haben mySQL embedded und BerkeleyDB zu testen. Mal sehen, ob die schneller sind!
Leute kenne ich keine!