Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsfield.cpp - Describes a field in a layer or table
3 : : --------------------------------------
4 : : Date : 01-Jan-2004
5 : : Copyright : (C) 2004 by Gary E.Sherman
6 : : email : sherman at mrcc.com
7 : :
8 : : ***************************************************************************
9 : : * *
10 : : * This program is free software; you can redistribute it and/or modify *
11 : : * it under the terms of the GNU General Public License as published by *
12 : : * the Free Software Foundation; either version 2 of the License, or *
13 : : * (at your option) any later version. *
14 : : * *
15 : : ***************************************************************************/
16 : :
17 : : #include "qgsfields.h"
18 : : #include "qgsfield_p.h"
19 : : #include "qgis.h"
20 : : #include "qgsapplication.h"
21 : : #include "qgssettings.h"
22 : :
23 : : #include <QDataStream>
24 : : #include <QIcon>
25 : : #include <QLocale>
26 : : #include <QJsonDocument>
27 : :
28 : : /***************************************************************************
29 : : * This class is considered CRITICAL and any change MUST be accompanied with
30 : : * full unit tests in testqgsfield.cpp.
31 : : * See details in QEP #17
32 : : ****************************************************************************/
33 : :
34 : : #if 0
35 : : QgsField::QgsField( QString nam, QString typ, int len, int prec, bool num,
36 : : QString comment )
37 : : : mName( nam ), mType( typ ), mLength( len ), mPrecision( prec ), mNumeric( num )
38 : : , mComment( comment )
39 : : {
40 : : // This function used to lower case the field name since some stores
41 : : // use upper case (e.g., shapefiles), but that caused problems with
42 : : // attribute actions getting confused between uppercase and
43 : : // lowercase versions of the attribute names, so just leave the
44 : : // names how they are now.
45 : : }
46 : : #endif
47 : 246 : QgsField::QgsField( const QString &name, QVariant::Type type,
48 : : const QString &typeName, int len, int prec, const QString &comment, QVariant::Type subType )
49 : 246 : {
50 : 246 : d = new QgsFieldPrivate( name, type, subType, typeName, len, prec, comment );
51 : 246 : }
52 : :
53 : 2895 : QgsField::QgsField( const QgsField &other ) //NOLINT
54 : 2895 : : d( other.d )
55 : 2895 : {
56 : :
57 : 2895 : }
58 : :
59 : 3129 : QgsField::~QgsField() = default;
60 : :
61 : : /***************************************************************************
62 : : * This class is considered CRITICAL and any change MUST be accompanied with
63 : : * full unit tests in testqgsfield.cpp.
64 : : * See details in QEP #17
65 : : ****************************************************************************/
66 : :
67 : 0 : QgsField &QgsField::operator =( const QgsField &other ) //NOLINT
68 : : {
69 : 0 : d = other.d;
70 : 0 : return *this;
71 : : }
72 : :
73 : 0 : bool QgsField::operator==( const QgsField &other ) const
74 : : {
75 : 0 : return *( other.d ) == *d;
76 : : }
77 : :
78 : 0 : bool QgsField::operator!=( const QgsField &other ) const
79 : : {
80 : 0 : return !( *this == other );
81 : : }
82 : :
83 : 1012 : QString QgsField::name() const
84 : : {
85 : 1012 : return d->name;
86 : : }
87 : :
88 : 0 : QString QgsField::displayName() const
89 : : {
90 : 0 : if ( !d->alias.isEmpty() )
91 : 0 : return d->alias;
92 : : else
93 : 0 : return d->name;
94 : 0 : }
95 : :
96 : 0 : QString QgsField::displayNameWithAlias() const
97 : : {
98 : 0 : if ( alias().isEmpty() )
99 : : {
100 : 0 : return name();
101 : : }
102 : 0 : return QStringLiteral( "%1 (%2)" ).arg( name() ).arg( alias() );
103 : 0 : }
104 : :
105 : 0 : QString QgsField::displayType( const bool showConstraints ) const
106 : : {
107 : 0 : QString typeStr = typeName();
108 : :
109 : 0 : if ( length() > 0 && precision() > 0 )
110 : 0 : typeStr += QStringLiteral( "(%1, %2)" ).arg( length() ).arg( precision() );
111 : 0 : else if ( length() > 0 )
112 : 0 : typeStr += QStringLiteral( "(%1)" ).arg( length() );
113 : :
114 : 0 : if ( showConstraints )
115 : : {
116 : 0 : typeStr += ( constraints().constraints() & QgsFieldConstraints::ConstraintNotNull )
117 : 0 : ? QStringLiteral( " NOT NULL" )
118 : 0 : : QStringLiteral( " NULL" );
119 : :
120 : 0 : typeStr += ( constraints().constraints() & QgsFieldConstraints::ConstraintUnique )
121 : 0 : ? QStringLiteral( " UNIQUE" )
122 : 0 : : QString();
123 : 0 : }
124 : :
125 : 0 : return typeStr;
126 : 0 : }
127 : :
128 : 1900 : QVariant::Type QgsField::type() const
129 : : {
130 : 1900 : return d->type;
131 : : }
132 : :
133 : 0 : QVariant::Type QgsField::subType() const
134 : : {
135 : 0 : return d->subType;
136 : : }
137 : :
138 : 0 : QString QgsField::typeName() const
139 : : {
140 : 0 : return d->typeName;
141 : : }
142 : :
143 : 0 : int QgsField::length() const
144 : : {
145 : 0 : return d->length;
146 : : }
147 : :
148 : 0 : int QgsField::precision() const
149 : : {
150 : 0 : return d->precision;
151 : : }
152 : :
153 : 0 : QString QgsField::comment() const
154 : : {
155 : 0 : return d->comment;
156 : : }
157 : :
158 : 0 : bool QgsField::isNumeric() const
159 : : {
160 : 0 : return d->type == QVariant::Double || d->type == QVariant::Int || d->type == QVariant::UInt || d->type == QVariant::LongLong || d->type == QVariant::ULongLong;
161 : : }
162 : :
163 : 0 : bool QgsField::isDateOrTime() const
164 : : {
165 : 0 : return d->type == QVariant::Date || d->type == QVariant::Time || d->type == QVariant::DateTime;
166 : : }
167 : :
168 : : /***************************************************************************
169 : : * This class is considered CRITICAL and any change MUST be accompanied with
170 : : * full unit tests in testqgsfield.cpp.
171 : : * See details in QEP #17
172 : : ****************************************************************************/
173 : :
174 : 0 : void QgsField::setName( const QString &name )
175 : : {
176 : 0 : d->name = name;
177 : 0 : }
178 : :
179 : 0 : void QgsField::setType( QVariant::Type type )
180 : : {
181 : 0 : d->type = type;
182 : 0 : }
183 : :
184 : 0 : void QgsField::setSubType( QVariant::Type subType )
185 : : {
186 : 0 : d->subType = subType;
187 : 0 : }
188 : :
189 : 0 : void QgsField::setTypeName( const QString &typeName )
190 : : {
191 : 0 : d->typeName = typeName;
192 : 0 : }
193 : :
194 : 0 : void QgsField::setLength( int len )
195 : : {
196 : 0 : d->length = len;
197 : 0 : }
198 : 0 : void QgsField::setPrecision( int precision )
199 : : {
200 : 0 : d->precision = precision;
201 : 0 : }
202 : :
203 : 0 : void QgsField::setComment( const QString &comment )
204 : : {
205 : 0 : d->comment = comment;
206 : 0 : }
207 : :
208 : 0 : QgsDefaultValue QgsField::defaultValueDefinition() const
209 : : {
210 : 0 : return d->defaultValueDefinition;
211 : : }
212 : :
213 : 0 : void QgsField::setDefaultValueDefinition( const QgsDefaultValue &defaultValueDefinition )
214 : : {
215 : 0 : d->defaultValueDefinition = defaultValueDefinition;
216 : 0 : }
217 : :
218 : 1 : void QgsField::setConstraints( const QgsFieldConstraints &constraints )
219 : : {
220 : 1 : d->constraints = constraints;
221 : 1 : }
222 : :
223 : 1 : const QgsFieldConstraints &QgsField::constraints() const
224 : : {
225 : 1 : return d->constraints;
226 : : }
227 : :
228 : 0 : QString QgsField::alias() const
229 : : {
230 : 0 : return d->alias;
231 : : }
232 : :
233 : 0 : void QgsField::setAlias( const QString &alias )
234 : : {
235 : 0 : d->alias = alias;
236 : 0 : }
237 : :
238 : 0 : QgsField::ConfigurationFlags QgsField::configurationFlags() const
239 : : {
240 : 0 : return d->flags;
241 : : }
242 : :
243 : 0 : void QgsField::setConfigurationFlags( QgsField::ConfigurationFlags flags )
244 : : {
245 : 0 : d->flags = flags;
246 : 0 : }
247 : :
248 : : /***************************************************************************
249 : : * This class is considered CRITICAL and any change MUST be accompanied with
250 : : * full unit tests in testqgsfield.cpp.
251 : : * See details in QEP #17
252 : : ****************************************************************************/
253 : :
254 : 0 : QString QgsField::displayString( const QVariant &v ) const
255 : : {
256 : 0 : if ( v.isNull() )
257 : : {
258 : 0 : return QgsApplication::nullRepresentation();
259 : : }
260 : :
261 : : // Special treatment for numeric types if group separator is set or decimalPoint is not a dot
262 : 0 : if ( d->type == QVariant::Double )
263 : : {
264 : : // if value doesn't contain a double (a default value expression for instance),
265 : : // apply no transformation
266 : : bool ok;
267 : 0 : v.toDouble( &ok );
268 : 0 : if ( !ok )
269 : 0 : return v.toString();
270 : :
271 : : // Locales with decimal point != '.' or that require group separator: use QLocale
272 : 0 : if ( QLocale().decimalPoint() != '.' ||
273 : 0 : !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
274 : : {
275 : 0 : if ( d->precision > 0 )
276 : : {
277 : 0 : if ( -1 < v.toDouble() && v.toDouble() < 1 )
278 : : {
279 : 0 : return QLocale().toString( v.toDouble(), 'g', d->precision );
280 : : }
281 : : else
282 : : {
283 : 0 : return QLocale().toString( v.toDouble(), 'f', d->precision );
284 : : }
285 : : }
286 : : else
287 : : {
288 : : // Precision is not set, let's guess it from the
289 : : // standard conversion to string
290 : 0 : QString s( v.toString() );
291 : 0 : int dotPosition( s.indexOf( '.' ) );
292 : : int precision;
293 : 0 : if ( dotPosition < 0 && s.indexOf( 'e' ) < 0 )
294 : : {
295 : 0 : precision = 0;
296 : 0 : return QLocale().toString( v.toDouble(), 'f', precision );
297 : : }
298 : : else
299 : : {
300 : 0 : if ( dotPosition < 0 ) precision = 0;
301 : 0 : else precision = s.length() - dotPosition - 1;
302 : :
303 : 0 : if ( -1 < v.toDouble() && v.toDouble() < 1 )
304 : : {
305 : 0 : return QLocale().toString( v.toDouble(), 'g', precision );
306 : : }
307 : : else
308 : : {
309 : 0 : return QLocale().toString( v.toDouble(), 'f', precision );
310 : : }
311 : : }
312 : 0 : }
313 : : }
314 : : // Default for doubles with precision
315 : 0 : else if ( d->type == QVariant::Double && d->precision > 0 )
316 : : {
317 : 0 : if ( -1 < v.toDouble() && v.toDouble() < 1 )
318 : : {
319 : 0 : return QString::number( v.toDouble(), 'g', d->precision );
320 : : }
321 : : else
322 : : {
323 : 0 : return QString::number( v.toDouble(), 'f', d->precision );
324 : : }
325 : : }
326 : 0 : }
327 : : // Other numeric types than doubles
328 : 0 : else if ( isNumeric() &&
329 : 0 : !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
330 : : {
331 : : bool ok;
332 : 0 : qlonglong converted( v.toLongLong( &ok ) );
333 : 0 : if ( ok )
334 : 0 : return QLocale().toString( converted );
335 : 0 : }
336 : 0 : else if ( d->typeName.compare( QLatin1String( "json" ), Qt::CaseInsensitive ) == 0 || d->typeName == QLatin1String( "jsonb" ) )
337 : : {
338 : 0 : QJsonDocument doc = QJsonDocument::fromVariant( v );
339 : 0 : return QString::fromUtf8( doc.toJson().data() );
340 : 0 : }
341 : 0 : else if ( d->type == QVariant::ByteArray )
342 : : {
343 : 0 : return QObject::tr( "BLOB" );
344 : : }
345 : : // Fallback if special rules do not apply
346 : 0 : return v.toString();
347 : 0 : }
348 : :
349 : 0 : QString QgsField::readableConfigurationFlag( QgsField::ConfigurationFlag flag )
350 : : {
351 : 0 : switch ( flag )
352 : : {
353 : : case ConfigurationFlag::None:
354 : 0 : return QObject::tr( "None" );
355 : : case ConfigurationFlag::NotSearchable:
356 : 0 : return QObject::tr( "Not searchable" );
357 : : case ConfigurationFlag::HideFromWms:
358 : 0 : return QObject::tr( "Do not expose via WMS" );
359 : : case ConfigurationFlag::HideFromWfs:
360 : 0 : return QObject::tr( "Do not expose via WFS" );
361 : : }
362 : 0 : return QString();
363 : 0 : }
364 : :
365 : : /***************************************************************************
366 : : * This class is considered CRITICAL and any change MUST be accompanied with
367 : : * full unit tests in testqgsfield.cpp.
368 : : * See details in QEP #17
369 : : ****************************************************************************/
370 : :
371 : 0 : bool QgsField::convertCompatible( QVariant &v, QString *errorMessage ) const
372 : : {
373 : 0 : const QVariant original = v;
374 : 0 : if ( errorMessage )
375 : 0 : errorMessage->clear();
376 : :
377 : 0 : if ( v.isNull() )
378 : : {
379 : 0 : v.convert( d->type );
380 : 0 : return true;
381 : : }
382 : :
383 : 0 : if ( d->type == QVariant::Int && v.toInt() != v.toLongLong() )
384 : : {
385 : 0 : v = QVariant( d->type );
386 : 0 : if ( errorMessage )
387 : 0 : *errorMessage = QObject::tr( "Value \"%1\" is too large for integer field" ).arg( original.toLongLong() );
388 : 0 : return false;
389 : : }
390 : :
391 : : // Give it a chance to convert to double since for not '.' locales
392 : : // we accept both comma and dot as decimal point
393 : 0 : if ( d->type == QVariant::Double && v.type() == QVariant::String )
394 : : {
395 : 0 : QVariant tmp( v );
396 : 0 : if ( !tmp.convert( d->type ) )
397 : : {
398 : : // This might be a string with thousand separator: use locale to convert
399 : 0 : bool ok = false;
400 : 0 : double d = qgsPermissiveToDouble( v.toString(), ok );
401 : 0 : if ( ok )
402 : : {
403 : 0 : v = QVariant( d );
404 : 0 : return true;
405 : : }
406 : : // For not 'dot' locales, we also want to accept '.'
407 : 0 : if ( QLocale().decimalPoint() != '.' )
408 : : {
409 : 0 : d = QLocale( QLocale::C ).toDouble( v.toString(), &ok );
410 : 0 : if ( ok )
411 : : {
412 : 0 : v = QVariant( d );
413 : 0 : return true;
414 : : }
415 : 0 : }
416 : 0 : }
417 : 0 : }
418 : :
419 : : // For string representation of an int we also might have thousand separator
420 : 0 : if ( d->type == QVariant::Int && v.type() == QVariant::String )
421 : : {
422 : 0 : QVariant tmp( v );
423 : 0 : if ( !tmp.convert( d->type ) )
424 : : {
425 : : // This might be a string with thousand separator: use locale to convert
426 : : bool ok;
427 : 0 : int i = qgsPermissiveToInt( v.toString(), ok );
428 : 0 : if ( ok )
429 : : {
430 : 0 : v = QVariant( i );
431 : 0 : return true;
432 : : }
433 : 0 : }
434 : 0 : }
435 : :
436 : : // For string representation of a long we also might have thousand separator
437 : 0 : if ( d->type == QVariant::LongLong && v.type() == QVariant::String )
438 : : {
439 : 0 : QVariant tmp( v );
440 : 0 : if ( !tmp.convert( d->type ) )
441 : : {
442 : : // This might be a string with thousand separator: use locale to convert
443 : : bool ok;
444 : 0 : qlonglong l = qgsPermissiveToLongLong( v.toString(), ok );
445 : 0 : if ( ok )
446 : : {
447 : 0 : v = QVariant( l );
448 : 0 : return true;
449 : : }
450 : 0 : }
451 : 0 : }
452 : :
453 : : //String representations of doubles in QVariant will return false to convert( QVariant::Int )
454 : : //work around this by first converting to double, and then checking whether the double is convertible to int
455 : 0 : if ( d->type == QVariant::Int && v.canConvert( QVariant::Double ) )
456 : : {
457 : 0 : bool ok = false;
458 : 0 : double dbl = v.toDouble( &ok );
459 : 0 : if ( !ok )
460 : : {
461 : : //couldn't convert to number
462 : 0 : v = QVariant( d->type );
463 : :
464 : 0 : if ( errorMessage )
465 : 0 : *errorMessage = QObject::tr( "Value \"%1\" is not a number" ).arg( original.toString() );
466 : :
467 : 0 : return false;
468 : : }
469 : :
470 : 0 : double round = std::round( dbl );
471 : 0 : if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
472 : : {
473 : : //double too large to fit in int
474 : 0 : v = QVariant( d->type );
475 : :
476 : 0 : if ( errorMessage )
477 : 0 : *errorMessage = QObject::tr( "Value \"%1\" is too large for integer field" ).arg( original.toDouble() );
478 : :
479 : 0 : return false;
480 : : }
481 : 0 : v = QVariant( static_cast< int >( std::round( dbl ) ) );
482 : 0 : return true;
483 : : }
484 : :
485 : : //String representations of doubles in QVariant will return false to convert( QVariant::LongLong )
486 : : //work around this by first converting to double, and then checking whether the double is convertible to longlong
487 : 0 : if ( d->type == QVariant::LongLong && v.canConvert( QVariant::Double ) )
488 : : {
489 : : //firstly test the conversion to longlong because conversion to double will rounded the value
490 : 0 : QVariant tmp( v );
491 : 0 : if ( !tmp.convert( d->type ) )
492 : : {
493 : 0 : bool ok = false;
494 : 0 : double dbl = v.toDouble( &ok );
495 : 0 : if ( !ok )
496 : : {
497 : : //couldn't convert to number
498 : 0 : v = QVariant( d->type );
499 : :
500 : 0 : if ( errorMessage )
501 : 0 : *errorMessage = QObject::tr( "Value \"%1\" is not a number" ).arg( original.toString() );
502 : :
503 : 0 : return false;
504 : : }
505 : :
506 : 0 : double round = std::round( dbl );
507 : 0 : if ( round > static_cast<double>( std::numeric_limits<long long>::max() ) || round < static_cast<double>( -std::numeric_limits<long long>::max() ) )
508 : : {
509 : : //double too large to fit in longlong
510 : 0 : v = QVariant( d->type );
511 : :
512 : 0 : if ( errorMessage )
513 : 0 : *errorMessage = QObject::tr( "Value \"%1\" is too large for long long field" ).arg( original.toDouble() );
514 : :
515 : 0 : return false;
516 : : }
517 : 0 : v = QVariant( static_cast< long long >( std::round( dbl ) ) );
518 : 0 : return true;
519 : : }
520 : 0 : }
521 : :
522 : 0 : if ( !v.convert( d->type ) )
523 : : {
524 : 0 : v = QVariant( d->type );
525 : :
526 : 0 : if ( errorMessage )
527 : 0 : *errorMessage = QObject::tr( "Could not convert value \"%1\" to target type" ).arg( original.toString() );
528 : :
529 : 0 : return false;
530 : : }
531 : :
532 : 0 : if ( d->type == QVariant::Double && d->precision > 0 )
533 : : {
534 : 0 : double s = std::pow( 10, d->precision );
535 : 0 : double d = v.toDouble() * s;
536 : 0 : v = QVariant( ( d < 0 ? std::ceil( d - 0.5 ) : std::floor( d + 0.5 ) ) / s );
537 : 0 : return true;
538 : : }
539 : :
540 : 0 : if ( d->type == QVariant::String && d->length > 0 && v.toString().length() > d->length )
541 : : {
542 : 0 : const int length = v.toString().length();
543 : 0 : v = v.toString().left( d->length );
544 : :
545 : 0 : if ( errorMessage )
546 : 0 : *errorMessage = QObject::tr( "String of length %1 exceeds maximum field length (%2)" ).arg( length ).arg( d->length );
547 : :
548 : 0 : return false;
549 : : }
550 : :
551 : 0 : return true;
552 : 0 : }
553 : :
554 : 0 : void QgsField::setEditorWidgetSetup( const QgsEditorWidgetSetup &v )
555 : : {
556 : 0 : d->editorWidgetSetup = v;
557 : 0 : }
558 : :
559 : 0 : QgsEditorWidgetSetup QgsField::editorWidgetSetup() const
560 : : {
561 : 0 : return d->editorWidgetSetup;
562 : : }
563 : :
564 : 0 : void QgsField::setReadOnly( bool readOnly )
565 : : {
566 : 0 : d->isReadOnly = readOnly;
567 : 0 : }
568 : :
569 : 0 : bool QgsField::isReadOnly() const
570 : : {
571 : 0 : return d->isReadOnly;
572 : : }
573 : :
574 : :
575 : : /***************************************************************************
576 : : * This class is considered CRITICAL and any change MUST be accompanied with
577 : : * full unit tests in testqgsfield.cpp.
578 : : * See details in QEP #17
579 : : ****************************************************************************/
580 : :
581 : 0 : QDataStream &operator<<( QDataStream &out, const QgsField &field )
582 : : {
583 : 0 : out << field.name();
584 : 0 : out << static_cast< quint32 >( field.type() );
585 : 0 : out << field.typeName();
586 : 0 : out << field.length();
587 : 0 : out << field.precision();
588 : 0 : out << field.comment();
589 : 0 : out << field.alias();
590 : 0 : out << field.defaultValueDefinition().expression();
591 : 0 : out << field.defaultValueDefinition().applyOnUpdate();
592 : 0 : out << field.constraints().constraints();
593 : 0 : out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintNotNull ) );
594 : 0 : out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintUnique ) );
595 : 0 : out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintExpression ) );
596 : 0 : out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintNotNull ) );
597 : 0 : out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintUnique ) );
598 : 0 : out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintExpression ) );
599 : 0 : out << field.constraints().constraintExpression();
600 : 0 : out << field.constraints().constraintDescription();
601 : 0 : out << static_cast< quint32 >( field.subType() );
602 : 0 : return out;
603 : 0 : }
604 : :
605 : 0 : QDataStream &operator>>( QDataStream &in, QgsField &field )
606 : : {
607 : : quint32 type;
608 : : quint32 subType;
609 : : quint32 length;
610 : : quint32 precision;
611 : : quint32 constraints;
612 : : quint32 originNotNull;
613 : : quint32 originUnique;
614 : : quint32 originExpression;
615 : : quint32 strengthNotNull;
616 : : quint32 strengthUnique;
617 : : quint32 strengthExpression;
618 : :
619 : : bool applyOnUpdate;
620 : :
621 : 0 : QString name;
622 : 0 : QString typeName;
623 : 0 : QString comment;
624 : 0 : QString alias;
625 : 0 : QString defaultValueExpression;
626 : 0 : QString constraintExpression;
627 : 0 : QString constraintDescription;
628 : :
629 : 0 : in >> name >> type >> typeName >> length >> precision >> comment >> alias
630 : 0 : >> defaultValueExpression >> applyOnUpdate >> constraints >> originNotNull >> originUnique >> originExpression >> strengthNotNull >> strengthUnique >> strengthExpression >>
631 : 0 : constraintExpression >> constraintDescription >> subType;
632 : 0 : field.setName( name );
633 : 0 : field.setType( static_cast< QVariant::Type >( type ) );
634 : 0 : field.setTypeName( typeName );
635 : 0 : field.setLength( static_cast< int >( length ) );
636 : 0 : field.setPrecision( static_cast< int >( precision ) );
637 : 0 : field.setComment( comment );
638 : 0 : field.setAlias( alias );
639 : 0 : field.setDefaultValueDefinition( QgsDefaultValue( defaultValueExpression, applyOnUpdate ) );
640 : 0 : QgsFieldConstraints fieldConstraints;
641 : 0 : if ( constraints & QgsFieldConstraints::ConstraintNotNull )
642 : : {
643 : 0 : fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintNotNull, static_cast< QgsFieldConstraints::ConstraintOrigin>( originNotNull ) );
644 : 0 : fieldConstraints.setConstraintStrength( QgsFieldConstraints::ConstraintNotNull, static_cast< QgsFieldConstraints::ConstraintStrength>( strengthNotNull ) );
645 : 0 : }
646 : : else
647 : 0 : fieldConstraints.removeConstraint( QgsFieldConstraints::ConstraintNotNull );
648 : 0 : if ( constraints & QgsFieldConstraints::ConstraintUnique )
649 : : {
650 : 0 : fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintUnique, static_cast< QgsFieldConstraints::ConstraintOrigin>( originUnique ) );
651 : 0 : fieldConstraints.setConstraintStrength( QgsFieldConstraints::ConstraintUnique, static_cast< QgsFieldConstraints::ConstraintStrength>( strengthUnique ) );
652 : 0 : }
653 : : else
654 : 0 : fieldConstraints.removeConstraint( QgsFieldConstraints::ConstraintUnique );
655 : 0 : if ( constraints & QgsFieldConstraints::ConstraintExpression )
656 : : {
657 : 0 : fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintExpression, static_cast< QgsFieldConstraints::ConstraintOrigin>( originExpression ) );
658 : 0 : fieldConstraints.setConstraintStrength( QgsFieldConstraints::ConstraintExpression, static_cast< QgsFieldConstraints::ConstraintStrength>( strengthExpression ) );
659 : 0 : }
660 : : else
661 : 0 : fieldConstraints.removeConstraint( QgsFieldConstraints::ConstraintExpression );
662 : 0 : fieldConstraints.setConstraintExpression( constraintExpression, constraintDescription );
663 : 0 : field.setConstraints( fieldConstraints );
664 : 0 : field.setSubType( static_cast< QVariant::Type >( subType ) );
665 : 0 : return in;
666 : 0 : }
|