Beispiel #1
0
void MSqlQuery::bindValues(const MSqlBindings &bindings)
{
    MSqlBindings::const_iterator it;
    for (it = bindings.begin(); it != bindings.end(); ++it)
    {
        bindValue(it.key(), it.value());
    }
}
Beispiel #2
0
void MSqlAddMoreBindings(MSqlBindings &output, MSqlBindings &addfrom)
{
    MSqlBindings::Iterator it;
    for (it = addfrom.begin(); it != addfrom.end(); ++it)
    {
        output.insert(it.key(), it.value());
    }
}
Beispiel #3
0
bool MSqlQuery::exec()
{
    if (!m_db)
    {
        // Database structure's been deleted
        return false;
    }

    if (m_last_prepared_query.isEmpty())
    {
        LOG(VB_GENERAL, LOG_ERR,
            "MSqlQuery::exec(void) called without a prepared query.");
        return false;
    }

#if DEBUG_RECONNECT
    if (random() < RAND_MAX / 50)
    {
        LOG(VB_GENERAL, LOG_INFO,
            "MSqlQuery disconnecting DB to test reconnection logic");
        m_db->m_db.close();
    }
#endif

    // Database connection down.  Try to restart it, give up if it's still
    // down
    if (!m_db->isOpen() && !Reconnect())
    {
        LOG(VB_GENERAL, LOG_INFO, "MySQL server disconnected");
        return false;
    }

    QElapsedTimer timer;
    timer.start();

    bool result = QSqlQuery::exec();
    qint64 elapsed = timer.elapsed();

    // if the query failed with "MySQL server has gone away"
    // Close and reopen the database connection and retry the query if it
    // connects again
    if (!result && QSqlQuery::lastError().number() == 2006 && Reconnect())
        result = QSqlQuery::exec();

    if (!result)
    {
        QString err = MythDB::GetError("MSqlQuery", *this);
        MSqlBindings tmp = QSqlQuery::boundValues();
        bool has_null_strings = false;
        for (MSqlBindings::iterator it = tmp.begin(); it != tmp.end(); ++it)
        {
            if (it->type() != QVariant::String)
                continue;
            if (it->isNull() || it->toString().isNull())
            {
                has_null_strings = true;
                *it = QVariant(QString(""));
            }
        }
        if (has_null_strings)
        {
            bindValues(tmp);
            timer.restart();
            result = QSqlQuery::exec();
            elapsed = timer.elapsed();
        }
        if (result)
        {
            LOG(VB_GENERAL, LOG_ERR,
                QString("Original query failed, but resend with empty "
                        "strings in place of NULL strings worked. ") +
                "\n" + err);
        }
    }

    if (VERBOSE_LEVEL_CHECK(VB_DATABASE, LOG_INFO))
    {
        QString str = lastQuery();

        // Database logging will cause an infinite loop here if not filtered
        // out
        if (!str.startsWith("INSERT INTO logging "))
        {
            // Sadly, neither executedQuery() nor lastQuery() display
            // the values in bound queries against a MySQL5 database.
            // So, replace the named placeholders with their values.

            QMapIterator<QString, QVariant> b = boundValues();
            while (b.hasNext())
            {
                b.next();
                str.replace(b.key(), '\'' + b.value().toString() + '\'');
            }

            LOG(VB_DATABASE, LOG_INFO,
                QString("MSqlQuery::exec(%1) %2%3%4")
                        .arg(m_db->MSqlDatabase::GetConnectionName()).arg(str)
                        .arg(QString(" <<<< Took %1ms").arg(QString::number(elapsed)))
                        .arg(isSelect() ? QString(", Returned %1 row(s)")
                                              .arg(size()) : QString()));
        }
    }

    return result;
}