KDb

KDbField.cpp
1 /* This file is part of the KDE project
2  Copyright (C) 2002 Lucijan Busch <[email protected]>
3  Copyright (C) 2002 Joseph Wenninger <[email protected]>
4  Copyright (C) 2003-2017 JarosÅ‚aw Staniek <[email protected]>
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
34 static int g_defaultMaxLength = 0; // unlimited
35 
36 //-------------------------------------------------------
37 //! @internal Used in s_typeNames member to handle translated type names
38 class FieldTypeNames
39 {
40 public:
41  FieldTypeNames();
42  QVector<QString> data;
44  QStringList names;
45 private:
46  Q_DISABLE_COPY(FieldTypeNames)
47 };
48 
49 //! @internal Used in m_typeGroupNames member to handle translated type group names
50 class FieldTypeGroupNames
51 {
52 public:
53  FieldTypeGroupNames();
54  QVector<QString> data;
56  QStringList names;
57 private:
58  Q_DISABLE_COPY(FieldTypeGroupNames)
59 };
60 
61 //! real translated type names (and nontranslated type name strings)
62 Q_GLOBAL_STATIC(FieldTypeNames, s_typeNames)
63 
64 //! real translated type group names (and nontranslated group name strings)
65 Q_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 
78 FieldTypeNames::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 
100 FieldTypeGroupNames::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 
114 class KDbFieldPrivate
115 {
116 public:
117  static KDbConnection *connection(const KDbTableSchema &table)
118  {
119  return table.connection();
120  }
121 };
122 
123 
124 class Q_DECL_HIDDEN KDbField::Private
125 {
126 public:
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;
170  QString name;
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 
197 KDbField::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 
221 KDbField::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 
236 KDbField::~KDbField()
237 {
238  delete d;
239 }
240 
242 {
243  return d->parent;
244 }
245 
246 const KDbFieldList *KDbField::parent() const
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 
276 void 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 
291 int KDbField::scale() const
292 {
293  return d->maxLength;
294 }
295 
297 {
298  return d->visibleDecimalPlaces;
299 }
300 
302 {
303  return d->constraints;
304 }
305 
306 int KDbField::order() const
307 {
308  return d->order;
309 }
310 
311 void KDbField::setOrder(int order)
312 {
313  d->order = order;
314 }
315 
317 {
318  return d->caption;
319 }
320 
321 void 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 
336 void 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 
418 template <typename T>
419 static 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:
506  case KDbField::Integer:
508  return true;
509  default:;
510  }
511  return false;
512 }
513 
515 {
516  switch (type) {
517  case KDbField::Byte:
519  case KDbField::Integer:
521  case KDbField::Float:
522  case KDbField::Double:
523  return true;
524  default:;
525  }
526  return false;
527 }
528 
530 {
531  return type == KDbField::Float || type == KDbField::Double;
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:
550  case KDbField::LongText:
551  return true;
552  default:;
553  }
554  return false;
555 }
556 
558 {
559  return KDbField::isTextType(type) || type == BLOB;
560 }
561 
563 {
565 }
566 
568 {
570  return TextGroup;
571  else if (KDbField::isIntegerType(type))
572  return IntegerGroup;
574  return FloatGroup;
575  else if (type == Boolean)
576  return BooleanGroup;
577  else if (KDbField::isDateTimeType(type))
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 
590 const 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 
605 const KDbQuerySchema* KDbField::query() const
606 {
607  return dynamic_cast<const KDbQuerySchema*>(d->parent);
608 }
609 
611 {
612  d->parent = querySchema;
613 }
614 
615 void 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 
650 void KDbField::setDefaultMaxLength(int maxLength)
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 
670 void 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 
928 void 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 
990 KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbField& field)
991 {
992  debug(dbg, field, KDbFieldDebugAddName);
993  return dbg.space();
994 }
995 
996 KDB_EXPORT QDebug operator<<(QDebug dbg, KDbField::Type type)
997 {
998  return dbg.space() << qPrintable(KDbField::typeString(type));
999 }
1000 
1001 KDB_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 
1016 const KDbExpression KDbField::expression() const
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 
1042 void 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 }
QString caption() const
Definition: KDbField.cpp:316
bool isNull() const const
static int defaultMaxLength()
Definition: KDbField.cpp:645
virtual QString sqlTypeName(KDbField::Type type, const KDbField &field) const
Definition: KDbDriver.cpp:128
ushort toUShort(bool *ok, int base) const const
bool isNull() const const
QVariant defaultValue() const
Definition: KDbField.cpp:281
double toDouble(bool *ok) const const
bool isNotEmpty() const
Definition: KDbField.h:307
bool isPrimaryKey() const
Definition: KDbField.h:287
QString description() const
Definition: KDbField.cpp:331
bool isIndexed() const
Definition: KDbField.h:312
static TypeGroup typeGroupForString(const QString &typeGroupString)
Definition: KDbField.cpp:496
QString number(int n, int base)
KDbQuerySchema * query()
Definition: KDbField.cpp:600
int order() const
Definition: KDbField.cpp:306
@ InvalidType
Definition: KDbField.h:86
QVariant customProperty(const QByteArray &propertyName, const QVariant &defaultValue=QVariant()) const
Definition: KDbField.cpp:1033
Type type(const QSqlDatabase &db)
KDbTableSchema * table()
Definition: KDbField.cpp:585
@ NotEmpty
only legal for string-like and blob fields
Definition: KDbField.h:139
T value() const const
@ Text
Definition: KDbField.h:98
QDebug & nospace()
@ LastSpecialType
Definition: KDbField.h:113
KDbConnection * connection() const
QHash< QByteArray, QVariant > CustomPropertiesMap
A data type used for handling custom properties of a field.
Definition: KDbField.h:688
void setOrder(int order)
Definition: KDbField.cpp:311
QDebug & space()
QDataStream & operator<<(QDataStream &out, const KDateTime &dateTime)
bool isValid() const const
bool isUniqueKey() const
Definition: KDbField.h:292
Options options() const
Definition: KDbField.cpp:261
MaxLengthStrategy
Definition: KDbField.h:429
int visibleDecimalPlaces() const
Definition: KDbField.cpp:296
KDbExpression expression()
Definition: KDbField.cpp:1011
void setExpression(const KDbExpression &expr)
Definition: KDbField.cpp:1021
QString caption()
int scale() const
Definition: KDbField.cpp:291
bool isFPNumericType() const
Definition: KDbField.h:335
virtual KDbField * copy()
Definition: KDbField.cpp:374
void setTable(KDbTableSchema *table)
Definition: KDbField.cpp:595
@ LastType
Definition: KDbField.h:102
void setAutoIncrement(bool a)
Definition: KDbField.cpp:857
void setPrecision(int p)
Definition: KDbField.cpp:676
void setUniqueKey(bool u)
Definition: KDbField.cpp:883
uint toUInt(bool *ok, int base) const const
Q_GLOBAL_STATIC(Internal::StaticControl, s_instance) class ControlPrivate
static QString defaultSqlTypeName(KDbField::Type type)
Definition: KDbDriver.cpp:164
void setNotNull(bool n)
Definition: KDbField.cpp:901
CustomPropertiesMap customProperties() const
Definition: KDbField.cpp:1053
QString typeName() const
Definition: KDbField.h:377
void setVisibleDecimalPlaces(int p)
Definition: KDbField.cpp:692
static QVariant convertToType(const QVariant &value, Type type)
Converts value value to variant corresponding to type type.
Definition: KDbField.cpp:426
float toFloat(bool *ok) const const
void setOptions(Options options)
Definition: KDbField.cpp:266
QString typeString() const
Definition: KDbField.h:393
void setType(Type t)
Definition: KDbField.cpp:620
void setPrimaryKey(bool p)
Definition: KDbField.cpp:867
typedef ConstIterator
static int typeGroupsCount()
Definition: KDbField.cpp:369
bool isAutoIncrementAllowed() const
Definition: KDbField.h:531
bool isTextType() const
Definition: KDbField.h:353
bool isIntegerType() const
Definition: KDbField.h:326
void setMaxLengthStrategy(MaxLengthStrategy strategy)
Definition: KDbField.cpp:660
void setConstraints(Constraints c)
Definition: KDbField.cpp:630
static QStringList typeGroupNames()
Definition: KDbField.cpp:480
QVariant::Type variantType() const
Converts field's type to QVariant equivalent as accurate as possible.
Definition: KDbField.h:368
@ Integer
Definition: KDbField.h:90
QString typeGroupString() const
Definition: KDbField.h:399
void setDescription(const QString &description)
Definition: KDbField.cpp:336
KDB_EXPORT bool supportsVisibleDecimalPlacesProperty(KDbField::Type type)
Definition: KDb.cpp:623
void setIndexed(bool s)
Definition: KDbField.cpp:915
bool isEmpty() const const
bool isForeignKey() const
Definition: KDbField.h:297
void setSubType(const QString &subType)
Definition: KDbField.cpp:276
void setUnsigned(bool u)
Definition: KDbField.cpp:700
void setForeignKey(bool f)
Definition: KDbField.cpp:894
Constraints constraints() const
Definition: KDbField.cpp:301
QString enumHint(int num)
Definition: KDbField.cpp:346
TypeGroup typeGroup() const
Definition: KDbField.h:382
int maxLength() const
Definition: KDbField.cpp:665
bool isValid() const const
void setNotEmpty(bool n)
Definition: KDbField.cpp:908
int precision() const
Definition: KDbField.cpp:286
QVector< QString > enumHints() const
Definition: KDbField.cpp:341
@ BigInteger
Definition: KDbField.h:91
Type type() const
Definition: KDbField.cpp:379
bool isNumericType() const
Definition: KDbField.h:317
void setCaption(const QString &caption)
Definition: KDbField.cpp:321
@ Double
Definition: KDbField.h:97
static int typesCount()
Definition: KDbField.cpp:357
bool isDateTimeType() const
Definition: KDbField.h:344
void setScale(int s)
Definition: KDbField.cpp:684
@ LongText
Definition: KDbField.h:99
@ Byte
Definition: KDbField.h:87
void setName(const QString &name)
Definition: KDbField.cpp:615
long toLong(bool *ok, int base) const const
bool canConvert(int targetTypeId) const const
QString typeGroupName() const
Definition: KDbField.h:387
void setEnumHints(const QVector< QString > &hints)
Definition: KDbField.cpp:351
@ DefinedMaxLength
Used if setMaxLength() was called to set specific maximum value or to unlimited (0).
Definition: KDbField.h:432
QString toLower() const const
static Type typeForString(const QString &typeString)
Definition: KDbField.cpp:491
int toInt(bool *ok, int base) const const
QDate fromString(const QString &string, Qt::DateFormat format)
bool isAutoIncrement() const
Definition: KDbField.h:282
bool isEmpty() const const
@ Boolean
Definition: KDbField.h:92
KDbQuerySchema provides information about database query.
KDB_EXPORT QString variantToString(const QVariant &v)
Definition: KDb.cpp:1856
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
void setDefaultValue(const QVariant &def)
Definition: KDbField.cpp:711
QString fromLatin1(const char *str, int size)
void setCustomProperty(const QByteArray &propertyName, const QVariant &value)
Sets value value for custom property propertyName.
Definition: KDbField.cpp:1042
bool isNotNull() const
Definition: KDbField.h:302
QString name(StandardShortcut id)
void setParent(KDbFieldList *parent)
Sets parent for this field.
Definition: KDbField.cpp:251
void setMaxLength(int maxLength)
Definition: KDbField.cpp:670
static void setDefaultMaxLength(int maxLength)
Definition: KDbField.cpp:650
bool isValid() const const
Meta-data for a field.
Definition: KDbField.h:71
bool hasEmptyProperty() const
Definition: KDbField.h:521
void setQuery(KDbQuerySchema *query)
Definition: KDbField.cpp:610
QString subType() const
Definition: KDbField.cpp:271
bool isExpression() const
Definition: KDbField.cpp:1006
MaxLengthStrategy maxLengthStrategy() const
Definition: KDbField.cpp:655
QChar * data()
@ Float
Definition: KDbField.h:96
static QStringList typeNames()
Definition: KDbField.cpp:463
int length() const const
static int specialTypesCount()
Definition: KDbField.cpp:363
Provides database connection, allowing queries and data modification.
Definition: KDbConnection.h:51
QString name() const
Definition: KDbField.cpp:256
KDbDriver * driver() const
KDbFieldList * parent()
Definition: KDbField.cpp:241
The KDbExpression class represents a base class for all expressions.
Definition: KDbExpression.h:51
const char * typeName() const const
@ ShortInteger
Definition: KDbField.h:89
QString captionOrName() const
Definition: KDbField.cpp:326
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Jun 25 2022 06:21:33 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.