QgsMemoryProvider::QgsMemoryProvider( const QString &uri, const ProviderOptions &options ) : QgsVectorDataProvider( uri, options ) { // Initialize the geometry with the uri to support old style uri's // (ie, just 'point', 'line', 'polygon') QUrl url = QUrl::fromEncoded( uri.toUtf8() ); QString geometry; if ( url.hasQueryItem( QStringLiteral( "geometry" ) ) ) { geometry = url.queryItemValue( QStringLiteral( "geometry" ) ); } else { geometry = url.path(); } if ( geometry.toLower() == QLatin1String( "none" ) ) { mWkbType = QgsWkbTypes::NoGeometry; } else { mWkbType = QgsWkbTypes::parseType( geometry ); } if ( url.hasQueryItem( QStringLiteral( "crs" ) ) ) { QString crsDef = url.queryItemValue( QStringLiteral( "crs" ) ); mCrs.createFromString( crsDef ); } mNextFeatureId = 1; setNativeTypes( QList< NativeType >() << QgsVectorDataProvider::NativeType( tr( "Whole number (integer)" ), QStringLiteral( "integer" ), QVariant::Int, 0, 10 ) // Decimal number from OGR/Shapefile/dbf may come with length up to 32 and // precision up to length-2 = 30 (default, if width is not specified in dbf is length = 24 precision = 15) // We know that double (QVariant::Double) has only 15-16 significant numbers, // but setting that correct limits would disable the use of memory provider with // data from Shapefiles. In any case, the data are handled as doubles. // So the limits set here are not correct but enable use of data from Shapefiles. << QgsVectorDataProvider::NativeType( tr( "Decimal number (real)" ), QStringLiteral( "double" ), QVariant::Double, 0, 32, 0, 30 ) << QgsVectorDataProvider::NativeType( tr( "Text (string)" ), QStringLiteral( "string" ), QVariant::String, 0, 255 ) // date type << QgsVectorDataProvider::NativeType( tr( "Date" ), QStringLiteral( "date" ), QVariant::Date, -1, -1, -1, -1 ) << QgsVectorDataProvider::NativeType( tr( "Time" ), QStringLiteral( "time" ), QVariant::Time, -1, -1, -1, -1 ) << QgsVectorDataProvider::NativeType( tr( "Date & Time" ), QStringLiteral( "datetime" ), QVariant::DateTime, -1, -1, -1, -1 ) // integer types << QgsVectorDataProvider::NativeType( tr( "Whole number (smallint - 16bit)" ), QStringLiteral( "int2" ), QVariant::Int, -1, -1, 0, 0 ) << QgsVectorDataProvider::NativeType( tr( "Whole number (integer - 32bit)" ), QStringLiteral( "int4" ), QVariant::Int, -1, -1, 0, 0 ) << QgsVectorDataProvider::NativeType( tr( "Whole number (integer - 64bit)" ), QStringLiteral( "int8" ), QVariant::LongLong, -1, -1, 0, 0 ) << QgsVectorDataProvider::NativeType( tr( "Decimal number (numeric)" ), QStringLiteral( "numeric" ), QVariant::Double, 1, 20, 0, 20 ) << QgsVectorDataProvider::NativeType( tr( "Decimal number (decimal)" ), QStringLiteral( "decimal" ), QVariant::Double, 1, 20, 0, 20 ) // floating point << QgsVectorDataProvider::NativeType( tr( "Decimal number (real)" ), QStringLiteral( "real" ), QVariant::Double, -1, -1, -1, -1 ) << QgsVectorDataProvider::NativeType( tr( "Decimal number (double)" ), QStringLiteral( "double precision" ), QVariant::Double, -1, -1, -1, -1 ) // string types << QgsVectorDataProvider::NativeType( tr( "Text, unlimited length (text)" ), QStringLiteral( "text" ), QVariant::String, -1, -1, -1, -1 ) ); if ( url.hasQueryItem( QStringLiteral( "field" ) ) ) { QList<QgsField> attributes; QRegExp reFieldDef( "\\:" "(int|integer|long|int8|real|double|string|date|time|datetime)" // type "(?:\\((\\-?\\d+)" // length "(?:\\,(\\d+))?" // precision "\\))?(\\[\\])?" // array "$", Qt::CaseInsensitive ); QStringList fields = url.allQueryItemValues( QStringLiteral( "field" ) ); for ( int i = 0; i < fields.size(); i++ ) { QString name = QUrl::fromPercentEncoding( fields.at( i ).toUtf8() ); QVariant::Type type = QVariant::String; QVariant::Type subType = QVariant::Invalid; QString typeName( QStringLiteral( "string" ) ); int length = 255; int precision = 0; int pos = reFieldDef.indexIn( name ); if ( pos >= 0 ) { name = name.mid( 0, pos ); typeName = reFieldDef.cap( 1 ).toLower(); if ( typeName == QLatin1String( "int" ) || typeName == QLatin1String( "integer" ) ) { type = QVariant::Int; typeName = QStringLiteral( "integer" ); length = -1; } else if ( typeName == QLatin1String( "int8" ) || typeName == QLatin1String( "long" ) ) { type = QVariant::LongLong; typeName = QStringLiteral( "int8" ); length = -1; } else if ( typeName == QLatin1String( "real" ) || typeName == QLatin1String( "double" ) ) { type = QVariant::Double; typeName = QStringLiteral( "double" ); length = 20; precision = 5; } else if ( typeName == QLatin1String( "date" ) ) { type = QVariant::Date; typeName = QStringLiteral( "date" ); length = -1; } else if ( typeName == QLatin1String( "time" ) ) { type = QVariant::Time; typeName = QStringLiteral( "time" ); length = -1; } else if ( typeName == QLatin1String( "datetime" ) ) { type = QVariant::DateTime; typeName = QStringLiteral( "datetime" ); length = -1; } if ( !reFieldDef.cap( 2 ).isEmpty() ) { length = reFieldDef.cap( 2 ).toInt(); } if ( !reFieldDef.cap( 3 ).isEmpty() ) { precision = reFieldDef.cap( 3 ).toInt(); } if ( !reFieldDef.cap( 4 ).isEmpty() ) { //array subType = type; type = ( subType == QVariant::String ? QVariant::StringList : QVariant::List ); } } if ( !name.isEmpty() ) attributes.append( QgsField( name, type, typeName, length, precision, QLatin1String( "" ), subType ) ); } addAttributes( attributes ); } if ( url.hasQueryItem( QStringLiteral( "index" ) ) && url.queryItemValue( QStringLiteral( "index" ) ) == QLatin1String( "yes" ) ) { createSpatialIndex(); } }
QgsDelimitedTextProvider::QgsDelimitedTextProvider( const QString& uri ) : QgsVectorDataProvider( uri ) , mLayerValid( false ) , mValid( false ) , mFile( nullptr ) , mGeomRep( GeomNone ) , mFieldCount( 0 ) , mXFieldIndex( -1 ) , mYFieldIndex( -1 ) , mWktFieldIndex( -1 ) , mWktHasPrefix( false ) , mXyDms( false ) , mSubsetString( QLatin1String( "" ) ) , mSubsetExpression( nullptr ) , mBuildSubsetIndex( true ) , mUseSubsetIndex( false ) , mMaxInvalidLines( 50 ) , mShowInvalidLines( true ) , mRescanRequired( false ) , mCrs() , mWkbType( QgsWkbTypes::NoGeometry ) , mGeometryType( QgsWkbTypes::UnknownGeometry ) , mBuildSpatialIndex( false ) , mSpatialIndex( nullptr ) { // Add supported types to enable creating expression fields in field calculator setNativeTypes( QList< NativeType >() << QgsVectorDataProvider::NativeType( tr( "Whole number (integer)" ), QStringLiteral( "integer" ), QVariant::Int, 0, 10 ) << QgsVectorDataProvider::NativeType( tr( "Whole number (integer - 64 bit)" ), QStringLiteral( "int8" ), QVariant::LongLong ) << QgsVectorDataProvider::NativeType( tr( "Decimal number (double)" ), QStringLiteral( "double precision" ), QVariant::Double, -1, -1, -1, -1 ) << QgsVectorDataProvider::NativeType( tr( "Text, unlimited length (text)" ), QStringLiteral( "text" ), QVariant::String, -1, -1, -1, -1 ) ); QgsDebugMsg( "Delimited text file uri is " + uri ); QUrl url = QUrl::fromEncoded( uri.toLatin1() ); mFile = new QgsDelimitedTextFile(); mFile->setFromUrl( url ); QString subset; if ( url.hasQueryItem( QStringLiteral( "geomType" ) ) ) { QString gtype = url.queryItemValue( QStringLiteral( "geomType" ) ).toLower(); if ( gtype == QLatin1String( "point" ) ) mGeometryType = QgsWkbTypes::PointGeometry; else if ( gtype == QLatin1String( "line" ) ) mGeometryType = QgsWkbTypes::LineGeometry; else if ( gtype == QLatin1String( "polygon" ) ) mGeometryType = QgsWkbTypes::PolygonGeometry; else if ( gtype == QLatin1String( "none " ) ) mGeometryType = QgsWkbTypes::NullGeometry; } if ( mGeometryType != QgsWkbTypes::NullGeometry ) { if ( url.hasQueryItem( QStringLiteral( "wktField" ) ) ) { mWktFieldName = url.queryItemValue( QStringLiteral( "wktField" ) ); mGeomRep = GeomAsWkt; QgsDebugMsg( "wktField is: " + mWktFieldName ); } else if ( url.hasQueryItem( QStringLiteral( "xField" ) ) && url.hasQueryItem( QStringLiteral( "yField" ) ) ) { mGeomRep = GeomAsXy; mGeometryType = QgsWkbTypes::PointGeometry; mXFieldName = url.queryItemValue( QStringLiteral( "xField" ) ); mYFieldName = url.queryItemValue( QStringLiteral( "yField" ) ); QgsDebugMsg( "xField is: " + mXFieldName ); QgsDebugMsg( "yField is: " + mYFieldName ); if ( url.hasQueryItem( QStringLiteral( "xyDms" ) ) ) { mXyDms = ! url.queryItemValue( QStringLiteral( "xyDms" ) ).toLower().startsWith( 'n' ); } } else { mGeometryType = QgsWkbTypes::NullGeometry; } } if ( url.hasQueryItem( QStringLiteral( "decimalPoint" ) ) ) mDecimalPoint = url.queryItemValue( QStringLiteral( "decimalPoint" ) ); if ( url.hasQueryItem( QStringLiteral( "crs" ) ) ) mCrs.createFromString( url.queryItemValue( QStringLiteral( "crs" ) ) ); if ( url.hasQueryItem( QStringLiteral( "subsetIndex" ) ) ) { mBuildSubsetIndex = ! url.queryItemValue( QStringLiteral( "subsetIndex" ) ).toLower().startsWith( 'n' ); } if ( url.hasQueryItem( QStringLiteral( "spatialIndex" ) ) ) { mBuildSpatialIndex = ! url.queryItemValue( QStringLiteral( "spatialIndex" ) ).toLower().startsWith( 'n' ); } if ( url.hasQueryItem( QStringLiteral( "subset" ) ) ) { // We need to specify FullyDecoded so that %25 is decoded as % subset = QUrlQuery( url ).queryItemValue( QStringLiteral( "subset" ) , QUrl::FullyDecoded ); QgsDebugMsg( "subset is: " + subset ); } if ( url.hasQueryItem( QStringLiteral( "quiet" ) ) ) mShowInvalidLines = false; // Do an initial scan of the file to determine field names, types, // geometry type (for Wkt), extents, etc. Parameter value subset.isEmpty() // avoid redundant building indexes if we will be building a subset string, // in which case indexes will be rebuilt. scanFile( subset.isEmpty() ); if ( ! subset.isEmpty() ) { setSubsetString( subset ); } }
QgsDb2Provider::QgsDb2Provider( const QString &uri ) : QgsVectorDataProvider( uri ) , mNumberFeatures( 0 ) , mFidColIdx( -1 ) , mEnvironment( ENV_LUW ) , mWkbType( QgsWkbTypes::Unknown ) { QgsDebugMsg( "uri: " + uri ); QgsDataSourceUri anUri = QgsDataSourceUri( uri ); if ( !anUri.srid().isEmpty() ) mSRId = anUri.srid().toInt(); else mSRId = -1; if ( 0 != anUri.wkbType() ) { mWkbType = anUri.wkbType(); } QgsDebugMsg( QString( "mWkbType: %1" ).arg( mWkbType ) ); QgsDebugMsg( QString( "new mWkbType: %1" ).arg( anUri.wkbType() ) ); mValid = true; mSkipFailures = false; int dim; // Not used db2WkbTypeAndDimension( mWkbType, mGeometryColType, dim ); // Get DB2 geometry type name mFidColName = anUri.keyColumn().toUpper(); QgsDebugMsg( "mFidColName " + mFidColName ); mExtents = anUri.param( QStringLiteral( "extents" ) ); QgsDebugMsg( "mExtents " + mExtents ); mUseEstimatedMetadata = anUri.useEstimatedMetadata(); QgsDebugMsg( QString( "mUseEstimatedMetadata: '%1'" ).arg( mUseEstimatedMetadata ) ); mSqlWhereClause = anUri.sql(); QString errMsg; mDatabase = getDatabase( uri, errMsg ); mConnInfo = anUri.connectionInfo(); QgsCoordinateReferenceSystem layerCrs = crs(); QgsDebugMsg( "CRS: " + layerCrs.toWkt() ); if ( !errMsg.isEmpty() ) { setLastError( errMsg ); QgsDebugMsg( mLastError ); mValid = false; return; } // Create a query for default connection mQuery = QSqlQuery( mDatabase ); mSchemaName = anUri.schema(); mTableName = anUri.table().toUpper(); QStringList sl = mTableName.split( '.' ); if ( sl.length() == 2 ) // Never seems to be the case { mSchemaName = sl[0]; mTableName = sl[1]; } if ( mSchemaName.isEmpty() ) { mSchemaName = anUri.username().toUpper(); } QgsDebugMsg( "mSchemaName: '" + mSchemaName + "; mTableName: '" + mTableName ); if ( !anUri.geometryColumn().isEmpty() ) mGeometryColName = anUri.geometryColumn().toUpper(); loadFields(); updateStatistics(); if ( mGeometryColName.isEmpty() ) { // table contains no geometries mWkbType = QgsWkbTypes::NoGeometry; mSRId = 0; } //fill type names into sets setNativeTypes( QList< NativeType >() // integer types << QgsVectorDataProvider::NativeType( tr( "8 Bytes integer" ), QStringLiteral( "bigint" ), QVariant::Int ) << QgsVectorDataProvider::NativeType( tr( "4 Bytes integer" ), QStringLiteral( "integer" ), QVariant::Int ) << QgsVectorDataProvider::NativeType( tr( "2 Bytes integer" ), QStringLiteral( "smallint" ), QVariant::Int ) << QgsVectorDataProvider::NativeType( tr( "Decimal number (numeric)" ), QStringLiteral( "numeric" ), QVariant::Double, 1, 31, 0, 31 ) << QgsVectorDataProvider::NativeType( tr( "Decimal number (decimal)" ), QStringLiteral( "decimal" ), QVariant::Double, 1, 31, 0, 31 ) // floating point << QgsVectorDataProvider::NativeType( tr( "Decimal number (real)" ), QStringLiteral( "real" ), QVariant::Double ) << QgsVectorDataProvider::NativeType( tr( "Decimal number (double)" ), QStringLiteral( "double" ), QVariant::Double ) // date/time types << QgsVectorDataProvider::NativeType( tr( "Date" ), QStringLiteral( "date" ), QVariant::Date, -1, -1, -1, -1 ) << QgsVectorDataProvider::NativeType( tr( "Time" ), QStringLiteral( "time" ), QVariant::Time, -1, -1, -1, -1 ) << QgsVectorDataProvider::NativeType( tr( "Date & Time" ), QStringLiteral( "datetime" ), QVariant::DateTime, -1, -1, -1, -1 ) // string types << QgsVectorDataProvider::NativeType( tr( "Text, fixed length (char)" ), QStringLiteral( "char" ), QVariant::String, 1, 254 ) << QgsVectorDataProvider::NativeType( tr( "Text, variable length (varchar)" ), QStringLiteral( "varchar" ), QVariant::String, 1, 32704 ) << QgsVectorDataProvider::NativeType( tr( "Text, variable length large object (clob)" ), QStringLiteral( "clob" ), QVariant::String, 1, 2147483647 ) //DBCLOB is for 1073741824 double-byte characters, data length should be the same as CLOB (2147483647)? << QgsVectorDataProvider::NativeType( tr( "Text, variable length large object (dbclob)" ), QStringLiteral( "dbclob" ), QVariant::String, 1, 1073741824 ) ); }