From d676ea3ec2997b4842ccbc847f774751eaf674f0 Mon Sep 17 00:00:00 2001
From: Kashiko Koibumi <kashiko@tuta.io>
Date: Thu, 30 May 2024 18:13:15 +0900
Subject: [PATCH] quick workaround for BLOB as TEXT problem (#2247)

---
 src/api.py                                 |  74 ++++++++++++---
 src/bitmessagecurses/__init__.py           |  41 ++++++--
 src/bitmessagekivy/baseclass/maildetail.py |   7 +-
 src/bitmessageqt/__init__.py               | 103 ++++++++++++++++-----
 src/bitmessageqt/account.py                |   7 +-
 src/bitmessageqt/foldertree.py             |   2 +-
 src/class_objectProcessor.py               |  23 +++--
 src/class_singleCleaner.py                 |   9 +-
 src/class_singleWorker.py                  |  62 ++++++++++---
 src/class_smtpServer.py                    |   7 +-
 src/class_sqlThread.py                     |   2 +-
 src/helper_inbox.py                        |  22 ++++-
 src/helper_sent.py                         |  19 +++-
 src/helper_sql.py                          |  13 ++-
 src/protocol.py                            |   3 +-
 src/storage/sqlite.py                      |   1 +
 src/tests/core.py                          |  11 ++-
 src/tests/test_helper_sql.py               |  15 ++-
 18 files changed, 320 insertions(+), 101 deletions(-)

diff --git a/src/api.py b/src/api.py
index a4445569..87af4d32 100644
--- a/src/api.py
+++ b/src/api.py
@@ -67,6 +67,7 @@ import subprocess  # nosec B404
 import time
 from binascii import hexlify, unhexlify
 from struct import pack, unpack
+import sqlite3
 
 import six
 from six.moves import configparser, http_client, xmlrpc_server
@@ -953,20 +954,32 @@ class BMRPCDispatcher(object):
                     23, 'Bool expected in readStatus, saw %s instead.'
                     % type(readStatus))
             queryreturn = sqlQuery(
-                "SELECT read FROM inbox WHERE msgid=?", msgid)
+                "SELECT read FROM inbox WHERE msgid=?", sqlite3.Binary(msgid))
+            if len(queryreturn) < 1:
+                queryreturn = sqlQuery(
+                    "SELECT read FROM inbox WHERE msgid=CAST(? AS TEXT)", msgid)
             # UPDATE is slow, only update if status is different
             try:
                 if (queryreturn[0][0] == 1) != readStatus:
-                    sqlExecute(
+                    rowcount = sqlExecute(
                         "UPDATE inbox set read = ? WHERE msgid=?",
-                        readStatus, msgid)
+                        readStatus, sqlite3.Binary(msgid))
+                    if rowcount < 1:
+                        rowcount = sqlExecute(
+                            "UPDATE inbox set read = ? WHERE msgid=CAST(? AS TEXT)",
+                            readStatus, msgid)
                     queues.UISignalQueue.put(('changedInboxUnread', None))
             except IndexError:
                 pass
         queryreturn = sqlQuery(
             "SELECT msgid, toaddress, fromaddress, subject, received, message,"
-            " encodingtype, read FROM inbox WHERE msgid=?", msgid
+            " encodingtype, read FROM inbox WHERE msgid=?", sqlite3.Binary(msgid)
         )
+        if len(queryreturn) < 1:
+            queryreturn = sqlQuery(
+                "SELECT msgid, toaddress, fromaddress, subject, received, message,"
+                " encodingtype, read FROM inbox WHERE msgid=CAST(? AS TEXT)", msgid
+            )
         try:
             return {"inboxMessage": [
                 self._dump_inbox_message(*queryreturn[0])]}
@@ -1035,8 +1048,14 @@ class BMRPCDispatcher(object):
         queryreturn = sqlQuery(
             "SELECT msgid, toaddress, fromaddress, subject, lastactiontime,"
             " message, encodingtype, status, ackdata FROM sent WHERE msgid=?",
-            msgid
+            sqlite3.Binary(msgid)
         )
