UNIX_TIMESTAMP() mit QSqlTableModel

Verschiedenes zu Qt
Antworten
pfusterschmied
Beiträge: 91
Registriert: 14. Mai 2007 11:19
Wohnort: Salzburg
Kontaktdaten:

UNIX_TIMESTAMP() mit QSqlTableModel

Beitrag von pfusterschmied »

Hallo,
Ich möchte folgenden SQL Befehl ausführen:

Code: Alles auswählen

UPDATE `my_DB`.`my_Table` SET `tstamp` = UNIX_TIMESTAMP() WHERE `my_Table`.`uid` =682 LIMIT 1 ;
Hintergrund:
Ich möchte jede Änderung an den MySQL Datensätzen mit einer Timestamp versehen.

Da ich mit meiner QSqlTableModel arbeite habe ich probleme die MySQL Anweisung umzusetzten. Ist es möglich diesen MySQL Befehl mit setData() des QSqlTableModel auszuführen?
Folgendes funktioniert nicht:

Code: Alles auswählen

OnlineModel->setData(OnlineModel->index(row,2),"UNIX_TIMESTAMP()");
Da ja nur jener timestamp des veränderten Datensatzes aktualisiert werden darf und ich in einer QTableView arbeite habe ich mit einem normalen QSqlQuery auch probleme.

Wäre für jeden kleinen Tipp dankbar, da ich schon seit Stunden auf dem Schlauch stehe.
pfusterschmied
Beiträge: 91
Registriert: 14. Mai 2007 11:19
Wohnort: Salzburg
Kontaktdaten:

Beitrag von pfusterschmied »

Mit QSqlQuery funktioniert es einwandfrei!
Nun bräuchte ich nur noch irgenwie den richtigen Datensatz ansprechen.

Möglicherweise über QIndex und die uid ???? K.A.

Code: Alles auswählen

QSqlQuery insertTime(QSqlDatabase::database ("online"));
	insertTime.prepare("UPDATE `my_DB`.`my_Table` SET `tstamp` = UNIX_TIMESTAMP() WHERE `my_Table`.`uid` =682 LIMIT 1 ; ");
	insertTime.exec();
pfusterschmied
Beiträge: 91
Registriert: 14. Mai 2007 11:19
Wohnort: Salzburg
Kontaktdaten:

Teillösung gefunden

Beitrag von pfusterschmied »

So ich hab jetzt zumindest einen kleinen Fortschritt erreicht. Mit folgendem Code wird bei jedem Klick auf die TableView automatisch in die TS Spalte was geschrieben:

Code: Alles auswählen

connect (tableViewOnline, SIGNAL(clicked(const QModelIndex) ),this,SLOT(changeTime(const QModelIndex) ));

void dbselect::changeTime(const QModelIndex index)
{
	QSqlRecord record = MySqlTableModel->record(index.row());
	qDebug() << record.value(2);
	
	record.setValue (2,"UNIX_TIMESTAMP()" ); //Liefert Null ??? 
	MySqlTableModel->setRecord (index.row(),record );
	
	// Änderungen übernehmen
	submit();
}
Nun bleiben dennoch zwei Probleme bestehen:
Ist es möglich nur ein Signal zu senden, wenn Daten in der TableView geändert werden?
Wie könnte ich einen Workaround bewerkstelligen, wenn UNIX_TIMESTAMP() anscheinend nicht als SQL Befehl gesetzt wird?

Bitte um kleinen Beistand!
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Entweder du verwendest eine Datenbank die das von sich aus kann (Postgres z.B.) oder du überlädst updateRowInTable
pfusterschmied
Beiträge: 91
Registriert: 14. Mai 2007 11:19
Wohnort: Salzburg
Kontaktdaten:

Beitrag von pfusterschmied »

Danke für den Tipp:
.. oder du überlädst updateRowInTable
Upsala, was würde ich nur ohne dich machen. Ich glaube du hast 80% aller meiner Posts beantwortet. Woher nimmst du bloß die Zeit dafür?

Die Methode der Klasse QSqlTableModel ist wie in der Doku steht virtual protected:

Code: Alles auswählen

bool QSqlTableModel::updateRowInTable ( int row, const QSqlRecord & values )   [virtual protected]
Ich trau mich gar nicht zu fragen aber ...
Als Neuling fehlen mir noch die Basics wie ich nun eine geschütze Methode innerhalb einer Klasse benutzen kann.

Ich vermute mal ich muss mir ne Klasse basteln die von der QSqlTableModel erbt (Polymorphismus) oder?

Ein kurzes Bsp. wäre nett.
Danke
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Woher nimmst du bloß die Zeit dafür?
Ich frag mich eher, was andere Leute in dieser Zeit machen...
Ich vermute mal ich muss mir ne Klasse basteln die von der QSqlTableModel erbt (Polymorphismus) oder?
Genau
abelmi
Beiträge: 16
Registriert: 19. Februar 2007 14:56

Beitrag von abelmi »

Ich arbeite gerade an einem ähnlichen Problem.

Wir haben die Sache mit den Timestamps über Trigger in der Datenbank (Oracle) gelöst. Dadurch ist sichergestellt, dass die Datensätze auch einen Timestamp erhalten, wenn sie nicht vom Programm aus in die Datenbank geschrieben werden. Dies ist z.B. der Fall beim Einspielen von Testdaten über Füllskripte.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Trigger sind bei MySQL erst ab Version 5.1 möglich.
pfusterschmied
Beiträge: 91
Registriert: 14. Mai 2007 11:19
Wohnort: Salzburg
Kontaktdaten:

Beitrag von pfusterschmied »

Ich arbeite mit MySQL 5.0....

