1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
|
/* This file is part of the KDE project
Copyright (C) 2002 Lucijan Busch <[email protected]>
Copyright (C) 2002 Joseph Wenninger <[email protected]>
Copyright (C) 2003-2006 Jaroslaw Staniek <[email protected]>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KEXIDB_FIELD_H
#define KEXIDB_FIELD_H
#include <tqvariant.h>
#include <tqstring.h>
#include <tqpair.h>
#include <tqvaluevector.h>
#include <tqptrvector.h>
#include "kexidb/kexidb_export.h"
namespace KexiDB {
class TableSchema;
class QuerySchema;
class FieldList;
class BaseExpr;
//! Meta-data for a field
/*! KexiDB::Field provides information about single database field.
Field class has defined following members:
- name
- type
- database constraints
- additional options
- length (make sense mostly for string types)
- precision (for floating-point type)
- defaultValue
- caption (user readable name that can be e.g. translated)
- description (user readable name additional text, can be useful for developers)
- width (a hint for displaying in tabular mode or as text box)
Field can also have assigned expression (see KexiDB::BaseExpr class,
and expression() method).
If an expression is defined, then field's name is
Note that aliases for fields are defined within query, not in Field object,
because the same field can be used in different queries with different alias.
Notes for advanced use: Field obeject is designed to be owned by a parent object.
Such a parent object can be KexiDB::TableSchema, if the field defines single table column,
or KexiDB::QuerySchema, if the field defines an expression (KexiDB::BaseExpr class).
Using expression class for fields allos to define expressions within queries like
"SELECT AVG(price) FROM products"
You can choose whether your field is owned by query or table,
using appropriate constructor, or using parameterless constructor and
calling setTable() or setQuery() later.
*/
class KEXI_DB_EXPORT Field
{
public:
typedef TQPtrList<Field> List; //!< list of fields
typedef TQPtrVector<Field> Vector; //!< vector of fields
typedef TQPtrListIterator<Field> ListIterator; //!< iterator for list of fields
typedef TQPair<Field*,Field*> Pair; //!< fields pair
typedef TQPtrList<Pair> PairList; //!< list of fields pair
/*! Unified (most common used) types of fields. */
enum Type
{
InvalidType = 0, /*!< Unsupported/Unimplemented type */
Byte = 1, /*!< 1 byte, signed or unsigned */
ShortInteger = 2,/*!< 2 bytes, signed or unsigned */
Integer = 3, /*!< 4 bytes, signed or unsigned */
BigInteger = 4, /*!< 8 bytes, signed or unsigned */
Boolean = 5, /*!< 0 or 1 */
Date = 6, /*!< */
DateTime = 7, /*!< */
Time = 8, /*!< */
Float = 9, /*!< 4 bytes */
Double = 10, /*!< 8 bytes */
Text = 11, /*!< Other name: Varchar; no more than 200 bytes, for efficiency */
LongText = 12, /*!< Other name: Memo. More than 200 bytes*/
BLOB = 13, /*!< Large binary object */
LastType = 13, /*!< This line should be at the end of the list of types! */
Null = 64, /*!< Used for fields that are "NULL" expressions. */
//! Special, internal types:
Asterisk = 128, /*!< Used in QueryAsterisk subclass objects only,
not used in table definitions,
but only in query definitions */
Enum = 129, /*!< An integer internal with a string list of hints */
Map = 130 /*!< Mapping from string to string list (more generic than Enum */
};
//TODO: make this configurable
static uint defaultTextLength() { return 200; }
/*! Type groups for fields. */
enum TypeGroup
{
InvalidGroup = 0,
TextGroup = 1,
IntegerGroup = 2,
FloatGroup = 3,
BooleanGroup = 4,
DateTimeGroup = 5,
BLOBGroup = 6, /* large binary object */
LastTypeGroup = 6 // This line should be at the end of the enum!
};
/*! Possible constraints defined for a field. */
enum Constraints
{
NoConstraints = 0,
AutoInc = 1,
Unique = 2,
PrimaryKey = 4,
ForeignKey = 8,
NotNull = 16,
NotEmpty = 32, //!< only legal for string-like and blob fields
Indexed = 64
};
/*! Possible options defined for a field. */
enum Options
{
NoOptions = 0,
Unsigned = 1
};
/*! Creates a database field as a child of \a tableSchema table
No other properties are set (even the name), so these should be set later. */
Field(TableSchema *tableSchema);
/*! Creates a database field without any properties set.
These should be set later. */
Field();
/*! Creates a database field with specified properties. */
Field(const TQString& name, Type ctype,
uint cconst=NoConstraints,
uint options = NoOptions,
uint length=0, uint precision=0,
TQVariant defaultValue=TQVariant(),
const TQString& caption = TQString(),
const TQString& description = TQString(),
uint width = 0);
/*! Copy constructor. */
Field(const Field& f);
virtual ~Field();
//! Converts type \a type to TQVariant equivalent as accurate as possible
static TQVariant::Type variantType(uint type);
/*! \return a i18n'd type name for \a type (\a type has to be an element from Field::Type,
not greater than Field::LastType) */
static TQString typeName(uint type);
/*! \return type string for \a type, e.g. "Integer" for Integer type
(not-i18n'd, \a type has to be an element from Field::Type,
not greater than Field::LastType) */
static TQString typeString(uint type);
/*! \return type for a given \a typeString */
static Type typeForString(const TQString& typeString);
/*! \return type group for a given \a typeGroupString */
static TypeGroup typeGroupForString(const TQString& typeGroupString);
/*! \return group for \a type */
static TypeGroup typeGroup(uint type);
/*! \return a i18n'd group name for \a typeGroup
(\a typeGroup has to be an element from Field::TypeGroup) */
static TQString typeGroupName(uint typeGroup);
/*! \return type group string for \a typeGroup, e.g. "IntegerGroup" for IntegerGroup type
(not-i18n'd, \a type has to be an element from Field::Type,
not greater than Field::LastType) */
static TQString typeGroupString(uint typeGroup);
/* ! \return the name of this field */
inline TQString name() const { return m_name; }
/*! \return table schema of table that owns this field
or null if it has no table assigned.
@see query() */
virtual TableSchema* table() const;
/*! Sets \a table schema of table that owns this field.
This does not adds the field to \a table object.
You do not need to call this method by hand.
Call TableSchema::addField(Field *field) instead.
@see setQuery() */
virtual void setTable(TableSchema *table);
/*! For special use when the field defines expression.
\return query schema of query that owns this field
or null if it has no query assigned.
@see table() */
QuerySchema* query() const;
/*! For special use when field defines expression.
Sets \a query schema of query that owns this field.
This does not adds the field to \a query object.
You do not need to call this method by hand.
Call QuerySchema::addField() instead.
@see setQuery() */
void setQuery(QuerySchema *query);
/*! \return true if the field is autoincrement (e.g. integer/numeric) */
inline bool isAutoIncrement() const { return constraints() & AutoInc; }
/*! \return true if the field is member of single-field primary key */
inline bool isPrimaryKey() const { return constraints() & PrimaryKey; }
/*! \return true if the field is member of single-field unique key */
inline bool isUniqueKey() const { return constraints() & Unique; }
/*! \return true if the field is member of single-field foreign key */
inline bool isForeignKey() const { return constraints() & ForeignKey; }
/*! \return true if the field is not allowed to be null */
inline bool isNotNull() const { return constraints() & NotNull; }
/*! \return true if the field is not allowed to be null */
inline bool isNotEmpty() const { return constraints() & NotEmpty; }
/*! \return true if the field is indexed using single-field database index. */
inline bool isIndexed() const { return constraints() & Indexed; }
/*! \return true if the field is of any numeric type (integer or floating point) */
inline bool isNumericType() const { return Field::isNumericType(type()); }
/*! static version of isNumericType() method
*! \return true if the field is of any numeric type (integer or floating point)*/
static bool isNumericType(uint type);
/*! \return true if the field is of any integer type */
inline bool isIntegerType() const { return Field::isIntegerType(type()); }
/*! static version of isIntegerType() method
*! \return true if the field is of any integer type */
static bool isIntegerType(uint type);
/*! \return true if the field is of any floating point numeric type */
inline bool isFPNumericType() const { return Field::isFPNumericType(type()); }
/*! static version of isFPNumericType() method
*! \return true if the field is of any floating point numeric type */
static bool isFPNumericType(uint type);
/*! \return true if the field is of any date or time related type */
inline bool isDateTimeType() const { return Field::isDateTimeType(type()); }
/*! static version of isDateTimeType() method
*! \return true if the field is of any date or time related type */
static bool isDateTimeType(uint type);
/*! @return true if the field is of any text type */
inline bool isTextType() const { return Field::isTextType(type()); }
/*! static version of isTextType() method
*! \return true if the field is of any text type */
static bool isTextType(uint type);
uint options() const { return m_options; }
void setOptions(uint options) { m_options = options; }
//! Converts field's type to TQVariant equivalent as accurate as possible
inline TQVariant::Type variantType() const { return variantType(type()); }
/*! \return a type for this field. If there's expression assigned,
type of the expression is returned instead. */
Type type() const;
//! \return a i18n'd type name for this field
inline TQString typeName() const { return Field::typeName(type()); }
//! \return type group for this field
inline TypeGroup typeGroup() const { return Field::typeGroup(type()); }
//! \return a i18n'd type group name for this field
inline TQString typeGroupName() const { return Field::typeGroupName(type()); }
//! \return a type string for this field,
//! for example "Integer" string for Field::Integer type.
inline TQString typeString() const { return Field::typeString(type()); }
//! \return a type group string for this field,
//! for example "Integer" string for Field::IntegerGroup.
inline TQString typeGroupString() const { return Field::typeGroupString(type()); }
/*! \return (optional) subtype for this field.
Subtype is a string providing additional hint for field's type.
E.g. for BLOB type, it can be a MIME type or certain TQVariant type name,
for example: TQPIXMAP_OBJECT_NAME_STRING, "TQColor" or "TQFont" */
inline TQString subType() const { return m_subType; }
/*! Sets (optional) subtype for this field.
\sa subType() */
inline void setSubType(const TQString& subType) { m_subType = subType; }
//! \return default value for this field. Null value means there
//! is no default value declared. The variant value is compatible with field's type.
inline TQVariant defaultValue() const { return m_defaultValue; }
/*! \return length of text, only meaningful if the field type is text.
0 means "default length". */
inline uint length() const { return m_length; }
/*! \return precision for numeric and other fields that have both length (scale)
and precision (floating point types). */
inline uint precision() const { return m_precision; }
/*! \return scale for numeric and other fields that have both length (scale)
and precision (floating point types).
The scale of a numeric is the count of decimal digits in the fractional part,
to the right of the decimal point. The precision of a numeric is the total count
of significant digits in the whole number, that is, the number of digits
to both sides of the decimal point. So the number 23.5141 has a precision
of 6 and a scale of 4. Integers can be considered to have a scale of zero. */
inline uint scale() const { return m_length; }
//! @todo should we keep extended properties here or move them to a TQVariant dictionary?
/*! \return number of decimal places that should be visible to the user,
e.g. within table view widget, form or printout.
Only meaningful if the field type is floating point or (in the future: decimal or currency).
- Any value less than 0 (-1 is the default) means that there should be displayed all digits
of the fractional part, except the ending zeros. This is known as "auto" mode.
For example, 12.345000 becomes 12.345.
- Value of 0 means that all the fractional part should be hidden (as well as the dot or comma).
For example, 12.345000 becomes 12.
- Value N > 0 means that the fractional part should take exactly N digits.
If the fractional part is shorter than N, additional zeros are appended.
For example, "12.345" becomes "12.345000" if N=6.
*/
inline int visibleDecimalPlaces() const { return m_visibleDecimalPlaces; }
/*! \return the constraints defined for this field. */
inline uint constraints() const { return m_constraints; }
/*! \return order of this field in containing table (counting starts from 0)
(-1 if unspecified). */
inline int order() const { return m_order; }
/*! \return caption of this field. */
inline TQString caption() const { return m_caption; }
/*! \return caption of this field or - if empty - return its name. */
inline TQString captionOrName() const { return m_caption.isEmpty() ? m_name : m_caption; }
/*! \return description text for this field. */
inline TQString description() const { return m_desc; }
/*! \return width of this field (usually in pixels or points)
0 (the default) means there is no hint for the width. */
inline uint width() const { return m_width; }
//! if the type has the unsigned attribute
inline bool isUnsigned() const { return m_options & Unsigned; }
/*! \return true if this field has EMPTY property (i.e. it is of type
string or is a BLOB). */
inline bool hasEmptyProperty() const { return Field::hasEmptyProperty(type()); }
/*! static version of hasEmptyProperty() method
\return true if this field type has EMPTY property (i.e. it is string or BLOB type) */
static bool hasEmptyProperty(uint type);
/*! \return true if this field can be auto-incremented.
Actually, returns true for integer field type. \sa IntegerType, isAutoIncrement() */
inline bool isAutoIncrementAllowed() const { return Field::isAutoIncrementAllowed(type()); }
/*! static version of isAutoIncrementAllowed() method
\return true if this field type can be auto-incremented. */
static bool isAutoIncrementAllowed(uint type);
/*! Sets type \a t for this field. This does nothing if there's already expression assigned,
see expression(). */
void setType(Type t);
/*! Sets name \a name for this field. */
void setName(const TQString& name);
/*! Sets constraints to \a c. If PrimaryKey is set in \a c, also
constraits implied by being primary key are enforced (see setPrimaryKey()).
If Indexed is not set in \a c, constraits implied by not being are
enforced as well (see setIndexed()). */
void setConstraints(uint c);
/*! Sets length for this field. Only works for Text Type (even not LongText!).
0 means "default length". @see length() */
void setLength(uint l);
/*! Sets scale for this field. Only works for floating-point types.
@see scale() */
void setScale(uint s);
/*! Sets number of decimal places that should be visible to the user.
@see visibleDecimalPlaces() */
void setVisibleDecimalPlaces(int p);
/*! Sets scale for this field. Only works for floating-point types. */
void setPrecision(uint p);
/*! Sets unsigned flag for this field. Only works for integer types. */
void setUnsigned(bool u);
/*! Sets default value for this field. Setting null value removes the default value.
@see defaultValue() */
void setDefaultValue(const TQVariant& def);
/*! Sets default value decoded from TQCString.
Decoding errors are detected (value is strictly checked against field type)
- if one is encountered, default value is cleared (defaultValue()==TQVariant()).
\return true if given value was valid for field type. */
bool setDefaultValue(const TQCString& def);
/*! Sets auto increment flag. Only available to set true,
if isAutoIncrementAllowed() is true. */
void setAutoIncrement(bool a);
/*! Specifies whether the field is single-field primary key or not
(KexiDB::PrimeryKey item).
Use this with caution. Setting this to true implies setting:
- setUniqueKey(true)
- setNotNull(true)
- setNotEmpty(true)
- setIndexed(true)
Setting this to false implies setting setAutoIncrement(false). */
void setPrimaryKey(bool p);
/*! Specifies whether the field has single-field unique constraint or not
(KexiDB::Unique item). Setting this to true implies setting Indexed flag
to true (setIndexed(true)), because index is required it control unique constraint. */
void setUniqueKey(bool u);
/*! Sets whether the field has to be declared with single-field foreign key.
Used in IndexSchema::setForeigKey(). */
void setForeignKey(bool f);
/*! Specifies whether the field has single-field unique constraint or not
(KexiDB::NotNull item). Setting this to true implies setting Indexed flag
to true (setIndexed(true)), because index is required it control
not null constraint. */
void setNotNull(bool n);
/*! Specifies whether the field has single-field unique constraint or not
(KexiDB::NotEmpty item). Setting this to true implies setting Indexed flag
to true (setIndexed(true)), because index is required it control
not empty constraint. */
void setNotEmpty(bool n);
/*! Specifies whether the field is indexed (KexiDB::Indexed item)
(by single-field implicit index) or not.
Use this with caution. Since index is used to control unique,
not null/empty constratins, setting this to false implies setting:
- setPrimaryKey(false)
- setUniqueKey(false)
- setNotNull(false)
- setNotEmpty(false)
because above flags need index to be present.
Similarly, setting one of the above flags to true, will automatically
do setIndexed(true) for the same reason. */
void setIndexed(bool s);
/*! Sets caption for this field to \a caption. */
void setCaption(const TQString& caption) { m_caption=caption; }
/*! Sets description for this field to \a description. */
void setDescription(const TQString& description) { m_desc=description; }
/*! Sets visible width for this field to \a w
(usually in pixels or points). 0 means there is no hint for the width. */
void setWidth(uint w) { m_width=w; }
/*! There can be added asterisks (QueryAsterisk objects)
to query schemas' field list. QueryAsterisk subclasses Field class,
and to check if the given object (pointed by Field*)
is asterisk or just ordinary field definition,
you can call this method. This is just effective version of TQObject::isA().
Every QueryAsterisk object returns true here,
and every Field object returns false.
*/
virtual bool isQueryAsterisk() const { return false; }
/*! \return string for debugging purposes. */
virtual TQString debugString() const;
/*! Shows debug information about this field. */
void debug();
/*! \return KexiDB::BaseExpr object if the field value is an
expression. Unless the expression is set with setExpression(), it is null.
*/
inline KexiDB::BaseExpr *expression() { return m_expr; }
/*! Sets expression data \a expr. If there was
already expression set, it is destroyed before new assignment.
This Field object becames owner of \a expr object,
so you do not have to worry about deleting it later.
If the \a expr is null, current field's expression is deleted, if exists.
Because the field defines an expression, it should be assigned to a query,
not to a table.
*/
void setExpression(KexiDB::BaseExpr *expr);
/*! \return true if there is expression defined for this field.
This method is provided for better readibility
- does the same as expression()!=NULL but */
inline bool isExpression() const { return m_expr!=NULL; }
//<TMP>
/*! \return the hints for enum fields. */
TQValueVector<TQString> enumHints() const { return m_hints; }
TQString enumHint(uint num) { return (num < m_hints.size()) ? m_hints.at(num) : TQString(); }
/*! sets the hint for enum fields */
void setEnumHints(const TQValueVector<TQString> &l) { m_hints = l; }
//</TMP>
/*! \return custom property \a propertyName.
If there is no such a property, \a defaultValue is returned. */
TQVariant customProperty(const TQCString& propertyName,
const TQVariant& defaultValue = TQVariant()) const;
//! Sets value \a value for custom property \a propertyName
void setCustomProperty(const TQCString& propertyName, const TQVariant& value);
//! A data type used for handling custom properties of a field
typedef TQMap<TQCString,TQVariant> CustomPropertiesMap;
//! \return all custom properties
inline const CustomPropertiesMap customProperties() const {
return m_customProperties ? *m_customProperties : CustomPropertiesMap(); }
protected:
/*! Creates a database field as a child of \a querySchema table
Assigns \a expr expression to this field, if present.
Used internally by query schemas, e.g. to declare asterisks or
to add expression columns.
No other properties are set, so these should be set later. */
Field(QuerySchema *querySchema, BaseExpr* expr = 0);
/*! @internal Used by constructors. */
void init();
//! \return a deep copy of this object. Used in @ref FieldList(const FieldList& fl).
virtual Field* copy() const;
FieldList *m_parent; //!< In most cases this points to a TableSchema
//!< object that field is assigned.
TQString m_name;
TQString m_subType;
uint m_constraints;
uint m_length; //!< also used for storing scale for floating point types
uint m_precision;
int m_visibleDecimalPlaces; //!< used in visibleDecimalPlaces()
uint m_options;
TQVariant m_defaultValue;
int m_order;
TQString m_caption;
TQString m_desc;
uint m_width;
TQValueVector<TQString> m_hints;
KexiDB::BaseExpr *m_expr;
CustomPropertiesMap* m_customProperties;
//! @internal Used in m_typeNames member to handle i18n'd type names
class KEXI_DB_EXPORT FieldTypeNames : public TQValueVector<TQString> {
public:
FieldTypeNames();
void init();
TQMap<TQString,Type> str2num;
protected:
bool m_initialized : 1;
};
//! @internal Used in m_typeGroupNames member to handle i18n'd type group names
class KEXI_DB_EXPORT FieldTypeGroupNames : public TQValueVector<TQString> {
public:
FieldTypeGroupNames();
void init();
TQMap<TQString,TypeGroup> str2num;
protected:
bool m_initialized : 1;
};
//! real i18n'd type names (and not-i18n'd type name strings)
static FieldTypeNames m_typeNames;
//! real i18n'd type group names (and not-i18n'd group name strings)
static FieldTypeGroupNames m_typeGroupNames;
private:
Type m_type;
friend class Connection;
friend class FieldList;
friend class TableSchema;
friend class QuerySchema;
};
} //namespace KexiDB
#endif
|