def test_source_escaping2(self): def create_test_db(dbfile): if os.path.exists(dbfile): os.remove(dbfile) con = spatialite_connect(dbfile) cur = con.cursor() cur.execute("SELECT InitSpatialMetadata(1)") cur.execute("CREATE TABLE test (id INTEGER, name TEXT)") cur.execute("SELECT AddGeometryColumn('test', 'geometry', 4326, 'POINT', 'XY')") sql = "INSERT INTO test (id, name, geometry) " sql += "VALUES (1, 'toto',GeomFromText('POINT(0 0)',4326))" cur.execute(sql) con.close() # the source contains ',' and single quotes fn = os.path.join(tempfile.gettempdir(), "test,.db") create_test_db(fn) source = "dbname='%s' table=\"test\" (geometry) sql=" % fn d = QgsVirtualLayerDefinition() d.addSource("t", source, "spatialite") l = QgsVectorLayer(d.toString(), "vtab", "virtual", False) self.assertEqual(l.isValid(), True) # the source contains ':' and single quotes fn = os.path.join(tempfile.gettempdir(), "test:.db") create_test_db(fn) source = "dbname='%s' table=\"test\" (geometry) sql=" % fn d = QgsVirtualLayerDefinition() d.addSource("t", source, "spatialite") l = QgsVectorLayer(d.toString(), "vtab", "virtual", False) self.assertEqual(l.isValid(), True)
def test_source_escaping(self): # the source contains ':' source = QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/test.csv")).toString() + "?type=csv&geomType=none&subsetIndex=no&watchFile=no" d = QgsVirtualLayerDefinition() d.addSource("t", source, "delimitedtext") l = QgsVectorLayer(d.toString(), "vtab", "virtual", False) self.assertEqual(l.isValid(), True)
def test_no_geometry(self): df = QgsVirtualLayerDefinition() df.addSource("vtab", os.path.join(self.testDataDir, "france_parts.shp"), "ogr") df.setGeometryWkbType(QgsWkbTypes.NoGeometry) l2 = QgsVectorLayer(df.toString(), "vtab2", "virtual", False) self.assertEqual(l2.isValid(), True) self.assertEqual(l2.dataProvider().wkbType(), 100) # NoGeometry
def processAlgorithm(self, feedback): layers = self.getParameterValue(self.INPUT_DATASOURCES) query = self.getParameterValue(self.INPUT_QUERY) uid_field = self.getParameterValue(self.INPUT_UID_FIELD) geometry_field = self.getParameterValue(self.INPUT_GEOMETRY_FIELD) geometry_type = self.getParameterValue(self.INPUT_GEOMETRY_TYPE) geometry_crs = self.getParameterValue(self.INPUT_GEOMETRY_CRS) df = QgsVirtualLayerDefinition() layerIdx = 1 if layers: for layerSource in layers.split(';'): layer = dataobjects.getObjectFromUri(layerSource) if layer: df.addSource('input{}'.format(layerIdx), layer.id()) layerIdx += 1 if query == '': raise GeoAlgorithmExecutionException( self.tr('Empty SQL. Please enter valid SQL expression and try again.')) else: df.setQuery(query) if uid_field: df.setUid(uid_field) if geometry_type == 1: # no geometry df.setGeometryWkbType(QgsWkbTypes.NullGeometry) else: if geometry_field: df.setGeometryField(geometry_field) if geometry_type > 1: df.setGeometryWkbType(geometry_type - 1) if geometry_crs: crs = QgsCoordinateReferenceSystem(geometry_crs) if crs.isValid(): df.setGeometrySrid(crs.postgisSrid()) vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual") if not vLayer.isValid(): raise GeoAlgorithmExecutionException(vLayer.dataProvider().error().message()) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter( vLayer.fields().toList(), # Create a point layer (without any points) if 'no geometry' is chosen vLayer.wkbType() if geometry_type != 1 else 1, vLayer.crs()) features = vector.features(vLayer) total = 100.0 / len(features) outFeat = QgsFeature() for current, inFeat in enumerate(features): outFeat.setAttributes(inFeat.attributes()) if geometry_type != 1: outFeat.setGeometry(inFeat.geometry()) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer
def setUpClass(cls): """Run before all tests""" # Create the layer for the common provider tests shp = os.path.join(TEST_DATA_DIR, 'provider/shapefile.shp') d = QgsVirtualLayerDefinition() d.addSource("vtab1", shp, "ogr") d.setUid("pk") cls.vl = QgsVectorLayer(d.toString(), u'test', u'virtual') assert (cls.vl.isValid()) cls.provider = cls.vl.dataProvider()
def processAlgorithm(self, parameters, context, feedback): layers = self.parameterAsLayerList(parameters, self.INPUT_DATASOURCES, context) query = self.parameterAsString(parameters, self.INPUT_QUERY, context) uid_field = self.parameterAsString(parameters, self.INPUT_UID_FIELD, context) geometry_field = self.parameterAsString(parameters, self.INPUT_GEOMETRY_FIELD, context) geometry_type = self.parameterAsEnum(parameters, self.INPUT_GEOMETRY_TYPE, context) geometry_crs = self.parameterAsCrs(parameters, self.INPUT_GEOMETRY_CRS, context) df = QgsVirtualLayerDefinition() for layerIdx, layer in enumerate(layers): df.addSource('input{}'.format(layerIdx + 1), layer.id()) if query == '': raise QgsProcessingException( self.tr('Empty SQL. Please enter valid SQL expression and try again.')) else: localContext = self.createExpressionContext(parameters, context) expandedQuery = QgsExpression.replaceExpressionText(query, localContext) df.setQuery(expandedQuery) if uid_field: df.setUid(uid_field) if geometry_type == 1: # no geometry df.setGeometryWkbType(QgsWkbTypes.NoGeometry) else: if geometry_field: df.setGeometryField(geometry_field) if geometry_type > 1: df.setGeometryWkbType(geometry_type - 1) if geometry_crs.isValid(): df.setGeometrySrid(geometry_crs.postgisSrid()) vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual") if not vLayer.isValid(): raise QgsProcessingException(vLayer.dataProvider().error().message()) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, vLayer.fields(), vLayer.wkbType() if geometry_type != 1 else 1, vLayer.crs()) if sink is None: raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT)) features = vLayer.getFeatures() total = 100.0 / vLayer.featureCount() if vLayer.featureCount() else 0 for current, inFeat in enumerate(features): if feedback.isCanceled(): break sink.addFeature(inFeat, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def test1(self): d = QgsVirtualLayerDefinition() self.assertEqual(d.toString(), "") d.setFilePath("/file") self.assertEqual(d.toString(), "file:///file") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).filePath(), "/file") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).filePath(), "/file") d.setFilePath(os.path.join("C:/", "file")) self.assertEqual(d.toString(), "file:///C:/file") # self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).filePath(), os.path.join('C:/', 'file')) d.setQuery("SELECT * FROM mytable") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).query(), "SELECT * FROM mytable") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).query(), "SELECT * FROM mytable") q = "SELECT * FROM tableéé /*:int*/" d.setQuery(q) self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).query(), q) self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).query(), q) s1 = "file://foo&bar=okié" d.addSource("name", s1, "provider", "utf8") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).sourceLayers()[0].source(), s1) self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).sourceLayers()[0].source(), s1) n1 = "éé ok" d.addSource(n1, s1, "provider") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).sourceLayers()[1].name(), n1) self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).sourceLayers()[1].name(), n1) d.addSource("ref1", "id0001") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).sourceLayers()[2].reference(), "id0001") self.assertEqual( QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).sourceLayers()[2].reference(), "id0001" ) s = "dbname='C:\\tt' table=\"test\" (geometry) sql=" d.addSource("nn", s, "spatialite") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).sourceLayers()[3].source(), s) self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).sourceLayers()[3].source(), s) d.setGeometryField("geom") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).geometryField(), "geom") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).geometryField(), "geom") d.setGeometryWkbType(QgsWkbTypes.Point) self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).geometryWkbType(), QgsWkbTypes.Point) self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).geometryWkbType(), QgsWkbTypes.Point) f = QgsFields() f.append(QgsField("a", QVariant.Int)) f.append(QgsField("f", QVariant.Double)) f.append(QgsField("s", QVariant.String)) d.setFields(f) f2 = QgsVirtualLayerDefinition.fromUrl(d.toUrl()).fields() self.assertEqual(f[0].name(), f2[0].name()) self.assertEqual(f[0].type(), f2[0].type()) self.assertEqual(f[1].name(), f2[1].name()) self.assertEqual(f[1].type(), f2[1].type()) self.assertEqual(f[2].name(), f2[2].name()) self.assertEqual(f[2].type(), f2[2].type())
def test_query_with_accents(self): # shapefile with accents and latin1 encoding df = QgsVirtualLayerDefinition() df.addSource("vtab", os.path.join(self.testDataDir, "france_parts.shp"), "ogr", "ISO-8859-1") df.setQuery("SELECT * FROM vtab WHERE TYPE_1 = 'Région'") vl = QgsVectorLayer(df.toString(), "testq", "virtual") self.assertEqual(vl.isValid(), True) ids = [f.id() for f in vl.getFeatures()] self.assertEqual(len(ids), 4) # the same shapefile with a wrong encoding df.addSource("vtab", os.path.join(self.testDataDir, "france_parts.shp"), "ogr", "UTF-8") df.setQuery("SELECT * FROM vtab WHERE TYPE_1 = 'Région'") vl2 = QgsVectorLayer(df.toString(), "testq", "virtual") self.assertEqual(vl2.isValid(), True) ids = [f.id() for f in vl2.getFeatures()] self.assertEqual(ids, [])
def setUpClass(cls): """Run before all tests""" # Create the layer for the common provider tests shp = os.path.join(TEST_DATA_DIR, 'provider/shapefile.shp') d = QgsVirtualLayerDefinition() d.addSource("vtab1", shp, "ogr") d.setUid("pk") cls.vl = QgsVectorLayer(d.toString(), 'test', 'virtual') assert (cls.vl.isValid()) cls.source = cls.vl.dataProvider() shp_poly = os.path.join(TEST_DATA_DIR, 'provider/shapefile_poly.shp') d = QgsVirtualLayerDefinition() d.addSource("vtab2", shp_poly, "ogr") d.setUid("pk") cls.poly_vl = QgsVectorLayer(d.toString(), 'test_poly', 'virtual') assert (cls.poly_vl.isValid()) cls.poly_provider = cls.poly_vl.dataProvider()
def setUpClass(cls): """Run before all tests""" # Create the layer for the common provider tests shp = os.path.join(TEST_DATA_DIR, "provider/shapefile.shp") d = QgsVirtualLayerDefinition() d.addSource("vtab1", shp, "ogr") d.setUid("pk") cls.vl = QgsVectorLayer(d.toString(), "test", "virtual") assert cls.vl.isValid() cls.provider = cls.vl.dataProvider() shp_poly = os.path.join(TEST_DATA_DIR, "provider/shapefile_poly.shp") d = QgsVirtualLayerDefinition() d.addSource("vtab2", shp_poly, "ogr") d.setUid("pk") cls.poly_vl = QgsVectorLayer(d.toString(), "test_poly", "virtual") assert cls.poly_vl.isValid() cls.poly_provider = cls.poly_vl.dataProvider()
def test_query_with_accents(self): # shapefile with accents and latin1 encoding df = QgsVirtualLayerDefinition() df.addSource("vtab", os.path.join(self.testDataDir, "france_parts.shp"), "ogr", "ISO-8859-1") df.setQuery("SELECT * FROM vtab WHERE TYPE_1 = 'Région'") vl = QgsVectorLayer(df.toString(), "testq", "virtual") self.assertEqual(vl.isValid(), True) ids = [f.id() for f in vl.getFeatures()] self.assertEqual(len(ids), 4) # the same shapefile with a wrong encoding df.addSource("vtab", os.path.join(self.testDataDir, "france_parts.shp"), "ogr", "UTF-8") df.setQuery("SELECT * FROM vtab WHERE TYPE_1 = 'Région'") vl2 = QgsVectorLayer(df.toString(), "testq", "virtual") self.assertEqual(vl2.isValid(), True) ids = [f.id() for f in vl2.getFeatures()] self.assertEqual(ids, [])
def test1(self): d = QgsVirtualLayerDefinition() self.assertEqual(d.toString(), "") d.setFilePath("/file") self.assertEqual(d.toString(), "/file") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).filePath(), "/file") d.setFilePath("C:\\file") self.assertEqual(d.toString(), "C:%5Cfile") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).filePath(), "C:\\file") d.setQuery("SELECT * FROM mytable") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).query(), "SELECT * FROM mytable") q = u"SELECT * FROM tableéé /*:int*/" d.setQuery(q) self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).query(), q) s1 = u"file://foo&bar=okié" d.addSource("name", s1, "provider", "utf8") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).sourceLayers()[0].source(), s1) n1 = u"éé ok" d.addSource(n1, s1, "provider") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).sourceLayers()[1].name(), n1) d.addSource("ref1", "id0001") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).sourceLayers()[2].reference(), "id0001") d.setGeometryField("geom") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).geometryField(), "geom") d.setGeometryWkbType(QgsWKBTypes.Point) self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).geometryWkbType(), QgsWKBTypes.Point) f = QgsFields() f.append(QgsField("a", QVariant.Int)) f.append(QgsField("f", QVariant.Double)) f.append(QgsField("s", QVariant.String)) d.setFields(f) f2 = QgsVirtualLayerDefinition.fromUrl(d.toUrl()).fields() self.assertEqual(f[0].name(), f2[0].name()) self.assertEqual(f[0].type(), f2[0].type()) self.assertEqual(f[1].name(), f2[1].name()) self.assertEqual(f[1].type(), f2[1].type()) self.assertEqual(f[2].name(), f2[2].name()) self.assertEqual(f[2].type(), f2[2].type())
def test1(self): d = QgsVirtualLayerDefinition() self.assertEqual(d.toString(), "") d.setFilePath("/file") self.assertEqual(d.toString(), "file:///file") self.assertEqual( QgsVirtualLayerDefinition.fromUrl(d.toUrl()).filePath(), "/file") self.assertEqual( QgsVirtualLayerDefinition.fromUrl(strToUrl( d.toString())).filePath(), "/file") d.setFilePath(os.path.join('C:/', 'file')) self.assertEqual(d.toString(), "file:///C:/file") # self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).filePath(), os.path.join('C:/', 'file')) d.setQuery("SELECT * FROM mytable") self.assertEqual( QgsVirtualLayerDefinition.fromUrl(d.toUrl()).query(), "SELECT * FROM mytable") self.assertEqual( QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).query(), "SELECT * FROM mytable") q = "SELECT * FROM tableéé /*:int*/" d.setQuery(q) self.assertEqual( QgsVirtualLayerDefinition.fromUrl(d.toUrl()).query(), q) self.assertEqual( QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).query(), q) s1 = "file://foo&bar=okié" d.addSource("name", s1, "provider", "utf8") self.assertEqual( QgsVirtualLayerDefinition.fromUrl( d.toUrl()).sourceLayers()[0].source(), s1) self.assertEqual( QgsVirtualLayerDefinition.fromUrl(strToUrl( d.toString())).sourceLayers()[0].source(), s1) n1 = "éé ok" d.addSource(n1, s1, "provider") self.assertEqual( QgsVirtualLayerDefinition.fromUrl( d.toUrl()).sourceLayers()[1].name(), n1) self.assertEqual( QgsVirtualLayerDefinition.fromUrl(strToUrl( d.toString())).sourceLayers()[1].name(), n1) d.addSource("ref1", "id0001") self.assertEqual( QgsVirtualLayerDefinition.fromUrl( d.toUrl()).sourceLayers()[2].reference(), "id0001") self.assertEqual( QgsVirtualLayerDefinition.fromUrl(strToUrl( d.toString())).sourceLayers()[2].reference(), "id0001") s = "dbname='C:\\tt' table=\"test\" (geometry) sql=" d.addSource("nn", s, "spatialite") self.assertEqual( QgsVirtualLayerDefinition.fromUrl( d.toUrl()).sourceLayers()[3].source(), s) self.assertEqual( QgsVirtualLayerDefinition.fromUrl(strToUrl( d.toString())).sourceLayers()[3].source(), s) d.setGeometryField("geom") self.assertEqual( QgsVirtualLayerDefinition.fromUrl(d.toUrl()).geometryField(), "geom") self.assertEqual( QgsVirtualLayerDefinition.fromUrl(strToUrl( d.toString())).geometryField(), "geom") d.setGeometryWkbType(QgsWkbTypes.Point) self.assertEqual( QgsVirtualLayerDefinition.fromUrl(d.toUrl()).geometryWkbType(), QgsWkbTypes.Point) self.assertEqual( QgsVirtualLayerDefinition.fromUrl(strToUrl( d.toString())).geometryWkbType(), QgsWkbTypes.Point) f = QgsFields() f.append(QgsField("a", QVariant.Int)) f.append(QgsField("f", QVariant.Double)) f.append(QgsField("s", QVariant.String)) d.setFields(f) f2 = QgsVirtualLayerDefinition.fromUrl(d.toUrl()).fields() self.assertEqual(f[0].name(), f2[0].name()) self.assertEqual(f[0].type(), f2[0].type()) self.assertEqual(f[1].name(), f2[1].name()) self.assertEqual(f[1].type(), f2[1].type()) self.assertEqual(f[2].name(), f2[2].name()) self.assertEqual(f[2].type(), f2[2].type())
def processAlgorithm(self, feedback): layers = self.getParameterValue(self.INPUT_DATASOURCES) query = self.getParameterValue(self.INPUT_QUERY) uid_field = self.getParameterValue(self.INPUT_UID_FIELD) geometry_field = self.getParameterValue(self.INPUT_GEOMETRY_FIELD) geometry_type = self.getParameterValue(self.INPUT_GEOMETRY_TYPE) geometry_crs = self.getParameterValue(self.INPUT_GEOMETRY_CRS) df = QgsVirtualLayerDefinition() layerIdx = 1 if layers: for layerSource in layers.split(';'): layer = dataobjects.getLayerFromString(layerSource) if layer: df.addSource('input{}'.format(layerIdx), layer.id()) layerIdx += 1 if query == '': raise GeoAlgorithmExecutionException( self. tr('Empty SQL. Please enter valid SQL expression and try again.' )) else: df.setQuery(query) if uid_field: df.setUid(uid_field) if geometry_type == 1: # no geometry df.setGeometryWkbType(QgsWkbTypes.NullGeometry) else: if geometry_field: df.setGeometryField(geometry_field) if geometry_type > 1: df.setGeometryWkbType(geometry_type - 1) if geometry_crs: crs = QgsCoordinateReferenceSystem(geometry_crs) if crs.isValid(): df.setGeometrySrid(crs.postgisSrid()) vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual") if not vLayer.isValid(): raise GeoAlgorithmExecutionException( vLayer.dataProvider().error().message()) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter( vLayer.fields().toList(), # Create a point layer (without any points) if 'no geometry' is chosen vLayer.wkbType() if geometry_type != 1 else 1, vLayer.crs()) features = vector.features(vLayer) total = 100.0 / len(features) outFeat = QgsFeature() for current, inFeat in enumerate(features): outFeat.setAttributes(inFeat.attributes()) if geometry_type != 1: outFeat.setGeometry(inFeat.geometry()) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layers = self.parameterAsLayerList(parameters, self.INPUT_DATASOURCES, context) query = self.parameterAsString(parameters, self.INPUT_QUERY, context) uid_field = self.parameterAsString(parameters, self.INPUT_UID_FIELD, context) geometry_field = self.parameterAsString(parameters, self.INPUT_GEOMETRY_FIELD, context) geometry_type = self.parameterAsEnum(parameters, self.INPUT_GEOMETRY_TYPE, context) geometry_crs = self.parameterAsCrs(parameters, self.INPUT_GEOMETRY_CRS, context) df = QgsVirtualLayerDefinition() for layerIdx, layer in enumerate(layers): df.addSource('input{}'.format(layerIdx + 1), layer.id()) if query == '': raise QgsProcessingException( self. tr('Empty SQL. Please enter valid SQL expression and try again.' )) else: localContext = self.createExpressionContext(parameters, context) expandedQuery = QgsExpression.replaceExpressionText( query, localContext) df.setQuery(expandedQuery) if uid_field: df.setUid(uid_field) if geometry_type == 1: # no geometry df.setGeometryWkbType(QgsWkbTypes.NoGeometry) else: if geometry_field: df.setGeometryField(geometry_field) if geometry_type > 1: df.setGeometryWkbType(geometry_type - 1) if geometry_crs.isValid(): df.setGeometrySrid(geometry_crs.postgisSrid()) vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual") if not vLayer.isValid(): raise QgsProcessingException( vLayer.dataProvider().error().message()) (sink, dest_id) = self.parameterAsSink( parameters, self.OUTPUT, context, vLayer.fields(), vLayer.wkbType() if geometry_type != 1 else 1, vLayer.crs()) if sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT)) features = vLayer.getFeatures() total = 100.0 / vLayer.featureCount() if vLayer.featureCount() else 0 for current, inFeat in enumerate(features): if feedback.isCanceled(): break sink.addFeature(inFeat, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def processAlgorithm(self, parameters, context, feedback): layers = self.parameterAsLayerList(parameters, self.INPUT_DATASOURCES, context) query = self.parameterAsString(parameters, self.INPUT_QUERY, context) uid_field = self.parameterAsString(parameters, self.INPUT_UID_FIELD, context) geometry_field = self.parameterAsString(parameters, self.INPUT_GEOMETRY_FIELD, context) geometry_type = self.parameterAsEnum(parameters, self.INPUT_GEOMETRY_TYPE, context) geometry_crs = self.parameterAsCrs(parameters, self.INPUT_GEOMETRY_CRS, context) df = QgsVirtualLayerDefinition() for layerIdx, layer in enumerate(layers): # Issue https://github.com/qgis/QGIS/issues/24041 # When using this algorithm from the graphic modeler, it may try to # access (thanks the QgsVirtualLayerProvider) to memory layer that # belongs to temporary QgsMapLayerStore, not project. # So, we write them to disk is this is the case. if context.project() and not context.project().mapLayer( layer.id()): basename = "memorylayer." + QgsVectorFileWriter.supportedFormatExtensions( )[0] tmp_path = QgsProcessingUtils.generateTempFilename(basename) QgsVectorFileWriter.writeAsVectorFormat( layer, tmp_path, layer.dataProvider().encoding()) df.addSource('input{}'.format(layerIdx + 1), tmp_path, "ogr") else: df.addSource('input{}'.format(layerIdx + 1), layer.id()) if query == '': raise QgsProcessingException( self. tr('Empty SQL. Please enter valid SQL expression and try again.' )) localContext = self.createExpressionContext(parameters, context) expandedQuery = QgsExpression.replaceExpressionText( query, localContext) df.setQuery(expandedQuery) if uid_field: df.setUid(uid_field) if geometry_type == 1: # no geometry df.setGeometryWkbType(QgsWkbTypes.NoGeometry) else: if geometry_field: df.setGeometryField(geometry_field) if geometry_type > 1: df.setGeometryWkbType(geometry_type - 1) if geometry_crs.isValid(): df.setGeometrySrid(geometry_crs.postgisSrid()) vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual") if not vLayer.isValid(): raise QgsProcessingException( vLayer.dataProvider().error().message()) if vLayer.wkbType() == QgsWkbTypes.Unknown: raise QgsProcessingException(self.tr("Cannot find geometry field")) (sink, dest_id) = self.parameterAsSink( parameters, self.OUTPUT, context, vLayer.fields(), vLayer.wkbType() if geometry_type != 1 else 1, vLayer.crs()) if sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT)) features = vLayer.getFeatures() total = 100.0 / vLayer.featureCount() if vLayer.featureCount() else 0 for current, inFeat in enumerate(features): if feedback.isCanceled(): break sink.addFeature(inFeat, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def test1(self): d = QgsVirtualLayerDefinition() self.assertEqual(d.toString(), "") d.setFilePath("/file") self.assertEqual(d.toString(), "/file") self.assertEqual( QgsVirtualLayerDefinition.fromUrl(d.toUrl()).filePath(), "/file") d.setFilePath("C:\\file") self.assertEqual(d.toString(), "C:%5Cfile") self.assertEqual( QgsVirtualLayerDefinition.fromUrl(d.toUrl()).filePath(), "C:\\file") d.setQuery("SELECT * FROM mytable") self.assertEqual( QgsVirtualLayerDefinition.fromUrl(d.toUrl()).query(), "SELECT * FROM mytable") q = u"SELECT * FROM tableéé /*:int*/" d.setQuery(q) self.assertEqual( QgsVirtualLayerDefinition.fromUrl(d.toUrl()).query(), q) s1 = u"file://foo&bar=okié" d.addSource("name", s1, "provider", "utf8") self.assertEqual( QgsVirtualLayerDefinition.fromUrl( d.toUrl()).sourceLayers()[0].source(), s1) n1 = u"éé ok" d.addSource(n1, s1, "provider") self.assertEqual( QgsVirtualLayerDefinition.fromUrl( d.toUrl()).sourceLayers()[1].name(), n1) d.addSource("ref1", "id0001") self.assertEqual( QgsVirtualLayerDefinition.fromUrl( d.toUrl()).sourceLayers()[2].reference(), "id0001") d.setGeometryField("geom") self.assertEqual( QgsVirtualLayerDefinition.fromUrl(d.toUrl()).geometryField(), "geom") d.setGeometryWkbType(QgsWKBTypes.Point) self.assertEqual( QgsVirtualLayerDefinition.fromUrl(d.toUrl()).geometryWkbType(), QgsWKBTypes.Point) f = QgsFields() f.append(QgsField("a", QVariant.Int)) f.append(QgsField("f", QVariant.Double)) f.append(QgsField("s", QVariant.String)) d.setFields(f) f2 = QgsVirtualLayerDefinition.fromUrl(d.toUrl()).fields() self.assertEqual(f[0].name(), f2[0].name()) self.assertEqual(f[0].type(), f2[0].type()) self.assertEqual(f[1].name(), f2[1].name()) self.assertEqual(f[1].type(), f2[1].type()) self.assertEqual(f[2].name(), f2[2].name()) self.assertEqual(f[2].type(), f2[2].type())
def test1(self): d = QgsVirtualLayerDefinition() self.assertEqual(d.toString(), "") d.setFilePath("/file") self.assertEqual(d.toString(), "file:///file") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).filePath(), "/file") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).filePath(), "/file") d.setFilePath(os.path.join('C:/', 'file')) self.assertEqual(d.toString(), "file:///C:/file") # self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).filePath(), os.path.join('C:/', 'file')) d.setQuery("SELECT * FROM mytable") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).query(), "SELECT * FROM mytable") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).query(), "SELECT * FROM mytable") q = "SELECT * FROM tableéé /*:int*/" d.setQuery(q) self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).query(), q) self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).query(), q) s1 = "file://foo&bar=okié" d.addSource("name", s1, "provider", "utf8") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).sourceLayers()[0].source(), s1) self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).sourceLayers()[0].source(), s1) n1 = "éé ok" d.addSource(n1, s1, "provider") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).sourceLayers()[1].name(), n1) self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).sourceLayers()[1].name(), n1) d.addSource("ref1", "id0001") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).sourceLayers()[2].reference(), "id0001") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).sourceLayers()[2].reference(), "id0001") s = "dbname='C:\\tt' table=\"test\" (geometry) sql=" d.addSource("nn", s, "spatialite") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).sourceLayers()[3].source(), s) self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).sourceLayers()[3].source(), s) d.setGeometryField("geom") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).geometryField(), "geom") self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).geometryField(), "geom") d.setGeometryWkbType(QgsWkbTypes.Point) self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).geometryWkbType(), QgsWkbTypes.Point) self.assertEqual(QgsVirtualLayerDefinition.fromUrl(strToUrl(d.toString())).geometryWkbType(), QgsWkbTypes.Point) f = QgsFields() f.append(QgsField("a", QVariant.Int)) f.append(QgsField("f", QVariant.Double)) f.append(QgsField("s", QVariant.String)) d.setFields(f) f2 = QgsVirtualLayerDefinition.fromUrl(d.toUrl()).fields() self.assertEqual(f[0].name(), f2[0].name()) self.assertEqual(f2[0].type(), QVariant.LongLong) self.assertEqual(f[1].name(), f2[1].name()) self.assertEqual(f[1].type(), f2[1].type()) self.assertEqual(f[2].name(), f2[2].name()) self.assertEqual(f[2].type(), f2[2].type()) # Issue https://github.com/qgis/QGIS/issues/44130 url = QUrl(r"?layer_ref=Reprojet%C3%A9_e888ce1e_17a9_46f4_b8c3_254eef3f2931:input1&query=SELECT%20*%20FROM%20input1") f3 = QgsVirtualLayerDefinition.fromUrl(url) self.assertEqual(f3.query(), 'SELECT * FROM input1') source_layer = f3.sourceLayers()[0] self.assertEqual(source_layer.reference(), 'Reprojeté_e888ce1e_17a9_46f4_b8c3_254eef3f2931')