Bis jetzt habe folgende Fortschitte gemacht:
Ich habe die bereits beschriebene Methode abgeändert. Bei jeden Click in die QTableView wird der entsprechenden TimeStamp des Index geändert:

Code: Alles auswählen

void epconfigurator::changeTime(const QModelIndex index)
{
	QSqlRecord record = OnlineModel->record(index.row());
	
	record.setValue (2,"UNIX_TIMESTAMP()" ); // Option 1
        //record.setValue (2,"666" ); // Option 2
	OnlineModel->setRecord (index.row(),record );
}
Natürlich ist dies nicht im Sinne des Erfinders.
Der Eintrag in die DB erfolgt zwar, jedoch wird die TimeStamp Spalte auf 0 gesetzt.
Wie könnte ich einen Workaround bewerkstelligen, wenn UNIX_TIMESTAMP() anscheinend nicht als SQL Befehl gesetzt wird?
Ich dreh mich seit 2 Tagen im total im Kreis.

Habe mittlerweile ein totales Verständnisproblem:
Wie funktioniert die Abarbeitung bei SQLModel?

QTabelview -> dataChanged -> QSqlTableModel->updateRowInTable() ????

Welches Signal wird gesendet, wenn der Content der QTableView bzw. QSqlTableModel geändert wird?


Weiters habe ich auch versucht auf die updateRowInTable Methode zuzugreifen, .....
leider scheiter ich da noch an den Basics. Muss wohl noch eine Menge C++ lernen.

Code: Alles auswählen

class MyQSqlTableModel : public QSqlTableModel
{			
	public:
		MyQSqlTableModel();
		~MyQSqlTableModel();
	private slots:
	void	updateRowInTable ( int row, const QSqlRecord & values );
};

Fehler:
/epconfigurator.h:45: error: conflicting return type specified for 'virtual void MyQSqlTableModel::updateRowInTable(int, const QSqlRecord&)'
/usr/include/qt4/QtSql/qsqltablemodel.h:126: error: overriding 'virtual bool QSqlTableModel::updateRowInTable(int, const QSqlRecord&)'

Fehlermeldung ist mir klar, nur wie ich meine Klassen definieren muss nicht!
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Bei meinen Projekten mit SQLite hab ich dem QSqlQuery immer ein QDateTime-Objekt übergeben (In der SQL-Tabelle ein "date_time"). Funktioniert problemlos. Da das QSqlTableModel wohl für die updates auch QSqlQuery verwendet, warum versuchst du nicht einfach dem index ein QDateTime::currentDateTime() unterzuschieben? Sollte doch eigentlich klappen...
pfusterschmied
Beiträge: 91
Registriert: 14. Mai 2007 11:19
Wohnort: Salzburg
Kontaktdaten:

Beitrag von pfusterschmied »

Klasse Idee, habe ich gerade ausprobiert,
das klappt ja 1A.
Besten Dank, aber:

Ich arbeite an einem Client Programm, welches mir Daten aus einem Online-Anmeldesystem holt (Typo3). Diese Daten sind alle mit einem Unix TimeStamp versehen.

Wenn es dafür eine Lösung gibt währe ich sehr dankbar.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Versteh die Frage nicht ganz :D
Du hast in deiner Tabelle eine Spalte mit dem Type "date_time". Qt konvertiert automatisch (falls notwendig) von QDateTime nach date_time und zurück.
Was du jetzt mit deinem Anmeldesystem machen willst ist mir schleierhaft ;) Wenn du einen Zugang zur Datenbank hast, kannst du doch die Verbindung direkt mit QSqlDatabase verwenden. Oder was genau willst du da jetzt machen?
pfusterschmied
Beiträge: 91
Registriert: 14. Mai 2007 11:19
Wohnort: Salzburg
Kontaktdaten:

Beitrag von pfusterschmied »

Ich habe in der Mysql Datenbank eine Spalte tstamp [ int(10)], welche vom Content Management System (Typo3) automatisch mit einer UNIX_TIMESTAMP() versehen wird.
Spricht der Datensatz in dieser Spalte hat folgendes Format : 1159894375

Nun habe ich eine neue Spalte epdate [datetime] einfach hinzugefügt und deinen Ratschlag befolgt, welche einwandfrei und gut funktioniert.

Wenn nun über das Content Management System ein Eintrag verändert wird ändert sich die tstamp Spalte wenn in meinem Client Programm ein Eintrag verändert wird ändert sich die epdate Spalte.

Da ich nun im Programm überprüfen muss ob der geänderte Datensatz auch aktueller ist als in der DB habe ich nun ein Problem....

Ich hoffe es ist in irgend einer Form verständlich.

Kurz:
Typo3 : UNIX_TIMESTAMP()
QT : ???
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Du darfst ruhig mal in der Doku blättern, so viele Funktionen bietet QDateTime nicht.
Deine UNIX_TIMESTAMP() zeigt die Anzahl der Sekunden seit "1970-01-01T00:00:00" an. In der Qt-Doku findest du diese Angabe auch.

Code: Alles auswählen

uint unix_timestamp = QDateTime::currentDateTime().toTime_t();
Für den aktuellen Zeitpunkt.
pfusterschmied
Beiträge: 91
Registriert: 14. Mai 2007 11:19
Wohnort: Salzburg
Kontaktdaten:

Beitrag von pfusterschmied »

Danke,

wer lesen kann ist natürlich klar im Vorteil.

Jetzt läuft fast alles so wie ich es brauche, muss jetzt "nur" noch einSignal finden dass meine Funktion nur dann aufruft, wenn Daten in der QTableView geändert wurden.

Brauche ich updateRowInTable zwingend dafür oder könnte man das anders auch lösen ?
Antworten