summaryrefslogtreecommitdiffstats
path: root/src/sql/qsqlrecord.cpp
diff options
context:
space:
mode:
authorTimothy Pearson <[email protected]>2011-07-10 15:24:15 -0500
committerTimothy Pearson <[email protected]>2011-07-10 15:24:15 -0500
commitbd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch)
tree7a520322212d48ebcb9fbe1087e7fca28b76185c /src/sql/qsqlrecord.cpp
downloadqt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz
qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip
Add Qt3 development HEAD version
Diffstat (limited to 'src/sql/qsqlrecord.cpp')
-rw-r--r--src/sql/qsqlrecord.cpp774
1 files changed, 774 insertions, 0 deletions
diff --git a/src/sql/qsqlrecord.cpp b/src/sql/qsqlrecord.cpp
new file mode 100644
index 0000000..bc6a25f
--- /dev/null
+++ b/src/sql/qsqlrecord.cpp
@@ -0,0 +1,774 @@
+/****************************************************************************
+**
+** Implementation of QSqlRecord class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the Qt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at [email protected].
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.QPL
+** included in the packaging of this file. Licensees holding valid Qt
+** Commercial licenses may use this file in accordance with the Qt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "qsqlrecord.h"
+
+#ifndef QT_NO_SQL
+
+#include "qregexp.h"
+#include "qvaluevector.h"
+#include "qshared.h"
+#include "qnamespace.h"
+
+class QSqlRecordPrivate
+{
+public:
+ class info {
+ public:
+ info() : nogen(FALSE){}
+ ~info() {}
+ info( const info& other )
+ : field( other.field ), nogen( other.nogen )
+ {
+ }
+ info& operator=(const info& other)
+ {
+ field = other.field;
+ nogen = other.nogen;
+ return *this;
+ }
+ bool isValid() const
+ {
+ return !field.name().isNull();
+ }
+ Q_DUMMY_COMPARISON_OPERATOR(info)
+ QSqlField field;
+ bool nogen;
+ };
+
+ QSqlRecordPrivate(): cnt(0)
+ {
+ }
+ QSqlRecordPrivate( const QSqlRecordPrivate& other )
+ {
+ *this = other;
+ }
+ ~QSqlRecordPrivate() {};
+ QSqlRecordPrivate& operator=( const QSqlRecordPrivate& other )
+ {
+ fi = other.fi;
+ cnt = other.cnt;
+ return *this;
+ }
+ void append( const QSqlField& field )
+ {
+ info i;
+ i.field = field;
+ fi.append( i );
+ cnt++;
+ }
+ void insert( int pos, const QSqlField& field )
+ {
+ info i;
+ i.field = field;
+ if ( pos == (int)fi.size() )
+ append( field );
+ if ( pos > (int)fi.size() ) {
+ fi.resize( pos + 1 );
+ cnt++;
+ }
+ fi[ pos ] = i;
+ }
+ void remove( int i )
+ {
+ info inf;
+ if ( i >= (int)fi.count() )
+ return;
+ if ( fi[ i ].isValid() )
+ cnt--;
+ fi[ i ] = inf;
+ // clean up some memory
+ while ( fi.count() && !fi.back().isValid() )
+ fi.pop_back();
+ }
+ void clear()
+ {
+ fi.clear();
+ cnt = 0;
+ }
+ bool isEmpty()
+ {
+ return cnt == 0;
+ }
+ info* fieldInfo( int i )
+ {
+ if ( i < (int)fi.count() )
+ return &fi[i];
+ return 0;
+ }
+ uint count() const
+ {
+ return cnt;
+ }
+ bool contains( int i ) const
+ {
+ return i >= 0 && i < (int)fi.count() && fi[ i ].isValid();
+ }
+private:
+ QValueVector< info > fi;
+ uint cnt;
+};
+
+QSqlRecordShared::~QSqlRecordShared()
+{
+ if ( d )
+ delete d;
+}
+
+/*!
+ \class QSqlRecord qsqlfield.h
+ \brief The QSqlRecord class encapsulates a database record, i.e. a
+ set of database fields.
+
+ \ingroup database
+ \module sql
+
+ The QSqlRecord class encapsulates the functionality and
+ characteristics of a database record (usually a table or view within
+ the database). QSqlRecords support adding and removing fields as
+ well as setting and retrieving field values.
+
+ QSqlRecord is implicitly shared. This means you can make copies of
+ the record in time O(1). If multiple QSqlRecord instances share
+ the same data and one is modifying the record's data then this
+ modifying instance makes a copy and modifies its private copy -
+ thus it does not affect other instances.
+
+ \sa QSqlRecordInfo
+*/
+
+
+/*!
+ Constructs an empty record.
+*/
+
+QSqlRecord::QSqlRecord()
+{
+ sh = new QSqlRecordShared( new QSqlRecordPrivate() );
+}
+
+/*!
+ Constructs a copy of \a other.
+*/
+
+QSqlRecord::QSqlRecord( const QSqlRecord& other )
+ : sh( other.sh )
+{
+ sh->ref();
+}
+
+/*!
+ Sets the record equal to \a other.
+*/
+
+QSqlRecord& QSqlRecord::operator=( const QSqlRecord& other )
+{
+ other.sh->ref();
+ deref();
+ sh = other.sh;
+ return *this;
+}
+
+/*! \internal
+*/
+
+void QSqlRecord::deref()
+{
+ if ( sh->deref() ) {
+ delete sh;
+ sh = 0;
+ }
+}
+
+/*! \internal
+*/
+
+bool QSqlRecord::checkDetach()
+{
+ if ( sh->count > 1 ) {
+ sh->deref();
+ sh = new QSqlRecordShared( new QSqlRecordPrivate( *sh->d ) );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+QSqlRecord::~QSqlRecord()
+{
+ deref();
+}
+
+/*!
+ Returns the value of the field located at position \a i in the
+ record. If field \a i does not exist the resultant behaviour is
+ undefined.
+
+ This function should be used with \l{QSqlQuery}s. When working
+ with a QSqlCursor the \link QSqlCursor::value() value(const
+ QString&)\endlink overload which uses field names is more
+ appropriate.
+*/
+
+QVariant QSqlRecord::value( int i ) const
+{
+ const QSqlField * f = field(i);
+
+ if( f )
+ return f->value();
+ return QVariant();
+}
+
+/*!
+ \overload
+
+ Returns the value of the field called \a name in the record. If
+ field \a name does not exist the resultant behaviour is undefined.
+*/
+
+QVariant QSqlRecord::value( const QString& name ) const
+{
+ const QSqlField * f = field( name );
+
+ if( f )
+ return f->value();
+ return QVariant();
+}
+
+/*!
+ Returns the name of the field at position \a i. If the field does
+ not exist, QString::null is returned.
+*/
+
+QString QSqlRecord::fieldName( int i ) const
+{
+ const QSqlField* f = field( i );
+ if ( f )
+ return f->name();
+ return QString::null;
+}
+
+/*!
+ Returns the position of the field called \a name within the
+ record, or -1 if it cannot be found. Field names are not
+ case-sensitive. If more than one field matches, the first one is
+ returned.
+*/
+
+int QSqlRecord::position( const QString& name ) const
+{
+ for ( uint i = 0; i < count(); ++i ) {
+ if ( fieldName(i).upper() == name.upper() )
+ return i;
+ }
+#ifdef QT_CHECK_RANGE
+ qWarning( "QSqlRecord::position: unable to find field %s", name.latin1() );
+#endif
+ return -1;
+}
+
+/*!
+ Returns the field at position \a i within the record, or 0 if it
+ cannot be found.
+*/
+
+QSqlField* QSqlRecord::field( int i )
+{
+ checkDetach();
+ if ( !sh->d->contains( i ) ) {
+#ifdef QT_CHECK_RANGE
+ qWarning( "QSqlRecord::field: index out of range: %d", i );
+#endif
+ return 0;
+ }
+ return &sh->d->fieldInfo( i )->field;
+}
+
+/*!
+ \overload
+
+ Returns the field called \a name within the record, or 0 if it
+ cannot be found. Field names are not case-sensitive.
+*/
+
+QSqlField* QSqlRecord::field( const QString& name )
+{
+ checkDetach();
+ if ( !sh->d->contains( position( name ) ) )
+ return 0;
+ return &sh->d->fieldInfo( position( name ) )->field;
+}
+
+
+/*!
+ \overload
+*/
+
+const QSqlField* QSqlRecord::field( int i ) const
+{
+ if ( !sh->d->contains( i ) ) {
+#ifdef QT_CHECK_RANGE
+ qWarning( "QSqlRecord::field: index out of range: %d", i );
+#endif // QT_CHECK_RANGE
+ return 0;
+ }
+ return &sh->d->fieldInfo( i )->field;
+}
+
+/*!
+ \overload
+
+ Returns the field called \a name within the record, or 0 if it
+ cannot be found. Field names are not case-sensitive.
+*/
+
+const QSqlField* QSqlRecord::field( const QString& name ) const
+{
+ if( !sh->d->contains( position( name ) ) )
+ return 0;
+ return &sh->d->fieldInfo( position( name ) )->field;
+}
+
+/*!
+ Append a copy of field \a field to the end of the record.
+*/
+
+void QSqlRecord::append( const QSqlField& field )
+{
+ checkDetach();
+ sh->d->append( field );
+}
+
+/*!
+ Insert a copy of \a field at position \a pos. If a field already
+ exists at \a pos, it is removed.
+*/
+
+void QSqlRecord::insert( int pos, const QSqlField& field ) // ### 4.0: rename to ::replace
+{
+ checkDetach();
+ sh->d->insert( pos, field );
+}
+
+/*!
+ Removes the field at \a pos. If \a pos does not exist, nothing
+ happens.
+*/
+
+void QSqlRecord::remove( int pos )
+{
+ checkDetach();
+ sh->d->remove( pos );
+}
+
+/*!
+ Removes all the record's fields.
+
+ \sa clearValues()
+*/
+
+void QSqlRecord::clear()
+{
+ checkDetach();
+ sh->d->clear();
+}
+
+/*!
+ Returns TRUE if there are no fields in the record; otherwise
+ returns FALSE.
+*/
+
+bool QSqlRecord::isEmpty() const
+{
+ return sh->d->isEmpty();
+}
+
+
+/*!
+ Returns TRUE if there is a field in the record called \a name;
+ otherwise returns FALSE.
+*/
+
+bool QSqlRecord::contains( const QString& name ) const
+{
+ for ( uint i = 0; i < count(); ++i ) {
+ if ( fieldName(i).upper() == name.upper() )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*!
+ Clears the value of all fields in the record. If \a nullify is
+ TRUE, (the default is FALSE), each field is set to NULL.
+*/
+
+void QSqlRecord::clearValues( bool nullify )
+{
+ checkDetach();
+ int cnt = (int)count();
+ int i;
+ for ( i = 0; i < cnt; ++i ) {
+ field( i )->clear( nullify );
+ }
+}
+
+/*!
+ Sets the generated flag for the field called \a name to \a
+ generated. If the field does not exist, nothing happens. Only
+ fields that have \a generated set to TRUE are included in the SQL
+ that is generated, e.g. by QSqlCursor.
+
+ \sa isGenerated()
+*/
+
+void QSqlRecord::setGenerated( const QString& name, bool generated )
+{
+ setGenerated( position( name ), generated );
+}
+
+/*!
+ \overload
+
+ Sets the generated flag for the field \a i to \a generated.
+
+ \sa isGenerated()
+*/
+
+void QSqlRecord::setGenerated( int i, bool generated )
+{
+ checkDetach();
+ if ( !field( i ) )
+ return;
+ sh->d->fieldInfo( i )->nogen = !generated;
+}
+
+/*!
+ \internal
+ ### Remove in 4.0
+*/
+bool QSqlRecord::isNull( int i )
+{
+ checkDetach();
+ QSqlField* f = field( i );
+ if ( f ) {
+ return f->isNull();
+ }
+ return TRUE;
+}
+
+/*!
+ \internal
+ ### Remove in 4.0
+*/
+bool QSqlRecord::isNull( const QString& name )
+{
+ return isNull( position( name ) );
+}
+
+/*!
+ \overload
+
+ Returns TRUE if the field \a i is NULL or if there is no field at
+ position \a i; otherwise returns FALSE.
+
+ \sa fieldName()
+*/
+bool QSqlRecord::isNull( int i ) const
+{
+ const QSqlField* f = field( i );
+ if ( f ) {
+ return f->isNull();
+ }
+ return TRUE;
+}
+
+/*!
+ Returns TRUE if the field called \a name is NULL or if there is no
+ field called \a name; otherwise returns FALSE.
+
+ \sa position()
+*/
+bool QSqlRecord::isNull( const QString& name ) const
+{
+ return isNull( position( name ) );
+}
+
+/*!
+ Sets the value of field \a i to NULL. If the field does not exist,
+ nothing happens.
+*/
+void QSqlRecord::setNull( int i )
+{
+ checkDetach();
+ QSqlField* f = field( i );
+ if ( f ) {
+ f->setNull();
+ }
+}
+
+/*!
+ \overload
+
+ Sets the value of the field called \a name to NULL. If the field
+ does not exist, nothing happens.
+*/
+void QSqlRecord::setNull( const QString& name )
+{
+ setNull( position( name ) );
+}
+
+
+/*!
+ Returns TRUE if the record has a field called \a name and this
+ field is to be generated (the default); otherwise returns FALSE.
+
+ \sa setGenerated()
+*/
+bool QSqlRecord::isGenerated( const QString& name ) const
+{
+ return isGenerated( position( name ) );
+}
+
+/*!
+ \overload
+
+ Returns TRUE if the record has a field at position \a i and this
+ field is to be generated (the default); otherwise returns FALSE.
+
+ \sa setGenerated()
+*/
+bool QSqlRecord::isGenerated( int i ) const
+{
+ if ( !field( i ) )
+ return FALSE;
+ return !sh->d->fieldInfo( i )->nogen;
+}
+
+
+/*!
+ Returns a list of all the record's field names as a string
+ separated by \a sep.
+
+ Note that fields which are not generated are \e not included (see
+ \l{isGenerated()}). The returned string is suitable, for example, for
+ generating SQL SELECT statements. If a \a prefix is specified,
+ e.g. a table name, all fields are prefixed in the form:
+
+ "\a{prefix}.\<fieldname\>"
+*/
+
+QString QSqlRecord::toString( const QString& prefix, const QString& sep ) const
+{
+ QString pflist;
+ bool comma = FALSE;
+ for ( uint i = 0; i < count(); ++i ){
+ if ( isGenerated( field(i)->name() ) ) {
+ if( comma )
+ pflist += sep + " ";
+ pflist += createField( i, prefix );
+ comma = TRUE;
+ }
+ }
+ return pflist;
+}
+
+/*!
+ Returns a list of all the record's field names, each having the
+ prefix \a prefix.
+
+ Note that fields which have generated set to FALSE are \e not
+ included. (See \l{isGenerated()}). If \a prefix is supplied, e.g.
+ a table name, all fields are prefixed in the form:
+
+ "\a{prefix}.\<fieldname\>"
+*/
+
+QStringList QSqlRecord::toStringList( const QString& prefix ) const
+{
+ QStringList s;
+ for ( uint i = 0; i < count(); ++i ) {
+ if ( isGenerated( field(i)->name() ) )
+ s += createField( i, prefix );
+ }
+ return s;
+}
+
+/*! \internal
+*/
+
+QString QSqlRecord::createField( int i, const QString& prefix ) const
+{
+ QString f;
+ if ( !prefix.isEmpty() )
+ f = prefix + ".";
+ f += field( i )->name();
+ return f;
+}
+
+/*!
+ Returns the number of fields in the record.
+*/
+
+uint QSqlRecord::count() const
+{
+ return sh->d->count();
+}
+
+/*!
+ Sets the value of the field at position \a i to \a val. If the
+ field does not exist, nothing happens.
+*/
+
+void QSqlRecord::setValue( int i, const QVariant& val )
+{
+ checkDetach();
+ QSqlField* f = field( i );
+ if ( f ) {
+ f->setValue( val );
+ }
+}
+
+
+/*!
+ \overload
+
+ Sets the value of the field called \a name to \a val. If the field
+ does not exist, nothing happens.
+*/
+
+void QSqlRecord::setValue( const QString& name, const QVariant& val )
+{
+ setValue( position( name ), val );
+}
+
+
+/******************************************/
+/******* QSqlRecordInfo Impl ******/
+/******************************************/
+
+/*!
+ \class QSqlRecordInfo qsqlrecord.h
+ \brief The QSqlRecordInfo class encapsulates a set of database field meta data.
+
+ \ingroup database
+ \module sql
+
+ This class is a QValueList that holds a set of database field meta
+ data. Use contains() to see if a given field name exists in the
+ record, and use find() to get a QSqlFieldInfo record for a named
+ field.
+
+ \sa QValueList, QSqlFieldInfo
+*/
+
+
+/*!
+ Constructs a QSqlRecordInfo object based on the fields in the
+ QSqlRecord \a other.
+*/
+QSqlRecordInfo::QSqlRecordInfo( const QSqlRecord& other )
+{
+ for ( uint i = 0; i < other.count(); ++i ) {
+ push_back( QSqlFieldInfo( *(other.field( i )), other.isGenerated( i ) ) );
+ }
+}
+
+/*!
+ Returns the number of times a field called \a fieldName occurs in
+ the record. Returns 0 if no field by that name could be found.
+*/
+QSqlRecordInfo::size_type QSqlRecordInfo::contains( const QString& fieldName ) const
+{
+ size_type i = 0;
+ QString fName = fieldName.upper();
+ for( const_iterator it = begin(); it != end(); ++it ) {
+ if ( (*it).name().upper() == fName ) {
+ ++i;
+ }
+ }
+ return i;
+}
+
+/*!
+ Returns a QSqlFieldInfo object for the first field in the record
+ which has the field name \a fieldName. If no matching field is
+ found then an empty QSqlFieldInfo object is returned.
+*/
+QSqlFieldInfo QSqlRecordInfo::find( const QString& fieldName ) const
+{
+ QString fName = fieldName.upper();
+ for( const_iterator it = begin(); it != end(); ++it ) {
+ if ( (*it).name().upper() == fName ) {
+ return *it;
+ }
+ }
+ return QSqlFieldInfo();
+}
+
+/*!
+ Returns an empty QSqlRecord based on the field information
+ in this QSqlRecordInfo.
+*/
+QSqlRecord QSqlRecordInfo::toRecord() const
+{
+ QSqlRecord buf;
+ for( const_iterator it = begin(); it != end(); ++it ) {
+ buf.append( (*it).toField() );
+ }
+ return buf;
+}
+
+/*!
+ \fn QSqlRecordInfo::QSqlRecordInfo()
+
+ Constructs an empty record info object
+*/
+
+/*!
+ \fn QSqlRecordInfo::QSqlRecordInfo( const QSqlFieldInfoList& other )
+
+ Constructs a copy of \a other.
+*/
+
+#endif