+        if len(queryreturn) < 1:
+            queryreturn = sqlQuery(
+                "SELECT msgid, toaddress, fromaddress, subject, lastactiontime,"
+                " message, encodingtype, status, ackdata FROM sent WHERE msgid=CAST(? AS TEXT)",
+                msgid
+            )
         try:
             return {"sentMessage": [
                 self._dump_sent_message(*queryreturn[0])
@@ -1072,8 +1091,14 @@ class BMRPCDispatcher(object):
         queryreturn = sqlQuery(
             "SELECT msgid, toaddress, fromaddress, subject, lastactiontime,"
             " message, encodingtype, status, ackdata FROM sent"
-            " WHERE ackdata=?", ackData
+            " WHERE ackdata=?", sqlite3.Binary(ackData)
         )
+        if len(queryreturn) < 1:
+            queryreturn = sqlQuery(
+                "SELECT msgid, toaddress, fromaddress, subject, lastactiontime,"
+                " message, encodingtype, status, ackdata FROM sent"
+                " WHERE ackdata=CAST(? AS TEXT)", ackData
+            )
 
         try:
             return {"sentMessage": [
@@ -1093,7 +1118,9 @@ class BMRPCDispatcher(object):
         # Trash if in inbox table
         helper_inbox.trash(msgid)
         # Trash if in sent table
-        sqlExecute("UPDATE sent SET folder='trash' WHERE msgid=?", msgid)
+        rowcount = sqlExecute("UPDATE sent SET folder='trash' WHERE msgid=?", sqlite3.Binary(msgid))
+        if rowcount < 1:
+            sqlExecute("UPDATE sent SET folder='trash' WHERE msgid=CAST(? AS TEXT)", msgid)
         return 'Trashed message (assuming message existed).'
 
     @command('trashInboxMessage')
@@ -1107,7 +1134,9 @@ class BMRPCDispatcher(object):
     def HandleTrashSentMessage(self, msgid):
         """Trash sent message by msgid (encoded in hex)."""
         msgid = self._decode(msgid, "hex")
-        sqlExecute('''UPDATE sent SET folder='trash' WHERE msgid=?''', msgid)
+        rowcount = sqlExecute('''UPDATE sent SET folder='trash' WHERE msgid=?''', sqlite3.Binary(msgid))
+        if rowcount < 1:
+            sqlExecute('''UPDATE sent SET folder='trash' WHERE msgid=CAST(? AS TEXT)''', msgid)
         return 'Trashed sent message (assuming message existed).'
 
     @command('sendMessage')
@@ -1217,7 +1246,10 @@ class BMRPCDispatcher(object):
             raise APIError(15, 'Invalid ackData object size.')
         ackdata = self._decode(ackdata, "hex")
         queryreturn = sqlQuery(
-            "SELECT status FROM sent where ackdata=?", ackdata)
+            "SELECT status FROM sent where ackdata=?", sqlite3.Binary(ackdata))
+        if len(queryreturn) < 1:
+            queryreturn = sqlQuery(
+                "SELECT status FROM sent where ackdata=CAST(? AS TEXT)", ackdata)
         try:
             return queryreturn[0][0]
         except IndexError:
@@ -1354,7 +1386,9 @@ class BMRPCDispatcher(object):
         """Trash a sent message by ackdata (hex encoded)"""
         # This API method should only be used when msgid is not available
         ackdata = self._decode(ackdata, "hex")
-        sqlExecute("UPDATE sent SET folder='trash' WHERE ackdata=?", ackdata)
+        rowcount = sqlExecute("UPDATE sent SET folder='trash' WHERE ackdata=?", sqlite3.Binary(ackdata))
+        if rowcount < 1:
+            sqlExecute("UPDATE sent SET folder='trash' WHERE ackdata=CAST(? AS TEXT)", ackdata)
         return 'Trashed sent message (assuming message existed).'
 
     @command('disseminatePubkey')
@@ -1421,19 +1455,29 @@ class BMRPCDispatcher(object):
         # use it we'll need to fill out a field in our inventory database
         # which is blank by default (first20bytesofencryptedmessage).
         queryreturn = sqlQuery(
-            "SELECT hash, payload FROM inventory WHERE tag = ''"
-            " and objecttype = 2")
+            "SELECT hash, payload FROM inventory WHERE tag = ?"
+            " and objecttype = 2", sqlite3.Binary(b""))
+        if len(queryreturn) < 1:
+            queryreturn = sqlQuery(
+                "SELECT hash, payload FROM inventory WHERE tag = CAST(? AS TEXT)"
+                " and objecttype = 2", b"")
         with SqlBulkExecute() as sql:
             for hash01, payload in queryreturn:
                 readPosition = 16  # Nonce length + time length
                 # Stream Number length
                 readPosition += decodeVarint(
                     payload[readPosition:readPosition + 10])[1]
-                t = (payload[readPosition:readPosition + 32], hash01)
-                sql.execute("UPDATE inventory SET tag=? WHERE hash=?", *t)
+                t = (payload[readPosition:readPosition + 32], sqlite3.Binary(hash01))
+                _, rowcount = sql.execute("UPDATE inventory SET tag=? WHERE hash=?", *t)
+                if rowcount < 1:
+                    t = (payload[readPosition:readPosition + 32], hash01)
+                    sql.execute("UPDATE inventory SET tag=? WHERE hash=CAST(? AS TEXT)", *t)
 
         queryreturn = sqlQuery(
-            "SELECT payload FROM inventory WHERE tag = ?", requestedHash)
+            "SELECT payload FROM inventory WHERE tag = ?", sqlite3.Binary(requestedHash))
+        if len(queryreturn) < 1:
+            queryreturn = sqlQuery(
+                "SELECT payload FROM inventory WHERE tag = CAST(? AS TEXT)", requestedHash)
         return {"receivedMessageDatas": [
             {'data': hexlify(payload)} for payload, in queryreturn
         ]}
diff --git a/src/bitmessagecurses/__init__.py b/src/bitmessagecurses/__init__.py
index 64fd735b..b87b9dde 100644
--- a/src/bitmessagecurses/__init__.py
+++ b/src/bitmessagecurses/__init__.py
@@ -17,6 +17,7 @@ import sys
 import time
 from textwrap import fill
 from threading import Timer
+import sqlite3
 
 from dialog import Dialog
 import helper_sent
@@ -358,7 +359,9 @@ def handlech(c, stdscr):
                                 inbox[inboxcur][1] +
                                 "\"")
                             data = ""       # pyint: disable=redefined-outer-name
-                            ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", inbox[inboxcur][0])
+                            ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", sqlite3.Binary(inbox[inboxcur][0]))
+                            if len(ret) < 1:
+                                ret = sqlQuery("SELECT message FROM inbox WHERE msgid=CAST(? AS TEXT)", inbox[inboxcur][0])
                             if ret != []:
                                 for row in ret:
                                     data, = row
@@ -367,12 +370,16 @@ def handlech(c, stdscr):
                                 for i, item in enumerate(data.split("\n")):
                                     msg += fill(item, replace_whitespace=False) + "\n"
                                 scrollbox(d, unicode(ascii(msg)), 30, 80)
-                                sqlExecute("UPDATE inbox SET read=1 WHERE msgid=?", inbox[inboxcur][0])
+                                rowcount = sqlExecute("UPDATE inbox SET read=1 WHERE msgid=?", sqlite3.Binary(inbox[inboxcur][0]))
+                                if rowcount < 1:
+                                    sqlExecute("UPDATE inbox SET read=1 WHERE msgid=CAST(? AS TEXT)", inbox[inboxcur][0])
                                 inbox[inboxcur][7] = 1
                             else:
                                 scrollbox(d, unicode("Could not fetch message."))
                         elif t == "2":       # Mark unread
-                            sqlExecute("UPDATE inbox SET read=0 WHERE msgid=?", inbox[inboxcur][0])
+                            rowcount = sqlExecute("UPDATE inbox SET read=0 WHERE msgid=?", sqlite3.Binary(inbox[inboxcur][0]))
+                            if rowcount < 1:
+                                sqlExecute("UPDATE inbox SET read=0 WHERE msgid=CAST(? AS TEXT)", inbox[inboxcur][0])
                             inbox[inboxcur][7] = 0
                         elif t == "3":       # Reply
                             curses.curs_set(1)
@@ -396,7 +403,9 @@ def handlech(c, stdscr):
                             if not m[5][:4] == "Re: ":
                                 subject = "Re: " + m[5]
                             body = ""
-                            ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", m[0])
+                            ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", sqlite3.Binary(m[0]))
+                            if len(ret) < 1:
+                                ret = sqlQuery("SELECT message FROM inbox WHERE msgid=CAST(? AS TEXT)", m[0])
                             if ret != []:
                                 body = "\n\n------------------------------------------------------\n"
                                 for row in ret:
@@ -422,7 +431,9 @@ def handlech(c, stdscr):
                             r, t = d.inputbox("Filename", init=inbox[inboxcur][5] + ".txt")
                             if r == d.DIALOG_OK:
                                 msg = ""
-                                ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", inbox[inboxcur][0])
+                                ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", sqlite3.Binary(inbox[inboxcur][0]))
+                                if len(ret) < 1:
+                                    ret = sqlQuery("SELECT message FROM inbox WHERE msgid=CAST(? AS TEXT)", inbox[inboxcur][0])
                                 if ret != []:
                                     for row in ret:
                                         msg, = row
@@ -432,7 +443,9 @@ def handlech(c, stdscr):
                                 else:
                                     scrollbox(d, unicode("Could not fetch message."))
                         elif t == "6":       # Move to trash
