00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <kexidb/field.h>
00023 #include <kexidb/connection.h>
00024 #include <kexidb/driver.h>
00025 #include <kexidb/expression.h>
00026
00027
00028 #include <kdebug.h>
00029 #include <klocale.h>
00030
00031 #include <qdatetime.h>
00032
00033 #include <assert.h>
00034
00035 using namespace KexiDB;
00036
00037 Field::FieldTypeNames Field::m_typeNames;
00038 Field::FieldTypeGroupNames Field::m_typeGroupNames;
00039
00040 Field::Field()
00041 {
00042 init();
00043 setConstraints(NoConstraints);
00044 }
00045
00046
00047 Field::Field(TableSchema *tableSchema)
00048 {
00049 init();
00050 m_parent = tableSchema;
00051 m_order = tableSchema->fieldCount();
00052 setConstraints(NoConstraints);
00053 }
00054
00055 Field::Field(QuerySchema *querySchema, BaseExpr* expr)
00056 {
00057 init();
00058 m_parent = querySchema;
00059 m_order = querySchema->fieldCount();
00060 setConstraints(NoConstraints);
00061 if (expr)
00062 setExpression(expr);
00063 }
00064
00065 Field::Field(const QString& name, Type ctype,
00066 uint cconst, uint options, uint length, uint precision,
00067 QVariant defaultValue, const QString& caption, const QString& description,
00068 uint width)
00069 : m_parent(0)
00070 ,m_name(name.lower())
00071 ,m_length(length)
00072 ,m_precision(precision)
00073 ,m_options(options)
00074 ,m_defaultValue(defaultValue)
00075 ,m_order(-1)
00076 ,m_caption(caption)
00077 ,m_desc(description)
00078 ,m_width(width)
00079 ,m_expr(0)
00080 ,m_type(ctype)
00081 {
00082 setConstraints(cconst);
00083 if (m_length==0) {
00084 if (m_type==Field::Text)
00085 m_length = defaultTextLength();
00086 }
00087 }
00088
00090 Field::Field(const Field& f)
00091 {
00092 (*this) = f;
00093 if (f.m_expr) {
00094
00095
00096
00097 } else
00098 m_expr = 0;
00099 }
00100
00101 Field::~Field()
00102 {
00103 delete m_expr;
00104 }
00105
00106 void Field::init()
00107 {
00108 m_parent = 0;
00109 m_name = "";
00110 m_type = InvalidType;
00111 m_length = 0;
00112 m_precision = 0;
00113 m_options = NoOptions;
00114 m_defaultValue = QVariant(QString::null);
00115 m_order = -1;
00116 m_width = 0;
00117 m_expr = 0;
00118 }
00119
00120 Field::Type Field::type() const
00121 {
00122 if (m_expr)
00123 return m_expr->type();
00124 return m_type;
00125 }
00126
00127 QVariant::Type Field::variantType(uint type)
00128 {
00129 switch(type)
00130 {
00131 case Byte:
00132 case ShortInteger:
00133 case Integer:
00134 case BigInteger:
00135
00136 return QVariant::Int;
00137 case Boolean:
00138 return QVariant::Bool;
00139 case Date:
00140 return QVariant::Date;
00141 case DateTime:
00142 return QVariant::DateTime;
00143 case Time:
00144 return QVariant::Time;
00145 case Float:
00146 case Double:
00147 return QVariant::Double;
00148 case Text:
00149 case LongText:
00150 return QVariant::String;
00151 case BLOB:
00152 return QVariant::ByteArray;
00153 default:
00154 return QVariant::Invalid;
00155 }
00156
00157 return QVariant::Invalid;
00158 }
00159
00160 QString Field::typeName(uint type)
00161 {
00162 m_typeNames.init();
00163 return (type <= LastType) ? m_typeNames.at(type) : QString::number(type);
00164 }
00165
00166 QString Field::typeString(uint type)
00167 {
00168 m_typeNames.init();
00169 return (type <= LastType) ? m_typeNames.at((int)LastType+1 + type) : QString("Type%1").arg(type);
00170 }
00171
00172 QString Field::typeGroupName(uint typeGroup)
00173 {
00174 m_typeGroupNames.init();
00175 return (typeGroup <= LastTypeGroup) ? m_typeGroupNames.at(typeGroup) : typeGroupString(typeGroup);
00176 }
00177
00178 QString Field::typeGroupString(uint typeGroup)
00179 {
00180 m_typeGroupNames.init();
00181 return (typeGroup <= LastTypeGroup) ? m_typeGroupNames.at((int)LastTypeGroup+1 + typeGroup) : QString("TypeGroup%1").arg(typeGroup);
00182 }
00183
00184 Field::Type Field::typeForString(const QString typeString)
00185 {
00186 m_typeNames.init();
00187 if (m_typeNames.str2num.find(typeString)==m_typeNames.str2num.end())
00188 return InvalidType;
00189 return m_typeNames.str2num[typeString];
00190 }
00191
00192 Field::TypeGroup Field::typeGroupForString(const QString typeGroupString)
00193 {
00194 m_typeGroupNames.init();
00195 if (m_typeGroupNames.str2num.find(typeGroupString)==m_typeGroupNames.str2num.end())
00196 return InvalidGroup;
00197 return m_typeGroupNames.str2num[typeGroupString];
00198 }
00199
00200 bool Field::isIntegerType( uint type )
00201 {
00202 switch (type) {
00203 case Field::Byte:
00204 case Field::ShortInteger:
00205 case Field::Integer:
00206 case Field::BigInteger:
00207 return true;
00208 default:;
00209 }
00210 return false;
00211 }
00212
00213 bool Field::isNumericType( uint type )
00214 {
00215 switch (type) {
00216 case Field::Byte:
00217 case Field::ShortInteger:
00218 case Field::Integer:
00219 case Field::BigInteger:
00220 case Field::Float:
00221 case Field::Double:
00222 return true;
00223 default:;
00224 }
00225 return false;
00226 }
00227
00228 bool Field::isFPNumericType( uint type )
00229 {
00230 return type==Field::Float || type==Field::Double;
00231 }
00232
00233 bool Field::isDateTimeType(uint type)
00234 {
00235 switch (type) {
00236 case Field::Date:
00237 case Field::DateTime:
00238 case Field::Time:
00239 return true;
00240 default:;
00241 }
00242 return false;
00243 }
00244
00245 bool Field::isTextType( uint type )
00246 {
00247 switch (type) {
00248 case Field::Text:
00249 case Field::LongText:
00250 return true;
00251 default:;
00252 }
00253 return false;
00254 }
00255
00256 bool Field::hasEmptyProperty(uint type)
00257 {
00258 return Field::isTextType(type) || type==BLOB;
00259 }
00260
00261 bool Field::isAutoIncrementAllowed(uint type)
00262 {
00263 return Field::isIntegerType(type);
00264 }
00265
00266 Field::TypeGroup Field::typeGroup(uint type)
00267 {
00268 if (Field::isTextType(type))
00269 return TextGroup;
00270 else if (Field::isIntegerType(type))
00271 return IntegerGroup;
00272 else if (Field::isFPNumericType(type))
00273 return FloatGroup;
00274 else if (type==Boolean)
00275 return BooleanGroup;
00276 else if (Field::isDateTimeType(type))
00277 return DateTimeGroup;
00278 else if (type==BLOB)
00279 return BLOBGroup;
00280
00281 return InvalidGroup;
00282 }
00283
00284 TableSchema*
00285 Field::table() const
00286 {
00287 return dynamic_cast<TableSchema*>(m_parent);
00288 }
00289
00290 void
00291 Field::setTable(TableSchema *tableSchema)
00292 {
00293 m_parent = tableSchema;
00294 }
00295
00296 QuerySchema*
00297 Field::query() const
00298 {
00299 return dynamic_cast<QuerySchema*>(m_parent);
00300 }
00301
00302 void
00303 Field::setQuery(QuerySchema *querySchema)
00304 {
00305 m_parent = querySchema;
00306 }
00307
00308 void
00309 Field::setName(const QString& n)
00310 {
00311 m_name = n.lower();
00312 }
00313
00314 void
00315 Field::setType(Type t)
00316 {
00317 if (m_expr) {
00318 KexiDBWarn << QString("Field::setType(%1)").arg(t)
00319 << " could not set type because the field has expression assigned!" << endl;
00320 return;
00321 }
00322 m_type = t;
00323 }
00324
00325 void
00326 Field::setConstraints(uint c)
00327 {
00328 m_constraints = c;
00329
00330 if (isPrimaryKey()) {
00331 setPrimaryKey(true);
00332 }
00333 if (isIndexed()) {
00334 setIndexed(true);
00335 }
00336 if (isAutoIncrement() && !isAutoIncrementAllowed()) {
00337 setAutoIncrement(false);
00338 }
00339 }
00340
00341 void
00342 Field::setLength(uint l)
00343 {
00344 if (type()!=Field::Text)
00345 return;
00346 m_length = l;
00347 }
00348
00349 void
00350 Field::setPrecision(uint p)
00351 {
00352 if (!isFPNumericType())
00353 return;
00354 m_precision = p;
00355 }
00356
00357 void
00358 Field::setScale(uint s)
00359 {
00360 if (!isFPNumericType())
00361 return;
00362 m_length = s;
00363 }
00364
00365 void
00366 Field::setUnsigned(bool u)
00367 {
00368 m_options |= Unsigned;
00369 m_options ^= (!u * Unsigned);
00370 }
00371
00372 void
00373 Field::setDefaultValue(const QVariant& def)
00374 {
00375 m_defaultValue = def;
00376 }
00377
00378 bool
00379 Field::setDefaultValue(const QCString& def)
00380 {
00381 if (def.isNull()) {
00382 m_defaultValue = QVariant();
00383 return true;
00384 }
00385
00386 bool ok;
00387 switch(type())
00388 {
00389 case Byte: {
00390 unsigned int v = def.toUInt(&ok);
00391 if (!ok || v > 255)
00392 m_defaultValue = QVariant();
00393 else
00394 m_defaultValue = QVariant(v);
00395 break;
00396 }case ShortInteger: {
00397 int v = def.toInt(&ok);
00398 if (!ok || (!(m_options & Unsigned) && (v < -32768 || v > 32768)) || ((m_options & Unsigned) && (v < 0 || v > 65535)))
00399 m_defaultValue = QVariant();
00400 else
00401 m_defaultValue = QVariant(v);
00402 break;
00403 }case Integer: {
00404 long v = def.toLong(&ok);
00405
00406 if (!ok || (!(m_options & Unsigned) && (-v > (int)0x07FFFFFFF || v > (int)(0x080000000-1))))
00407 m_defaultValue = QVariant();
00408 else
00409 m_defaultValue = QVariant((Q_LLONG)v);
00410 break;
00411 }case BigInteger: {
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 break;
00424 }case Boolean: {
00425 unsigned short v = def.toUShort(&ok);
00426 if (!ok || v > 1)
00427 m_defaultValue = QVariant();
00428 else
00429 m_defaultValue = QVariant((bool)v);
00430 break;
00431 }case Date: {
00432 QDate date = QDate::fromString( def, Qt::ISODate );
00433 if (!date.isValid())
00434 m_defaultValue = QVariant();
00435 else
00436 m_defaultValue = QVariant(date);
00437 break;
00438 }case DateTime: {
00439 QDateTime dt = QDateTime::fromString( def, Qt::ISODate );
00440 if (!dt.isValid())
00441 m_defaultValue = QVariant();
00442 else
00443 m_defaultValue = QVariant(dt);
00444 break;
00445 }case Time: {
00446 QTime time = QTime::fromString( def, Qt::ISODate );
00447 if (!time.isValid())
00448 m_defaultValue = QVariant();
00449 else
00450 m_defaultValue = QVariant(time);
00451 break;
00452 }case Float: {
00453 float v = def.toFloat(&ok);
00454 if (!ok || ((m_options & Unsigned) && (v < 0.0)))
00455 m_defaultValue = QVariant();
00456 else
00457 m_defaultValue = QVariant(v);
00458 break;
00459 }case Double: {
00460 double v = def.toDouble(&ok);
00461 if (!ok || ((m_options & Unsigned) && (v < 0.0)))
00462 m_defaultValue = QVariant();
00463 else
00464 m_defaultValue = QVariant(v);
00465 break;
00466 }case Text: {
00467 if (def.isNull() || (def.length() > 255))
00468 m_defaultValue = QVariant();
00469 else
00470 m_defaultValue = QVariant((QString)def);
00471 break;
00472 }case LongText: {
00473 if (def.isNull())
00474 m_defaultValue = QVariant();
00475 else
00476 m_defaultValue = QVariant((QString)def);
00477 break;
00478 }case BLOB: {
00479
00480 if (def.isNull())
00481 m_defaultValue = QVariant();
00482 else
00483 m_defaultValue = QVariant(def);
00484 break;
00485 }default:
00486 m_defaultValue = QVariant();
00487 }
00488 return m_defaultValue.isNull();
00489 }
00490
00491 void
00492 Field::setAutoIncrement(bool a)
00493 {
00494 if (a && !isAutoIncrementAllowed())
00495 return;
00496 if (isAutoIncrement() != a)
00497 m_constraints = static_cast<Field::Constraints>(m_constraints ^ Field::AutoInc);
00498 }
00499
00500 void
00501 Field::setPrimaryKey(bool p)
00502 {
00503 if(isPrimaryKey() != p)
00504 m_constraints = static_cast<Field::Constraints>(m_constraints ^ Field::PrimaryKey);
00505 if (p) {
00506 setUniqueKey(true);
00507 setNotNull(true);
00508 setNotEmpty(true);
00509 setIndexed(true);
00510 }
00511 else {
00513 setAutoIncrement(false);
00514 }
00515 }
00516
00517 void
00518 Field::setUniqueKey(bool u)
00519 {
00520 if(isUniqueKey() != u) {
00521 m_constraints = static_cast<Field::Constraints>(m_constraints ^ Field::Unique);
00522 if (u)
00523 setNotNull(true);
00524 }
00525 }
00526
00527 void
00528 Field::setForeignKey(bool f)
00529 {
00530 if (isForeignKey() != f)
00531 m_constraints = static_cast<Field::Constraints>(m_constraints ^ Field::ForeignKey);
00532 }
00533
00534 void
00535 Field::setNotNull(bool n)
00536 {
00537 if (isNotNull() != n)
00538 m_constraints = static_cast<Field::Constraints>(m_constraints ^ Field::NotNull);
00539 }
00540
00541 void Field::setNotEmpty(bool n)
00542 {
00543 if (isNotEmpty() != n)
00544 m_constraints = static_cast<Field::Constraints>(m_constraints ^ Field::NotEmpty);
00545 }
00546
00547 void Field::setIndexed(bool s)
00548 {
00549 if (isIndexed() != s)
00550 m_constraints = static_cast<Field::Constraints>(m_constraints ^ Field::Indexed);
00551 if (!s) {
00552 setPrimaryKey(false);
00553 setUniqueKey(false);
00554 setNotNull(false);
00555 setNotEmpty(false);
00556 }
00557 }
00558
00559
00560 QString Field::debugString()
00561 {
00562 KexiDB::Connection *conn = table() ? table()->connection() : 0;
00563 QString dbg = (m_name.isEmpty() ? "<NONAME> " : m_name + " ");
00564 if (m_options & Field::Unsigned)
00565 dbg += " UNSIGNED ";
00566 dbg += (conn && conn->driver()) ? conn->driver()->sqlTypeName(type()) : Driver::defaultSQLTypeName(type());
00567 if (isFPNumericType() && m_precision>0) {
00568 if (scale()>0)
00569 dbg += QString::fromLatin1("(%1,%2)").arg(m_precision).arg(scale());
00570 else
00571 dbg += QString::fromLatin1("(%1)").arg(m_precision);
00572 }
00573 else if (m_type==Field::Text && m_length>0)
00574 dbg += QString::fromLatin1("(%1)").arg(m_length);
00575 if (m_constraints & Field::AutoInc)
00576 dbg += " AUTOINC";
00577 if (m_constraints & Field::Unique)
00578 dbg += " UNIQUE";
00579 if (m_constraints & Field::PrimaryKey)
00580 dbg += " PKEY";
00581 if (m_constraints & Field::ForeignKey)
00582 dbg += " FKEY";
00583 if (m_constraints & Field::NotNull)
00584 dbg += " NOTNULL";
00585 if (m_constraints & Field::NotEmpty)
00586 dbg += " NOTEMPTY";
00587 if (m_expr)
00588 dbg += " EXPRESSION=" + m_expr->debugString();
00589 return dbg;
00590 }
00591
00592 void Field::debug()
00593 {
00594 KexiDBDbg << debugString() << endl;
00595 }
00596
00597 void Field::setExpression(KexiDB::BaseExpr *expr)
00598 {
00599 assert(!m_parent || dynamic_cast<QuerySchema*>(m_parent));
00600 if (m_expr==expr)
00601 return;
00602 if (m_expr) {
00603 delete m_expr;
00604 }
00605 m_expr = expr;
00606 }
00607
00608
00609 #define ADDTYPE(type, i18, str) this->at(Field::type) = i18; \
00610 this->at(Field::type+Field::LastType+1) = str; \
00611 str2num.insert(str, type)
00612 #define ADDGROUP(type, i18, str) this->at(Field::type) = i18; \
00613 this->at(Field::type+Field::LastTypeGroup+1) = str; \
00614 str2num.insert(str, type)
00615
00616 Field::FieldTypeNames::FieldTypeNames()
00617 : QValueVector<QString>()
00618 , m_initialized(false)
00619 {
00620 }
00621
00622 void Field::FieldTypeNames::init()
00623 {
00624 if (m_initialized)
00625 return;
00626 m_initialized = true;
00627 resize((Field::LastType + 1)*2);
00628
00629 ADDTYPE( InvalidType, i18n("Invalid Type"), "InvalidType" );
00630 ADDTYPE( Byte, i18n("Byte"), "Byte" );
00631 ADDTYPE( ShortInteger, i18n("Short Integer Number"), "ShortInteger" );
00632 ADDTYPE( Integer, i18n("Integer Number"), "Integer" );
00633 ADDTYPE( BigInteger, i18n("Big Integer Number"), "BigInteger" );
00634 ADDTYPE( Boolean, i18n("Yes/No Value"), "Boolean" );
00635 ADDTYPE( Date, i18n("Date"), "Date" );
00636 ADDTYPE( DateTime, i18n("Date and Time"), "DateTime" );
00637 ADDTYPE( Time, i18n("Time"), "Time" );
00638 ADDTYPE( Float, i18n("Single Precision Number"), "Float" );
00639 ADDTYPE( Double, i18n("Double Precision Number"), "Double" );
00640 ADDTYPE( Text, i18n("Text"), "Text" );
00641 ADDTYPE( LongText, i18n("Long Text"), "LongText" );
00642 ADDTYPE( BLOB, i18n("Object"), "BLOB" );
00643 }
00644
00645
00646
00647 Field::FieldTypeGroupNames::FieldTypeGroupNames()
00648 : QValueVector<QString>()
00649 , m_initialized(false)
00650 {
00651 }
00652
00653 void Field::FieldTypeGroupNames::init()
00654 {
00655 if (m_initialized)
00656 return;
00657 m_initialized = true;
00658 resize((Field::LastTypeGroup + 1)*2);
00659
00660 ADDGROUP( InvalidGroup, i18n("Invalid Group"), "InvalidGroup" );
00661 ADDGROUP( TextGroup, i18n("Text"), "TextGroup" );
00662 ADDGROUP( IntegerGroup, i18n("Integer Number"), "IntegerGroup" );
00663 ADDGROUP( FloatGroup, i18n("Floating Point Number"), "FloatGroup" );
00664 ADDGROUP( BooleanGroup, i18n("Yes/No"), "BooleanGroup" );
00665 ADDGROUP( DateTimeGroup, i18n("Date/Time"), "DateTimeGroup" );
00666 ADDGROUP( BLOBGroup, i18n("Object"), "BLOBGroup" );
00667 }
00668
00669
00670