KDb

KDbField.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2002 Lucijan Busch <lucijan@gmx.at>
3 Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
4 Copyright (C) 2003-2017 Jarosław Staniek <staniek@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22#include "KDbField.h"
23#include "KDbField_p.h"
24#include "KDbConnection.h"
25#include "KDbDriver.h"
26#include "KDbExpression.h"
27#include "KDbQuerySchema.h"
28#include "KDb.h"
29#include "kdb_debug.h"
30
31#include <QDateTime>
32
33//! @todo make this configurable
34static int g_defaultMaxLength = 0; // unlimited
35
36//-------------------------------------------------------
37//! @internal Used in s_typeNames member to handle translated type names
38class FieldTypeNames
39{
40public:
41 FieldTypeNames();
44 QStringList names;
45private:
46 Q_DISABLE_COPY(FieldTypeNames)
47};
48
49//! @internal Used in m_typeGroupNames member to handle translated type group names
50class FieldTypeGroupNames
51{
52public:
53 FieldTypeGroupNames();
56 QStringList names;
57private:
58 Q_DISABLE_COPY(FieldTypeGroupNames)
59};
60
61//! real translated type names (and nontranslated type name strings)
62Q_GLOBAL_STATIC(FieldTypeNames, s_typeNames)
63
64//! real translated type group names (and nontranslated group name strings)
65Q_GLOBAL_STATIC(FieldTypeGroupNames, s_typeGroupNames)
66
67#define ADDTYPE(type, i18, str) \
68 data[KDbField::type] = i18; \
69 data[KDbField::type+KDbField::Null+1] = QStringLiteral(str); \
70 str2num[ QString::fromLatin1(str).toLower() ] = KDbField::type; \
71 names.append(i18)
72#define ADDGROUP(type, i18, str) \
73 data[KDbField::type] = i18; \
74 data[KDbField::type+KDbField::LastTypeGroup+1] = QStringLiteral(str); \
75 str2num[ QString::fromLatin1(str).toLower() ] = KDbField::type; \
76 names.append(i18)
77
78FieldTypeNames::FieldTypeNames()
79 : data((KDbField::Null + 1)*2)
80{
81 ADDTYPE(InvalidType, KDbField::tr("Invalid Type"), "InvalidType");
82 ADDTYPE(Byte, KDbField::tr("Byte"), "Byte");
83 ADDTYPE(ShortInteger, KDbField::tr("Short Integer Number"), "ShortInteger");
84 ADDTYPE(Integer, KDbField::tr("Integer Number"), "Integer");
85 ADDTYPE(BigInteger, KDbField::tr("Big Integer Number"), "BigInteger");
86 ADDTYPE(Boolean, KDbField::tr("Yes/No Value"), "Boolean");
87 ADDTYPE(Date, KDbField::tr("Date"), "Date");
88 ADDTYPE(DateTime, KDbField::tr("Date and Time"), "DateTime");
89 ADDTYPE(Time, KDbField::tr("Time"), "Time");
90 ADDTYPE(Float, KDbField::tr("Single Precision Number"), "Float");
91 ADDTYPE(Double, KDbField::tr("Double Precision Number"), "Double");
92 ADDTYPE(Text, KDbField::tr("Text"), "Text");
93 ADDTYPE(LongText, KDbField::tr("Long Text"), "LongText");
94 ADDTYPE(BLOB, KDbField::tr("Object"), "BLOB");
95 ADDTYPE(Null, QLatin1String("NULL")/*don't translate*/, "NULL");
96}
97
98//-------------------------------------------------------
99
100FieldTypeGroupNames::FieldTypeGroupNames()
101 : data((KDbField::LastTypeGroup + 1)*2)
102{
103 ADDGROUP(InvalidGroup, KDbField::tr("Invalid Group"), "InvalidGroup");
104 ADDGROUP(TextGroup, KDbField::tr("Text"), "TextGroup");
105 ADDGROUP(IntegerGroup, KDbField::tr("Integer Number"), "IntegerGroup");
106 ADDGROUP(FloatGroup, KDbField::tr("Floating Point Number"), "FloatGroup");
107 ADDGROUP(BooleanGroup, KDbField::tr("Yes/No"), "BooleanGroup");
108 ADDGROUP(DateTimeGroup, KDbField::tr("Date/Time"), "DateTimeGroup");
109 ADDGROUP(BLOBGroup, KDbField::tr("Object"), "BLOBGroup");
110}
111
112//-------------------------------------------------------
113
114class KDbFieldPrivate
115{
116public:
117 static KDbConnection *connection(const KDbTableSchema &table)
118 {
119 return table.connection();
120 }
121};
122
123
124class Q_DECL_HIDDEN KDbField::Private
125{
126public:
127 Private(KDbFieldList *aParent = nullptr, int aOrder = -1)
128 : parent(aParent)
129 , type(KDbField::InvalidType)
130 , precision(0)
131 , options(KDbField::NoOptions)
132 , defaultValue(QString())
133 , order(aOrder)
134 {
135 }
136 Private(const QString &aName, KDbField::Type aType, KDbField::Options aOptions, int aPrecision,
137 const QVariant &aDefaultValue, const QString &aCaption, const QString &aDescription)
138 : parent(nullptr)
139 , type(aType)
140 , name(aName)
141 , caption(aCaption)
142 , description(aDescription)
143 , precision(aPrecision)
144 , options(aOptions)
145 , defaultValue(aDefaultValue)
146 , order(-1)
147 {
148 }
149 Private(const Private &o)
150 {
151 (*this) = o;
152 if (o.customProperties) {
153 customProperties = new CustomPropertiesMap(*o.customProperties);
154 }
155 if (!o.expr.isNull()) {//deep copy the expression
156 //! @todo expr = new KDbExpression(o.expr);
157 expr = KDbExpression(o.expr.clone());
158 } else {
159 expr = KDbExpression();
160 }
161 }
162
163 ~Private() {
164 delete customProperties;
165 }
166
167 //! In most cases this points to a KDbTableSchema object that field is assigned
168 KDbFieldList *parent;
171 QString caption;
172 QString description;
173 QString subType;
174 KDbField::Constraints constraints;
175 KDbField::MaxLengthStrategy maxLengthStrategy;
176 int maxLength; //!< also used for storing scale for floating point types
177 int precision;
178 int visibleDecimalPlaces = -1; //!< used in visibleDecimalPlaces()
179 KDbField::Options options;
180 QVariant defaultValue;
181 int order;
182 KDbExpression expr;
183 KDbField::CustomPropertiesMap* customProperties = nullptr;
184 QVector<QString> hints;
185};
186
187//-------------------------------------------------------
188
190 : d(new Private)
191{
192 setMaxLength(0); // do not move this line up!
193 setMaxLengthStrategy(DefinedMaxLength); // do not move this line up!
194 setConstraints(NoConstraints);
195}
196
197KDbField::KDbField(KDbFieldList *aParent, int aOrder)
198 : d(new Private(aParent, aOrder))
199{
200 setMaxLength(0); // do not move this line up!
201 setMaxLengthStrategy(DefinedMaxLength); // do not move this line up!
202 setConstraints(NoConstraints);
203}
204
206 : KDbField(tableSchema, tableSchema->fieldCount())
207{
208}
209
211 : KDbField(querySchema, querySchema->fieldCount())
212{
213 setExpression(expr);
214}
215
217 : KDbField(querySchema, querySchema->fieldCount())
218{
219}
220
221KDbField::KDbField(const QString &name, Type type, Constraints constr, Options options,
222 int maxLength, int precision, const QVariant &defaultValue,
223 const QString &caption, const QString &description)
224 : d(new Private(name, type, options, precision, defaultValue, caption, description))
225{
227 setConstraints(constr);
228}
229
230/*! Copy constructor. */
232 : d(new Private(*f.d))
233{
234}
235
236KDbField::~KDbField()
237{
238 delete d;
239}
240
242{
243 return d->parent;
244}
245
247{
248 return d->parent;
249}
250
252{
253 d->parent = parent;
254}
255
257{
258 return d->name;
259}
260
262{
263 return d->options;
264}
265
267{
268 d->options = options;
269}
270
272{
273 return d->subType;
274}
275
276void KDbField::setSubType(const QString& subType)
277{
278 d->subType = subType;
279}
280
282{
283 return d->defaultValue;
284}
285
287{
288 return d->precision;
289}
290
292{
293 return d->maxLength;
294}
295
297{
298 return d->visibleDecimalPlaces;
299}
300
302{
303 return d->constraints;
304}
305
307{
308 return d->order;
309}
310
311void KDbField::setOrder(int order)
312{
313 d->order = order;
314}
315
317{
318 return d->caption;
319}
320
321void KDbField::setCaption(const QString& caption)
322{
323 d->caption = caption;
324}
325
327{
328 return d->caption.isEmpty() ? d->name : d->caption;
329}
330
332{
333 return d->description;
334}
335
336void KDbField::setDescription(const QString& description)
337{
338 d->description = description;
339}
340
342{
343 return d->hints;
344}
345
347{
348 return (num < d->hints.size()) ? d->hints.at(num) : QString();
349}
350
352{
353 d->hints = hints;
354}
355
356// static
358{
359 return LastType - InvalidType + 1;
360}
361
362// static
364{
365 return LastSpecialType - Null + 1;
366}
367
368// static
370{
371 return LastTypeGroup - InvalidGroup + 1;
372}
373
375{
376 return new KDbField(*this);
377}
378
380{
381 if (!d->expr.isNull()) {
382 return d->expr.type();
383 }
384 return d->type;
385}
386
388{
389 switch (type) {
390 case Byte:
391 case ShortInteger:
392 case Integer:
393 case BigInteger:
394 return QVariant::Int;
395 case Boolean:
396 return QVariant::Bool;
397 case Date:
398 return QVariant::Date;
399 case DateTime:
400 return QVariant::DateTime;
401 case Time:
402 return QVariant::Time;
403 case Float:
404 case Double:
405 return QVariant::Double;
406 case Text:
407 case LongText:
408 return QVariant::String;
409 case BLOB:
410 return QVariant::ByteArray;
411 default:
412 break;
413 }
414
415 return QVariant::Invalid;
416}
417
418template <typename T>
419static inline QVariant tryConvert(const QVariant &value)
420{
421 return value.canConvert<T>() ? value.value<T>() : value;
422}
423
424//static
425//! @todo use an array of functions?
427{
428 switch (type) {
429 case Byte:
430 case ShortInteger:
431 case Integer:
432 return tryConvert<int>(value);
433 case BigInteger:
434 return tryConvert<qlonglong>(value);
435 case Boolean:
436 return tryConvert<bool>(value);
437 case Date:
438 return tryConvert<QDate>(value);
439 case DateTime:
440 return tryConvert<QDateTime>(value);
441 case Time:
442 return tryConvert<QTime>(value);
443 case Float:
444 return tryConvert<float>(value);
445 case Double:
446 return tryConvert<double>(value);
447 case Text:
448 case LongText:
449 return tryConvert<QString>(value);
450 case BLOB:
451 return tryConvert<QByteArray>(value);
452 default:
453 break;
454 }
455 return QVariant();
456}
457
459{
460 return s_typeNames->data.value(type, QString::number(type));
461}
462
464{
465 return s_typeNames->names;
466}
467
469{
470 return (type <= Null) ? s_typeNames->data.at(int(Null) + 1 + type)
471 : (QLatin1String("Type") + QString::number(type));
472}
473
475{
476 return (typeGroup <= LastTypeGroup) ? s_typeGroupNames->data.at(typeGroup)
478}
479
481{
482 return s_typeGroupNames->names;
483}
484
486{
487 return s_typeGroupNames->data.value(int(LastTypeGroup) + 1 + typeGroup,
488 QLatin1String("TypeGroup") + QString::number(typeGroup));
489}
490
492{
493 return s_typeNames->str2num.value(typeString.toLower(), InvalidType);
494}
495
497{
498 return s_typeGroupNames->str2num.value(typeGroupString.toLower(), InvalidGroup);
499}
500
502{
503 switch (type) {
504 case KDbField::Byte:
508 return true;
509 default:;
510 }
511 return false;
512}
513
515{
516 switch (type) {
517 case KDbField::Byte:
521 case KDbField::Float:
522 case KDbField::Double:
523 return true;
524 default:;
525 }
526 return false;
527}
528
530{
532}
533
535{
536 switch (type) {
537 case KDbField::Date:
538 case KDbField::DateTime:
539 case KDbField::Time:
540 return true;
541 default:;
542 }
543 return false;
544}
545
547{
548 switch (type) {
549 case KDbField::Text:
551 return true;
552 default:;
553 }
554 return false;
555}
556
558{
559 return KDbField::isTextType(type) || type == BLOB;
560}
561
566
568{
570 return TextGroup;
572 return IntegerGroup;
574 return FloatGroup;
575 else if (type == Boolean)
576 return BooleanGroup;
578 return DateTimeGroup;
579 else if (type == BLOB)
580 return BLOBGroup;
581
582 return InvalidGroup; //unknown
583}
584
586{
587 return dynamic_cast<KDbTableSchema*>(d->parent);
588}
589
590const KDbTableSchema* KDbField::table() const
591{
592 return dynamic_cast<const KDbTableSchema*>(d->parent);
593}
594
596{
597 d->parent = tableSchema;
598}
599
601{
602 return dynamic_cast<KDbQuerySchema*>(d->parent);
603}
604
605const KDbQuerySchema* KDbField::query() const
606{
607 return dynamic_cast<const KDbQuerySchema*>(d->parent);
608}
609
611{
612 d->parent = querySchema;
613}
614
615void KDbField::setName(const QString& name)
616{
617 d->name = name.toLower();
618}
619
621{
622 if (!d->expr.isNull()) {
623 kdbWarning() << "Could not set type" << KDbField::typeName(t)
624 << "because the field has expression assigned!";
625 return;
626 }
627 d->type = t;
628}
629
631{
632 d->constraints = c;
633 //pkey must be unique notnull
634 if (isPrimaryKey()) {
635 setPrimaryKey(true);
636 }
637 if (isIndexed()) {
638 setIndexed(true);
639 }
641 setAutoIncrement(false);
642 }
643}
644
646{
647 return g_defaultMaxLength;
648}
649
651{
652 g_defaultMaxLength = maxLength;
653}
654
656{
657 return d->maxLengthStrategy;
658}
659
661{
662 d->maxLengthStrategy = strategy;
663}
664
666{
667 return d->maxLength;
668}
669
670void KDbField::setMaxLength(int maxLength)
671{
672 d->maxLength = maxLength;
673 d->maxLengthStrategy = DefinedMaxLength;
674}
675
677{
678 if (!isFPNumericType()) {
679 return;
680 }
681 d->precision = p;
682}
683
685{
686 if (!isFPNumericType()) {
687 return;
688 }
689 d->maxLength = s;
690}
691
693{
695 return;
696 }
697 d->visibleDecimalPlaces = p < 0 ? -1 : p;
698}
699
701{
702 if (!isIntegerType()) {
703 return;
704 }
705 d->options |= Unsigned;
706 if (!u) {
707 d->options ^= Unsigned;
708 }
709}
710
712{
713 d->defaultValue = def;
714}
715
717{
718 if (def.isNull()) {
719 d->defaultValue = QVariant();
720 return true;
721 }
722
723 bool ok;
724 switch (type()) {
725 case Byte: {
726 unsigned int v = def.toUInt(&ok);
727 if (!ok || v > 255) {
728 d->defaultValue = QVariant();
729 } else {
730 d->defaultValue = QVariant(v);
731 }
732 break;
733 }
734 case ShortInteger: {
735 int v = def.toInt(&ok);
736 if (!ok || (!(d->options & Unsigned) && (v < -32768 || v > 32767))
737 || ((d->options & Unsigned) && (v < 0 || v > 65535)))
738 {
739 d->defaultValue = QVariant();
740 } else {
741 d->defaultValue = QVariant(v);
742 }
743 break;
744 }
745 case Integer: {//4 bytes
746 long v = def.toLong(&ok);
747 //! @todo if (!ok || (!(d->options & Unsigned) && (-v > 0x080000000 || v >
748 //! (0x080000000-1))) || ((d->options & Unsigned) && (v < 0 || v > 0x100000000)))
749 if (!ok || (!(d->options & Unsigned)
750 && (-v > (int)0x07FFFFFFF || v > (int)(0x080000000 - 1))))
751 {
752 d->defaultValue = QVariant();
753 } else {
754 d->defaultValue = QVariant((qint64)v);
755 }
756 break;
757 }
758 case BigInteger: {//8 bytes
759//! @todo BigInteger support
760 /*
761 qint64 long v = def.toLongLong(&ok);
762 //! @todo 2-part decoding
763 if (!ok || (!(d->options & Unsigned) && (-v > 0x080000000 || v > (0x080000000-1))))
764 d->defaultValue = QVariant();
765 else
766 if (d->options & Unsigned)
767 d->defaultValue=QVariant((quint64) v);
768 else
769 d->defaultValue = QVariant((qint64)v);*/
770 break;
771 }
772 case Boolean: {
773 unsigned short v = def.toUShort(&ok);
774 if (!ok || v > 1) {
775 d->defaultValue = QVariant();
776 } else {
777 d->defaultValue = QVariant((bool)v);
778 }
779 break;
780 }
781 case Date: {//YYYY-MM-DD
783 if (!date.isValid()) {
784 d->defaultValue = QVariant();
785 } else {
786 d->defaultValue = QVariant(date);
787 }
788 break;
789 }
790 case DateTime: {//YYYY-MM-DDTHH:MM:SS.ms
791 const QDateTime dt = KDbUtils::dateTimeFromISODateStringWithMs(QString::fromLatin1(def));
792 if (!dt.isValid()) {
793 d->defaultValue = QVariant();
794 } else {
795 d->defaultValue = QVariant(dt);
796 }
797 break;
798 }
799 case Time: {//HH:MM:SS.ms
800 const QTime time = KDbUtils::timeFromISODateStringWithMs(QString::fromLatin1(def));
801 if (!time.isValid()) {
802 d->defaultValue = QVariant();
803 } else {
804 d->defaultValue = QVariant(time);
805 }
806 break;
807 }
808 case Float: {
809 float v = def.toFloat(&ok);
810 if (!ok || ((d->options & Unsigned) && (v < 0.0))) {
811 d->defaultValue = QVariant();
812 } else {
813 d->defaultValue = QVariant(v);
814 }
815 break;
816 }
817 case Double: {
818 double v = def.toDouble(&ok);
819 if (!ok || ((d->options & Unsigned) && (v < 0.0))) {
820 d->defaultValue = QVariant();
821 } else {
822 d->defaultValue = QVariant(v);
823 }
824 break;
825 }
826 case Text: {
827 if (def.isNull() || def.length() > maxLength()) {
828 d->defaultValue = QVariant();
829 } else {
830 d->defaultValue = QVariant(QLatin1String(def));
831 }
832 break;
833 }
834 case LongText: {
835 if (def.isNull()) {
836 d->defaultValue = QVariant();
837 } else {
838 d->defaultValue = QVariant(QLatin1String(def));
839 }
840 break;
841 }
842 case BLOB: {
843//! @todo
844 if (def.isNull()) {
845 d->defaultValue = QVariant();
846 } else {
847 d->defaultValue = QVariant(def);
848 }
849 break;
850 }
851 default:
852 d->defaultValue = QVariant();
853 }
854 return d->defaultValue.isNull();
855}
856
858{
859 if (a && !isAutoIncrementAllowed()) {
860 return;
861 }
862 if (isAutoIncrement() != a) {
863 d->constraints ^= KDbField::AutoInc;
864 }
865}
866
868{
869 if (isPrimaryKey() != p) {
870 d->constraints ^= KDbField::PrimaryKey;
871 }
872 if (p) {//also set implied constraints
873 setUniqueKey(true);
874 setNotNull(true);
875 setNotEmpty(true);
876 setIndexed(true);
877 } else {
878//! @todo is this ok for all engines?
879 setAutoIncrement(false);
880 }
881}
882
884{
885 if (isUniqueKey() != u) {
886 d->constraints ^= KDbField::Unique;
887 if (u) { //also set implied constraints
888 setNotNull(true);
889 setIndexed(true);
890 }
891 }
892}
893
895{
896 if (isForeignKey() != f) {
897 d->constraints ^= KDbField::ForeignKey;
898 }
899}
900
902{
903 if (isNotNull() != n) {
904 d->constraints ^=KDbField::NotNull;
905 }
906}
907
909{
910 if (isNotEmpty() != n) {
911 d->constraints ^= KDbField::NotEmpty;
912 }
913}
914
916{
917 if (isIndexed() != s) {
918 d->constraints ^= KDbField::Indexed;
919 }
920 if (!s) {//also set implied constraints
921 setPrimaryKey(false);
922 setUniqueKey(false);
923 setNotNull(false);
924 setNotEmpty(false);
925 }
926}
927
928void debug(QDebug dbg, const KDbField& field, KDbFieldDebugOptions options)
929{
930 const KDbConnection *conn = field.table() ? KDbFieldPrivate::connection(*field.table()) : nullptr;
931 if (options & KDbFieldDebugAddName) {
932 if (field.name().isEmpty()) {
933 dbg.nospace() << "<NONAME> ";
934 } else {
935 dbg.nospace() << field.name() << ' ';
936 }
937 }
938 if (field.options() & KDbField::Unsigned)
939 dbg.nospace() << " UNSIGNED";
940 dbg.nospace() << ' ' << qPrintable((conn && conn->driver())
941 ? conn->driver()->sqlTypeName(field.type(), field) : KDbDriver::defaultSqlTypeName(field.type()));
942 if (field.isFPNumericType() && field.precision() > 0) {
943 if (field.scale() > 0)
944 dbg.nospace() << qPrintable(QString::fromLatin1("(%1,%2)").arg(field.precision()).arg(field.scale()));
945 else
946 dbg.nospace() << qPrintable(QString::fromLatin1("(%1)").arg(field.precision()));
947 }
948 else if (field.type() == KDbField::Text && field.maxLength() > 0)
949 dbg.space() << qPrintable(QString::fromLatin1("(%1)").arg(field.maxLength()));
950
951 if (field.constraints() & KDbField::AutoInc)
952 dbg.nospace() << " AUTOINC";
953 if (field.constraints() & KDbField::Unique)
954 dbg.nospace() << " UNIQUE";
955 if (field.constraints() & KDbField::PrimaryKey)
956 dbg.nospace() << " PKEY";
957 if (field.constraints() & KDbField::ForeignKey)
958 dbg.nospace() << " FKEY";
959 if (field.constraints() & KDbField::NotNull)
960 dbg.nospace() << " NOTNULL";
961 if (field.constraints() & KDbField::NotEmpty)
962 dbg.nospace() << " NOTEMPTY";
963 if (!field.defaultValue().isNull()) {
964 dbg.nospace() << qPrintable(QString::fromLatin1(" DEFAULT=[%1]")
965 .arg(QLatin1String(field.defaultValue().typeName())));
966 dbg.nospace() << qPrintable(KDb::variantToString(field.defaultValue()));
967 }
968 if (field.isExpression()) {
969 dbg.nospace() << " EXPRESSION=";
970 dbg.nospace() << field.expression();
971 }
972 const KDbField::CustomPropertiesMap customProperties(field.customProperties());
973 if (!customProperties.isEmpty()) {
974 dbg.space() << qPrintable(QString::fromLatin1("CUSTOM PROPERTIES (%1): ").arg(customProperties.count()));
975 bool first = true;
976 for (KDbField::CustomPropertiesMap::ConstIterator it(customProperties.constBegin());
977 it != customProperties.constEnd(); ++it)
978 {
979 if (first)
980 first = false;
981 else
982 dbg.nospace() << ',';
983 dbg.space() << qPrintable(QString::fromLatin1("%1 = %2 (%3)")
984 .arg(QLatin1String(it.key()), it.value().toString(),
985 QLatin1String(it.value().typeName())));
986 }
987 }
988}
989
990KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbField& field)
991{
992 debug(dbg, field, KDbFieldDebugAddName);
993 return dbg.space();
994}
995
996KDB_EXPORT QDebug operator<<(QDebug dbg, KDbField::Type type)
997{
998 return dbg.space() << qPrintable(KDbField::typeString(type));
999}
1000
1001KDB_EXPORT QDebug operator<<(QDebug dbg, KDbField::TypeGroup typeGroup)
1002{
1003 return dbg.space() << qPrintable(KDbField::typeGroupString(typeGroup));
1004}
1005
1007{
1008 return !d->expr.isNull();
1009}
1010
1012{
1013 return d->expr;
1014}
1015
1017{
1018 return d->expr;
1019}
1020
1022{
1023 if (d->parent && !dynamic_cast<KDbQuerySchema*>(d->parent)) {
1024 kdbWarning() << "Cannot set expression if parent is set and it is not a query";
1025 return;
1026 }
1027 if (d->expr == expr) {
1028 return;
1029 }
1030 d->expr = expr;
1031}
1032
1034 const QVariant& defaultValue) const
1035{
1036 if (!d->customProperties) {
1037 return defaultValue;
1038 }
1039 return d->customProperties->value(propertyName, defaultValue);
1040}
1041
1042void KDbField::setCustomProperty(const QByteArray& propertyName, const QVariant& value)
1043{
1044 if (propertyName.isEmpty()) {
1045 return;
1046 }
1047 if (!d->customProperties) {
1048 d->customProperties = new CustomPropertiesMap();
1049 }
1050 d->customProperties->insert(propertyName, value);
1051}
1052
1054{
1055 return d->customProperties ? *d->customProperties : CustomPropertiesMap();
1056}
Provides database connection, allowing queries and data modification.
KDbDriver * driver() const
Database driver's abstraction.
Definition KDbDriver.h:50
virtual QString sqlTypeName(KDbField::Type type, const KDbField &field) const
The KDbExpression class represents a base class for all expressions.
bool isNull() const
KDbField::Type type() const
Meta-data for a field.
Definition KDbField.h:72
void setIndexed(bool s)
Definition KDbField.cpp:915
void setSubType(const QString &subType)
Definition KDbField.cpp:276
static int typeGroupsCount()
Definition KDbField.cpp:369
MaxLengthStrategy maxLengthStrategy() const
Definition KDbField.cpp:655
void setDescription(const QString &description)
Definition KDbField.cpp:336
int precision() const
Definition KDbField.cpp:286
bool isNumericType() const
Definition KDbField.h:317
KDbTableSchema * table()
Definition KDbField.cpp:585
static Type typeForString(const QString &typeString)
Definition KDbField.cpp:491
bool isAutoIncrementAllowed() const
Definition KDbField.h:531
bool isTextType() const
Definition KDbField.h:353
static int specialTypesCount()
Definition KDbField.cpp:363
void setEnumHints(const QVector< QString > &hints)
Definition KDbField.cpp:351
void setType(Type t)
Definition KDbField.cpp:620
void setOptions(Options options)
Definition KDbField.cpp:266
KDbFieldList * parent()
Definition KDbField.cpp:241
QString name() const
Definition KDbField.cpp:256
QVariant::Type variantType() const
Converts field's type to QVariant equivalent as accurate as possible.
Definition KDbField.h:368
bool isNotEmpty() const
Definition KDbField.h:307
CustomPropertiesMap customProperties() const
void setNotEmpty(bool n)
Definition KDbField.cpp:908
static QVariant convertToType(const QVariant &value, Type type)
Converts value value to variant corresponding to type type.
Definition KDbField.cpp:426
bool isAutoIncrement() const
Definition KDbField.h:282
void setCaption(const QString &caption)
Definition KDbField.cpp:321
static int typesCount()
Definition KDbField.cpp:357
bool isNotNull() const
Definition KDbField.h:302
static void setDefaultMaxLength(int maxLength)
Definition KDbField.cpp:650
bool isExpression() const
int maxLength() const
Definition KDbField.cpp:665
MaxLengthStrategy
Definition KDbField.h:429
@ DefinedMaxLength
Used if setMaxLength() was called to set specific maximum value or to unlimited (0).
Definition KDbField.h:432
void setPrimaryKey(bool p)
Definition KDbField.cpp:867
QString captionOrName() const
Definition KDbField.cpp:326
static QStringList typeNames()
Definition KDbField.cpp:463
QString caption() const
Definition KDbField.cpp:316
bool isDateTimeType() const
Definition KDbField.h:344
QHash< QByteArray, QVariant > CustomPropertiesMap
A data type used for handling custom properties of a field.
Definition KDbField.h:688
bool isForeignKey() const
Definition KDbField.h:297
QVariant customProperty(const QByteArray &propertyName, const QVariant &defaultValue=QVariant()) const
QString enumHint(int num)
Definition KDbField.cpp:346
virtual KDbField * copy()
Definition KDbField.cpp:374
QString description() const
Definition KDbField.cpp:331
void setDefaultValue(const QVariant &def)
Definition KDbField.cpp:711
QString typeName() const
Definition KDbField.h:377
void setMaxLengthStrategy(MaxLengthStrategy strategy)
Definition KDbField.cpp:660
void setQuery(KDbQuerySchema *query)
Definition KDbField.cpp:610
bool isIndexed() const
Definition KDbField.h:312
static TypeGroup typeGroupForString(const QString &typeGroupString)
Definition KDbField.cpp:496
int scale() const
Definition KDbField.cpp:291
static QStringList typeGroupNames()
Definition KDbField.cpp:480
@ Integer
Definition KDbField.h:90
@ Boolean
Definition KDbField.h:92
@ ShortInteger
Definition KDbField.h:89
@ LastSpecialType
Definition KDbField.h:113
@ InvalidType
Definition KDbField.h:86
@ BigInteger
Definition KDbField.h:91
@ LongText
Definition KDbField.h:99
void setPrecision(int p)
Definition KDbField.cpp:676
bool isFPNumericType() const
Definition KDbField.h:335
@ NotEmpty
only legal for string-like and blob fields
Definition KDbField.h:139
void setVisibleDecimalPlaces(int p)
Definition KDbField.cpp:692
Type type() const
Definition KDbField.cpp:379
void setParent(KDbFieldList *parent)
Sets parent for this field.
Definition KDbField.cpp:251
QString typeGroupString() const
Definition KDbField.h:399
void setName(const QString &name)
Definition KDbField.cpp:615
Constraints constraints() const
Definition KDbField.cpp:301
void setAutoIncrement(bool a)
Definition KDbField.cpp:857
void setMaxLength(int maxLength)
Definition KDbField.cpp:670
void setNotNull(bool n)
Definition KDbField.cpp:901
KDbQuerySchema * query()
Definition KDbField.cpp:600
bool isIntegerType() const
Definition KDbField.h:326
QString typeString() const
Definition KDbField.h:393
bool hasEmptyProperty() const
Definition KDbField.h:521
void setUniqueKey(bool u)
Definition KDbField.cpp:883
bool isUniqueKey() const
Definition KDbField.h:292
void setUnsigned(bool u)
Definition KDbField.cpp:700
int visibleDecimalPlaces() const
Definition KDbField.cpp:296
int order() const
Definition KDbField.cpp:306
QString typeGroupName() const
Definition KDbField.h:387
QVariant defaultValue() const
Definition KDbField.cpp:281
KDbExpression expression()
static int defaultMaxLength()
Definition KDbField.cpp:645
void setCustomProperty(const QByteArray &propertyName, const QVariant &value)
Sets value value for custom property propertyName.
Options options() const
Definition KDbField.cpp:261
void setConstraints(Constraints c)
Definition KDbField.cpp:630
void setExpression(const KDbExpression &expr)
void setOrder(int order)
Definition KDbField.cpp:311
QString subType() const
Definition KDbField.cpp:271
void setForeignKey(bool f)
Definition KDbField.cpp:894
void setScale(int s)
Definition KDbField.cpp:684
bool isPrimaryKey() const
Definition KDbField.h:287
TypeGroup typeGroup() const
Definition KDbField.h:382
QVector< QString > enumHints() const
Definition KDbField.cpp:341
void setTable(KDbTableSchema *table)
Definition KDbField.cpp:595
KDbQuerySchema provides information about database query.
KDbConnection * connection() const
KDB_EXPORT QString variantToString(const QVariant &v)
Definition KDb.cpp:1848
KDB_EXPORT bool supportsVisibleDecimalPlacesProperty(KDbField::Type type)
Definition KDb.cpp:623
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
QString name(StandardAction id)
KTEXTEDITOR_EXPORT QDebug operator<<(QDebug s, const MovingCursor &cursor)
bool isEmpty() const const
bool isNull() const const
qsizetype length() const const
double toDouble(bool *ok) const const
float toFloat(bool *ok) const const
int toInt(bool *ok, int base) const const
long toLong(bool *ok, int base) const const
uint toUInt(bool *ok, int base) const const
ushort toUShort(bool *ok, int base) const const
QDate fromString(QStringView string, QStringView format, QCalendar cal)
bool isValid(int year, int month, int day)
bool isValid() const const
QDebug & nospace()
QDebug & space()
typedef ConstIterator
iterator insert(const Key &key, const T &value)
T value(const Key &key) const const
QString arg(Args &&... args) const const
QChar * data()
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
QString number(double n, char format, int precision)
QString toLower() const const
bool isValid(int h, int m, int s, int ms)
bool canConvert() const const
bool isNull() const const
const char * typeName() const const
T value() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jun 21 2024 11:55:43 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.