-                            sqlExecute("UPDATE inbox SET folder='trash' WHERE msgid=?", inbox[inboxcur][0])
+                            rowcount = sqlExecute("UPDATE inbox SET folder='trash' WHERE msgid=?", sqlite3.Binary(inbox[inboxcur][0]))
+                            if rowcount < 1:
+                                sqlExecute("UPDATE inbox SET folder='trash' WHERE msgid=CAST(? AS TEXT)", inbox[inboxcur][0])
                             del inbox[inboxcur]
                             scrollbox(d, unicode(
                                 "Message moved to trash. There is no interface to view your trash,"
@@ -464,7 +477,12 @@ def handlech(c, stdscr):
                             ret = sqlQuery(
                                 "SELECT message FROM sent WHERE subject=? AND ackdata=?",
                                 sentbox[sentcur][4],
-                                sentbox[sentcur][6])
+                                sqlite3.Binary(sentbox[sentcur][6]))
+                            if len(ret) < 1:
+                                ret = sqlQuery(
+                                    "SELECT message FROM sent WHERE subject=? AND ackdata=CAST(? AS TEXT)",
+                                    sentbox[sentcur][4],
+                                    sentbox[sentcur][6])
                             if ret != []:
                                 for row in ret:
                                     data, = row
@@ -476,10 +494,15 @@ def handlech(c, stdscr):
                             else:
                                 scrollbox(d, unicode("Could not fetch message."))
                         elif t == "2":       # Move to trash
-                            sqlExecute(
+                            rowcount = sqlExecute(
                                 "UPDATE sent SET folder='trash' WHERE subject=? AND ackdata=?",
                                 sentbox[sentcur][4],
-                                sentbox[sentcur][6])
+                                sqlite3.Binary(sentbox[sentcur][6]))
+                            if rowcount < 1:
+                                rowcount = sqlExecute(
+                                    "UPDATE sent SET folder='trash' WHERE subject=? AND ackdata=CAST(? AS TEXT)",
+                                    sentbox[sentcur][4],
+                                    sentbox[sentcur][6])
                             del sentbox[sentcur]
                             scrollbox(d, unicode(
                                 "Message moved to trash. There is no interface to view your trash"
diff --git a/src/bitmessagekivy/baseclass/maildetail.py b/src/bitmessagekivy/baseclass/maildetail.py
index 6ddf322d..3d57ce88 100644
--- a/src/bitmessagekivy/baseclass/maildetail.py
+++ b/src/bitmessagekivy/baseclass/maildetail.py
@@ -7,6 +7,7 @@ Maildetail screen for inbox, sent, draft and trash.
 
 import os
 from datetime import datetime
+import sqlite3
 
 from kivy.core.clipboard import Clipboard
 from kivy.clock import Clock
@@ -111,7 +112,11 @@ class MailDetail(Screen):  # pylint: disable=too-many-instance-attributes
             elif self.kivy_state.detail_page_type == 'inbox':
                 data = sqlQuery(
                     "select toaddress, fromaddress, subject, message, received from inbox"
-                    " where msgid = ?", self.kivy_state.mail_id)
+                    " where msgid = ?", sqlite3.Binary(self.kivy_state.mail_id))
+                if len(data) < 1:
+                    data = sqlQuery(
+                        "select toaddress, fromaddress, subject, message, received from inbox"
+                        " where msgid = CAST(? AS TEXT)", self.kivy_state.mail_id)
                 self.assign_mail_details(data)
                 App.get_running_app().set_mail_detail_header()
         except Exception as e:  # pylint: disable=unused-variable
diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py
index 40113b5a..42ef6f80 100644
--- a/src/bitmessageqt/__init__.py
+++ b/src/bitmessageqt/__init__.py
@@ -14,6 +14,7 @@ import threading
 import time
 from datetime import datetime, timedelta
 from sqlite3 import register_adapter
+import sqlite3
 
 from PyQt4 import QtCore, QtGui
 from PyQt4.QtNetwork import QLocalSocket, QLocalServer
@@ -2671,14 +2672,19 @@ class MyForm(settingsmixin.SMainWindow):
 
         msgids = []
         for i in range(0, idCount):
-            msgids.append(tableWidget.item(i, 3).data())
+            msgids.append(sqlite3.Binary(tableWidget.item(i, 3).data()))
             for col in xrange(tableWidget.columnCount()):
                 tableWidget.item(i, col).setUnread(False)
 
         markread = sqlExecuteChunked(
             "UPDATE inbox SET read = 1 WHERE msgid IN({0}) AND read=0",
-            idCount, *msgids
+            False, idCount, *msgids
         )
+        if markread < 1:
+            markread = sqlExecuteChunked(
+                "UPDATE inbox SET read = 1 WHERE msgid IN({0}) AND read=0",
+                True, idCount, *msgids
+            )
 
         if markread > 0:
             self.propagateUnreadCount()
@@ -2916,7 +2922,10 @@ class MyForm(settingsmixin.SMainWindow):
         if not msgid:
             return
         queryreturn = sqlQuery(
-            '''select message from inbox where msgid=?''', msgid)
+            '''select message from inbox where msgid=?''', sqlite3.Binary(msgid))
+        if len(queryreturn) < 1:
+            queryreturn = sqlQuery(
+                '''select message from inbox where msgid=CAST(? AS TEXT)''', msgid)
         if queryreturn != []:
             for row in queryreturn:
                 messageText, = row
@@ -2946,7 +2955,7 @@ class MyForm(settingsmixin.SMainWindow):
         # modified = 0
         for row in tableWidget.selectedIndexes():
             currentRow = row.row()
-            msgid = tableWidget.item(currentRow, 3).data()
+            msgid = sqlite3.Binary(tableWidget.item(currentRow, 3).data())
             msgids.add(msgid)
             # if not tableWidget.item(currentRow, 0).unread:
             #     modified += 1
@@ -2955,10 +2964,15 @@ class MyForm(settingsmixin.SMainWindow):
         # for 1081
         idCount = len(msgids)
         # rowcount =
-        sqlExecuteChunked(
+        total_row_count = sqlExecuteChunked(
             '''UPDATE inbox SET read=0 WHERE msgid IN ({0}) AND read=1''',
-            idCount, *msgids
+            False, idCount, *msgids
         )
+        if total_row_count < 1:
+            sqlExecuteChunked(
+                '''UPDATE inbox SET read=0 WHERE msgid IN ({0}) AND read=1''',
+                True, idCount, *msgids
+            )
 
         self.propagateUnreadCount()
         # tableWidget.selectRow(currentRow + 1)
@@ -3038,8 +3052,12 @@ class MyForm(settingsmixin.SMainWindow):
             currentInboxRow, column_from).address
         msgid = tableWidget.item(currentInboxRow, 3).data()
         queryreturn = sqlQuery(
-            "SELECT message FROM inbox WHERE msgid=?", msgid
-        ) or sqlQuery("SELECT message FROM sent WHERE ackdata=?", msgid)
+            "SELECT message FROM inbox WHERE msgid=?", sqlite3.Binary(msgid)
+        ) or sqlQuery("SELECT message FROM sent WHERE ackdata=?", sqlite3.Binary(msgid))
+        if len(queryreturn) < 1:
+            queryreturn = sqlQuery(
+                "SELECT message FROM inbox WHERE msgid=CAST(? AS TEXT)", msgid
+            ) or sqlQuery("SELECT message FROM sent WHERE ackdata=CAST(? AS TEXT)", msgid)
         if queryreturn != []:
             for row in queryreturn:
                 messageAtCurrentInboxRow, = row
