# Buggy code
def upsert(self, tableName, valueDict, keyDict):
    """
    Update values, or if no updates done, insert values
    TODO: Make this return true/false on success/error

    :param tableName: table to update/insert
    :param valueDict: values in table to update/insert
    :param keyDict:  columns in table to update/insert
    """

    changesBefore = self.connection.total_changes

    genParams = lambda myDict: [x + " = ?" for x in myDict]

    query = (
        "UPDATE ["
        + tableName
        + "] SET "
        + ", ".join(genParams(valueDict))
        + " WHERE "
        + " AND ".join(genParams(keyDict))
    )

    self.action(query, list(itervalues(valueDict)) + list(itervalues(keyDict)))

    if self.connection.total_changes == changesBefore:
        query = (
            "INSERT INTO ["
            + tableName
            + "] ("
            + ", ".join(list(valueDict) + list(keyDict))
            + ")"
            + " VALUES ("
            + ", ".join(["?"] * len(list(valueDict) + list(keyDict)))
            + ")"
        )
        self.action(query, list(itervalues(valueDict)) + list(itervalues(keyDict)))


# Traceback (OperationalError)
2017-10-28 14:56:23 DEBUG    SEARCHQUEUE-FORCED-71712 :: [BITHDTV] :: [42b1e5f] Traceback (most recent call last):
  File "/home/pi/Medusa/medusa/search/core.py", line 555, in search_providers
    down_cur_quality, manual_search, manual_search_type)
  File "/home/pi/Medusa/medusa/providers/generic_provider.py", line 428, in find_search_results
    db.mass_action(cl)
  File "/home/pi/Medusa/medusa/db.py", line 223, in mass_action
    self.connection.rollback()
OperationalError: cannot rollback - no transaction is active
2017-10-28 14:56:23 ERROR    SEARCHQUEUE-FORCED-71712 :: [BITHDTV] :: [42b1e5f] Unknown exception while searching BITHDTV. Error: 'cannot rollback - no transaction is active'
Traceback (most recent call last):
  File "/home/pi/Medusa/medusa/search/core.py", line 555, in search_prov2017-10-28 16:05:06 DEBUG    DAILYSEARCHER :: [42b1e5f] Started updating network timezones

# Fixed code
def upsert(self, tableName, valueDict, keyDict):
    """
    Update values, or if no updates done, insert values
    TODO: Make this return true/false on success/error

    :param tableName: table to update/insert
    :param valueDict: values in table to update/insert
    :param keyDict:  columns in table to update/insert
    """

    changesBefore = self.connection.total_changes

    def gen_params(my_dict):
        return [x + " = ?" for x in my_dict]

    query = (
        "UPDATE ["
        + tableName
        + "] SET "
        + ", ".join(gen_params(valueDict))
        + " WHERE "
        + " AND ".join(gen_params(keyDict))
    )

    self.action(query, list(itervalues(valueDict)) + list(itervalues(keyDict)))

    if self.connection.total_changes == changesBefore:
        query = (
            "INSERT INTO ["
            + tableName
            + "] ("
            + ", ".join(list(valueDict) + list(keyDict))
            + ")"
            + " VALUES ("
            + ", ".join(["?"] * len(list(valueDict) + list(keyDict)))
            + ")"
        )
        self.action(query, list(itervalues(valueDict)) + list(itervalues(keyDict)))