File indexing completed on 2024-04-28 15:58:54
0001 /* This file is part of the KDE project 0002 Copyright (C) 2003-2016 Jarosław Staniek <staniek@kde.org> 0003 0004 This program is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this program; see the file COPYING. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 * Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #ifndef KDB_SQLITECONN_P_H 0021 #define KDB_SQLITECONN_P_H 0022 0023 #include "KDbConnection_p.h" 0024 #include "SqliteConnection.h" 0025 #include "KDbSqlField.h" 0026 #include "KDbSqlRecord.h" 0027 #include "KDbSqlResult.h" 0028 #include "KDbSqlString.h" 0029 0030 #include <sqlite3.h> 0031 0032 /*! Internal SQLite connection data. Also used by SqliteCursor. */ 0033 class SqliteConnectionInternal : public KDbConnectionInternal 0034 { 0035 public: 0036 explicit SqliteConnectionInternal(KDbConnection *connection); 0037 virtual ~SqliteConnectionInternal(); 0038 0039 //! @return true if loading extensions is enabled 0040 bool extensionsLoadingEnabled() const; 0041 0042 //! Sets loading extensions flag to @a set 0043 void setExtensionsLoadingEnabled(bool set); 0044 0045 static QString serverResultName(int serverResultCode); 0046 0047 void storeResult(KDbResult *result); 0048 0049 sqlite3 *data; 0050 bool data_owned; //!< true if data pointer should be freed on destruction 0051 0052 private: 0053 bool m_extensionsLoadingEnabled; 0054 Q_DISABLE_COPY(SqliteConnectionInternal) 0055 }; 0056 0057 class SqliteSqlField : public KDbSqlField 0058 { 0059 public: 0060 inline SqliteSqlField(sqlite3_stmt *st, int i) : prepared_st(st), index(i) 0061 { 0062 } 0063 //! @return column name 0064 inline QString name() override { 0065 return QString::fromUtf8(sqlite3_column_name(prepared_st, index)); 0066 } 0067 //! @return column type 0068 inline int type() override { 0069 return sqlite3_column_type(prepared_st, index); 0070 } 0071 //! @return length limit - no limits for SQLite 0072 inline int length() override { 0073 return std::numeric_limits<int>::max(); 0074 } 0075 private: 0076 sqlite3_stmt * const prepared_st; 0077 const int index; 0078 Q_DISABLE_COPY(SqliteSqlField) 0079 }; 0080 0081 class SqliteSqlRecord : public KDbSqlRecord 0082 { 0083 public: 0084 inline SqliteSqlRecord(sqlite3_stmt *st) 0085 : prepared_st(st) 0086 { 0087 Q_ASSERT(st); 0088 } 0089 inline ~SqliteSqlRecord() override { 0090 } 0091 inline QString stringValue(int index) override { 0092 return QString::fromUtf8( 0093 (const char*)sqlite3_column_text(prepared_st, index), 0094 sqlite3_column_bytes(prepared_st, index)); 0095 } 0096 inline KDbSqlString cstringValue(int index) override { 0097 // sqlite3_column_text() returns UTF-8 but it's OK if the data is a C string 0098 return KDbSqlString((const char*)sqlite3_column_text(prepared_st, index), 0099 sqlite3_column_bytes(prepared_st, index)); 0100 } 0101 inline QByteArray toByteArray(int index) override { 0102 return QByteArray((const char*)sqlite3_column_blob(prepared_st, index), 0103 sqlite3_column_bytes(prepared_st, index)); 0104 } 0105 0106 private: 0107 sqlite3_stmt * const prepared_st; 0108 Q_DISABLE_COPY(SqliteSqlRecord) 0109 }; 0110 0111 //! Used by SqliteSqlResult::cacheFieldInfo(const QString&) 0112 struct SqliteSqlFieldInfo { 0113 void setConstraints(KDbField* field); 0114 QString defaultValue; 0115 bool isNotNull; 0116 bool isPrimaryKey; 0117 }; 0118 0119 class SqliteSqlResult : public KDbSqlResult 0120 { 0121 public: 0122 inline SqliteSqlResult(SqliteConnection *c, sqlite3_stmt *st) 0123 : conn(c), prepared_st(st) 0124 { 0125 Q_ASSERT(c); 0126 } 0127 0128 inline ~SqliteSqlResult() override { 0129 // don't check result here, done elsewhere already 0130 (void)sqlite3_finalize(prepared_st); 0131 } 0132 0133 inline KDbConnection *connection() const override { 0134 return conn; 0135 } 0136 0137 inline int fieldsCount() override { 0138 // We're using sqlite3_column_count instead of sqlite3_data_count to know 0139 // the column count before fetching. User will know if fetching succeeded anyway. 0140 return sqlite3_column_count(prepared_st); 0141 } 0142 0143 Q_REQUIRED_RESULT inline KDbSqlField *field(int index) override 0144 { 0145 return prepared_st ? new SqliteSqlField(prepared_st, index) : nullptr; 0146 } 0147 0148 Q_REQUIRED_RESULT KDbField *createField(const QString &tableName, int index) override; 0149 0150 Q_REQUIRED_RESULT inline QSharedPointer<KDbSqlRecord> fetchRecord() override 0151 { 0152 SqliteSqlRecord *record; 0153 const int res = sqlite3_step(prepared_st); 0154 if (res == SQLITE_ROW) { 0155 record = new SqliteSqlRecord(prepared_st); 0156 } else { 0157 record = nullptr; 0158 } 0159 return QSharedPointer<KDbSqlRecord>(record); 0160 } 0161 0162 inline KDbResult lastResult() override { 0163 KDbResult res; 0164 const int err = sqlite3_errcode(conn->d->data); 0165 if (err != SQLITE_ROW && err != SQLITE_OK && err != SQLITE_DONE) { 0166 res.setCode(ERR_OTHER); 0167 res.setServerErrorCode(err); 0168 conn->d->storeResult(&res); 0169 } 0170 return res; 0171 } 0172 0173 inline quint64 lastInsertRecordId() override { 0174 return static_cast<quint64>(sqlite3_last_insert_rowid(conn->d->data)); 0175 } 0176 0177 protected: 0178 //! @return a KDb type for a SQLite type 0179 //! The returned type is a guess, for example KDbField::Integer is returned for SQLITE_INTEGER. 0180 //! For unsupported types returns KDbField::InvalidType. 0181 //! See https://www.sqlite.org/c3ref/c_blob.html 0182 static KDbField::Type type(int sqliteType); 0183 0184 //! Sets constraints to a @a field based on SQLite's internal schema: 0185 //! - whether the column can be NULL 0186 //! - the default value for the column 0187 //! - whether the column is primary key 0188 //! @note @a field should have its name set 0189 //! See https://www.sqlite.org/pragma.html#pragma_table_info 0190 //! @todo support keys 0191 bool setConstraints(const QString &tableName, KDbField* field); 0192 0193 //! Caches information about the fields, for setConstraints() 0194 //! @todo Support composite primary keys 0195 //! @todo Default values are only encoded as string 0196 bool cacheFieldInfo(const QString &tableName); 0197 0198 private: 0199 SqliteConnection * const conn; 0200 sqlite3_stmt * const prepared_st; 0201 KDbUtils::AutodeletedHash<QString, SqliteSqlFieldInfo*> cachedFieldInfos; 0202 friend class SqlitePreparedStatement; 0203 Q_DISABLE_COPY(SqliteSqlResult) 0204 }; 0205 0206 #endif