Knowledgebase
26 Jun
Ich habe mich der Sache mit meinem Fehlerhaften SMS-Speicher nochmals angenommen. Offensichtlich bin ich nicht der Einzige, der damit Probleme hat, siehe Apple Forum.
Eine Chance zur Reparatur hat man sowieso nur, wenn man ein offenes iPhone (Jailbreak) hat und ein sshd installiert ist. Damit habe ich mir mal die SQLite-Datenbank sms.db aus
/var/mobile/Library/SMS/sms.db
wegkopiert und analysiert. Die SMS-Nachrichten selbst landen in der Tabelle “message”. Zusätzlich gibt es noch eine Tabelle “msg_group”, in der eine Zusammenfassung über die verwalteten SMS abgelegt ist. Hier ist nach den Message-Centern sortiert die Anzahl der offenen SMS eingetragen. Aus dem Trigger “delete_message” der Tabelle “message” läßt sich erkennen, dass die Anzahl der gelesenen SMS in “msg_group” immer um -1 reduziert wird. Das kann natürlich ab und an zu den Fehlern führen, wie ich sie habe.
Wichtig: Vor Änderungen bitte
Ein update auf “msg_group” hilft hier schon einmal:
sqlite3 /var/mobile/Library/SMS/sms.dbsqlite> update msg_group set unread_count=0;
Das Problem ist nur, dass es in der Datenbank immer noch Einträge gibt, die als nicht gelesen markiert sind:
sqlite> select * from message where read<>1;sqlite> deletefrom message where read<>1;
SQL error: no such function: read
Aha. Beim Feld “read” handelt es sich anscheinend um ein Bitmap, dessen zweites Bit das Flag “read” darstellt. Nach langem suchen habe ich ein Script gefunden, das alle SMS pauschal löscht. Zwei kleine Anpassungen (fett) und schon klappts sowohl mit iPhone OS 3.0 als auch mit den “defekten” Nachrichten:
#! /usr/bin/pythonfrom sqlite3 import dbapi2 as sqlitedef message_read(flags): """reimplementation of an sqlite user defined function called by a trigger on the messages table.the trigger checks the message flags to see if a message has been read to see if the counter of unread messages in another needs to be updated when a message is deleted. """# second bit is the "was read" flag return (int(flags) & 0x02) >> 1db = sqlite.connect('/var/mobile/Library/SMS/sms.db')# register the user-defined function used by delete trigger db.create_function('read', 1, message_read)c = db.cursor()c.execute('delete from message where read<>1;') c.execute('update msg_group set unread_count=0;') db.commit()# vim:set ts=4 sw=4 ai et tw=80:
Es gibt inzwischen auch eine eine App “SMSFix” aus dem Cydia-Repository, die hat bei mir allerdings nicht funktioniert.
Weitere Quellen: toofisches.net, sukkology.net
6 Responses for "iPhone SMS-Fehler beheben"
Auch noch eine Variante: Den korrupten Trigger einfach kurz wegpusten:
sqlite> drop trigger delete_message;
Ab jetzt gehen deletes von einzelnen SMS sauber.
Im Fall der Fälle danach den Trigger wieder auf den korrupten Werkszustand zurück stellen:
CREATE TRIGGER delete_message AFTER DELETE ON message WHEN NOT read(old.flags) BEGIN UPDATE msg_group SET unread_count = (SELECT unread_count FROM msg_group WHERE ROWID = old.group_id) – 1 WHERE ROWID = old.group_id; END;
Grüsse Reto
Hallo,
ich habe mal eine kleine Frage! Ich befasse mich auch gerade mit der sms.db, habe dabei aber das Problem, dass die SMS an sich nicht richtig angezeigt werden, habe auch schon ein Backup usw. versucht, aber das brachte nix.
Ich bekomme bei einer beliebigen SQL query immer die Fehlermeldung: “SQL error: no such function: read”
In dieser Anleitung wurde das zwar angesprochen, aber schlau werde ich daraus trotzdem nicht!
Könntet ihr mir erklären was es bedeutet und wie ich die sms.db ändern kann ohne alle SMS löschen zu müssen!
Vielen Dank schon mal im Voraus
Grüße ACE
Hallo ACE,
richtig, die Function read macht ein Problem. Deshalb wird in der oberen Angabe diese auch eigens eine definiert. Dann klappts auch mit den SQL-Queries ;-)
Hallo Thomas,
Danke für die schnelle Antwort!
Aber ich verstehe es immer noch nicht so ganz wie das überhaupt alles zusammenwirkt also überhaupt an sich funktioniert?!
Müssen die Befehle über Python eingegeben werden oder wie ist das überhaupt aufgebaut!?!?
Ich habe ein wenig rumgewerkelt und bekomme sowas hier:
lPhone:~ root# /usr/bin/python
Python 2.5.1 (r251:54863, xx/xx/xx, xx:xx:xx)
[GCC 4.2.1 (Based on Apple Inc. build 5555)] on darwin
Type “help”, “copyright”, “credits” or “license” for more information.
>>> #! /usr/bin/python
… from sqlite3 import dbapi2 as sqlite
def message_read(flags):
“”"reimplementation of an sqlite user defined
function called by a trigger on the messages table.
the trigger checks the message flags to see if a
message has been read to see if the counter of
unread messages in another needs to be updated when
a message is deleted.
“”"
# second bit is the “was read” flag
return (int(flags) & 0×02) >> 1
db = sqlite.connect(’/var/mobile/Library/SMS/sms.db’)
# register the user-defined function used by delete trigger
db.create_function(’read’, 1, message_read)
c = db.cursor()
c.execute(’delete from message where read1;’)
c.execute(’update msg_group set unread_count=0;’)
db.commit()
# vim:set ts=4 sw=4 ai et tw=80:>>> def message_read(flags):
… “”"reimplementation of an sqlite user defined
… function called by a trigger on the messages table.
… the trigger checks the message flags to see if a
… message has been read to see if the counter of
… unread messages in another needs to be updated when
… a message is deleted.
… “”"
File “”, line 8
“”"
^
IndentationError: expected an indented block
>>> # second bit is the “was read” flag
… return (int(flags) & 0×02) >> 1
File “”, line 2
SyntaxError: ‘return’ outside function
>>> db = sqlite.connect(’/var/mobile/Library/SMS/sms.db’)
>>> # register the user-defined function used by delete trigger
… db.create_function(’read’, 1, message_read)
Traceback (most recent call last):
File “”, line 2, in
NameError: name ‘message_read’ is not defined
>>> c = db.cursor()
>>> c.execute(’delete from message where read1;’)
Traceback (most recent call last):
File “”, line 1, in
sqlite3.OperationalError: no such function: read
>>> c.execute(’update msg_group set unread_count=0;’)
>>>
>>> db.commit()
>>> # vim:set ts=4 sw=4 ai et tw=80:
geht das ungefähr in die richtige Richtung?!?! Oder übersehe ich gerade noch was?
Du musst mich entschuldigen, mit Datenbanken kenne ich mich noch nicht so dolle aus (habe gerade mal die Grundlagen gehört) aber das sollte sogar mit meinem Halbwissen machbar sein.
Danke
Grüße
ACE
Hallo ACE,
Python ist eine Programmiersprache. Du musst den Python-Code in eine Datei schreiben, ausführbar machen und dann auch ausführen. Ein paar Linuxkentnisse sind da schon hilfreich. An der ersten Zeile “#! /usr/bin/python” wird Unix die Lage der zu verwendenden Programmierumgebung angegeben. Hoffe, das hilft.
Aha! Jetzt ist alles klar! Super danke vielmals!
Also mein Problem war, dass ich dachte mit dem Script wäre eine Art Hintergrunddienst gestartet worden, der diese “read” Funktion imitiert, aber dabei müssen die Befehle lediglich mit Hilfe von Phyton eingespielt werden! Ich arbeite eigentlich nicht mit Scripts und Phyton ist für mich sowieso noch ein unerforschtes Gebiet…bis jetzt!
Nur noch vielleicht eine Frage, das Datum ist in der DB auf eine komische Art und weise kodiert, weißt du wie ich den Inhalt meiner alten SMS mit dem Originaldatum in die DB integrieren, kann bzw. wie komme ich von diesem Schlüssel auf das Datum in Klartext und wieder zurück?!!?
Vielen vielen Dank nochmal, damit ist das iPhone noch perfekter!
Grüße
ACE
Leave a reply