summaryrefslogtreecommitdiffstats
path: root/src/sql/tqsqlrecord.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sql/tqsqlrecord.cpp')
-rw-r--r--src/sql/tqsqlrecord.cpp774
1 files changed, 774 insertions, 0 deletions
diff --git a/src/sql/tqsqlrecord.cpp b/src/sql/tqsqlrecord.cpp
new file mode 100644
index 000000000..b12541f8b
--- /dev/null
+++ b/src/sql/tqsqlrecord.cpp
@@ -0,0 +1,774 @@
+/****************************************************************************
+**
+** Implementation of TQSqlRecord class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt 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 TQt 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 sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** 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 "tqsqlrecord.h"
+
+#ifndef TQT_NO_SQL
+
+#include "ntqregexp.h"
+#include "ntqvaluevector.h"
+#include "ntqshared.h"
+#include "ntqnamespace.h"
+
+class TQSqlRecordPrivate
+{
+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();
+ }
+ TQ_DUMMY_COMPARISON_OPERATOR(info)
+ TQSqlField field;
+ bool nogen;
+ };
+
+ TQSqlRecordPrivate(): cnt(0)
+ {
+ }
+ TQSqlRecordPrivate( const TQSqlRecordPrivate& other )
+ {
+ *this = other;
+ }
+ ~TQSqlRecordPrivate() {};
+ TQSqlRecordPrivate& operator=( const TQSqlRecordPrivate& other )
+ {
+ fi = other.fi;
+ cnt = other.cnt;
+ return *this;
+ }
+ void append( const TQSqlField& field )
+ {
+ info i;
+ i.field = field;
+ fi.append( i );
+ cnt++;
+ }
+ void insert( int pos, const TQSqlField& 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:
+ TQValueVector< info > fi;
+ uint cnt;
+};
+
+TQSqlRecordShared::~TQSqlRecordShared()
+{
+ if ( d )
+ delete d;
+}
+
+/*!
+ \class TQSqlRecord tqsqlfield.h
+ \brief The TQSqlRecord class encapsulates a database record, i.e. a
+ set of database fields.
+
+ \ingroup database
+ \module sql
+
+ The TQSqlRecord class encapsulates the functionality and
+ characteristics of a database record (usually a table or view within
+ the database). TQSqlRecords support adding and removing fields as
+ well as setting and retrieving field values.
+
+ TQSqlRecord is implicitly shared. This means you can make copies of
+ the record in time O(1). If multiple TQSqlRecord 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 TQSqlRecordInfo
+*/
+
+
+/*!
+ Constructs an empty record.
+*/
+
+TQSqlRecord::TQSqlRecord()
+{
+ sh = new TQSqlRecordShared( new TQSqlRecordPrivate() );
+}
+
+/*!
+ Constructs a copy of \a other.
+*/
+
+TQSqlRecord::TQSqlRecord( const TQSqlRecord& other )
+ : sh( other.sh )
+{
+ sh->ref();
+}
+
+/*!
+ Sets the record equal to \a other.
+*/
+
+TQSqlRecord& TQSqlRecord::operator=( const TQSqlRecord& other )
+{
+ other.sh->ref();
+ deref();
+ sh = other.sh;
+ return *this;
+}
+
+/*! \internal
+*/
+
+void TQSqlRecord::deref()
+{
+ if ( sh->deref() ) {
+ delete sh;
+ sh = 0;
+ }
+}
+
+/*! \internal
+*/
+
+bool TQSqlRecord::checkDetach()
+{
+ if ( sh->count > 1 ) {
+ sh->deref();
+ sh = new TQSqlRecordShared( new TQSqlRecordPrivate( *sh->d ) );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQSqlRecord::~TQSqlRecord()
+{
+ 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{TQSqlQuery}s. When working
+ with a TQSqlCursor the \link TQSqlCursor::value() value(const
+ TQString&)\endlink overload which uses field names is more
+ appropriate.
+*/
+
+TQVariant TQSqlRecord::value( int i ) const
+{
+ const TQSqlField * f = field(i);
+
+ if( f )
+ return f->value();
+ return TQVariant();
+}
+
+/*!
+ \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.
+*/
+
+TQVariant TQSqlRecord::value( const TQString& name ) const
+{
+ const TQSqlField * f = field( name );
+
+ if( f )
+ return f->value();
+ return TQVariant();
+}
+
+/*!
+ Returns the name of the field at position \a i. If the field does
+ not exist, TQString::null is returned.
+*/
+
+TQString TQSqlRecord::fieldName( int i ) const
+{
+ const TQSqlField* f = field( i );
+ if ( f )
+ return f->name();
+ return TQString::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 TQSqlRecord::position( const TQString& name ) const
+{
+ for ( uint i = 0; i < count(); ++i ) {
+ if ( fieldName(i).upper() == name.upper() )
+ return i;
+ }
+#ifdef QT_CHECK_RANGE
+ tqWarning( "TQSqlRecord::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.
+*/
+
+TQSqlField* TQSqlRecord::field( int i )
+{
+ checkDetach();
+ if ( !sh->d->contains( i ) ) {
+#ifdef QT_CHECK_RANGE
+ tqWarning( "TQSqlRecord::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.
+*/
+
+TQSqlField* TQSqlRecord::field( const TQString& name )
+{
+ checkDetach();
+ if ( !sh->d->contains( position( name ) ) )
+ return 0;
+ return &sh->d->fieldInfo( position( name ) )->field;
+}
+
+
+/*!
+ \overload
+*/
+
+const TQSqlField* TQSqlRecord::field( int i ) const
+{
+ if ( !sh->d->contains( i ) ) {
+#ifdef QT_CHECK_RANGE
+ tqWarning( "TQSqlRecord::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 TQSqlField* TQSqlRecord::field( const TQString& 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 TQSqlRecord::append( const TQSqlField& 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 TQSqlRecord::insert( int pos, const TQSqlField& 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 TQSqlRecord::remove( int pos )
+{
+ checkDetach();
+ sh->d->remove( pos );
+}
+
+/*!
+ Removes all the record's fields.
+
+ \sa clearValues()
+*/
+
+void TQSqlRecord::clear()
+{
+ checkDetach();
+ sh->d->clear();
+}
+
+/*!
+ Returns TRUE if there are no fields in the record; otherwise
+ returns FALSE.
+*/
+
+bool TQSqlRecord::isEmpty() const
+{
+ return sh->d->isEmpty();
+}
+
+
+/*!
+ Returns TRUE if there is a field in the record called \a name;
+ otherwise returns FALSE.
+*/
+
+bool TQSqlRecord::contains( const TQString& 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 TQSqlRecord::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 TQSqlCursor.
+
+ \sa isGenerated()
+*/
+
+void TQSqlRecord::setGenerated( const TQString& name, bool generated )
+{
+ setGenerated( position( name ), generated );
+}
+
+/*!
+ \overload
+
+ Sets the generated flag for the field \a i to \a generated.
+
+ \sa isGenerated()
+*/
+
+void TQSqlRecord::setGenerated( int i, bool generated )
+{
+ checkDetach();
+ if ( !field( i ) )
+ return;
+ sh->d->fieldInfo( i )->nogen = !generated;
+}
+
+/*!
+ \internal
+ ### Remove in 4.0
+*/
+bool TQSqlRecord::isNull( int i )
+{
+ checkDetach();
+ TQSqlField* f = field( i );
+ if ( f ) {
+ return f->isNull();
+ }
+ return TRUE;
+}
+
+/*!
+ \internal
+ ### Remove in 4.0
+*/
+bool TQSqlRecord::isNull( const TQString& 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 TQSqlRecord::isNull( int i ) const
+{
+ const TQSqlField* 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 TQSqlRecord::isNull( const TQString& name ) const
+{
+ return isNull( position( name ) );
+}
+
+/*!
+ Sets the value of field \a i to NULL. If the field does not exist,
+ nothing happens.
+*/
+void TQSqlRecord::setNull( int i )
+{
+ checkDetach();
+ TQSqlField* 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 TQSqlRecord::setNull( const TQString& 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 TQSqlRecord::isGenerated( const TQString& 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 TQSqlRecord::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\>"
+*/
+
+TQString TQSqlRecord::toString( const TQString& prefix, const TQString& sep ) const
+{
+ TQString 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\>"
+*/
+
+TQStringList TQSqlRecord::toStringList( const TQString& prefix ) const
+{
+ TQStringList s;
+ for ( uint i = 0; i < count(); ++i ) {
+ if ( isGenerated( field(i)->name() ) )
+ s += createField( i, prefix );
+ }
+ return s;
+}
+
+/*! \internal
+*/
+
+TQString TQSqlRecord::createField( int i, const TQString& prefix ) const
+{
+ TQString f;
+ if ( !prefix.isEmpty() )
+ f = prefix + ".";
+ f += field( i )->name();
+ return f;
+}
+
+/*!
+ Returns the number of fields in the record.
+*/
+
+uint TQSqlRecord::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 TQSqlRecord::setValue( int i, const TQVariant& val )
+{
+ checkDetach();
+ TQSqlField* 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 TQSqlRecord::setValue( const TQString& name, const TQVariant& val )
+{
+ setValue( position( name ), val );
+}
+
+
+/******************************************/
+/******* TQSqlRecordInfo Impl ******/
+/******************************************/
+
+/*!
+ \class TQSqlRecordInfo tqsqlrecord.h
+ \brief The TQSqlRecordInfo class encapsulates a set of database field meta data.
+
+ \ingroup database
+ \module sql
+
+ This class is a TQValueList 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 TQSqlFieldInfo record for a named
+ field.
+
+ \sa TQValueList, TQSqlFieldInfo
+*/
+
+
+/*!
+ Constructs a TQSqlRecordInfo object based on the fields in the
+ TQSqlRecord \a other.
+*/
+TQSqlRecordInfo::TQSqlRecordInfo( const TQSqlRecord& other )
+{
+ for ( uint i = 0; i < other.count(); ++i ) {
+ push_back( TQSqlFieldInfo( *(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.
+*/
+TQSqlRecordInfo::size_type TQSqlRecordInfo::contains( const TQString& fieldName ) const
+{
+ size_type i = 0;
+ TQString fName = fieldName.upper();
+ for( const_iterator it = begin(); it != end(); ++it ) {
+ if ( (*it).name().upper() == fName ) {
+ ++i;
+ }
+ }
+ return i;
+}
+
+/*!
+ Returns a TQSqlFieldInfo object for the first field in the record
+ which has the field name \a fieldName. If no matching field is
+ found then an empty TQSqlFieldInfo object is returned.
+*/
+TQSqlFieldInfo TQSqlRecordInfo::find( const TQString& fieldName ) const
+{
+ TQString fName = fieldName.upper();
+ for( const_iterator it = begin(); it != end(); ++it ) {
+ if ( (*it).name().upper() == fName ) {
+ return *it;
+ }
+ }
+ return TQSqlFieldInfo();
+}
+
+/*!
+ Returns an empty TQSqlRecord based on the field information
+ in this TQSqlRecordInfo.
+*/
+TQSqlRecord TQSqlRecordInfo::toRecord() const
+{
+ TQSqlRecord buf;
+ for( const_iterator it = begin(); it != end(); ++it ) {
+ buf.append( (*it).toField() );
+ }
+ return buf;
+}
+
+/*!
+ \fn TQSqlRecordInfo::TQSqlRecordInfo()
+
+ Constructs an empty record info object
+*/
+
+/*!
+ \fn TQSqlRecordInfo::TQSqlRecordInfo( const TQSqlFieldInfoList& other )
+
+ Constructs a copy of \a other.
+*/
+
+#endif