File indexing completed on 2025-01-05 04:46:58
0001 /* 0002 SPDX-FileCopyrightText: 2006 Tobias Koenig <tokoe@kde.org> 0003 SPDX-FileCopyrightText: 2012 Volker Krause <vkrause@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 #pragma once 0008 0009 #include <QHash> 0010 #include <QSharedPointer> 0011 #include <QSqlDatabase> 0012 #include <QStringList> 0013 0014 class DbIntrospectorTest; 0015 0016 namespace Akonadi 0017 { 0018 namespace Server 0019 { 0020 /** 0021 * Methods for introspecting the current state of a database schema. 0022 * I.e. this is about the structure of a database, not its content. 0023 */ 0024 class DbIntrospector 0025 { 0026 public: 0027 using Ptr = QSharedPointer<DbIntrospector>; 0028 0029 /** A structure describing an existing foreign key. */ 0030 class ForeignKey 0031 { 0032 public: 0033 QString name; 0034 QString column; 0035 QString refTable; 0036 QString refColumn; 0037 QString onUpdate; // TODO use same enum as DbInitializer 0038 QString onDelete; // dito 0039 }; 0040 0041 /** 0042 * Returns an introspector instance for a given database. 0043 */ 0044 static DbIntrospector::Ptr createInstance(const QSqlDatabase &database); 0045 0046 virtual ~DbIntrospector(); 0047 0048 /** 0049 * Returns @c true if table @p tableName exists. 0050 * The default implementation relies on QSqlDatabase::tables(). Usually this 0051 * does not need to be reimplemented. 0052 */ 0053 virtual bool hasTable(const QString &tableName); 0054 0055 /** 0056 * Returns @c true of the given table has an index with the given name. 0057 * The default implementation performs the query returned by hasIndexQuery(). 0058 * @see hasIndexQuery() 0059 * @throws DbException on database errors. 0060 */ 0061 virtual bool hasIndex(const QString &tableName, const QString &indexName); 0062 0063 /** 0064 * Check whether table @p tableName has a column named @p columnName. 0065 * The default implementation should work with all backends. 0066 */ 0067 virtual bool hasColumn(const QString &tableName, const QString &columnName); 0068 0069 /** 0070 * Check whether table @p tableName is empty, ie. does not contain any rows. 0071 * The default implementation should work for all backends. 0072 * @throws DbException on database errors. 0073 */ 0074 virtual bool isTableEmpty(const QString &tableName); 0075 0076 /** 0077 * Returns the foreign key constraints on table @p tableName. 0078 * The default implementation returns an empty list, so any backend supporting 0079 * referential integrity should reimplement this. 0080 */ 0081 virtual QList<ForeignKey> foreignKeyConstraints(const QString &tableName); 0082 0083 /** 0084 * Returns query to retrieve the next autoincrement value for @p tableName.@p columnName. 0085 */ 0086 virtual QString getAutoIncrementValueQuery(const QString &tableName, const QString &columnName) = 0; 0087 0088 /** 0089 * Returns query to update the next autoincrement value for @p tableName.@p columnName to value @p value. 0090 */ 0091 virtual QString updateAutoIncrementValueQuery(const QString &tableName, const QString &columnName, qint64 value) = 0; 0092 0093 protected: 0094 /** 0095 * Creates a new database introspector, call from subclass. 0096 * 0097 * @param database The database to introspect. 0098 */ 0099 DbIntrospector(const QSqlDatabase &database); 0100 0101 /** 0102 * Returns a query string to determine if @p tableName has an index @p indexName. 0103 * The query is expected to have one boolean result row/column. 0104 * This is used by the default implementation of hasIndex() only, thus reimplementation 0105 * is not necessary if you reimplement hasIndex() 0106 * The default implementation asserts. 0107 */ 0108 virtual QString hasIndexQuery(const QString &tableName, const QString &indexName); 0109 0110 /** The database connection we are introspecting. */ 0111 QSqlDatabase m_database; 0112 0113 private: 0114 Q_DISABLE_COPY_MOVE(DbIntrospector) 0115 0116 friend class ::DbIntrospectorTest; 0117 QHash<QString, QStringList> m_columnCache; // avoids extra db roundtrips 0118 }; 0119 0120 } // namespace Server 0121 } // namespace Akonadi