// For license of this file, see /LICENSE.md. #include "core/messagesmodelsqllayer.h" #include "database/databasequeries.h" #include "definitions/definitions.h" #include "miscellaneous/application.h" MessagesModelSqlLayer::MessagesModelSqlLayer() : m_filter(QSL(DEFAULT_SQL_MESSAGES_FILTER)), m_fieldNames({}), m_orderByNames({}), m_sortColumns({}), m_numericColumns({}), m_sortOrders({}) { m_db = qApp->database()->driver()->connection(QSL("MessagesModel")); // Used in : SELECT , FROM ....; m_fieldNames = DatabaseQueries::messageTableAttributes(false, m_db.driverName() == QSL(APP_DB_SQLITE_DRIVER)); // Used in : SELECT ... FROM ... ORDER BY DESC, ASC; m_orderByNames[MSG_DB_ID_INDEX] = QSL("Messages.id"); m_orderByNames[MSG_DB_READ_INDEX] = QSL("Messages.is_read"); m_orderByNames[MSG_DB_IMPORTANT_INDEX] = QSL("Messages.is_important"); m_orderByNames[MSG_DB_DELETED_INDEX] = QSL("Messages.is_deleted"); m_orderByNames[MSG_DB_PDELETED_INDEX] = QSL("Messages.is_pdeleted"); m_orderByNames[MSG_DB_FEED_CUSTOM_ID_INDEX] = QSL("Messages.feed"); m_orderByNames[MSG_DB_TITLE_INDEX] = QSL("Messages.title"); m_orderByNames[MSG_DB_URL_INDEX] = QSL("Messages.url"); m_orderByNames[MSG_DB_AUTHOR_INDEX] = QSL("Messages.author"); m_orderByNames[MSG_DB_DCREATED_INDEX] = QSL("Messages.date_created"); m_orderByNames[MSG_DB_CONTENTS_INDEX] = QSL("Messages.contents"); m_orderByNames[MSG_DB_ENCLOSURES_INDEX] = QSL("Messages.enclosures"); m_orderByNames[MSG_DB_SCORE_INDEX] = QSL("Messages.score"); m_orderByNames[MSG_DB_ACCOUNT_ID_INDEX] = QSL("Messages.account_id"); m_orderByNames[MSG_DB_CUSTOM_ID_INDEX] = QSL("Messages.custom_id"); m_orderByNames[MSG_DB_CUSTOM_HASH_INDEX] = QSL("Messages.custom_hash"); m_orderByNames[MSG_DB_FEED_TITLE_INDEX] = QSL("Feeds.title"); m_orderByNames[MSG_DB_FEED_IS_RTL_INDEX] = QSL("Feeds.is_rtl"); m_orderByNames[MSG_DB_HAS_ENCLOSURES] = QSL("has_enclosures"); m_orderByNames[MSG_DB_LABELS] = QSL("msg_labels"); m_orderByNames[MSG_DB_LABELS_IDS] = QSL("Messages.labels"); m_numericColumns << MSG_DB_ID_INDEX << MSG_DB_READ_INDEX << MSG_DB_DELETED_INDEX << MSG_DB_PDELETED_INDEX << MSG_DB_IMPORTANT_INDEX << MSG_DB_ACCOUNT_ID_INDEX << MSG_DB_DCREATED_INDEX << MSG_DB_SCORE_INDEX << MSG_DB_FEED_IS_RTL_INDEX; } void MessagesModelSqlLayer::addSortState(int column, Qt::SortOrder order, bool ignore_multicolumn_sorting) { int existing = m_sortColumns.indexOf(column); bool is_ctrl_pressed = (QApplication::queryKeyboardModifiers() & Qt::KeyboardModifier::ControlModifier) == Qt::KeyboardModifier::ControlModifier; if (existing >= 0) { m_sortColumns.removeAt(existing); m_sortOrders.removeAt(existing); } if (m_sortColumns.size() >= MAX_MULTICOLUMN_SORT_STATES) { // We support only limited number of sort states // due to DB performance. m_sortColumns.removeAt(0); m_sortOrders.removeAt(0); } if (is_ctrl_pressed && !ignore_multicolumn_sorting) { // User is activating the multicolumn sort mode. m_sortColumns.append(column); m_sortOrders.append(order); qDebugNN << "CTRL is pressed while sorting articles - sorting with multicolumn mode."; } else { m_sortColumns.prepend(column); m_sortOrders.prepend(order); qDebugNN << "CTRL is NOT pressed while sorting articles - sorting with standard mode."; } } void MessagesModelSqlLayer::setFilter(const QString& filter) { m_filter = filter; } QString MessagesModelSqlLayer::formatFields() const { return m_fieldNames.values().join(QSL(", ")); } bool MessagesModelSqlLayer::isColumnNumeric(int column_id) const { return m_numericColumns.contains(column_id); } QString MessagesModelSqlLayer::selectStatement() const { return QL1S("SELECT ") + formatFields() + QL1C(' ') + QL1S("FROM Messages LEFT JOIN Feeds ON Messages.feed = Feeds.custom_id AND Messages.account_id = " "Feeds.account_id " "WHERE ") + m_filter + orderByClause() + QL1C(';'); } QString MessagesModelSqlLayer::orderByClause() const { if (m_sortColumns.isEmpty()) { return QString(); } else { QStringList sorts; for (int i = 0; i < m_sortColumns.size(); i++) { QString field_name(m_orderByNames[m_sortColumns[i]]); QString order_sql = isColumnNumeric(m_sortColumns[i]) ? QSL("%1") : QSL("LOWER(%1)"); // sorts.append(QSL("LENGTH(%1)").arg(order_sql.arg(field_name)) + // (m_sortOrders[i] == Qt::SortOrder::AscendingOrder ? QSL(" ASC") : QSL(" DESC"))); sorts.append(order_sql.arg(field_name) + (m_sortOrders[i] == Qt::SortOrder::AscendingOrder ? QSL(" ASC") : QSL(" DESC"))); } return QL1S(" ORDER BY ") + sorts.join(QSL(", ")); } }