source: trunk/src/sql/qsqlrecord.cpp

Last change on this file was 196, checked in by rudi, 14 years ago

Add SQL module (currently it isn't build by default, however it's needed for QtDesigner)

File size: 16.8 KB
Line 
1/****************************************************************************
2**
3** Implementation of QSqlRecord class
4**
5** Created : 2000-11-03
6**
7** Copyright (C) 2005-2007 Trolltech ASA. All rights reserved.
8**
9** This file is part of the sql module of the Qt GUI Toolkit.
10**
11** This file may be distributed under the terms of the Q Public License
12** as defined by Trolltech ASA of Norway and appearing in the file
13** LICENSE.QPL included in the packaging of this file.
14**
15** This file may be distributed and/or modified under the terms of the
16** GNU General Public License version 2 as published by the Free Software
17** Foundation and appearing in the file LICENSE.GPL included in the
18** packaging of this file.
19**
20** Licensees holding valid Qt Enterprise Edition licenses may use this
21** file in accordance with the Qt Commercial License Agreement provided
22** with the Software.
23**
24** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26**
27** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
28** information about Qt Commercial License Agreements.
29** See http://www.trolltech.com/qpl/ for QPL licensing information.
30** See http://www.trolltech.com/gpl/ for GPL licensing information.
31**
32** Contact info@trolltech.com if any conditions of this licensing are
33** not clear to you.
34**
35**********************************************************************/
36
37#include "qsqlrecord.h"
38
39#ifndef QT_NO_SQL
40
41#include "qregexp.h"
42#include "qvaluevector.h"
43#include "qshared.h"
44#include "qnamespace.h"
45
46class QSqlRecordPrivate
47{
48public:
49 class info {
50 public:
51 info() : nogen(FALSE){}
52 ~info() {}
53 info( const info& other )
54 : field( other.field ), nogen( other.nogen )
55 {
56 }
57 info& operator=(const info& other)
58 {
59 field = other.field;
60 nogen = other.nogen;
61 return *this;
62 }
63 bool isValid() const
64 {
65 return !field.name().isNull();
66 }
67 Q_DUMMY_COMPARISON_OPERATOR(info)
68 QSqlField field;
69 bool nogen;
70 };
71
72 QSqlRecordPrivate(): cnt(0)
73 {
74 }
75 QSqlRecordPrivate( const QSqlRecordPrivate& other )
76 {
77 *this = other;
78 }
79 ~QSqlRecordPrivate() {};
80 QSqlRecordPrivate& operator=( const QSqlRecordPrivate& other )
81 {
82 fi = other.fi;
83 cnt = other.cnt;
84 return *this;
85 }
86 void append( const QSqlField& field )
87 {
88 info i;
89 i.field = field;
90 fi.append( i );
91 cnt++;
92 }
93 void insert( int pos, const QSqlField& field )
94 {
95 info i;
96 i.field = field;
97 if ( pos == (int)fi.size() )
98 append( field );
99 if ( pos > (int)fi.size() ) {
100 fi.resize( pos + 1 );
101 cnt++;
102 }
103 fi[ pos ] = i;
104 }
105 void remove( int i )
106 {
107 info inf;
108 if ( i >= (int)fi.count() )
109 return;
110 if ( fi[ i ].isValid() )
111 cnt--;
112 fi[ i ] = inf;
113 // clean up some memory
114 while ( fi.count() && !fi.back().isValid() )
115 fi.pop_back();
116 }
117 void clear()
118 {
119 fi.clear();
120 cnt = 0;
121 }
122 bool isEmpty()
123 {
124 return cnt == 0;
125 }
126 info* fieldInfo( int i )
127 {
128 if ( i < (int)fi.count() )
129 return &fi[i];
130 return 0;
131 }
132 uint count() const
133 {
134 return cnt;
135 }
136 bool contains( int i ) const
137 {
138 return i >= 0 && i < (int)fi.count() && fi[ i ].isValid();
139 }
140private:
141 QValueVector< info > fi;
142 uint cnt;
143};
144
145QSqlRecordShared::~QSqlRecordShared()
146{
147 if ( d )
148 delete d;
149}
150
151/*!
152 \class QSqlRecord qsqlfield.h
153 \brief The QSqlRecord class encapsulates a database record, i.e. a
154 set of database fields.
155
156 \ingroup database
157 \module sql
158
159 The QSqlRecord class encapsulates the functionality and
160 characteristics of a database record (usually a table or view within
161 the database). QSqlRecords support adding and removing fields as
162 well as setting and retrieving field values.
163
164 QSqlRecord is implicitly shared. This means you can make copies of
165 the record in time O(1). If multiple QSqlRecord instances share
166 the same data and one is modifying the record's data then this
167 modifying instance makes a copy and modifies its private copy -
168 thus it does not affect other instances.
169
170 \sa QSqlRecordInfo
171*/
172
173
174/*!
175 Constructs an empty record.
176*/
177
178QSqlRecord::QSqlRecord()
179{
180 sh = new QSqlRecordShared( new QSqlRecordPrivate() );
181}
182
183/*!
184 Constructs a copy of \a other.
185*/
186
187QSqlRecord::QSqlRecord( const QSqlRecord& other )
188 : sh( other.sh )
189{
190 sh->ref();
191}
192
193/*!
194 Sets the record equal to \a other.
195*/
196
197QSqlRecord& QSqlRecord::operator=( const QSqlRecord& other )
198{
199 other.sh->ref();
200 deref();
201 sh = other.sh;
202 return *this;
203}
204
205/*! \internal
206*/
207
208void QSqlRecord::deref()
209{
210 if ( sh->deref() ) {
211 delete sh;
212 sh = 0;
213 }
214}
215
216/*! \internal
217*/
218
219bool QSqlRecord::checkDetach()
220{
221 if ( sh->count > 1 ) {
222 sh->deref();
223 sh = new QSqlRecordShared( new QSqlRecordPrivate( *sh->d ) );
224 return TRUE;
225 }
226 return FALSE;
227}
228
229/*!
230 Destroys the object and frees any allocated resources.
231*/
232
233QSqlRecord::~QSqlRecord()
234{
235 deref();
236}
237
238/*!
239 Returns the value of the field located at position \a i in the
240 record. If field \a i does not exist the resultant behaviour is
241 undefined.
242
243 This function should be used with \l{QSqlQuery}s. When working
244 with a QSqlCursor the \link QSqlCursor::value() value(const
245 QString&)\endlink overload which uses field names is more
246 appropriate.
247*/
248
249QVariant QSqlRecord::value( int i ) const
250{
251 const QSqlField * f = field(i);
252
253 if( f )
254 return f->value();
255 return QVariant();
256}
257
258/*!
259 \overload
260
261 Returns the value of the field called \a name in the record. If
262 field \a name does not exist the resultant behaviour is undefined.
263*/
264
265QVariant QSqlRecord::value( const QString& name ) const
266{
267 const QSqlField * f = field( name );
268
269 if( f )
270 return f->value();
271 return QVariant();
272}
273
274/*!
275 Returns the name of the field at position \a i. If the field does
276 not exist, QString::null is returned.
277*/
278
279QString QSqlRecord::fieldName( int i ) const
280{
281 const QSqlField* f = field( i );
282 if ( f )
283 return f->name();
284 return QString::null;
285}
286
287/*!
288 Returns the position of the field called \a name within the
289 record, or -1 if it cannot be found. Field names are not
290 case-sensitive. If more than one field matches, the first one is
291 returned.
292*/
293
294int QSqlRecord::position( const QString& name ) const
295{
296 for ( uint i = 0; i < count(); ++i ) {
297 if ( fieldName(i).upper() == name.upper() )
298 return i;
299 }
300#ifdef QT_CHECK_RANGE
301 qWarning( "QSqlRecord::position: unable to find field " + name );
302#endif
303 return -1;
304}
305
306/*!
307 Returns the field at position \a i within the record, or 0 if it
308 cannot be found.
309*/
310
311QSqlField* QSqlRecord::field( int i )
312{
313 checkDetach();
314 if ( !sh->d->contains( i ) ) {
315#ifdef QT_CHECK_RANGE
316 qWarning( "QSqlRecord::field: index out of range: " + QString::number( i ) );
317#endif
318 return 0;
319 }
320 return &sh->d->fieldInfo( i )->field;
321}
322
323/*!
324 \overload
325
326 Returns the field called \a name within the record, or 0 if it
327 cannot be found. Field names are not case-sensitive.
328*/
329
330QSqlField* QSqlRecord::field( const QString& name )
331{
332 checkDetach();
333 if ( !sh->d->contains( position( name ) ) )
334 return 0;
335 return &sh->d->fieldInfo( position( name ) )->field;
336}
337
338
339/*!
340 \overload
341*/
342
343const QSqlField* QSqlRecord::field( int i ) const
344{
345 if ( !sh->d->contains( i ) ) {
346#ifdef QT_CHECK_RANGE
347 qWarning( "QSqlRecord::field: index out of range: " + QString::number( i ) );
348#endif // QT_CHECK_RANGE
349 return 0;
350 }
351 return &sh->d->fieldInfo( i )->field;
352}
353
354/*!
355 \overload
356
357 Returns the field called \a name within the record, or 0 if it
358 cannot be found. Field names are not case-sensitive.
359*/
360
361const QSqlField* QSqlRecord::field( const QString& name ) const
362{
363 if( !sh->d->contains( position( name ) ) )
364 return 0;
365 return &sh->d->fieldInfo( position( name ) )->field;
366}
367
368/*!
369 Append a copy of field \a field to the end of the record.
370*/
371
372void QSqlRecord::append( const QSqlField& field )
373{
374 checkDetach();
375 sh->d->append( field );
376}
377
378/*!
379 Insert a copy of \a field at position \a pos. If a field already
380 exists at \a pos, it is removed.
381*/
382
383void QSqlRecord::insert( int pos, const QSqlField& field ) // ### 4.0: rename to ::replace
384{
385 checkDetach();
386 sh->d->insert( pos, field );
387}
388
389/*!
390 Removes the field at \a pos. If \a pos does not exist, nothing
391 happens.
392*/
393
394void QSqlRecord::remove( int pos )
395{
396 checkDetach();
397 sh->d->remove( pos );
398}
399
400/*!
401 Removes all the record's fields.
402
403 \sa clearValues()
404*/
405
406void QSqlRecord::clear()
407{
408 checkDetach();
409 sh->d->clear();
410}
411
412/*!
413 Returns TRUE if there are no fields in the record; otherwise
414 returns FALSE.
415*/
416
417bool QSqlRecord::isEmpty() const
418{
419 return sh->d->isEmpty();
420}
421
422
423/*!
424 Returns TRUE if there is a field in the record called \a name;
425 otherwise returns FALSE.
426*/
427
428bool QSqlRecord::contains( const QString& name ) const
429{
430 for ( uint i = 0; i < count(); ++i ) {
431 if ( fieldName(i).upper() == name.upper() )
432 return TRUE;
433 }
434 return FALSE;
435}
436
437/*!
438 Clears the value of all fields in the record. If \a nullify is
439 TRUE, (the default is FALSE), each field is set to NULL.
440*/
441
442void QSqlRecord::clearValues( bool nullify )
443{
444 checkDetach();
445 int cnt = (int)count();
446 int i;
447 for ( i = 0; i < cnt; ++i ) {
448 field( i )->clear( nullify );
449 }
450}
451
452/*!
453 Sets the generated flag for the field called \a name to \a
454 generated. If the field does not exist, nothing happens. Only
455 fields that have \a generated set to TRUE are included in the SQL
456 that is generated, e.g. by QSqlCursor.
457
458 \sa isGenerated()
459*/
460
461void QSqlRecord::setGenerated( const QString& name, bool generated )
462{
463 setGenerated( position( name ), generated );
464}
465
466/*!
467 \overload
468
469 Sets the generated flag for the field \a i to \a generated.
470
471 \sa isGenerated()
472*/
473
474void QSqlRecord::setGenerated( int i, bool generated )
475{
476 checkDetach();
477 if ( !field( i ) )
478 return;
479 sh->d->fieldInfo( i )->nogen = !generated;
480}
481
482/*!
483 \internal
484 ### Remove in 4.0
485*/
486bool QSqlRecord::isNull( int i )
487{
488 checkDetach();
489 QSqlField* f = field( i );
490 if ( f ) {
491 return f->isNull();
492 }
493 return TRUE;
494}
495
496/*!
497 \internal
498 ### Remove in 4.0
499*/
500bool QSqlRecord::isNull( const QString& name )
501{
502 return isNull( position( name ) );
503}
504
505/*!
506 \overload
507
508 Returns TRUE if the field \a i is NULL or if there is no field at
509 position \a i; otherwise returns FALSE.
510
511 \sa fieldName()
512*/
513bool QSqlRecord::isNull( int i ) const
514{
515 const QSqlField* f = field( i );
516 if ( f ) {
517 return f->isNull();
518 }
519 return TRUE;
520}
521
522/*!
523 Returns TRUE if the field called \a name is NULL or if there is no
524 field called \a name; otherwise returns FALSE.
525
526 \sa position()
527*/
528bool QSqlRecord::isNull( const QString& name ) const
529{
530 return isNull( position( name ) );
531}
532
533/*!
534 Sets the value of field \a i to NULL. If the field does not exist,
535 nothing happens.
536*/
537void QSqlRecord::setNull( int i )
538{
539 checkDetach();
540 QSqlField* f = field( i );
541 if ( f ) {
542 f->setNull();
543 }
544}
545
546/*!
547 \overload
548
549 Sets the value of the field called \a name to NULL. If the field
550 does not exist, nothing happens.
551*/
552void QSqlRecord::setNull( const QString& name )
553{
554 setNull( position( name ) );
555}
556
557
558/*!
559 Returns TRUE if the record has a field called \a name and this
560 field is to be generated (the default); otherwise returns FALSE.
561
562 \sa setGenerated()
563*/
564bool QSqlRecord::isGenerated( const QString& name ) const
565{
566 return isGenerated( position( name ) );
567}
568
569/*!
570 \overload
571
572 Returns TRUE if the record has a field at position \a i and this
573 field is to be generated (the default); otherwise returns FALSE.
574
575 \sa setGenerated()
576*/
577bool QSqlRecord::isGenerated( int i ) const
578{
579 if ( !field( i ) )
580 return FALSE;
581 return !sh->d->fieldInfo( i )->nogen;
582}
583
584
585/*!
586 Returns a list of all the record's field names as a string
587 separated by \a sep.
588
589 Note that fields which are not generated are \e not included (see
590 \l{isGenerated()}). The returned string is suitable, for example, for
591 generating SQL SELECT statements. If a \a prefix is specified,
592 e.g. a table name, all fields are prefixed in the form:
593
594 "\a{prefix}.\<fieldname\>"
595*/
596
597QString QSqlRecord::toString( const QString& prefix, const QString& sep ) const
598{
599 QString pflist;
600 bool comma = FALSE;
601 for ( uint i = 0; i < count(); ++i ){
602 if ( isGenerated( field(i)->name() ) ) {
603 if( comma )
604 pflist += sep + " ";
605 pflist += createField( i, prefix );
606 comma = TRUE;
607 }
608 }
609 return pflist;
610}
611
612/*!
613 Returns a list of all the record's field names, each having the
614 prefix \a prefix.
615
616 Note that fields which have generated set to FALSE are \e not
617 included. (See \l{isGenerated()}). If \a prefix is supplied, e.g.
618 a table name, all fields are prefixed in the form:
619
620 "\a{prefix}.\<fieldname\>"
621*/
622
623QStringList QSqlRecord::toStringList( const QString& prefix ) const
624{
625 QStringList s;
626 for ( uint i = 0; i < count(); ++i ) {
627 if ( isGenerated( field(i)->name() ) )
628 s += createField( i, prefix );
629 }
630 return s;
631}
632
633/*! \internal
634*/
635
636QString QSqlRecord::createField( int i, const QString& prefix ) const
637{
638 QString f;
639 if ( !prefix.isEmpty() )
640 f = prefix + ".";
641 f += field( i )->name();
642 return f;
643}
644
645/*!
646 Returns the number of fields in the record.
647*/
648
649uint QSqlRecord::count() const
650{
651 return sh->d->count();
652}
653
654/*!
655 Sets the value of the field at position \a i to \a val. If the
656 field does not exist, nothing happens.
657*/
658
659void QSqlRecord::setValue( int i, const QVariant& val )
660{
661 checkDetach();
662 QSqlField* f = field( i );
663 if ( f ) {
664 f->setValue( val );
665 }
666}
667
668
669/*!
670 \overload
671
672 Sets the value of the field called \a name to \a val. If the field
673 does not exist, nothing happens.
674*/
675
676void QSqlRecord::setValue( const QString& name, const QVariant& val )
677{
678 setValue( position( name ), val );
679}
680
681
682/******************************************/
683/******* QSqlRecordInfo Impl ******/
684/******************************************/
685
686/*!
687 \class QSqlRecordInfo qsqlrecord.h
688 \brief The QSqlRecordInfo class encapsulates a set of database field meta data.
689
690 \ingroup database
691 \module sql
692
693 This class is a QValueList that holds a set of database field meta
694 data. Use contains() to see if a given field name exists in the
695 record, and use find() to get a QSqlFieldInfo record for a named
696 field.
697
698 \sa QValueList, QSqlFieldInfo
699*/
700
701
702/*!
703 Constructs a QSqlRecordInfo object based on the fields in the
704 QSqlRecord \a other.
705*/
706QSqlRecordInfo::QSqlRecordInfo( const QSqlRecord& other )
707{
708 for ( uint i = 0; i < other.count(); ++i ) {
709 push_back( QSqlFieldInfo( *(other.field( i )), other.isGenerated( i ) ) );
710 }
711}
712
713/*!
714 Returns the number of times a field called \a fieldName occurs in
715 the record. Returns 0 if no field by that name could be found.
716*/
717QSqlRecordInfo::size_type QSqlRecordInfo::contains( const QString& fieldName ) const
718{
719 size_type i = 0;
720 QString fName = fieldName.upper();
721 for( const_iterator it = begin(); it != end(); ++it ) {
722 if ( (*it).name().upper() == fName ) {
723 ++i;
724 }
725 }
726 return i;
727}
728
729/*!
730 Returns a QSqlFieldInfo object for the first field in the record
731 which has the field name \a fieldName. If no matching field is
732 found then an empty QSqlFieldInfo object is returned.
733*/
734QSqlFieldInfo QSqlRecordInfo::find( const QString& fieldName ) const
735{
736 QString fName = fieldName.upper();
737 for( const_iterator it = begin(); it != end(); ++it ) {
738 if ( (*it).name().upper() == fName ) {
739 return *it;
740 }
741 }
742 return QSqlFieldInfo();
743}
744
745/*!
746 Returns an empty QSqlRecord based on the field information
747 in this QSqlRecordInfo.
748*/
749QSqlRecord QSqlRecordInfo::toRecord() const
750{
751 QSqlRecord buf;
752 for( const_iterator it = begin(); it != end(); ++it ) {
753 buf.append( (*it).toField() );
754 }
755 return buf;
756}
757
758/*!
759 \fn QSqlRecordInfo::QSqlRecordInfo()
760
761 Constructs an empty record info object
762*/
763
764/*!
765 \fn QSqlRecordInfo::QSqlRecordInfo( const QSqlFieldInfoList& other )
766
767 Constructs a copy of \a other.
768*/
769
770#endif
Note: See TracBrowser for help on using the repository browser.