@@ -3213,16 +3231,21 @@ class MyForm(settingsmixin.SMainWindow):
         )[::-1]:
             for i in range(r.bottomRow() - r.topRow() + 1):
                 inventoryHashesToTrash.add(
-                    tableWidget.item(r.topRow() + i, 3).data())
+                    sqlite3.Binary(tableWidget.item(r.topRow() + i, 3).data()))
             currentRow = r.topRow()
             self.getCurrentMessageTextedit().setText("")
             tableWidget.model().removeRows(
                 r.topRow(), r.bottomRow() - r.topRow() + 1)
         idCount = len(inventoryHashesToTrash)
-        sqlExecuteChunked(
+        total_row_count = sqlExecuteChunked(
             ("DELETE FROM inbox" if folder == "trash" or shifted else
              "UPDATE inbox SET folder='trash', read=1") +
-            " WHERE msgid IN ({0})", idCount, *inventoryHashesToTrash)
+            " WHERE msgid IN ({0})", False, idCount, *inventoryHashesToTrash)
+        if total_row_count < 1:
+            sqlExecuteChunked(
+                ("DELETE FROM inbox" if folder == "trash" or shifted else
+                 "UPDATE inbox SET folder='trash', read=1") +
+                " WHERE msgid IN ({0})", True, idCount, *inventoryHashesToTrash)
         tableWidget.selectRow(0 if currentRow == 0 else currentRow - 1)
         tableWidget.setUpdatesEnabled(True)
         self.propagateUnreadCount(folder)
@@ -3241,16 +3264,20 @@ class MyForm(settingsmixin.SMainWindow):
         )[::-1]:
             for i in range(r.bottomRow() - r.topRow() + 1):
                 inventoryHashesToTrash.add(
-                    tableWidget.item(r.topRow() + i, 3).data())
+                    sqlite3.Binary(tableWidget.item(r.topRow() + i, 3).data()))
             currentRow = r.topRow()
             self.getCurrentMessageTextedit().setText("")
             tableWidget.model().removeRows(
                 r.topRow(), r.bottomRow() - r.topRow() + 1)
         tableWidget.selectRow(0 if currentRow == 0 else currentRow - 1)
         idCount = len(inventoryHashesToTrash)
-        sqlExecuteChunked(
+        total_row_count = sqlExecuteChunked(
             "UPDATE inbox SET folder='inbox' WHERE msgid IN({0})",
-            idCount, *inventoryHashesToTrash)
+            False, idCount, *inventoryHashesToTrash)
+        if total_row_count < 1:
+            sqlExecuteChunked(
+                "UPDATE inbox SET folder='inbox' WHERE msgid IN({0})",
+                True, idCount, *inventoryHashesToTrash, as_text=True)
         tableWidget.selectRow(0 if currentRow == 0 else currentRow - 1)
         tableWidget.setUpdatesEnabled(True)
         self.propagateUnreadCount()
@@ -3270,7 +3297,10 @@ class MyForm(settingsmixin.SMainWindow):
         # Retrieve the message data out of the SQL database
         msgid = tableWidget.item(currentInboxRow, 3).data()
         queryreturn = sqlQuery(
-            '''select message from inbox where msgid=?''', msgid)
+            '''select message from inbox where msgid=?''', sqlite3.Binary(msgid))
+        if len(queryreturn) < 1:
+            queryreturn = sqlQuery(
+                '''select message from inbox where msgid=CAST(? AS TEXT)''', msgid)
         if queryreturn != []:
             for row in queryreturn:
                 message, = row
@@ -3301,11 +3331,17 @@ class MyForm(settingsmixin.SMainWindow):
         while tableWidget.selectedIndexes() != []:
             currentRow = tableWidget.selectedIndexes()[0].row()
             ackdataToTrash = tableWidget.item(currentRow, 3).data()
