24 #include <QDataStream>
27 #include <QJsonDocument>
38 : mName( nam ), mType( typ ), mLength( len ), mPrecision( prec ), mNumeric( num )
49 const QString &
typeName,
int len,
int prec,
const QString &comment, QVariant::Type subType )
76 return *( other.d ) == *d;
81 return !( *
this == other );
91 if ( !d->alias.isEmpty() )
99 if (
alias().isEmpty() )
103 return QStringLiteral(
"%1 (%2)" ).arg(
name() ).arg(
alias() );
111 typeStr += QStringLiteral(
"(%1, %2)" ).arg(
length() ).arg(
precision() );
113 typeStr += QStringLiteral(
"(%1)" ).arg(
length() );
115 if ( showConstraints )
118 ? QStringLiteral(
" NOT NULL" )
119 : QStringLiteral(
" NULL" );
122 ? QStringLiteral(
" UNIQUE" )
161 return d->type == QVariant::Double || d->type == QVariant::Int || d->type == QVariant::UInt || d->type == QVariant::LongLong || d->type == QVariant::ULongLong;
166 return d->type == QVariant::Date || d->type == QVariant::Time || d->type == QVariant::DateTime;
211 return d->defaultValueDefinition;
226 return d->constraints;
262 if ( v.userType() == QMetaType::type(
"QgsReferencedGeometry" ) )
269 QString wkt = geom.
asWkt();
270 if ( wkt.length() >= 1050 )
272 wkt = wkt.left( 999 ) + QChar( 0x2026 );
275 return formattedText;
280 if ( d->type == QVariant::Double )
290 if ( QLocale().decimalPoint() !=
'.' ||
291 !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
293 if ( d->precision > 0 )
295 if ( -1 < v.toDouble() && v.toDouble() < 1 )
297 return QLocale().toString( v.toDouble(),
'g', d->precision );
301 return QLocale().toString( v.toDouble(),
'f', d->precision );
308 const QString s( v.toString() );
309 const int dotPosition( s.indexOf(
'.' ) );
311 if ( dotPosition < 0 && s.indexOf(
'e' ) < 0 )
314 return QLocale().toString( v.toDouble(),
'f',
precision );
319 else precision = s.length() - dotPosition - 1;
321 if ( -1 < v.toDouble() && v.toDouble() < 1 )
323 return QLocale().toString( v.toDouble(),
'g',
precision );
327 return QLocale().toString( v.toDouble(),
'f',
precision );
333 else if ( d->precision > 0 )
335 if ( -1 < v.toDouble() && v.toDouble() < 1 )
337 return QString::number( v.toDouble(),
'g', d->precision );
341 return QString::number( v.toDouble(),
'f', d->precision );
347 !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
350 const qlonglong converted( v.toLongLong( &ok ) );
352 return QLocale().toString( converted );
354 else if ( d->typeName.compare( QLatin1String(
"json" ), Qt::CaseInsensitive ) == 0 || d->typeName == QLatin1String(
"jsonb" ) )
356 const QJsonDocument doc = QJsonDocument::fromVariant( v );
357 return QString::fromUtf8( doc.toJson().data() );
359 else if ( d->type == QVariant::ByteArray )
361 return QObject::tr(
"BLOB" );
363 else if ( d->type == QVariant::StringList || d->type == QVariant::List )
366 const QVariantList list = v.toList();
367 for (
const QVariant &var : list )
369 if ( !result.isEmpty() )
370 result.append( QStringLiteral(
", " ) );
371 result.append( var.toString() );
385 return QObject::tr(
"None" );
387 return QObject::tr(
"Not searchable" );
389 return QObject::tr(
"Do not expose via WMS" );
391 return QObject::tr(
"Do not expose via WFS" );
404 const QVariant original = v;
406 errorMessage->clear();
410 v.convert( d->type );
414 if ( d->type == QVariant::Int && v.toInt() != v.toLongLong() )
416 v = QVariant( d->type );
418 *errorMessage = QObject::tr(
"Value \"%1\" is too large for integer field" ).arg( original.toLongLong() );
424 if ( d->type == QVariant::Double && v.type() == QVariant::String )
427 if ( !tmp.convert( d->type ) )
438 if ( QLocale().decimalPoint() !=
'.' )
440 d = QLocale( QLocale::C ).toDouble( v.toString(), &ok );
451 if ( d->type == QVariant::Int && v.type() == QVariant::String )
454 if ( !tmp.convert( d->type ) )
468 if ( d->type == QVariant::LongLong && v.type() == QVariant::String )
471 if ( !tmp.convert( d->type ) )
486 if ( d->type == QVariant::Int && v.canConvert( QVariant::Double ) )
489 const double dbl = v.toDouble( &ok );
493 v = QVariant( d->type );
496 *errorMessage = QObject::tr(
"Value \"%1\" is not a number" ).arg( original.toString() );
501 const double round = std::round( dbl );
502 if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
505 v = QVariant( d->type );
508 *errorMessage = QObject::tr(
"Value \"%1\" is too large for integer field" ).arg( original.toDouble() );
512 v = QVariant(
static_cast< int >( std::round( dbl ) ) );
518 if ( d->type == QVariant::LongLong && v.canConvert( QVariant::Double ) )
522 if ( !tmp.convert( d->type ) )
525 const double dbl = v.toDouble( &ok );
529 v = QVariant( d->type );
532 *errorMessage = QObject::tr(
"Value \"%1\" is not a number" ).arg( original.toString() );
537 const double round = std::round( dbl );
538 if ( round >
static_cast<double>( std::numeric_limits<long long>::max() ) || round <
static_cast<double>( -std::numeric_limits<long long>::max() ) )
541 v = QVariant( d->type );
544 *errorMessage = QObject::tr(
"Value \"%1\" is too large for long long field" ).arg( original.toDouble() );
548 v = QVariant(
static_cast< long long >( std::round( dbl ) ) );
553 if ( d->type == QVariant::String && ( d->typeName.compare( QLatin1String(
"json" ), Qt::CaseInsensitive ) == 0 || d->typeName == QLatin1String(
"jsonb" ) ) )
555 const QJsonDocument doc = QJsonDocument::fromVariant( v );
558 v = QString::fromUtf8( doc.toJson( QJsonDocument::Compact ).constData() );
561 v = QVariant( d->type );
565 if ( !v.convert( d->type ) )
567 v = QVariant( d->type );
570 *errorMessage = QObject::tr(
"Could not convert value \"%1\" to target type" ).arg( original.toString() );
575 if ( d->type == QVariant::Double && d->precision > 0 )
577 const double s = std::pow( 10, d->precision );
578 const double d = v.toDouble() * s;
579 v = QVariant( ( d < 0 ? std::ceil( d - 0.5 ) : std::floor( d + 0.5 ) ) / s );
583 if ( d->type == QVariant::String && d->length > 0 && v.toString().length() > d->length )
585 const int length = v.toString().length();
586 v = v.toString().left( d->length );
589 *errorMessage = QObject::tr(
"String of length %1 exceeds maximum field length (%2)" ).arg(
length ).arg( d->length );
599 d->editorWidgetSetup = v;
604 return d->editorWidgetSetup;
609 d->isReadOnly = readOnly;
614 return d->isReadOnly;
627 out << static_cast< quint32 >(
field.
type() );
655 quint32 originNotNull;
656 quint32 originUnique;
657 quint32 originExpression;
658 quint32 strengthNotNull;
659 quint32 strengthUnique;
660 quint32 strengthExpression;
668 QString defaultValueExpression;
669 QString constraintExpression;
670 QString constraintDescription;
673 >> defaultValueExpression >> applyOnUpdate >> constraints >> originNotNull >> originUnique >> originExpression >> strengthNotNull >> strengthUnique >> strengthExpression >>
674 constraintExpression >> constraintDescription >> subType;