File indexing completed on 2024-12-08 07:18:24

0001 /* This file is part of the KDE project
0002    Copyright (C) 2002   Lucijan Busch <lucijan@gmx.at>
0003    Copyright (C) 2003   Daniel Molkentin <molkentin@kde.org>
0004    Copyright (C) 2003-2016 Jarosław Staniek <staniek@kde.org>
0005 
0006    This program is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU Library General Public
0008    License as published by the Free Software Foundation; either
0009    version 2 of the License, or (at your option) any later version.
0010 
0011    This program is distributed in the hope that it will be useful,
0012    but WITHOUT ANY WARRANTY; without even the implied warranty of
0013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014    Library General Public License for more details.
0015 
0016    You should have received a copy of the GNU Library General Public License
0017    along with this program; see the file COPYING.  If not, write to
0018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019  * Boston, MA 02110-1301, USA.
0020 
0021    Original Author:  Till Busch <till@bux.at>
0022    Original Project: buX (www.bux.at)
0023 */
0024 
0025 #ifndef KDB_RECORDDATA_H
0026 #define KDB_RECORDDATA_H
0027 
0028 #include <QVariant>
0029 #include "kdb_export.h"
0030 
0031 //! @short Structure for storing single record with type information.
0032 //! @todo consider forking QVariant to a non-shared Variant class, with type information stored elsewhere.
0033 //! @todo Variant should have toQVariant() method
0034 //! @todo look if we can have zero-copy strategy for SQLite and other backends
0035 //! @todo look if we can use memory allocator for strings, etc.
0036 class KDB_EXPORT KDbRecordData
0037 {
0038 public:
0039     /*! Creates a new empty record. */
0040     inline KDbRecordData() : m_data(nullptr), m_numCols(0) {}
0041 
0042     /*! Creates a new record data with @a numCols columns.
0043      Values are initialized to null. */
0044     inline explicit KDbRecordData(int numCols)
0045         : m_numCols(numCols)
0046     {
0047         if (m_numCols > 0) {
0048             m_data = static_cast<QVariant **>(malloc(m_numCols * sizeof(QVariant *)));
0049             memset(m_data, 0, m_numCols * sizeof(QVariant *));
0050         } else {
0051             m_data = nullptr;
0052         }
0053     }
0054 
0055     inline ~KDbRecordData() {
0056         if (m_numCols > 0) {
0057             for (int i = 0; i < m_numCols; i++)
0058                 delete m_data[i];
0059             free(m_data);
0060         }
0061     }
0062 
0063     inline bool isEmpty() const { return m_numCols == 0; }
0064 
0065     inline int size() const { return m_numCols; }
0066 
0067     inline int count() const { return m_numCols; }
0068 
0069     /*! @return the value at position @a i.
0070      @a i must be a valid index. i.e. 0 <= i < size().
0071      @see value(), operator[](). */
0072     inline const QVariant& at(int i) const {
0073         if (!m_data[i])
0074             return s_null;
0075         return *m_data[i];
0076     }
0077 
0078     /*! @return the value at position @a i as a modifiable reference.
0079      @a i must be a valid index, i.e. 0 <= i < size().
0080      @see at(), value(). */
0081     inline QVariant& operator[](int i) {
0082         if (!m_data[i]) {
0083             return *(m_data[i] = new QVariant);
0084         }
0085         return *m_data[i];
0086     }
0087 
0088     /*! @return true id value at position @a i is null.
0089      @a i must be a valid index, i.e. 0 <= i < size().
0090      @see at(), value(). */
0091     inline bool isNull(int i) const { return !m_data[i] || m_data[i]->isNull(); }
0092 
0093     /*! Overloaded function.*/
0094     inline const QVariant& operator[](int i) const {
0095         if (!m_data[i])
0096             return s_null;
0097         return *m_data[i];
0098     }
0099 
0100     /*! @return the value at index position @a i in the vector.
0101      If the index @a i is out of bounds, the function returns a default-constructed value.
0102      If you are certain that @a i is within bounds, you can use at() or operator[] instead, which is
0103      slightly faster. */
0104     inline QVariant value(int i) const {
0105         if (!m_data || i < 0 || i >= m_numCols || !m_data[i])
0106             return QVariant();
0107         return *m_data[i];
0108     }
0109 
0110     /*! @return the value at index position @a i in the vector.
0111      This is an overloaded function.
0112      If the index @a i is out of bounds, the function returns a @a defaultValue.
0113      If you are certain that i is within bounds, you can use at() instead, which is slightly faster. */
0114     inline QVariant value(int i, const QVariant& defaultValue) const {
0115         if (!m_data || i < 0 || i >= m_numCols)
0116             return defaultValue;
0117         if (!m_data[i])
0118             return QVariant();
0119         return *m_data[i];
0120     }
0121 
0122     /*! Sets all column values to null, current number of columns is preserved. */
0123     void clearValues();
0124 
0125     /*! Clears all columns, the record is set empty. */
0126     void clear();
0127 
0128     /*! Resizes the record to @a numCols.
0129      If @a numCols differ from size(), new with record with all values set to null is created.
0130      If @a numCols equals size() nothing is performed. */
0131     void resize(int numCols);
0132 
0133     //! Converts this record to QList<QVariant>
0134     QList<QVariant> toList() const;
0135 
0136 private:
0137     Q_DISABLE_COPY(KDbRecordData)
0138     QVariant **m_data;
0139     int m_numCols;
0140     static QVariant s_null;
0141 };
0142 
0143 //! Sends information about record data @a data to debug output @a dbg.
0144 KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbRecordData& data);
0145 
0146 #endif