File indexing completed on 2024-04-14 14:53:09

0001 /* This file is part of the KDE project
0002    Copyright (C) 2003-2018 Jarosław Staniek <staniek@kde.org>
0003 
0004    Based on nexp.cpp : Parser module of Python-like language
0005    (C) 2001 Jarosław Staniek, MIMUW (www.mimuw.edu.pl)
0006 
0007    This library is free software; you can redistribute it and/or
0008    modify it under the terms of the GNU Library General Public
0009    License as published by the Free Software Foundation; either
0010    version 2 of the License, or (at your option) any later version.
0011 
0012    This library is distributed in the hope that it will be useful,
0013    but WITHOUT ANY WARRANTY; without even the implied warranty of
0014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015    Library General Public License for more details.
0016 
0017    You should have received a copy of the GNU Library General Public License
0018    along with this library; see the file COPYING.LIB.  If not, write to
0019    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020  * Boston, MA 02110-1301, USA.
0021  */
0022 
0023 #include "KDbExpression.h"
0024 #include "KDb.h"
0025 #include "KDbQuerySchema.h"
0026 #include "KDbDriver.h"
0027 #include "kdb_debug.h"
0028 #include "generated/sqlparser.h"
0029 
0030 #include <QPoint>
0031 
0032 KDbConstExpressionData::KDbConstExpressionData(const QVariant& aValue)
0033  : KDbExpressionData()
0034  , value(aValue)
0035 {
0036     ExpressionDebug << "ConstExpressionData" << ref;
0037 }
0038 
0039 KDbConstExpressionData::~KDbConstExpressionData()
0040 {
0041     ExpressionDebug << "~ConstExpressionData" << ref;
0042 }
0043 
0044 KDbConstExpressionData* KDbConstExpressionData::clone()
0045 {
0046     ExpressionDebug << "ConstExpressionData::clone" << *this;
0047     return new KDbConstExpressionData(*this);
0048 }
0049 
0050 KDbField::Type KDbConstExpressionData::typeInternal(KDb::ExpressionCallStack* callStack) const
0051 {
0052     Q_UNUSED(callStack);
0053     switch (token.value()) {
0054     case SQL_NULL:
0055         return KDbField::Null;
0056     case INTEGER_CONST:
0057 //! @todo ok?
0058 //! @todo add sign info?
0059         if (value.type() == QVariant::Int || value.type() == QVariant::UInt) {
0060             qint64 v = value.toInt();
0061             if (v <= 0xff && v > -0x80)
0062                 return KDbField::Byte;
0063             if (v <= 0xffff && v > -0x8000)
0064                 return KDbField::ShortInteger;
0065             return KDbField::Integer;
0066         }
0067         return KDbField::BigInteger;
0068     case CHARACTER_STRING_LITERAL:
0069         if (KDbField::defaultMaxLength() > 0
0070             && value.toString().length() > KDbField::defaultMaxLength())
0071         {
0072             return KDbField::LongText;
0073         }
0074         else {
0075             return KDbField::Text;
0076         }
0077     case SQL_TRUE:
0078     case SQL_FALSE:
0079         return KDbField::Boolean;
0080     case REAL_CONST:
0081         return KDbField::Double;
0082     case DATE_CONST:
0083         if (value.canConvert<KDbDate>() && value.value<KDbDate>().isValid()) {
0084             return KDbField::Date;
0085         } else if (value.canConvert<QDate>() && value.toDate().isValid()) {
0086             return KDbField::Date;
0087         }
0088         break;
0089     case DATETIME_CONST:
0090         if (value.canConvert<KDbDateTime>() && value.value<KDbDateTime>().isValid()) {
0091             return KDbField::DateTime;
0092         } else if (value.canConvert<QDateTime>() && value.toDateTime().isValid()) {
0093             return KDbField::DateTime;
0094         }
0095         break;
0096     case TIME_CONST:
0097         if (value.canConvert<KDbTime>() && value.value<KDbTime>().isValid()) {
0098             return KDbField::Time;
0099         } else if (value.canConvert<QTime>() && value.toTime().isValid()) {
0100             return KDbField::Time;
0101         }
0102         break;
0103     }
0104     return KDbField::InvalidType;
0105 }
0106 
0107 void KDbConstExpressionData::debugInternal(QDebug dbg, KDb::ExpressionCallStack* callStack) const
0108 {
0109     Q_UNUSED(callStack);
0110     QString res = QLatin1String("ConstExp(")
0111         + token.name()
0112         + QLatin1String(",") + toString(nullptr).toString()
0113         + QString::fromLatin1(",type=%1").arg(KDbDriver::defaultSqlTypeName(type()));
0114     if (value.type() == QVariant::Point && token.value() == REAL_CONST) {
0115         res += QLatin1String(",DECIMAL");
0116     }
0117     res += QLatin1String(")");
0118     dbg.nospace() << qPrintable(res);
0119 }
0120 
0121 KDbEscapedString KDbConstExpressionData::toStringInternal(
0122                                         const KDbDriver *driver,
0123                                         KDbQuerySchemaParameterValueListIterator* params,
0124                                         KDb::ExpressionCallStack* callStack) const
0125 {
0126     Q_UNUSED(params);
0127     Q_UNUSED(callStack);
0128     switch (token.value()) {
0129     case SQL_NULL:
0130         return KDb::valueToSql(driver, KDbField::Null, QVariant());
0131     case CHARACTER_STRING_LITERAL:
0132 //! @todo better escaping!
0133         return KDb::valueToSql(driver, KDbField::Text, value);
0134     case SQL_TRUE:
0135         return KDb::valueToSql(driver, KDbField::Boolean, 1);
0136     case SQL_FALSE:
0137         return KDb::valueToSql(driver, KDbField::Boolean, 0);
0138     case REAL_CONST:
0139         return KDbEscapedString(value.toByteArray());
0140     case DATE_CONST:
0141         return KDb::valueToSql(driver, KDbField::Date, value);
0142     case DATETIME_CONST:
0143         return KDb::valueToSql(driver, KDbField::Date, value);
0144     case TIME_CONST:
0145         return KDb::valueToSql(driver, KDbField::Time, value);
0146     case INTEGER_CONST:
0147     default:
0148         break;
0149     }
0150     return KDbEscapedString(value.toByteArray());
0151 }
0152 
0153 void KDbConstExpressionData::getQueryParameters(QList<KDbQuerySchemaParameter>* params)
0154 {
0155     Q_UNUSED(params);
0156 }
0157 
0158 bool KDbConstExpressionData::validateInternal(KDbParseInfo *parseInfo, KDb::ExpressionCallStack* callStack)
0159 {
0160     Q_UNUSED(parseInfo);
0161     return typeInternal(callStack) != KDbField::InvalidType;
0162 }
0163 
0164 //=========================================
0165 
0166 KDbConstExpression::KDbConstExpression()
0167  : KDbExpression(new KDbConstExpressionData(QVariant()))
0168 {
0169     ExpressionDebug << "KDbConstExpression() ctor" << *this;
0170 }
0171 
0172 KDbConstExpression::KDbConstExpression(KDbToken token, const QVariant& value)
0173         : KDbExpression(new KDbConstExpressionData(value), KDb::ConstExpression, token)
0174 {
0175 }
0176 
0177 KDbConstExpression::KDbConstExpression(KDbExpressionData* data, KDb::ExpressionClass aClass,
0178                                        KDbToken token)
0179         : KDbExpression(data, aClass, token)
0180 {
0181 }
0182 
0183 KDbConstExpression::KDbConstExpression(KDbExpressionData* data)
0184     : KDbExpression(data)
0185 {
0186 }
0187 
0188 KDbConstExpression::KDbConstExpression(const ExplicitlySharedExpressionDataPointer &ptr)
0189     : KDbExpression(ptr)
0190 {
0191 }
0192 
0193 KDbConstExpression::KDbConstExpression(const KDbConstExpression& expr)
0194         : KDbExpression(expr)
0195 {
0196 }
0197 
0198 KDbConstExpression::~KDbConstExpression()
0199 {
0200 }
0201 
0202 QVariant KDbConstExpression::value() const
0203 {
0204     return d->convert<const KDbConstExpressionData>()->value;
0205 }
0206 
0207 void KDbConstExpression::setValue(const QVariant& value)
0208 {
0209     d->convert<KDbConstExpressionData>()->value = value;
0210 }