-            sqlExecute(
+            rowcount = sqlExecute(
                 "DELETE FROM sent" if folder == "trash" or shifted else
                 "UPDATE sent SET folder='trash'"
-                " WHERE ackdata = ?", ackdataToTrash
+                " WHERE ackdata = ?", sqlite3.Binary(ackdataToTrash)
             )
+            if rowcount < 1:
+                sqlExecute(
+                    "DELETE FROM sent" if folder == "trash" or shifted else
+                    "UPDATE sent SET folder='trash'"
+                    " WHERE ackdata = CAST(? AS TEXT)", ackdataToTrash
+                )
             self.getCurrentMessageTextedit().setPlainText("")
             tableWidget.removeRow(currentRow)
             self.updateStatusBar(_translate(
@@ -3319,9 +3355,13 @@ class MyForm(settingsmixin.SMainWindow):
         addressAtCurrentRow = self.ui.tableWidgetInbox.item(
             currentRow, 0).data(QtCore.Qt.UserRole)
         toRipe = decodeAddress(addressAtCurrentRow)[3]
-        sqlExecute(
+        rowcount = sqlExecute(
             '''UPDATE sent SET status='forcepow' WHERE toripe=? AND status='toodifficult' and folder='sent' ''',
-            toRipe)
+            sqlite3.Binary(toRipe))
+        if rowcount < 1:
+            sqlExecute(
+                '''UPDATE sent SET status='forcepow' WHERE toripe=CAST(? AS TEXT) AND status='toodifficult' and folder='sent' ''',
+                toRipe)
         queryreturn = sqlQuery('''select ackdata FROM sent WHERE status='forcepow' ''')
         for row in queryreturn:
             ackdata, = row
@@ -4017,7 +4057,9 @@ class MyForm(settingsmixin.SMainWindow):
         # menu option (Force Send) if it is.
         if currentRow >= 0:
             ackData = self.ui.tableWidgetInbox.item(currentRow, 3).data()
-            queryreturn = sqlQuery('''SELECT status FROM sent where ackdata=?''', ackData)
+            queryreturn = sqlQuery('''SELECT status FROM sent where ackdata=?''', sqlite3.Binary(ackData))
+            if len(queryreturn) < 1:
+                queryreturn = sqlQuery('''SELECT status FROM sent where ackdata=CAST(? AS TEXT)''', ackData)
             for row in queryreturn:
                 status, = row
             if status == 'toodifficult':
@@ -4119,8 +4161,15 @@ class MyForm(settingsmixin.SMainWindow):
                 '''SELECT message FROM %s WHERE %s=?''' % (
                     ('sent', 'ackdata') if folder == 'sent'
                     else ('inbox', 'msgid')
-                ), msgid
+                ), sqlite3.Binary(msgid)
             )
+            if len(queryreturn) < 1:
+                queryreturn = sqlQuery(
+                    '''SELECT message FROM %s WHERE %s=CAST(? AS TEXT)''' % (
+                        ('sent', 'ackdata') if folder == 'sent'
+                        else ('inbox', 'msgid')
+                    ), msgid
+                )
 
         try:
             message = queryreturn[-1][0]
@@ -4138,10 +4187,16 @@ class MyForm(settingsmixin.SMainWindow):
             if tableWidget.item(currentRow, 0).unread is True:
                 self.updateUnreadStatus(tableWidget, currentRow, msgid)
             # propagate
-            if folder != 'sent' and sqlExecute(
+            rowcount = sqlExecute(
                 '''UPDATE inbox SET read=1 WHERE msgid=? AND read=0''',
-                msgid
-            ) > 0:
+                sqlite3.Binary(msgid)
+            )
+            if rowcount < 1:
+                rowcount = sqlExecute(
+                    '''UPDATE inbox SET read=1 WHERE msgid=CAST(? AS TEXT) AND read=0''',
+                    msgid
+                )
+            if folder != 'sent' and rowcount > 0:
                 self.propagateUnreadCount()
 
         messageTextedit.setCurrentFont(QtGui.QFont())
diff --git a/src/bitmessageqt/account.py b/src/bitmessageqt/account.py
index 8c82c6f6..5c58b0ec 100644
--- a/src/bitmessageqt/account.py
+++ b/src/bitmessageqt/account.py
@@ -13,6 +13,7 @@ import inspect
 import re
 import sys
 import time
+import sqlite3
 
 from PyQt4 import QtGui
 
@@ -201,13 +202,13 @@ class GatewayAccount(BMAccount):
         ackdata = genAckPayload(streamNumber, stealthLevel)
         sqlExecute(
             '''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''',
-            '',
+            sqlite3.Binary(''),
             self.toAddress,
-            ripe,
+            sqlite3.Binary(ripe),
             self.fromAddress,
             self.subject,
             self.message,
-            ackdata,
+            sqlite3.Binary(ackdata),
             int(time.time()),  # sentTime (this will never change)
             int(time.time()),  # lastActionTime
             0,  # sleepTill time. This will get set when the POW gets done.
diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py
index c50b7d3d..ea4333fb 100644
--- a/src/bitmessageqt/foldertree.py
+++ b/src/bitmessageqt/foldertree.py
@@ -478,7 +478,7 @@ class MessageList_TimeWidget(BMTableWidgetItem):
 
     def __init__(self, label=None, unread=False, timestamp=None, msgid=''):
         super(MessageList_TimeWidget, self).__init__(label, unread)
-        self.setData(QtCore.Qt.UserRole, QtCore.QByteArray(msgid))
+        self.setData(QtCore.Qt.UserRole, QtCore.QByteArray(bytes(msgid)))
         self.setData(TimestampRole, int(timestamp))
 
     def __lt__(self, other):
diff --git a/src/class_objectProcessor.py b/src/class_objectProcessor.py
index 469ccbfa..dc567d4b 100644
--- a/src/class_objectProcessor.py
+++ b/src/class_objectProcessor.py
@@ -12,6 +12,7 @@ import subprocess  # nosec B404
 import threading
 import time
 from binascii import hexlify
+import sqlite3
 
 import helper_bitcoin
 import helper_inbox
@@ -121,7 +122,7 @@ class objectProcessor(threading.Thread):
                         objectType, data = queues.objectProcessorQueue.get()
                         sql.execute(
                             'INSERT INTO objectprocessorqueue VALUES (?,?)',
-                            objectType, data)
+                            objectType, sqlite3.Binary(data))
                         numberOfObjectsThatWereInTheObjectProcessorQueue += 1
                 logger.debug(
                     'Saved %s objects from the objectProcessorQueue to'
@@ -143,9 +144,13 @@ class objectProcessor(threading.Thread):
         if data[readPosition:] in state.ackdataForWhichImWatching:
             logger.info('This object is an acknowledgement bound for me.')
             del state.ackdataForWhichImWatching[data[readPosition:]]
-            sqlExecute(
+            rowcount = sqlExecute(
                 "UPDATE sent SET status='ackreceived', lastactiontime=?"
-                " WHERE ackdata=?", int(time.time()), data[readPosition:])
+                " WHERE ackdata=?", int(time.time()), sqlite3.Binary(data[readPosition:]))
+            if rowcount < 1:
+                rowcount = sqlExecute(
+                    "UPDATE sent SET status='ackreceived', lastactiontime=?"
+                    " WHERE ackdata=CAST(? AS TEXT)", int(time.time()), data[readPosition:])
             queues.UISignalQueue.put((
                 'updateSentItemStatusByAckdata', (
                     data[readPosition:],
@@ -333,13 +338,13 @@ class objectProcessor(threading.Thread):
             if queryreturn != []:
                 logger.info(
                     'We HAVE used this pubkey personally. Updating time.')
-                t = (address, addressVersion, dataToStore,
+                t = (address, addressVersion, sqlite3.Binary(dataToStore),
                      int(time.time()), 'yes')
             else:
                 logger.info(
                     'We have NOT used this pubkey personally. Inserting'
                     ' in database.')
-                t = (address, addressVersion, dataToStore,
+                t = (address, addressVersion, sqlite3.Binary(dataToStore),
                      int(time.time()), 'no')
             sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t)
             self.possibleNewPubkey(address)
@@ -395,13 +400,13 @@ class objectProcessor(threading.Thread):
             if queryreturn != []:
                 logger.info(
                     'We HAVE used this pubkey personally. Updating time.')
-                t = (address, addressVersion, dataToStore,
+                t = (address, addressVersion, sqlite3.Binary(dataToStore),
                      int(time.time()), 'yes')
             else:
                 logger.info(
                     'We have NOT used this pubkey personally. Inserting'
                     ' in database.')
-                t = (address, addressVersion, dataToStore,
+                t = (address, addressVersion, sqlite3.Binary(dataToStore),
                      int(time.time()), 'no')
             sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t)
             self.possibleNewPubkey(address)
@@ -592,7 +597,7 @@ class objectProcessor(threading.Thread):
             '''INSERT INTO pubkeys VALUES (?,?,?,?,?)''',
             fromAddress,
             sendersAddressVersionNumber,
-            decryptedData[:endOfThePublicKeyPosition],
+            sqlite3.Binary(decryptedData[:endOfThePublicKeyPosition]),
             int(time.time()),
             'yes')
 
@@ -929,7 +934,7 @@ class objectProcessor(threading.Thread):
         sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''',
                    fromAddress,
                    sendersAddressVersion,
-                   decryptedData[:endOfPubkeyPosition],
+                   sqlite3.Binary(decryptedData[:endOfPubkeyPosition]),
                    int(time.time()),
                    'yes')
 
diff --git a/src/class_singleCleaner.py b/src/class_singleCleaner.py
index 06153dcf..3f3c9140 100644
--- a/src/class_singleCleaner.py
+++ b/src/class_singleCleaner.py
@@ -22,6 +22,7 @@ It resends messages when there has been no response:
 import gc
 import os
 import time
+import sqlite3
 
 import queues
 import state
@@ -177,9 +178,13 @@ class singleCleaner(StoppableThread):
             'It has been a long time and we haven\'t heard an acknowledgement'
             ' to our msg. Sending again.'
         )
-        sqlExecute(
+        rowcount = sqlExecute(
             "UPDATE sent SET status = 'msgqueued'"
-            " WHERE ackdata = ? AND folder = 'sent'", ackdata)
+            " WHERE ackdata = ? AND folder = 'sent'", sqlite3.Binary(ackdata))
+        if rowcount < 1:
+            sqlExecute(
+                "UPDATE sent SET status = 'msgqueued'"
+                " WHERE ackdata = CAST(? AS TEXT) AND folder = 'sent'", ackdata)
         queues.workerQueue.put(('sendmessage', ''))
         queues.UISignalQueue.put((
             'updateStatusBar',
diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py
index f2821f65..60b18efa 100644
--- a/src/class_singleWorker.py
+++ b/src/class_singleWorker.py
@@ -11,6 +11,7 @@ import time
 from binascii import hexlify, unhexlify
 from struct import pack
 from subprocess import call  # nosec
+import sqlite3
 
 import defaults
 import helper_inbox
@@ -107,10 +108,15 @@ class singleWorker(StoppableThread):
                 # attach legacy header, always constant (msg/1/1)
                 newack = '\x00\x00\x00\x02\x01\x01' + oldack
                 state.ackdataForWhichImWatching[newack] = 0
-                sqlExecute(
+                rowcount = sqlExecute(
                     '''UPDATE sent SET ackdata=? WHERE ackdata=? AND folder = 'sent' ''',
-                    newack, oldack
+                    sqlite3.Binary(newack), sqlite3.Binary(oldack)
                 )
+                if rowcount < 1:
+                    sqlExecute(
+                        '''UPDATE sent SET ackdata=? WHERE ackdata=CAST(? AS TEXT) AND folder = 'sent' ''',
+                        sqlite3.Binary(newack), oldack
+                    )
                 del state.ackdataForWhichImWatching[oldack]
 
         # For the case if user deleted knownnodes
@@ -578,11 +584,18 @@ class singleWorker(StoppableThread):
                 ))
                 continue
 
-            if not sqlExecute(
+            rowcount = sqlExecute(
                     '''UPDATE sent SET status='doingbroadcastpow' '''
                     ''' WHERE ackdata=? AND status='broadcastqueued' '''
                     ''' AND folder='sent' ''',
-                    ackdata):
+                    sqlite3.Binary(ackdata))
+            if rowcount < 1:
+                rowcount = sqlExecute(
+                        '''UPDATE sent SET status='doingbroadcastpow' '''
+                        ''' WHERE ackdata=CAST(? AS TEXT) AND status='broadcastqueued' '''
+                        ''' AND folder='sent' ''',
+                        ackdata)
+            if rowcount < 1:
                 continue
 
             # At this time these pubkeys are 65 bytes long
@@ -703,11 +716,17 @@ class singleWorker(StoppableThread):
 
             # Update the status of the message in the 'sent' table to have
             # a 'broadcastsent' status
-            sqlExecute(
+            rowcount = sqlExecute(
                 '''UPDATE sent SET msgid=?, status=?, lastactiontime=? '''
                 ''' WHERE ackdata=? AND folder='sent' ''',
-                inventoryHash, 'broadcastsent', int(time.time()), ackdata
+                sqlite3.Binary(inventoryHash), 'broadcastsent', int(time.time()), sqlite3.Binary(ackdata)
             )
+            if rowcount < 1:
+                sqlExecute(
+                    '''UPDATE sent SET msgid=?, status=?, lastactiontime=? '''
+                    ''' WHERE ackdata=CAST(? AS TEXT) AND folder='sent' ''',
+                    sqlite3.Binary(inventoryHash), 'broadcastsent', int(time.time()), ackdata
+                )
 
     def sendMsg(self):
         """Send a message-type object (assemble the object, perform PoW and put it to the inv announcement queue)"""
@@ -1065,10 +1084,15 @@ class singleWorker(StoppableThread):
                         if cond1 or cond2:
                             # The demanded difficulty is more than
                             # we are willing to do.
-                            sqlExecute(
+                            rowcount = sqlExecute(
                                 '''UPDATE sent SET status='toodifficult' '''
                                 ''' WHERE ackdata=? AND folder='sent' ''',
-                                ackdata)
+                                sqlite3.Binary(ackdata))
+                            if rowcount < 1:
+                                sqlExecute(
+                                    '''UPDATE sent SET status='toodifficult' '''
+                                    ''' WHERE ackdata=CAST(? AS TEXT) AND folder='sent' ''',
+                                    ackdata)
                             queues.UISignalQueue.put((
                                 'updateSentItemStatusByAckdata', (
                                     ackdata,
@@ -1231,10 +1255,15 @@ class singleWorker(StoppableThread):
                 )
             except:  # noqa:E722
                 self.logger.warning("highlevelcrypto.encrypt didn't work")
-                sqlExecute(
+                rowcount = sqlExecute(
                     '''UPDATE sent SET status='badkey' WHERE ackdata=? AND folder='sent' ''',
-                    ackdata
+                    sqlite3.Binary(ackdata)
                 )
+                if rowcount < 1:
+                    sqlExecute(
+                        '''UPDATE sent SET status='badkey' WHERE ackdata=CAST(? AS TEXT) AND folder='sent' ''',
+                        ackdata
+                    )
                 queues.UISignalQueue.put((
                     'updateSentItemStatusByAckdata', (
                         ackdata,
@@ -1337,12 +1366,19 @@ class singleWorker(StoppableThread):
                 newStatus = 'msgsent'
             # wait 10% past expiration
             sleepTill = int(time.time() + TTL * 1.1)
-            sqlExecute(
+            rowcount = sqlExecute(
                 '''UPDATE sent SET msgid=?, status=?, retrynumber=?, '''
                 ''' sleeptill=?, lastactiontime=? WHERE ackdata=? AND folder='sent' ''',
-                inventoryHash, newStatus, retryNumber + 1,
-                sleepTill, int(time.time()), ackdata
+                sqlite3.Binary(inventoryHash), newStatus, retryNumber + 1,
+                sleepTill, int(time.time()), sqlite3.Binary(ackdata)
             )
+            if rowcount < 1:
+                sqlExecute(
+                    '''UPDATE sent SET msgid=?, status=?, retrynumber=?, '''
+                    ''' sleeptill=?, lastactiontime=? WHERE ackdata=CAST(? AS TEXT) AND folder='sent' ''',
+                    sqlite3.Binary(inventoryHash), newStatus, retryNumber + 1,
+                    sleepTill, int(time.time()), ackdata
+                )
 
             # If we are sending to ourselves or a chan, let's put
             # the message in our own inbox.
diff --git a/src/class_smtpServer.py b/src/class_smtpServer.py
index 44ea7c9c..45dbb01e 100644
--- a/src/class_smtpServer.py
+++ b/src/class_smtpServer.py
@@ -12,6 +12,7 @@ import threading
 import time
 from email.header import decode_header
 from email.parser import Parser
+import sqlite3
 
 import queues
 from addresses import decodeAddress
@@ -88,13 +89,13 @@ class smtpServerPyBitmessage(smtpd.SMTPServer):
         ackdata = genAckPayload(streamNumber, stealthLevel)
         sqlExecute(
             '''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''',
-            '',
+            sqlite3.Binary(''),
             toAddress,
-            ripe,
+            sqlite3.Binary(ripe),
             fromAddress,
             subject,
             message,
-            ackdata,
+            sqlite3.Binary(ackdata),
             int(time.time()),  # sentTime (this will never change)
             int(time.time()),  # lastActionTime
             0,  # sleepTill time. This will get set when the POW gets done.
diff --git a/src/class_sqlThread.py b/src/class_sqlThread.py
index 7df9e253..a2eab646 100644
--- a/src/class_sqlThread.py
+++ b/src/class_sqlThread.py
@@ -73,7 +73,7 @@ class sqlThread(threading.Thread):
                 '''INSERT INTO subscriptions VALUES'''
                 '''('Bitmessage new releases/announcements','BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw',1)''')
             self.cur.execute(
-                '''CREATE TABLE settings (key blob, value blob, UNIQUE(key) ON CONFLICT REPLACE)''')
+                '''CREATE TABLE settings (key text, value blob, UNIQUE(key) ON CONFLICT REPLACE)''')
             self.cur.execute('''INSERT INTO settings VALUES('version','11')''')
             self.cur.execute('''INSERT INTO settings VALUES('lastvacuumtime',?)''', (
                 int(time.time()),))
diff --git a/src/helper_inbox.py b/src/helper_inbox.py
index 555795df..b20edf94 100644
--- a/src/helper_inbox.py
+++ b/src/helper_inbox.py
@@ -1,12 +1,15 @@
 """Helper Inbox performs inbox messages related operations"""
 
+import sqlite3
+
 import queues
 from helper_sql import sqlExecute, sqlQuery
 
 
 def insert(t):
     """Perform an insert into the "inbox" table"""
-    sqlExecute('''INSERT INTO inbox VALUES (?,?,?,?,?,?,?,?,?,?)''', *t)
+    u = [sqlite3.Binary(t[0]), t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], sqlite3.Binary(t[9])]
+    sqlExecute('''INSERT INTO inbox VALUES (?,?,?,?,?,?,?,?,?,?)''', *u)
     # shouldn't emit changedInboxUnread and displayNewInboxMessage
     # at the same time
     # queues.UISignalQueue.put(('changedInboxUnread', None))
@@ -14,22 +17,31 @@ def insert(t):
 
 def trash(msgid):
     """Mark a message in the `inbox` as `trash`"""
-    sqlExecute('''UPDATE inbox SET folder='trash' WHERE msgid=?''', msgid)
+    rowcount = sqlExecute('''UPDATE inbox SET folder='trash' WHERE msgid=?''', sqlite3.Binary(msgid))
+    if rowcount < 1:
+        sqlExecute('''UPDATE inbox SET folder='trash' WHERE msgid=CAST(? AS TEXT)''', msgid)
     queues.UISignalQueue.put(('removeInboxRowByMsgid', msgid))
 
 
 def delete(ack_data):
     """Permanent delete message from trash"""
-    sqlExecute("DELETE FROM inbox WHERE msgid = ?", ack_data)
+    rowcount = sqlExecute("DELETE FROM inbox WHERE msgid = ?", sqlite3.Binary(ack_data))
+    if rowcount < 1:
+        sqlExecute("DELETE FROM inbox WHERE msgid = CAST(? AS TEXT)", ack_data)
 
 
 def undeleteMessage(msgid):
     """Undelte the message"""
-    sqlExecute('''UPDATE inbox SET folder='inbox' WHERE msgid=?''', msgid)
+    rowcount = sqlExecute('''UPDATE inbox SET folder='inbox' WHERE msgid=?''', sqlite3.Binary(msgid))
+    if rowcount < 1:
+        sqlExecute('''UPDATE inbox SET folder='inbox' WHERE msgid=CAST(? AS TEXT)''', msgid)
 
 
 def isMessageAlreadyInInbox(sigHash):
     """Check for previous instances of this message"""
     queryReturn = sqlQuery(
-        '''SELECT COUNT(*) FROM inbox WHERE sighash=?''', sigHash)
+        '''SELECT COUNT(*) FROM inbox WHERE sighash=?''', sqlite3.Binary(sigHash))
+    if len(queryReturn) < 1:
+        queryReturn = sqlQuery(
+            '''SELECT COUNT(*) FROM inbox WHERE sighash=CAST(? AS TEXT)''', sigHash)
     return queryReturn[0][0] != 0
diff --git a/src/helper_sent.py b/src/helper_sent.py
index aa76e756..8dca93e9 100644
--- a/src/helper_sent.py
+++ b/src/helper_sent.py
@@ -4,6 +4,7 @@ Insert values into sent table
 
 import time
 import uuid
+import sqlite3
 from addresses import decodeAddress
 from bmconfigparser import config
 from helper_ackPayload import genAckPayload
@@ -38,7 +39,7 @@ def insert(msgid=None, toAddress='[Broadcast subscribers]', fromAddress=None, su
 
         ttl = ttl if ttl else config.getint('bitmessagesettings', 'ttl')
 
-        t = (msgid, toAddress, ripe, fromAddress, subject, message, ackdata,
+        t = (sqlite3.Binary(msgid), toAddress, sqlite3.Binary(ripe), fromAddress, subject, message, sqlite3.Binary(ackdata),
              sentTime, lastActionTime, sleeptill, status, retryNumber, folder,
              encoding, ttl)
 
@@ -50,20 +51,30 @@ def insert(msgid=None, toAddress='[Broadcast subscribers]', fromAddress=None, su
 
 def delete(ack_data):
     """Perform Delete query"""
-    sqlExecute("DELETE FROM sent WHERE ackdata = ?", ack_data)
+    rowcount = sqlExecute("DELETE FROM sent WHERE ackdata = ?", sqlite3.Binary(ack_data))
+    if rowcount < 1:
+        sqlExecute("DELETE FROM sent WHERE ackdata = CAST(? AS TEXT)", ack_data)
 
 
 def retrieve_message_details(ack_data):
     """Retrieving Message details"""
     data = sqlQuery(
-        "select toaddress, fromaddress, subject, message, received from inbox where msgid = ?", ack_data
+        "select toaddress, fromaddress, subject, message, received from inbox where msgid = ?", sqlite3.Binary(ack_data)
     )
+    if len(data) < 1:
+        data = sqlQuery(
+            "select toaddress, fromaddress, subject, message, received from inbox where msgid = CAST(? AS TEXT)", ack_data
+        )
     return data
 
 
 def trash(ackdata):
     """Mark a message in the `sent` as `trash`"""
     rowcount = sqlExecute(
-        '''UPDATE sent SET folder='trash' WHERE ackdata=?''', ackdata
+        '''UPDATE sent SET folder='trash' WHERE ackdata=?''', sqlite3.Binary(ackdata)
     )
+    if rowcount < 1:
+        rowcount = sqlExecute(
+            '''UPDATE sent SET folder='trash' WHERE ackdata=CAST(? AS TEXT)''', ackdata
+        )
     return rowcount
diff --git a/src/helper_sql.py b/src/helper_sql.py
index 8dee9e0c..cfacfde9 100644
--- a/src/helper_sql.py
+++ b/src/helper_sql.py
@@ -61,7 +61,7 @@ def sqlQuery(sql_statement, *args):
     return queryreturn
 
 
-def sqlExecuteChunked(sql_statement, idCount, *args):
+def sqlExecuteChunked(sql_statement, as_text, idCount, *args):
     """Execute chunked SQL statement to avoid argument limit"""
     # SQLITE_MAX_VARIABLE_NUMBER,
     # unfortunately getting/setting isn't exposed to python
@@ -80,9 +80,14 @@ def sqlExecuteChunked(sql_statement, idCount, *args):
             chunk_slice = args[
                 i:i + sqlExecuteChunked.chunkSize - (len(args) - idCount)
             ]
-            sqlSubmitQueue.put(
-                sql_statement.format(','.join('?' * len(chunk_slice)))
-            )
+            if as_text:
+                sqlSubmitQueue.put(
+                    sql_statement.format(','.join('CAST(? AS TEXT)' * len(chunk_slice)))
+                )
+            else:
+                sqlSubmitQueue.put(
+                    sql_statement.format(','.join('?' * len(chunk_slice)))
+                )
             # first static args, and then iterative chunk
             sqlSubmitQueue.put(
                 args[0:len(args) - idCount] + chunk_slice
diff --git a/src/protocol.py b/src/protocol.py
index 7f9830e5..596e0647 100644
--- a/src/protocol.py
+++ b/src/protocol.py
@@ -12,6 +12,7 @@ import sys
 import time
 from binascii import hexlify
 from struct import Struct, pack, unpack
+import sqlite3
 
 import defaults
 import highlevelcrypto
@@ -558,7 +559,7 @@ def decryptAndCheckPubkeyPayload(data, address):
             hexlify(pubSigningKey), hexlify(pubEncryptionKey)
         )
 
-        t = (address, addressVersion, storedData, int(time.time()), 'yes')
+        t = (address, addressVersion, sqlite3.Binary(storedData), int(time.time()), 'yes')
         sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t)
         return 'successful'
     except varintDecodeError:
diff --git a/src/storage/sqlite.py b/src/storage/sqlite.py
index eb5df098..aa97c52a 100644
--- a/src/storage/sqlite.py
+++ b/src/storage/sqlite.py
@@ -107,6 +107,7 @@ class SqliteInventory(InventoryStorage):
             # always use the inventoryLock OUTSIDE of the sqlLock.
             with SqlBulkExecute() as sql:
                 for objectHash, value in self._inventory.items():
+                    value = [value[0], value[1], sqlite3.Binary(value[2]), value[3], sqlite3.Binary(value[4])]
                     sql.execute(
                         'INSERT INTO inventory VALUES (?, ?, ?, ?, ?, ?)',
                         sqlite3.Binary(objectHash), *value)
diff --git a/src/tests/core.py b/src/tests/core.py
index f1a11a06..aa42ada0 100644
--- a/src/tests/core.py
+++ b/src/tests/core.py
@@ -15,6 +15,7 @@ import sys
 import threading
 import time
 import unittest
+import sqlite3
 
 import protocol
 import state
@@ -345,11 +346,17 @@ class TestCore(unittest.TestCase):
             subject=subject, message=message
         )
         queryreturn = sqlQuery(
-            '''select msgid from sent where ackdata=?''', result)
+            '''select msgid from sent where ackdata=?''', sqlite3.Binary(result))
+        if len(queryreturn) < 1:
+            queryreturn = sqlQuery(
+                '''select msgid from sent where ackdata=CAST(? AS TEXT)''', result)
         self.assertNotEqual(queryreturn[0][0] if queryreturn else '', '')
 
         column_type = sqlQuery(
-            '''select typeof(msgid) from sent where ackdata=?''', result)
+            '''select typeof(msgid) from sent where ackdata=?''', sqlite3.Binary(result))
+        if len(column_type) < 1:
+            column_type = sqlQuery(
+                '''select typeof(msgid) from sent where ackdata=CAST(? AS TEXT)''', result)
         self.assertEqual(column_type[0][0] if column_type else '', 'text')
 
     @unittest.skipIf(frozen, 'not packed test_pattern into the bundle')
diff --git a/src/tests/test_helper_sql.py b/src/tests/test_helper_sql.py
index 036bd2c9..50ffbc13 100644
--- a/src/tests/test_helper_sql.py
+++ b/src/tests/test_helper_sql.py
@@ -1,6 +1,7 @@
 """Test cases for helper_sql"""
 
 import unittest
+import sqlite3
 
 try:
     # Python 3
@@ -49,8 +50,14 @@ class TestHelperSql(unittest.TestCase):
         rowcount = helper_sql.sqlExecute(
             "UPDATE sent SET status = 'msgqueued'"
             "WHERE ackdata = ? AND folder = 'sent'",
-            "1710652313",
+            sqlite3.Binary("1710652313"),
         )
+        if rowcount < 0:
+            rowcount = helper_sql.sqlExecute(
+                "UPDATE sent SET status = 'msgqueued'"
+                "WHERE ackdata = CAST(? AS TEXT) AND folder = 'sent'",
+                "1710652313",
+            )
         self.assertEqual(mock_sqlsubmitqueue_put.call_count, 3)
         self.assertEqual(rowcount, 1)
 
@@ -80,7 +87,7 @@ class TestHelperSql(unittest.TestCase):
         for i in range(0, ID_COUNT):
             args.append("arg{}".format(i))
         total_row_count_return = helper_sql.sqlExecuteChunked(
-            "INSERT INTO table VALUES {}", ID_COUNT, *args
+            "INSERT INTO table VALUES {}", False, ID_COUNT, *args
         )
         self.assertEqual(TOTAL_ROW_COUNT, total_row_count_return)
         self.assertTrue(mock_sqlsubmitqueue_put.called)
@@ -97,7 +104,7 @@ class TestHelperSql(unittest.TestCase):
         for i in range(0, ID_COUNT):
             args.append("arg{}".format(i))
         total_row_count = helper_sql.sqlExecuteChunked(
-            "INSERT INTO table VALUES {}", ID_COUNT, *args
+            "INSERT INTO table VALUES {}", False, ID_COUNT, *args
         )
         self.assertEqual(total_row_count, 0)
         self.assertFalse(mock_sqlsubmitqueue_put.called)
@@ -112,7 +119,7 @@ class TestHelperSql(unittest.TestCase):
         ID_COUNT = 12
         args = ["args0", "arg1"]
         total_row_count = helper_sql.sqlExecuteChunked(
-            "INSERT INTO table VALUES {}", ID_COUNT, *args
+            "INSERT INTO table VALUES {}", False, ID_COUNT, *args
         )
         self.assertEqual(total_row_count, 0)
         self.assertFalse(mock_sqlsubmitqueue_put.called)