合并 1 个在 iOS 4.0.1 上运行的 iPhone 3GS 的 2 个 SMS 数据库 (sms.db),并将输出文件放回到 iPhone 上,而不会导致 SMS 应用程序崩溃
首先,我从来没有真正做过任何繁重的编程,只是用Python闲逛了一下。如果我的任何问题听起来很奇怪,请尝试理解我。
我遇到以下问题:
我的 iPhone 3GS 在 iOS 4.0.1 上运行,拨打电话时出现问题。解决此问题的唯一方法是将 iPhone 恢复至出厂设置。对于 iPhone 用户来说,显而易见的是,这样做我会丢失短信历史记录等信息。通过将 *.db 扩展名添加到包含整个 SMS 历史记录的数字命名文件中,我能够从备份中检索 sms.db 文件。
我现在拥有的是 2 个这样的 SMS 数据库:检索到的数据库和手机上已有新消息的数据库。我想做的是将这两个数据库中的数据合并到一个文件中(为了实现我的目标,我的 iPhone 显然是越狱的)。
iPhone sms.db 数据库包含各种表,其中之一称为“messages”,包含电话号码、SMS 消息文本、标志等信息。我能够使用 SQL 数据库浏览器 2.0 b1 将“message”表从较新的数据库导出到较旧的数据库中,并将其命名为“message2”。后来执行的时候遇到一些问题
INSERT INTO
statement in SQLite Manager for Firefox, I found out that first I had to drop and recreate the triggers causing theNo such function: "read"
error by executing the following statement:drop trigger insert_unread_message;
drop trigger mark_message_unread;
drop trigger mark_message_read;
drop trigger delete_message;
CREATE TRIGGER insert_unread_message AFTER INSERT ON message WHEN NOT new.flags = 2 BEGIN UPDATE msg_group SET unread_count = (SELECT unread_count FROM msg_group WHERE ROWID = new.group_id) + 1 WHERE ROWID = new.group_id; END;
CREATE TRIGGER mark_message_unread AFTER UPDATE ON message WHEN old.flags = 2 AND NOT new.flags = 2 BEGIN UPDATE msg_group SET unread_count = (SELECT unread_count FROM msg_group WHERE ROWID = new.group_id) + 1 WHERE ROWID = new.group_id; END;
CREATE TRIGGER mark_message_read AFTER UPDATE ON message WHEN NOT old.flags = 2 AND new.flags = 2 BEGIN UPDATE msg_group SET unread_count = (SELECT unread_count FROM msg_group WHERE ROWID = new.group_id) - 1 WHERE ROWID = new.group_id; END;
CREATE TRIGGER delete_message AFTER DELETE ON message WHEN NOT old.flags = 2 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;
经过所有这些,我终于能够将新的短信添加到旧的数据库中。然而,这并不标志着不同问题的结束。首先,我添加的新消息被放置在表的顶部(旧消息上方),“ROWID”列中的数字低于旧消息。表的正确(和逻辑)格式应该是将这些较新的消息放置在表的最底部,并为其分配更高的编号。我不知道要执行什么样的 SQL 语句才能仅返回以下格式的“ROWID”列:
ROWID
1
2
3
and so on, these numbers being the ones assigned to the newer messages. I've tried to achieve this by doing the following:SELECT * FROM message
WHERE ROWID='1' AND '2' AND '3'
and so on, but SQLite Manager returned only the row with the "1", not the rest. What sort of statement could be used to achieve what I want?另外,当我通过 SSH 重新连接到 iPhone 上已编辑的 sms.db 时,每次我撰写消息并点击“确定”按钮发送消息时,SMS 应用程序都会崩溃(消息中的长度或任何符号都不会)事情)。我读到,短信应用程序在渲染和显示某些字符不正确(例如 UNICODE)时可能会崩溃。我发现了 1 条 UNICODE 字符渲染错误的短信,并手动更正了它,但更正后应用程序仍然崩溃。我只是不确定我发现的是否是渲染的唯一错误。有没有什么方法(无论是在 SQL 中还是其他方式)来仅查找具有此类错误的文本?
此外,SSH-ed sms.db 的运行有点奇怪,因为它不显示列表中的所有消息。我可以通过使用搜索功能并输入消息的一部分来找到其中一些未显示的内容。然后 iPhone 找到它,只显示文本预览,没有任何姓名或电话号码,但当我点击它时无法打开它。它要么根本不响应点击,要么将我重定向到不同的对话历史记录。
如果有人对修改 sms.db 有更多的见解,或者对可能导致 SMS 应用程序崩溃的其他原因有任何想法,请随时发布您要说的内容:)
编辑:正如我所期望的那样,为 SMS 应用程序分配更高的数字新消息并将它们放在列表底部是有效的,现在我最关心的对话都显示了:)此外,短信应用程序不再崩溃:)但是,我仍然遇到的唯一问题是有些消息在您查看时不在列表中,但在搜索时键入的关键字与这些消息的内容匹配时会显示。和以前一样,它们在显示时既没有数字,也无法从搜索视图中打开。由于这些消息对我来说并不重要,因此我从 sms.db“消息”表中删除了它们,并将更改后的文件放回到 iPhone 上。虽然这些消息不再出现在 sms.bd 文件中,但在搜索时它们仍然会显示:/ 这不是一个大问题,因为其他一切都可以正常工作,但将它们出现在搜索结果中有点令人恼火。有谁知道我该如何解决这个问题?
感谢您到目前为止所得到的帮助,也感谢您提前提供更多帮助:)
First of all, I've never really done any heavy programming, just fooling around a bit with Python. If any of my questions sound odd or so, please try to understand me.
I have a following problem:
My iPhone 3GS running on iOS 4.0.1 had problems with making outgoing calls. The only way to solve this problem was to restore iPhone to its factory settings. As it's obvious to iPhone owners, doing so I lost things such as my SMS messages history. I was able to retrieve the sms.db file from the backup by adding the *.db extension to a numerically named file containing the whole SMS history.
What I have now are 2 such SMS databases: The retrieved one and the one with new messages already on the phone. What I would like to do is to merge data from these 2 databases into one, single file (for the purpose of my goal my iPhone is, obviosly, jailbroken).
The iPhone sms.db database contains various tables, one of which is called "messages" and contains information such the telephone numbers, SMS message text, flags and so on. I was able to export the "message" table from the newer database into the older one by using the SQL Database Browser 2.0 b1, and calling it "message2". Later, having some problems with executing the
INSERT INTO
statement in SQLite Manager for Firefox, I found out that first I had to drop and recreate the triggers causing the
No such function: "read"
error by executing the following statement:
drop trigger insert_unread_message;
drop trigger mark_message_unread;
drop trigger mark_message_read;
drop trigger delete_message;
CREATE TRIGGER insert_unread_message AFTER INSERT ON message WHEN NOT new.flags = 2 BEGIN UPDATE msg_group SET unread_count = (SELECT unread_count FROM msg_group WHERE ROWID = new.group_id) + 1 WHERE ROWID = new.group_id; END;
CREATE TRIGGER mark_message_unread AFTER UPDATE ON message WHEN old.flags = 2 AND NOT new.flags = 2 BEGIN UPDATE msg_group SET unread_count = (SELECT unread_count FROM msg_group WHERE ROWID = new.group_id) + 1 WHERE ROWID = new.group_id; END;
CREATE TRIGGER mark_message_read AFTER UPDATE ON message WHEN NOT old.flags = 2 AND new.flags = 2 BEGIN UPDATE msg_group SET unread_count = (SELECT unread_count FROM msg_group WHERE ROWID = new.group_id) - 1 WHERE ROWID = new.group_id; END;
CREATE TRIGGER delete_message AFTER DELETE ON message WHEN NOT old.flags = 2 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;
After all of this, I was able to finally add the newer SMS messages into the older database. This, however, didn't mark the end of different issues. First of all, the newer messages I added got placed at the top of the table (above the older ones) with numbers in the "ROWID" column lower than the older messages. The correct (and logical) format of the table should be for these newer messages to be placed at the very bottom of the table, having higher numbers assigned to them. I don't know what kind of SQL statement to execute to be returned only the "ROWID" column in the following format:
ROWID
1
2
3
and so on, these numbers being the ones assigned to the newer messages. I've tried to achieve this by doing the following:
SELECT * FROM message
WHERE ROWID='1' AND '2' AND '3'
and so on, but SQLite Manager returned only the row with the "1", not the rest. What sort of statement could be used to achieve what I want?
Also, when I SSH the edited sms.db I already have back on the iPhone, the SMS app crashes each time I compose a message and tap the "OK" button to send it (the length or any signs within the message don't matter). I've read that the SMS app may crash when it renders and displays some characters incorrectly (e.g. UNICODE). I found 1 SMS message in which the UNICODE characters were render incorrectly and corrected it manually, but the app still crashes after the correction. I'm just not sure if what I found was the only error with the rendering. Is there any way (either in SQL or other) to find only texts with such errors?
Besides, the SSH-ed sms.db operates a bit oddly, since it doesn't display all the messages in the list. I can find some of those it doesn't display by using the search function and typing a part of a message. Then iPhone finds it, displaying only the preview of the text without any name or phone number, but can't oen it when I tap on it. It either doesn't respond to the tapping at all or it redirects my to a different conversation history.
If anyone has more insight in modifying the sms.db or has any thoughts on what else may be causing the SMS app to crash, feel free to post what you have to say :)
EDIT: Just as I expected, assigning higher numbers to the newer messages and placing them at the bottom of te list worked, and now the conversations I cared the most about are all displayed :) Besides, the SMS app doesn't crash anymore :) The only problem I still have, however, is that there are some messages which aren't on the list while you view it, but are displayed when key words typed while searching match the contents of these messages. Just as it was before, They neither have no numbers while being displayed, nor can they be opened from the search view. As these messages in particular weren't important to me, I deleted them from the sms.db "message" table, and put back the altered file back onto the iPhone. Although these messages aren't in the sms.bd file anymore, they are still displayed while searching :/ It's not such a big problem, because everything else works again, but it's a bit irritating to have them in the search results. Does anyone have any idea how I could fix this?
Thank you for help I got so far, and also thank you for a bit more of it in advance :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当你说
你实际上是在说
我怀疑“2”和“3”被解释为 TRUE 时。此外,ROWID 应该是整数。将它们与字符串进行比较是可行的,因为 sqlite3 会自动将整数转换为字符串。
你的意思可能是这样的
When you say
You actually are saying
I suspect '2' and '3' are being interpreted as TRUE. Also, ROWIDs are supposed to be integers. Comparing them to strings works because sqlite3 automatically converts ints to strings.
You probably mean something like
使用移动终端并输入:
Use mobile terminal and type :