kexi

field.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-2006 Jaroslaw Staniek <js@iidea.pl>
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 "field.h"
23#include "connection.h"
24#include "driver.h"
25#include "expression.h"
26#include "utils.h"
27
28// we use here i18n() but this depends on kde libs: TODO: add #ifdefs
29#include <kdebug.h>
30#include <tdelocale.h>
31
32#include <tqdatetime.h>
33
34#include <assert.h>
35
36using namespace KexiDB;
37
38Field::FieldTypeNames Field::m_typeNames;
39Field::FieldTypeGroupNames Field::m_typeGroupNames;
40
42{
43 init();
44 setConstraints(NoConstraints);
45}
46
47
48Field::Field(TableSchema *tableSchema)
49{
50 init();
51 m_parent = tableSchema;
52 m_order = tableSchema->fieldCount();
53 setConstraints(NoConstraints);
54}
55
56Field::Field(QuerySchema *querySchema, BaseExpr* expr)
57{
58 init();
59 m_parent = querySchema;
60 m_order = querySchema->fieldCount();
61 setConstraints(NoConstraints);
62 if (expr)
63 setExpression(expr);
64}
65
66Field::Field(const TQString& name, Type ctype,
67 uint cconst, uint options, uint length, uint precision,
68 TQVariant defaultValue, const TQString& caption, const TQString& description,
69 uint width)
70 : m_parent(0)
71 ,m_name(name.lower())
73 ,m_precision(precision)
75 ,m_options(options)
76 ,m_defaultValue(defaultValue)
77 ,m_order(-1)
78 ,m_caption(caption)
79 ,m_desc(description)
80 ,m_width(width)
81 ,m_expr(0)
82 ,m_customProperties(0)
83 ,m_type(ctype)
84{
85 setConstraints(cconst);
86 if (m_length==0) {//0 means default length:
87 if (m_type==Field::Text)
88 m_length = defaultTextLength();
89 }
90}
91
94{
95 (*this) = f;
96 if (f.m_customProperties)
97 m_customProperties = new CustomPropertiesMap( f.customProperties() );
98
99 if (f.m_expr) {//deep copy the expression
100//TODO m_expr = new BaseExpr(*f.m_expr);
101
102// m_expr->m_field = this;
103 } else
104 m_expr = 0;
105}
106
107Field::~Field()
108{
109 delete m_expr;
110 delete m_customProperties;
111}
112
114{
115 return new Field(*this);
116}
117
118void Field::init()
119{
120 m_parent = 0;
121 m_name = "";
122 m_type = InvalidType;
123 m_length = 0;
124 m_precision = 0;
126 m_options = NoOptions;
127 m_defaultValue = TQVariant(TQString());
128 m_order = -1;
129 m_width = 0;
130 m_expr = 0;
131 m_customProperties = 0;
132}
133
135{
136 if (m_expr)
137 return m_expr->type();
138 return m_type;
139}
140
141TQVariant::Type Field::variantType(uint type)
142{
143 switch(type)
144 {
145 case Byte:
146 case ShortInteger:
147 case Integer:
148 case BigInteger:
149 return TQVariant::Int;
150 case Boolean:
151 return TQVariant::Bool;
152 case Date:
153 return TQVariant::Date;
154 case DateTime:
155 return TQVariant::DateTime;
156 case Time:
157 return TQVariant::Time;
158 case Float:
159 case Double:
160 return TQVariant::Double;
161 case Text:
162 case LongText:
163 return TQVariant::String;
164 case BLOB:
165 return TQVariant::ByteArray;
166 default:
167 return TQVariant::Invalid;
168 }
169
170 return TQVariant::Invalid;
171}
172
173TQString Field::typeName(uint type)
174{
175 m_typeNames.init();
176 return (type <= LastType) ? m_typeNames.at(type) : TQString::number(type);
177}
178
180{
181 m_typeNames.init();
182 return (type <= LastType) ? m_typeNames.at((int)LastType+1 + type) : TQString("Type%1").arg(type);
183}
184
186{
187 m_typeGroupNames.init();
188 return (typeGroup <= LastTypeGroup) ? m_typeGroupNames.at(typeGroup) : typeGroupString(typeGroup);
189}
190
192{
193 m_typeGroupNames.init();
194 return (typeGroup <= LastTypeGroup) ? m_typeGroupNames.at((int)LastTypeGroup+1 + typeGroup) : TQString("TypeGroup%1").arg(typeGroup);
195}
196
198{
199 m_typeNames.init();
200 TQMap<TQString,Type>::ConstIterator it = m_typeNames.str2num.find(typeString.lower());
201 if (it==m_typeNames.str2num.end())
202 return InvalidType;
203 return it.data();
204}
205
207{
208 m_typeGroupNames.init();
209 TQMap<TQString,TypeGroup>::ConstIterator it = m_typeGroupNames.str2num.find(typeGroupString.lower());
210 if (it==m_typeGroupNames.str2num.end())
211 return InvalidGroup;
212 return it.data();
213}
214
216{
217 switch (type) {
218 case Field::Byte:
220 case Field::Integer:
222 return true;
223 default:;
224 }
225 return false;
226}
227
229{
230 switch (type) {
231 case Field::Byte:
233 case Field::Integer:
235 case Field::Float:
236 case Field::Double:
237 return true;
238 default:;
239 }
240 return false;
241}
242
244{
246}
247
249{
250 switch (type) {
251 case Field::Date:
252 case Field::DateTime:
253 case Field::Time:
254 return true;
255 default:;
256 }
257 return false;
258}
259
261{
262 switch (type) {
263 case Field::Text:
264 case Field::LongText:
265 return true;
266 default:;
267 }
268 return false;
269}
270
272{
273 return Field::isTextType(type) || type==BLOB;
274}
275
280
282{
284 return TextGroup;
285 else if (Field::isIntegerType(type))
286 return IntegerGroup;
288 return FloatGroup;
289 else if (type==Boolean)
290 return BooleanGroup;
291 else if (Field::isDateTimeType(type))
292 return DateTimeGroup;
293 else if (type==BLOB)
294 return BLOBGroup;
295
296 return InvalidGroup; //unknown
297}
298
301{
302 return dynamic_cast<TableSchema*>(m_parent);
303}
304
305void
306Field::setTable(TableSchema *tableSchema)
307{
308 m_parent = tableSchema;
309}
310
313{
314 return dynamic_cast<QuerySchema*>(m_parent);
315}
316
317void
318Field::setQuery(QuerySchema *querySchema)
319{
320 m_parent = querySchema;
321}
322
323void
324Field::setName(const TQString& n)
325{
326 m_name = n.lower();
327}
328
329void
331{
332 if (m_expr) {
333 KexiDBWarn << TQString("Field::setType(%1)").arg(t)
334 << " could not set type because the field has expression assigned!" << endl;
335 return;
336 }
337 m_type = t;
338}
339
340void
342{
343 m_constraints = c;
344 //pkey must be unique notnull
345 if (isPrimaryKey()) {
346 setPrimaryKey(true);
347 }
348 if (isIndexed()) {
349 setIndexed(true);
350 }
352 setAutoIncrement(false);
353 }
354}
355
356void
358{
359 if (type()!=Field::Text)
360 return;
361 m_length = l;
362}
363
364void
366{
367 if (!isFPNumericType())
368 return;
369 m_precision = p;
370}
371
372void
374{
375 if (!isFPNumericType())
376 return;
377 m_length = s;
378}
379
380void
387
388void
390{
391 m_options |= Unsigned;
392 m_options ^= (!u * Unsigned);
393}
394
395void
396Field::setDefaultValue(const TQVariant& def)
397{
398 m_defaultValue = def;
399}
400
401bool
402Field::setDefaultValue(const TQCString& def)
403{
404 if (def.isNull()) {
405 m_defaultValue = TQVariant();
406 return true;
407 }
408
409 bool ok;
410 switch(type())
411 {
412 case Byte: {
413 unsigned int v = def.toUInt(&ok);
414 if (!ok || v > 255)
415 m_defaultValue = TQVariant();
416 else
417 m_defaultValue = TQVariant(v);
418 break;
419 }case ShortInteger: {
420 int v = def.toInt(&ok);
421 if (!ok || (!(m_options & Unsigned) && (v < -32768 || v > 32767)) || ((m_options & Unsigned) && (v < 0 || v > 65535)))
422 m_defaultValue = TQVariant();
423 else
424 m_defaultValue = TQVariant(v);
425 break;
426 }case Integer: {//4 bytes
427 long v = def.toLong(&ok);
428//js: FIXME if (!ok || (!(m_options & Unsigned) && (-v > 0x080000000 || v > (0x080000000-1))) || ((m_options & Unsigned) && (v < 0 || v > 0x100000000)))
429 if (!ok || (!(m_options & Unsigned) && (-v > (int)0x07FFFFFFF || v > (int)(0x080000000-1))))
430 m_defaultValue = TQVariant();
431 else
432 m_defaultValue = TQVariant((TQ_LLONG)v);
433 break;
434 }case BigInteger: {//8 bytes
436/*
437 TQ_LLONG long v = def.toLongLong(&ok);
438//TODO: 2-part decoding
439 if (!ok || (!(m_options & Unsigned) && (-v > 0x080000000 || v > (0x080000000-1))))
440 m_defaultValue = TQVariant();
441 else
442 if (m_options & Unsigned)
443 m_defaultValue=TQVariant((TQ_ULLONG) v);
444 else
445 m_defaultValue = TQVariant((TQ_LLONG)v);*/
446 break;
447 }case Boolean: {
448 unsigned short v = def.toUShort(&ok);
449 if (!ok || v > 1)
450 m_defaultValue = TQVariant();
451 else
452 m_defaultValue = TQVariant((bool)v);
453 break;
454 }case Date: {//YYYY-MM-DD
455 TQDate date = TQDate::fromString( def, TQt::ISODate );
456 if (!date.isValid())
457 m_defaultValue = TQVariant();
458 else
459 m_defaultValue = TQVariant(date);
460 break;
461 }case DateTime: {//YYYY-MM-DDTHH:MM:SS
462 TQDateTime dt = TQDateTime::fromString( def, TQt::ISODate );
463 if (!dt.isValid())
464 m_defaultValue = TQVariant();
465 else
466 m_defaultValue = TQVariant(dt);
467 break;
468 }case Time: {//HH:MM:SS
469 TQTime time = TQTime::fromString( def, TQt::ISODate );
470 if (!time.isValid())
471 m_defaultValue = TQVariant();
472 else
473 m_defaultValue = TQVariant(time);
474 break;
475 }case Float: {
476 float v = def.toFloat(&ok);
477 if (!ok || ((m_options & Unsigned) && (v < 0.0)))
478 m_defaultValue = TQVariant();
479 else
480 m_defaultValue = TQVariant(v);
481 break;
482 }case Double: {
483 double v = def.toDouble(&ok);
484 if (!ok || ((m_options & Unsigned) && (v < 0.0)))
485 m_defaultValue = TQVariant();
486 else
487 m_defaultValue = TQVariant(v);
488 break;
489 }case Text: {
490 if (def.isNull() || (def.length() > 255))
491 m_defaultValue = TQVariant();
492 else
493 m_defaultValue = TQVariant((TQString)def);
494 break;
495 }case LongText: {
496 if (def.isNull())
497 m_defaultValue = TQVariant();
498 else
499 m_defaultValue = TQVariant((TQString)def);
500 break;
501 }case BLOB: {
502//TODO
503 if (def.isNull())
504 m_defaultValue = TQVariant();
505 else
506 m_defaultValue = TQVariant(def);
507 break;
508 }default:
509 m_defaultValue = TQVariant();
510 }
511 return m_defaultValue.isNull();
512}
513
514void
516{
517 if (a && !isAutoIncrementAllowed())
518 return;
519 if (isAutoIncrement() != a)
520 m_constraints = static_cast<Field::Constraints>(m_constraints ^ Field::AutoInc);
521}
522
523void
525{
526 if(isPrimaryKey() != p)
527 m_constraints = static_cast<Field::Constraints>(m_constraints ^ Field::PrimaryKey);
528 if (p) {//also set implied constraints
529 setUniqueKey(true);
530 setNotNull(true);
531 setNotEmpty(true);
532 setIndexed(true);
533 }
534 else {
536 setAutoIncrement(false);
537 }
538}
539
540void
542{
543 if(isUniqueKey() != u) {
544 m_constraints = static_cast<Field::Constraints>(m_constraints ^ Field::Unique);
545 if (u)
546 setNotNull(true);
547 }
548}
549
550void
552{
553 if (isForeignKey() != f)
554 m_constraints = static_cast<Field::Constraints>(m_constraints ^ Field::ForeignKey);
555}
556
557void
559{
560 if (isNotNull() != n)
561 m_constraints = static_cast<Field::Constraints>(m_constraints ^ Field::NotNull);
562}
563
565{
566 if (isNotEmpty() != n)
567 m_constraints = static_cast<Field::Constraints>(m_constraints ^ Field::NotEmpty);
568}
569
571{
572 if (isIndexed() != s)
573 m_constraints = static_cast<Field::Constraints>(m_constraints ^ Field::Indexed);
574 if (!s) {//also set implied constraints
575 setPrimaryKey(false);
576 setUniqueKey(false);
577 setNotNull(false);
578 setNotEmpty(false);
579 }
580}
581
582
583TQString Field::debugString() const
584{
585 KexiDB::Connection *conn = table() ? table()->connection() : 0;
586 TQString dbg = (m_name.isEmpty() ? "<NONAME> " : m_name + " ");
587 if (m_options & Field::Unsigned)
588 dbg += " UNSIGNED ";
589 dbg += (conn && conn->driver()) ? conn->driver()->sqlTypeName(type()) : Driver::defaultSQLTypeName(type());
590 if (isFPNumericType() && m_precision>0) {
591 if (scale()>0)
592 dbg += TQString::fromLatin1("(%1,%2)").arg(m_precision).arg(scale());
593 else
594 dbg += TQString::fromLatin1("(%1)").arg(m_precision);
595 }
596 else if (m_type==Field::Text && m_length>0)
597 dbg += TQString::fromLatin1("(%1)").arg(m_length);
598 if (m_constraints & Field::AutoInc)
599 dbg += " AUTOINC";
600 if (m_constraints & Field::Unique)
601 dbg += " UNIQUE";
602 if (m_constraints & Field::PrimaryKey)
603 dbg += " PKEY";
604 if (m_constraints & Field::ForeignKey)
605 dbg += " FKEY";
606 if (m_constraints & Field::NotNull)
607 dbg += " NOTNULL";
608 if (m_constraints & Field::NotEmpty)
609 dbg += " NOTEMPTY";
610 if (!m_defaultValue.isNull())
611 dbg += TQString(" DEFAULT=[%1]").arg(m_defaultValue.typeName()) + KexiDB::variantToString(m_defaultValue);
612 if (m_expr)
613 dbg += " EXPRESSION=" + m_expr->debugString();
614 if (m_customProperties && !m_customProperties->isEmpty()) {
615 dbg += TQString(" CUSTOM PROPERTIES (%1): ").arg(m_customProperties->count());
616 bool first = true;
617 foreach (CustomPropertiesMap::ConstIterator, it, *m_customProperties) {
618 if (first)
619 first = false;
620 else
621 dbg += ", ";
622 dbg += TQString("%1 = %2 (%3)").arg(TQString(it.key())).arg(TQString(it.data().toString())).arg(TQString(it.data().typeName()));
623 }
624 }
625 return dbg;
626}
627
629{
630 KexiDBDbg << debugString() << endl;
631}
632
634{
635 assert(!m_parent || dynamic_cast<QuerySchema*>(m_parent));
636 if (m_expr==expr)
637 return;
638 if (m_expr) {
639 delete m_expr;
640 }
641 m_expr = expr;
642}
643
644TQVariant Field::customProperty(const TQCString& propertyName,
645 const TQVariant& defaultValue) const
646{
647 if (!m_customProperties)
648 return defaultValue;
649 CustomPropertiesMap::ConstIterator it(m_customProperties->find(propertyName));
650 if (it==m_customProperties->constEnd())
651 return defaultValue;
652 return it.data();
653}
654
655void Field::setCustomProperty(const TQCString& propertyName, const TQVariant& value)
656{
657 if (propertyName.isEmpty())
658 return;
659 if (!m_customProperties)
660 m_customProperties = new CustomPropertiesMap();
661 m_customProperties->insert(propertyName, value);
662}
663
664//-------------------------------------------------------
665#define ADDTYPE(type, i18, str) this->at(Field::type) = i18; \
666 this->at(Field::type+Field::LastType+1) = str; \
667 str2num.insert(TQString::fromLatin1(str).lower(), type)
668#define ADDGROUP(type, i18, str) this->at(Field::type) = i18; \
669 this->at(Field::type+Field::LastTypeGroup+1) = str; \
670 str2num.insert(TQString::fromLatin1(str).lower(), type)
671
672Field::FieldTypeNames::FieldTypeNames()
673 : TQValueVector<TQString>()
674 , m_initialized(false)
675{
676}
677
678void Field::FieldTypeNames::init()
679{
680 if (m_initialized)
681 return;
682 m_initialized = true;
683 resize((Field::LastType + 1)*2);
684
685 ADDTYPE( InvalidType, i18n("Invalid Type"), "InvalidType" );
686 ADDTYPE( Byte, i18n("Byte"), "Byte" );
687 ADDTYPE( ShortInteger, i18n("Short Integer Number"), "ShortInteger" );
688 ADDTYPE( Integer, i18n("Integer Number"), "Integer" );
689 ADDTYPE( BigInteger, i18n("Big Integer Number"), "BigInteger" );
690 ADDTYPE( Boolean, i18n("Yes/No Value"), "Boolean" );
691 ADDTYPE( Date, i18n("Date"), "Date" );
692 ADDTYPE( DateTime, i18n("Date and Time"), "DateTime" );
693 ADDTYPE( Time, i18n("Time"), "Time" );
694 ADDTYPE( Float, i18n("Single Precision Number"), "Float" );
695 ADDTYPE( Double, i18n("Double Precision Number"), "Double" );
696 ADDTYPE( Text, i18n("Text"), "Text" );
697 ADDTYPE( LongText, i18n("Long Text"), "LongText" );
698 ADDTYPE( BLOB, i18n("Object"), "BLOB" );
699}
700
701//-------------------------------------------------------
702
703Field::FieldTypeGroupNames::FieldTypeGroupNames()
704 : TQValueVector<TQString>()
705 , m_initialized(false)
706{
707}
708
709void Field::FieldTypeGroupNames::init()
710{
711 if (m_initialized)
712 return;
713 m_initialized = true;
714 resize((Field::LastTypeGroup + 1)*2);
715
716 ADDGROUP( InvalidGroup, i18n("Invalid Group"), "InvalidGroup" );
717 ADDGROUP( TextGroup, i18n("Text"), "TextGroup" );
718 ADDGROUP( IntegerGroup, i18n("Integer Number"), "IntegerGroup" );
719 ADDGROUP( FloatGroup, i18n("Floating Point Number"), "FloatGroup" );
720 ADDGROUP( BooleanGroup, i18n("Yes/No"), "BooleanGroup" );
721 ADDGROUP( DateTimeGroup, i18n("Date/Time"), "DateTimeGroup" );
722 ADDGROUP( BLOBGroup, i18n("Object"), "BLOBGroup" );
723}
724
725//-------------------------------------------------------
726
A base class for all expressions.
Definition expression.h:67
Provides database connection, allowing queries and data modification.
Definition connection.h:62
Driver * driver() const
Definition connection.h:78
static TQString defaultSQLTypeName(int id_t)
Definition driver.cpp:206
virtual TQString sqlTypeName(int id_t, int p=0) const
Definition driver.cpp:170
uint fieldCount() const
Definition fieldlist.h:58
bool isPrimaryKey() const
Definition field.h:234
TQString typeName() const
Definition field.h:298
virtual Field * copy() const
Definition field.cpp:113
bool isNotNull() const
Definition field.h:243
bool isIndexed() const
Definition field.h:249
void setIndexed(bool s)
Definition field.cpp:570
bool isAutoIncrementAllowed() const
Definition field.h:396
TQString caption() const
Definition field.h:371
virtual TQString debugString() const
Definition field.cpp:583
@ NotEmpty
only legal for string-like and blob fields
Definition field.h:137
void setName(const TQString &name)
Definition field.cpp:324
Type type() const
Definition field.cpp:134
TQVariant customProperty(const TQCString &propertyName, const TQVariant &defaultValue=TQVariant()) const
Definition field.cpp:644
void setVisibleDecimalPlaces(int p)
Definition field.cpp:381
QuerySchema * query() const
Definition field.cpp:312
@ ShortInteger
Definition field.h:86
@ InvalidType
Definition field.h:84
TQVariant::Type variantType() const
Converts field's type to TQVariant equivalent as accurate as possible.
Definition field.h:291
const CustomPropertiesMap customProperties() const
Definition field.h:559
TQString typeString() const
Definition field.h:308
void setConstraints(uint c)
Definition field.cpp:341
void setPrecision(uint p)
Definition field.cpp:365
TQString typeGroupString() const
Definition field.h:312
void setNotEmpty(bool n)
Definition field.cpp:564
void setQuery(QuerySchema *query)
Definition field.cpp:318
void setDefaultValue(const TQVariant &def)
Definition field.cpp:396
bool hasEmptyProperty() const
Definition field.h:388
static TypeGroup typeGroupForString(const TQString &typeGroupString)
Definition field.cpp:206
FieldList * m_parent
Definition field.h:576
uint m_length
also used for storing scale for floating point types
Definition field.h:581
bool isFPNumericType() const
Definition field.h:266
virtual void setTable(TableSchema *table)
Definition field.cpp:306
void setScale(uint s)
Definition field.cpp:373
void setPrimaryKey(bool p)
Definition field.cpp:524
bool isIntegerType() const
Definition field.h:259
bool isAutoIncrement() const
Definition field.h:231
void setUniqueKey(bool u)
Definition field.cpp:541
static TQString typeGroupString(uint typeGroup)
Definition field.cpp:191
void debug()
Definition field.cpp:628
static Type typeForString(const TQString &typeString)
Definition field.cpp:197
void setAutoIncrement(bool a)
Definition field.cpp:515
void setCustomProperty(const TQCString &propertyName, const TQVariant &value)
Sets value value for custom property propertyName.
Definition field.cpp:655
void setType(Type t)
Definition field.cpp:330
static FieldTypeGroupNames m_typeGroupNames
real i18n'd type group names (and not-i18n'd group name strings)
Definition field.h:619
bool isNotEmpty() const
Definition field.h:246
bool isNumericType() const
Definition field.h:252
TypeGroup typeGroup() const
Definition field.h:301
uint scale() const
Definition field.h:343
TQString typeGroupName() const
Definition field.h:304
void setNotNull(bool n)
Definition field.cpp:558
void setUnsigned(bool u)
Definition field.cpp:389
bool isTextType() const
Definition field.h:280
bool isForeignKey() const
Definition field.h:240
static TypeGroup typeGroup(uint type)
Definition field.cpp:281
int m_visibleDecimalPlaces
used in visibleDecimalPlaces()
Definition field.h:583
void setExpression(KexiDB::BaseExpr *expr)
Definition field.cpp:633
TQString description() const
Definition field.h:377
TQMap< TQCString, TQVariant > CustomPropertiesMap
A data type used for handling custom properties of a field.
Definition field.h:556
void setForeignKey(bool f)
Definition field.cpp:551
virtual TableSchema * table() const
Definition field.cpp:300
uint precision() const
Definition field.h:334
TQVariant defaultValue() const
Definition field.h:326
bool isUniqueKey() const
Definition field.h:237
bool isDateTimeType() const
Definition field.h:273
Field(TableSchema *tableSchema)
Definition field.cpp:48
static FieldTypeNames m_typeNames
real i18n'd type names (and not-i18n'd type name strings)
Definition field.h:616
void setLength(uint l)
Definition field.cpp:357
uint width() const
Definition field.h:381
uint length() const
Definition field.h:330
static TQString typeString(uint type)
Definition field.cpp:179
KexiDB::QuerySchema provides information about database query.
Connection * connection() const
High-level database connectivity library with database backend drivers.
KEXI_DB_EXPORT bool supportsVisibleDecimalPlacesProperty(Field::Type type)
KEXI_DB_EXPORT TQString variantToString(const TQVariant &v)