/** * @brief Repository::updateById Updates the row associated with the given id in the database. The * new values are in the pBindValues Qhash. * @param id Id of the row to update. * @param pBindValues Columns to update with their new values. */ void Repository::updateById(int id, QHash<QString, QVariant> pBindValues) { QueryBuilder qb = updateByIdQB(id, pBindValues.keys()); QSqlQuery query = qb.getPreparedQuery(); bindValues(&query, pBindValues); Database::instance()->push(query); }
GLvoid Light::bind(Shader &shader) { std::string i = std::to_string(index); std::string data = getType(); data += "[" + i + "]."; BIND_LIGHT_VALUE(diffuse); BIND_LIGHT_VALUE(ambient); BIND_LIGHT_VALUE(specular); bindValues(shader, data); }
/** * @brief Repository::insert Inserts a row in the database with the query given by the QueryBuilder * (qb) and the given bind values (pBindValues). Retrieves the id of the inserted row and sets it on * the DBItem. * @param item Item associated with the inserted row in the database which will be given an id once * the insertion is successful. * @param qb QueryBuilder holding the query which will be executed. * @param pBindValues Holds the values to be bound with the request. * @param db Database * @return Id of the inserted row. */ int Repository::insert(DBItem *item, QueryBuilder qb, QHash<QString, QVariant> pBindValues) { qb.withAsSelect(qb, "id"); QSqlQuery query = qb.getPreparedQuery(); bindValues(&query, pBindValues); int id = Database::instance()->pushPreparedWithId(query); item->setId(id); return id; }
bool MSqlQuery::Reconnect(void) { if (!m_db->Reconnect()) return false; if (!m_last_prepared_query.isEmpty()) { MSqlBindings tmp = QSqlQuery::boundValues(); if (!QSqlQuery::prepare(m_last_prepared_query)) return false; bindValues(tmp); } return true; }
int applyDelete(sqlite3* db, const Instruction* instr) { int rc; auto columnNames = getColumnNames(db, instr->table->tableName); std::string sql = std::string() + "DELETE FROM " + instr->table->tableName + " WHERE "; uint8_t nCol = instr->table->nCol; std::vector<std::string> wheres; std::vector<sqlite_value> whereValues; for (int i=0; i < nCol; i++) { if (instr->values[i].type) { wheres.push_back(columnNames.at(i) + " = ?"); whereValues.push_back(instr->values[i]); } } sql += std::accumulate(wheres.cbegin()+1, wheres.cend(), wheres.at(0), [&columnNames](const std::string&a, const std::string& b) { return a + " AND " + b; }); sqlite3_stmt* stmt; rc = sqlite3_prepare_v2(db, sql.data(), sql.size(), &stmt, nullptr); if (rc != SQLITE_OK) { std::cerr << "Failed preparing DELETE statement " << sql << std::endl; return rc; } rc = bindValues(stmt, whereValues.data(), whereValues.size()); if (rc != SQLITE_OK) { std::cerr << "Failed binding to DELETE statement " << sql << std::endl; return rc; } rc = sqlite3_step(stmt); sqlite3_finalize(stmt); if (rc != SQLITE_DONE) { return rc; } return SQLITE_OK; }
int applyInsert(sqlite3* db, const Instruction* instr) { int rc; int nCol = instr->table->nCol; const char* tableName = instr->table->tableName; std::string sql = std::string() + "INSERT INTO " + tableName + " VALUES ("; for (int i=0; i < nCol; i++) { sql += "?"; if (i < nCol - 1) { sql += ", "; } } sql += ");"; sqlite3_stmt* stmt; rc = sqlite3_prepare_v2(db, sql.data(), sql.size(), &stmt, nullptr); if (rc != SQLITE_OK) { return rc; } rc = bindValues(stmt, instr->values, nCol); if (rc != SQLITE_OK) { return rc; } rc = sqlite3_step(stmt); sqlite3_finalize(stmt); if (rc != SQLITE_DONE) { std::cerr << "Error applying insert: " << sqlite3_errmsg(db) << std::endl; return rc; } return SQLITE_OK; }
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; }