src/sql/kernel/qsqlrecord.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtSql module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qsqlrecord.h"
       
    43 
       
    44 #include "qdebug.h"
       
    45 #include "qstringlist.h"
       
    46 #include "qatomic.h"
       
    47 #include "qsqlfield.h"
       
    48 #include "qstring.h"
       
    49 #include "qvector.h"
       
    50 
       
    51 QT_BEGIN_NAMESPACE
       
    52 
       
    53 class QSqlRecordPrivate
       
    54 {
       
    55 public:
       
    56     QSqlRecordPrivate();
       
    57     QSqlRecordPrivate(const QSqlRecordPrivate &other);
       
    58 
       
    59     inline bool contains(int index) { return index >= 0 && index < fields.count(); }
       
    60     QString createField(int index, const QString &prefix) const;
       
    61 
       
    62     QVector<QSqlField> fields;
       
    63     QAtomicInt ref;
       
    64 };
       
    65 
       
    66 QSqlRecordPrivate::QSqlRecordPrivate()
       
    67 {
       
    68     ref = 1;
       
    69 }
       
    70 
       
    71 QSqlRecordPrivate::QSqlRecordPrivate(const QSqlRecordPrivate &other): fields(other.fields)
       
    72 {
       
    73     ref = 1;
       
    74 }
       
    75 
       
    76 /*! \internal
       
    77     Just for compat
       
    78 */
       
    79 QString QSqlRecordPrivate::createField(int index, const QString &prefix) const
       
    80 {
       
    81     QString f;
       
    82     if (!prefix.isEmpty())
       
    83         f = prefix + QLatin1Char('.');
       
    84     f += fields.at(index).name();
       
    85     return f;
       
    86 }
       
    87 
       
    88 /*!
       
    89     \class QSqlRecord
       
    90     \brief The QSqlRecord class encapsulates a database record.
       
    91 
       
    92     \ingroup database
       
    93     \ingroup shared
       
    94     \inmodule QtSql
       
    95 
       
    96     The QSqlRecord class encapsulates the functionality and
       
    97     characteristics of a database record (usually a row in a table or
       
    98     view within the database). QSqlRecord supports adding and
       
    99     removing fields as well as setting and retrieving field values.
       
   100 
       
   101     The values of a record's fields' can be set by name or position
       
   102     with setValue(); if you want to set a field to null use
       
   103     setNull(). To find the position of a field by name use indexOf(),
       
   104     and to find the name of a field at a particular position use
       
   105     fieldName(). Use field() to retrieve a QSqlField object for a
       
   106     given field. Use contains() to see if the record contains a
       
   107     particular field name.
       
   108 
       
   109     When queries are generated to be executed on the database only
       
   110     those fields for which isGenerated() is true are included in the
       
   111     generated SQL.
       
   112 
       
   113     A record can have fields added with append() or insert(), replaced
       
   114     with replace(), and removed with remove(). All the fields can be
       
   115     removed with clear(). The number of fields is given by count();
       
   116     all their values can be cleared (to null) using clearValues().
       
   117 
       
   118     \sa QSqlField, QSqlQuery::record()
       
   119 */
       
   120 
       
   121 
       
   122 /*!
       
   123     Constructs an empty record.
       
   124 
       
   125     \sa isEmpty(), append(), insert()
       
   126 */
       
   127 
       
   128 QSqlRecord::QSqlRecord()
       
   129 {
       
   130     d = new QSqlRecordPrivate();
       
   131 }
       
   132 
       
   133 /*!
       
   134     Constructs a copy of \a other.
       
   135 
       
   136     QSqlRecord is \l{implicitly shared}. This means you can make copies
       
   137     of a record in \l{constant time}.
       
   138 */
       
   139 
       
   140 QSqlRecord::QSqlRecord(const QSqlRecord& other)
       
   141 {
       
   142     d = other.d;
       
   143     d->ref.ref();
       
   144 }
       
   145 
       
   146 /*!
       
   147     Sets the record equal to \a other.
       
   148 
       
   149     QSqlRecord is \l{implicitly shared}. This means you can make copies
       
   150     of a record in \l{constant time}.
       
   151 */
       
   152 
       
   153 QSqlRecord& QSqlRecord::operator=(const QSqlRecord& other)
       
   154 {
       
   155     qAtomicAssign(d, other.d);
       
   156     return *this;
       
   157 }
       
   158 
       
   159 /*!
       
   160     Destroys the object and frees any allocated resources.
       
   161 */
       
   162 
       
   163 QSqlRecord::~QSqlRecord()
       
   164 {
       
   165     if (!d->ref.deref())
       
   166         delete d;
       
   167 }
       
   168 
       
   169 /*!
       
   170     \fn bool QSqlRecord::operator!=(const QSqlRecord &other) const
       
   171 
       
   172     Returns true if this object is not identical to \a other;
       
   173     otherwise returns false.
       
   174 
       
   175     \sa operator==()
       
   176 */
       
   177 
       
   178 /*!
       
   179     Returns true if this object is identical to \a other (i.e., has
       
   180     the same fields in the same order); otherwise returns false.
       
   181 
       
   182     \sa operator!=()
       
   183 */
       
   184 bool QSqlRecord::operator==(const QSqlRecord &other) const
       
   185 {
       
   186     return d->fields == other.d->fields;
       
   187 }
       
   188 
       
   189 /*!
       
   190     Returns the value of the field located at position \a index in
       
   191     the record. If \a index is out of bounds, an invalid QVariant
       
   192     is returned.
       
   193 
       
   194     \sa fieldName() isNull()
       
   195 */
       
   196 
       
   197 QVariant QSqlRecord::value(int index) const
       
   198 {
       
   199     return d->fields.value(index).value();
       
   200 }
       
   201 
       
   202 /*!
       
   203     \overload
       
   204 
       
   205     Returns the value of the field called \a name in the record. If
       
   206     field \a name does not exist an invalid variant is returned.
       
   207 
       
   208     \sa indexOf()
       
   209 */
       
   210 
       
   211 QVariant QSqlRecord::value(const QString& name) const
       
   212 {
       
   213     return value(indexOf(name));
       
   214 }
       
   215 
       
   216 /*!
       
   217     Returns the name of the field at position \a index. If the field
       
   218     does not exist, an empty string is returned.
       
   219 
       
   220     \sa indexOf()
       
   221 */
       
   222 
       
   223 QString QSqlRecord::fieldName(int index) const
       
   224 {
       
   225     return d->fields.value(index).name();
       
   226 }
       
   227 
       
   228 /*!
       
   229     Returns the position of the field called \a name within the
       
   230     record, or -1 if it cannot be found. Field names are not
       
   231     case-sensitive. If more than one field matches, the first one is
       
   232     returned.
       
   233 
       
   234     \sa fieldName()
       
   235 */
       
   236 
       
   237 int QSqlRecord::indexOf(const QString& name) const
       
   238 {
       
   239     QString nm = name.toUpper();
       
   240     for (int i = 0; i < count(); ++i) {
       
   241         if (d->fields.at(i).name().toUpper() == nm) // TODO: case-insensitive comparison
       
   242             return i;
       
   243     }
       
   244     return -1;
       
   245 }
       
   246 
       
   247 #ifdef QT3_SUPPORT
       
   248 /*!
       
   249     \obsolete
       
   250     Use field() instead
       
   251 */
       
   252 const QSqlField* QSqlRecord::fieldPtr(int index) const
       
   253 {
       
   254     if (!d->contains(index))
       
   255         return 0;
       
   256 
       
   257     return &d->fields.at(index);
       
   258 }
       
   259 
       
   260 /*!
       
   261     \obsolete
       
   262     Use field() instead
       
   263 */
       
   264 
       
   265 const QSqlField* QSqlRecord::fieldPtr(const QString& name) const
       
   266 {
       
   267     int i = indexOf(name);
       
   268     if (!d->contains(i))
       
   269         return 0;
       
   270 
       
   271     return &d->fields.at(i);
       
   272 }
       
   273 #endif //QT3_SUPPORT
       
   274 
       
   275 /*!
       
   276     Returns the field at position \a index. If the position is out of
       
   277     range, an empty field is returned.
       
   278  */
       
   279 QSqlField QSqlRecord::field(int index) const
       
   280 {
       
   281     return d->fields.value(index);
       
   282 }
       
   283 
       
   284 /*! \overload
       
   285     Returns the field called \a name.
       
   286  */
       
   287 QSqlField QSqlRecord::field(const QString &name) const
       
   288 {
       
   289     return field(indexOf(name));
       
   290 }
       
   291 
       
   292 
       
   293 /*!
       
   294     Append a copy of field \a field to the end of the record.
       
   295 
       
   296     \sa insert() replace() remove()
       
   297 */
       
   298 
       
   299 void QSqlRecord::append(const QSqlField& field)
       
   300 {
       
   301     detach();
       
   302     d->fields.append(field);
       
   303 }
       
   304 
       
   305 /*!
       
   306     Inserts the field \a field at position \a pos in the record.
       
   307 
       
   308     \sa append() replace() remove()
       
   309  */
       
   310 void QSqlRecord::insert(int pos, const QSqlField& field)
       
   311 {
       
   312    detach();
       
   313    d->fields.insert(pos, field);
       
   314 }
       
   315 
       
   316 /*!
       
   317     Replaces the field at position \a pos with the given \a field. If
       
   318     \a pos is out of range, nothing happens.
       
   319 
       
   320     \sa append() insert() remove()
       
   321 */
       
   322 
       
   323 void QSqlRecord::replace(int pos, const QSqlField& field)
       
   324 {
       
   325     if (!d->contains(pos))
       
   326         return;
       
   327 
       
   328     detach();
       
   329     d->fields[pos] = field;
       
   330 }
       
   331 
       
   332 /*!
       
   333     Removes the field at position \a pos. If \a pos is out of range,
       
   334     nothing happens.
       
   335 
       
   336     \sa append() insert() replace()
       
   337 */
       
   338 
       
   339 void QSqlRecord::remove(int pos)
       
   340 {
       
   341     if (!d->contains(pos))
       
   342         return;
       
   343 
       
   344     detach();
       
   345     d->fields.remove(pos);
       
   346 }
       
   347 
       
   348 /*!
       
   349     Removes all the record's fields.
       
   350 
       
   351     \sa clearValues() isEmpty()
       
   352 */
       
   353 
       
   354 void QSqlRecord::clear()
       
   355 {
       
   356     detach();
       
   357     d->fields.clear();
       
   358 }
       
   359 
       
   360 /*!
       
   361     Returns true if there are no fields in the record; otherwise
       
   362     returns false.
       
   363 
       
   364     \sa append() insert() clear()
       
   365 */
       
   366 
       
   367 bool QSqlRecord::isEmpty() const
       
   368 {
       
   369     return d->fields.isEmpty();
       
   370 }
       
   371 
       
   372 
       
   373 /*!
       
   374     Returns true if there is a field in the record called \a name;
       
   375     otherwise returns false.
       
   376 */
       
   377 
       
   378 bool QSqlRecord::contains(const QString& name) const
       
   379 {
       
   380     return indexOf(name) >= 0;
       
   381 }
       
   382 
       
   383 /*!
       
   384     Clears the value of all fields in the record and sets each field
       
   385     to null.
       
   386 
       
   387     \sa setValue()
       
   388 */
       
   389 
       
   390 void QSqlRecord::clearValues()
       
   391 {
       
   392     detach();
       
   393     int count = d->fields.count();
       
   394     for (int i = 0; i < count; ++i)
       
   395         d->fields[i].clear();
       
   396 }
       
   397 
       
   398 /*!
       
   399     Sets the generated flag for the field called \a name to \a
       
   400     generated. If the field does not exist, nothing happens. Only
       
   401     fields that have \a generated set to true are included in the SQL
       
   402     that is generated by QSqlQueryModel for example.
       
   403 
       
   404     \sa isGenerated()
       
   405 */
       
   406 
       
   407 void QSqlRecord::setGenerated(const QString& name, bool generated)
       
   408 {
       
   409     setGenerated(indexOf(name), generated);
       
   410 }
       
   411 
       
   412 /*!
       
   413     \overload
       
   414 
       
   415     Sets the generated flag for the field \a index to \a generated.
       
   416 
       
   417     \sa isGenerated()
       
   418 */
       
   419 
       
   420 void QSqlRecord::setGenerated(int index, bool generated)
       
   421 {
       
   422     if (!d->contains(index))
       
   423         return;
       
   424     detach();
       
   425     d->fields[index].setGenerated(generated);
       
   426 }
       
   427 
       
   428 /*!
       
   429     \overload
       
   430 
       
   431     Returns true if the field \a index is null or if there is no field at
       
   432     position \a index; otherwise returns false.
       
   433 */
       
   434 bool QSqlRecord::isNull(int index) const
       
   435 {
       
   436     return d->fields.value(index).isNull();
       
   437 }
       
   438 
       
   439 /*!
       
   440     Returns true if the field called \a name is null or if there is no
       
   441     field called \a name; otherwise returns false.
       
   442 
       
   443     \sa setNull()
       
   444 */
       
   445 bool QSqlRecord::isNull(const QString& name) const
       
   446 {
       
   447     return isNull(indexOf(name));
       
   448 }
       
   449 
       
   450 /*!
       
   451     Sets the value of field \a index to null. If the field does not exist,
       
   452     nothing happens.
       
   453 
       
   454     \sa setValue()
       
   455 */
       
   456 void QSqlRecord::setNull(int index)
       
   457 {
       
   458     if (!d->contains(index))
       
   459         return;
       
   460     detach();
       
   461     d->fields[index].clear();
       
   462 }
       
   463 
       
   464 /*!
       
   465     \overload
       
   466 
       
   467     Sets the value of the field called \a name to null. If the field
       
   468     does not exist, nothing happens.
       
   469 */
       
   470 void QSqlRecord::setNull(const QString& name)
       
   471 {
       
   472     setNull(indexOf(name));
       
   473 }
       
   474 
       
   475 
       
   476 /*!
       
   477     Returns true if the record has a field called \a name and this
       
   478     field is to be generated (the default); otherwise returns false.
       
   479 
       
   480     \sa setGenerated()
       
   481 */
       
   482 bool QSqlRecord::isGenerated(const QString& name) const
       
   483 {
       
   484     return isGenerated(indexOf(name));
       
   485 }
       
   486 
       
   487 /*! \overload
       
   488 
       
   489     Returns true if the record has a field at position \a index and this
       
   490     field is to be generated (the default); otherwise returns false.
       
   491 
       
   492     \sa setGenerated()
       
   493 */
       
   494 bool QSqlRecord::isGenerated(int index) const
       
   495 {
       
   496     return d->fields.value(index).isGenerated();
       
   497 }
       
   498 
       
   499 #ifdef QT3_SUPPORT
       
   500 /*!
       
   501     Returns a list of all the record's field names as a string
       
   502     separated by \a sep.
       
   503 
       
   504     In the unlikely event that you used this function in Qt 3, you
       
   505     can simulate it using the rest of the QSqlRecord public API.
       
   506 */
       
   507 
       
   508 QString QSqlRecord::toString(const QString& prefix, const QString& sep) const
       
   509 {
       
   510     QString pflist;
       
   511     bool comma = false;
       
   512     for (int i = 0; i < count(); ++i) {
       
   513         if (!d->fields.value(i).isGenerated()) {
       
   514             if (comma)
       
   515                 pflist += sep + QLatin1Char(' ');
       
   516             pflist += d->createField(i, prefix);
       
   517             comma = true;
       
   518         }
       
   519     }
       
   520     return pflist;
       
   521 }
       
   522 
       
   523 /*!
       
   524     Returns a list of all the record's field names, each having the
       
   525     prefix \a prefix.
       
   526 
       
   527     In the unlikely event that you used this function in Qt 3, you
       
   528     can simulate it using the rest of the QSqlRecord public API.
       
   529 */
       
   530 
       
   531 QStringList QSqlRecord::toStringList(const QString& prefix) const
       
   532 {
       
   533     QStringList s;
       
   534     for (int i = 0; i < count(); ++i) {
       
   535         if (!d->fields.value(i).isGenerated())
       
   536             s += d->createField(i, prefix);
       
   537     }
       
   538     return s;
       
   539 }
       
   540 #endif // QT3_SUPPORT
       
   541 
       
   542 /*!
       
   543     Returns the number of fields in the record.
       
   544 
       
   545     \sa isEmpty()
       
   546 */
       
   547 
       
   548 int QSqlRecord::count() const
       
   549 {
       
   550     return d->fields.count();
       
   551 }
       
   552 
       
   553 /*!
       
   554     Sets the value of the field at position \a index to \a val. If the
       
   555     field does not exist, nothing happens.
       
   556 
       
   557     \sa setNull()
       
   558 */
       
   559 
       
   560 void QSqlRecord::setValue(int index, const QVariant& val)
       
   561 {
       
   562     if (!d->contains(index))
       
   563         return;
       
   564     detach();
       
   565     d->fields[index].setValue(val);
       
   566 }
       
   567 
       
   568 
       
   569 /*!
       
   570     \overload
       
   571 
       
   572     Sets the value of the field called \a name to \a val. If the field
       
   573     does not exist, nothing happens.
       
   574 */
       
   575 
       
   576 void QSqlRecord::setValue(const QString& name, const QVariant& val)
       
   577 {
       
   578     setValue(indexOf(name), val);
       
   579 }
       
   580 
       
   581 
       
   582 /*! \internal
       
   583 */
       
   584 void QSqlRecord::detach()
       
   585 {
       
   586     qAtomicDetach(d);
       
   587 }
       
   588 
       
   589 #ifndef QT_NO_DEBUG_STREAM
       
   590 QDebug operator<<(QDebug dbg, const QSqlRecord &r)
       
   591 {
       
   592     dbg << "QSqlRecord(" << r.count() << ')';
       
   593     for (int i = 0; i < r.count(); ++i)
       
   594         dbg << '\n' << QString::fromLatin1("%1:").arg(i, 2) << r.field(i) << r.value(i).toString();
       
   595     return dbg;
       
   596 }
       
   597 #endif
       
   598 
       
   599 /*!
       
   600     \fn int QSqlRecord::position(const QString& name) const
       
   601 
       
   602     Use indexOf() instead.
       
   603 */
       
   604 
       
   605 QT_END_NAMESPACE