def test_ogr_gmt_coord_only(): with gdaltest.tempfile('/vsimem/test.gmt', """1 2 3\n"""): ds = ogr.Open('/vsimem/test.gmt') lyr = ds.GetLayer(0) f = lyr.GetNextFeature() assert not ogrtest.check_feature_geometry(f, 'POINT Z (1 2 3)'), f.GetGeometryRef().ExportToIsoWkt()
def test_ogr2ogr_lib_makevalid(): # Check if MakeValid() is available g = ogr.CreateGeometryFromWkt('POLYGON ((0 0,10 10,0 10,10 0,0 0))') with gdaltest.error_handler(): make_valid_available = g.MakeValid() is not None tmpfilename = '/vsimem/tmp.csv' with gdaltest.tempfile( tmpfilename, """id,WKT 1,"POLYGON ((0 0,10 10,0 10,10 0,0 0))" 2,"POLYGON ((0 0,0 1,0.5 1,0.5 0.75,0.5 1,1 1,1 0,0 0))" """): if make_valid_available: ds = gdal.VectorTranslate('', tmpfilename, format='Memory', makeValid=True) else: with gdaltest.error_handler(): with pytest.raises(Exception): gdal.VectorTranslate('', tmpfilename, format='Memory', makeValid=True) return lyr = ds.GetLayer(0) f = lyr.GetNextFeature() assert ogrtest.check_feature_geometry( f, "MULTIPOLYGON (((0 0,5 5,10 0,0 0)),((5 5,0 10,10 10,5 5)))") == 0 f = lyr.GetNextFeature() assert ogrtest.check_feature_geometry( f, "POLYGON ((0 0,0 1,0.5 1.0,1 1,1 0,0 0))") == 0
def test_jpegxl_lossless_copy_of_jpeg(): has_box_api = 'COMPRESS_BOX' in gdal.GetDriverByName('JPEGXL').GetMetadataItem('DMD_CREATIONOPTIONLIST') src_ds = gdal.Open('data/jpeg/albania.jpg') outfilename = '/vsimem/out.jxl' gdal.GetDriverByName('JPEGXL').CreateCopy(outfilename, src_ds) if has_box_api: assert gdal.VSIStatL(outfilename + '.aux.xml') is None ds = gdal.Open(outfilename) assert ds is not None if has_box_api: assert set(ds.GetMetadataDomainList()) == set(['DERIVED_SUBDATASETS', 'EXIF', 'IMAGE_STRUCTURE']) assert ds.GetMetadataItem('HAS_JPEG_RECONSTRUCTION_DATA', '_DEBUG_') == 'YES' ds = None gdal.GetDriverByName('JPEGXL').Delete(outfilename) # Test failure in JxlEncoderAddJPEGFrame() by adding a truncated JPEG file data = open('data/jpeg/albania.jpg', 'rb').read() data = data[0:len(data)//2] with gdaltest.tempfile('/vsimem/truncated.jpg', data): src_ds = gdal.Open('/vsimem/truncated.jpg') with gdaltest.error_handler(): assert gdal.GetDriverByName('JPEGXL').CreateCopy(outfilename, src_ds) is None
def test_ogr_gmt_coord_only(): with gdaltest.tempfile('/vsimem/test.gmt', """1 2 3\n"""): ds = ogr.Open('/vsimem/test.gmt') lyr = ds.GetLayer(0) f = lyr.GetNextFeature() assert not ogrtest.check_feature_geometry(f, 'POINT Z (1 2 3)'), f.GetGeometryRef().ExportToIsoWkt()
def test_ogr2ogr_lib_sql_filename(): with gdaltest.tempfile('/vsimem/my.sql', """-- initial comment\nselect\n'--''--' as literalfield,* from --comment\npoly\n-- trailing comment"""): ds = gdal.VectorTranslate('', '../ogr/data/poly.shp', options = '-f Memory -sql @/vsimem/my.sql') lyr = ds.GetLayer(0) assert lyr.GetFeatureCount() == 10 assert lyr.GetLayerDefn().GetFieldIndex('literalfield') == 0
def test_contour_too_many_levels(): ogr_ds = ogr.GetDriverByName('ESRI Shapefile').CreateDataSource( '/vsimem/contour.shp') ogr_lyr = ogr_ds.CreateLayer('contour', geom_type=ogr.wkbLineString) field_defn = ogr.FieldDefn('ID', ogr.OFTInteger) ogr_lyr.CreateField(field_defn) content1 = """ncols 2 nrows 2 xllcorner 0 yllcorner 0 cellsize 1 1e30 0 0 0""" content2 = """ncols 2 nrows 2 xllcorner 0 yllcorner 0 cellsize 1 1e6 0 0 0""" for content in (content1, content2): with gdaltest.tempfile('/vsimem/test.asc', content): ds = gdal.Open('/vsimem/test.asc') with gdaltest.error_handler(): assert gdal.ContourGenerateEx( ds.GetRasterBand(1), ogr_lyr, options=["LEVEL_INTERVAL=1", "ID_FIELD=0"]) != 0 with gdaltest.tempfile('/vsimem/test.asc', content): ds = gdal.Open('/vsimem/test.asc') with gdaltest.error_handler(): assert gdal.ContourGenerateEx( ds.GetRasterBand(1), ogr_lyr, options=[ "LEVEL_INTERVAL=1", "LEVEL_EXP_BASE=1.0001", "ID_FIELD=0" ]) != 0 ogr_ds = None ogr.GetDriverByName('ESRI Shapefile').DeleteDataSource( '/vsimem/contour.shp')
def test_xyz_9(): content = """"A" "B" "C" 0 0 50 10 0 100 0 10 150 10 10 200 """ with gdaltest.tempfile('/vsimem/grid.xyz', content): ds = gdal.Open('/vsimem/grid.xyz') assert ds.RasterXSize == 2 and ds.RasterYSize == 2 cs = ds.GetRasterBand(1).Checksum() assert cs == 22
def test_xyz_organized_by_columns_float32(): content = """X Y Z 0 20 50.5 0 10 100 0 0 150 10 20 200 10 10 250 10 0 300 """ with gdaltest.tempfile('/vsimem/grid.xyz', content): ds = gdal.Open('/vsimem/grid.xyz') assert ds.RasterXSize == 2 and ds.RasterYSize == 3 assert ds.GetGeoTransform() == (-5.0, 10.0, 0.0, 25.0, 0.0, -10.0) assert ds.GetRasterBand(1).DataType == gdal.GDT_Float32 assert struct.unpack('f' * 6, ds.ReadRaster()) == (50.5, 200.0, 100.0, 250.0, 150.0, 300.0)
def test_xyz_floating_point_step_organized_by_columns_float32(): content = """X Y Z 1.1 1.3 50.5 1.1 1.2 100 1.1 1.1 150 1.2 1.3 200 1.2 1.2 250 1.2 1.1 300 1.3 1.3 350 1.3 1.2 400 1.3 1.1 450 """ with gdaltest.tempfile('/vsimem/grid.xyz', content): ds = gdal.Open('/vsimem/grid.xyz') assert ds.RasterXSize == 3 and ds.RasterYSize == 3 assert ds.GetGeoTransform() == pytest.approx( (1.05, 0.1, 0.0, 1.35, 0, -0.1)) assert ds.GetRasterBand(1).DataType == gdal.GDT_Float32 assert struct.unpack('f' * 9, ds.ReadRaster()) == (50.5, 200.0, 350.0, 100.0, 250.0, 400.0, 150.0, 300.0, 450.0)
def test_xyz_floating_point_step_organized_by_rows_int16(): content = """X Y Z 1.1 1.1 50 1.2 1.1 100 1.3 1.1 150 1.1 1.2 200 1.2 1.2 250 1.3 1.2 300 1.1 1.3 350 1.2 1.3 400 1.3 1.3 450 """ with gdaltest.tempfile('/vsimem/grid.xyz', content): ds = gdal.Open('/vsimem/grid.xyz') assert ds.RasterXSize == 3 and ds.RasterYSize == 3 assert ds.GetGeoTransform() == pytest.approx( (1.05, 0.1, 0.0, 1.05, 0, 0.1)) assert ds.GetRasterBand(1).DataType == gdal.GDT_Int16 assert struct.unpack('h' * 9, ds.ReadRaster()) == (50, 100, 150, 200, 250, 300, 350, 400, 450)
def test_ogr_carto_vsimem(): if ogrtest.carto_drv is None: pytest.skip() ogrtest.carto_api_key_ori = gdal.GetConfigOption('CARTO_API_KEY') gdal.SetConfigOption('CARTO_API_URL', '/vsimem/carto') gdal.SetConfigOption('CPL_CURL_ENABLE_VSIMEM', 'YES') gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT postgis_version() LIMIT 500 OFFSET 0&api_key=foo', """{"rows":[{"postgis_version":"2.1 USE_GEOS=1 USE_PROJ=1 USE_STATS=1"}],"time":0.001,"fields":{"postgis_version":{"type":"string"}},"total_rows":1}""" ) gdal.PushErrorHandler() ds = ogr.Open('CARTO:foo') gdal.PopErrorHandler() assert ds is None gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """Content-Type: text/html\r Error""") gdal.PushErrorHandler() ds = ogr.Open('CARTO:foo') gdal.PopErrorHandler() assert ds is None and gdal.GetLastErrorMsg().find('HTML error page') >= 0 gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """""") ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{""") gdal.PushErrorHandler() ds = ogr.Open('CARTO:foo') gdal.PopErrorHandler() assert ds is None and gdal.GetLastErrorMsg().find( 'JSON parsing error') >= 0 gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """ "not_expected_json" """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "error" : [ "bla"] }""") gdal.PushErrorHandler() ds = ogr.Open('CARTO:foo') gdal.PopErrorHandler() assert ds is None and gdal.GetLastErrorMsg().find( 'Error returned by server : bla') >= 0 gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "fields" : null } """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "fields" : "invalid" } """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "fields" : {} } """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "fields" : { "foo": "invalid" } } """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "fields" : { "foo": {} } } """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "fields" : { "foo": { "type" : null } } } """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "fields" : { "foo": { "type" : {} } } } """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "fields" : { "foo": { "type" : "string" } } } """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{"rows":[ {"field1": "foo", "field2": "bar"} ],"fields":{"field1":{"type":"string"}, "field2":{"type":"string"}}}""" ) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{"rows":[],"fields":{"current_schema":{"type":"string"}}}""") gdal.PushErrorHandler() ds = ogr.Open('CARTO:foo') gdal.PopErrorHandler() assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{"rows":[{"current_schema":"public"}],"fields":{"current_schema":{"type":"unknown(19)"}}}""" ) gdal.PushErrorHandler() ds = ogr.Open('CARTO:foo') gdal.PopErrorHandler() assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT CDB_UserTables() LIMIT 500 OFFSET 0', """{"rows":[{"cdb_usertables":"table1"}],"fields":{"cdb_usertables":{"type":"string"}}}""" ) ds = ogr.Open('CARTO:foo') assert ds is not None and ds.GetLayerCount() == 1, gdal.GetLastErrorMsg() gdal.PushErrorHandler() lyr_defn = ds.GetLayer(0).GetLayerDefn() gdal.PopErrorHandler() assert lyr_defn.GetFieldCount() == 0 # Empty layer gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT * FROM "table1" LIMIT 0', """{"rows":[],"fields":{}}""") ds = ogr.Open('CARTO:foo') lyr = ds.GetLayer(0) lyr_defn = lyr.GetLayerDefn() assert lyr_defn.GetFieldCount() == 0 gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT * FROM "table1" LIMIT 500 OFFSET 0', """{"rows":[{}],"fields":{}}}""") f = lyr.GetNextFeature() if f.GetFID() != 0: f.DumpReadable() pytest.fail() # Layer without geometry or primary key gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT * FROM "table1" LIMIT 0', """{"rows":[],"fields":{"strfield":{"type":"string"}, "realfield":{"type":"number"}, "boolfield":{"type":"boolean"}, "datefield":{"type":"date"}}}""" ) ds = ogr.Open('CARTO:foo') lyr = ds.GetLayer(0) lyr_defn = lyr.GetLayerDefn() assert lyr_defn.GetFieldCount() == 4 assert (lyr_defn.GetFieldDefn(0).GetName() == 'strfield' and \ lyr_defn.GetFieldDefn(0).GetType() == ogr.OFTString) assert (lyr_defn.GetFieldDefn(1).GetName() == 'realfield' and \ lyr_defn.GetFieldDefn(1).GetType() == ogr.OFTReal) assert (lyr_defn.GetFieldDefn(2).GetName() == 'boolfield' and \ lyr_defn.GetFieldDefn(2).GetType() == ogr.OFTInteger and \ lyr_defn.GetFieldDefn(2).GetSubType() == ogr.OFSTBoolean) assert (lyr_defn.GetFieldDefn(3).GetName() == 'datefield' and \ lyr_defn.GetFieldDefn(3).GetType() == ogr.OFTDateTime) gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT "strfield", "realfield", "boolfield", "datefield" FROM "table1" LIMIT 500 OFFSET 0', """{"rows":[{ "strfield": "foo", "realfield": 1.23, "boolfield": true, "datefield": "2015-04-24T12:34:56.123Z" }],"fields":{"strfield":{"type":"string"}, "realfield":{"type":"number"}, "boolfield":{"type":"boolean"}, "datefield":{"type":"date"}}}""" ) f = lyr.GetNextFeature() if f['strfield'] != 'foo' or f['realfield'] != 1.23 or f['boolfield'] != 1 or \ f['datefield'] != '2015/04/24 12:34:56.123+00': f.DumpReadable() pytest.fail() gdal.SetConfigOption('CARTO_API_KEY', 'foo') gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0&api_key=foo', """{"rows":[{"current_schema":"public"}],"fields":{"current_schema":{"type":"unknown(19)"}}}""" ) gdal.FileFromMemBuffer( '/vsimem/carto&POSTFIELDS=q=SELECT CDB_UserTables() LIMIT 500 OFFSET 0&api_key=foo', """{"rows":[{"cdb_usertables":"table1"}],"fields":{"cdb_usertables":{"type":"string"}}}""" ) ds = ogr.Open('CARTO:foo') gdal.PushErrorHandler() lyr_defn = ds.GetLayer(0).GetLayerDefn() gdal.PopErrorHandler() assert lyr_defn.GetFieldCount() == 0 get_full_details_fields_url = """/vsimem/carto&POSTFIELDS=q=SELECT a.attname, t.typname, a.attlen, format_type(a.atttypid,a.atttypmod), a.attnum, a.attnotnull, i.indisprimary, pg_get_expr(def.adbin, c.oid) AS defaultexpr, postgis_typmod_dims(a.atttypmod) dim, postgis_typmod_srid(a.atttypmod) srid, postgis_typmod_type(a.atttypmod)::text geomtyp, srtext FROM pg_class c JOIN pg_attribute a ON a.attnum > 0 AND a.attrelid = c.oid AND c.relname = 'table1' JOIN pg_type t ON a.atttypid = t.oid JOIN pg_namespace n ON c.relnamespace=n.oid AND n.nspname= 'public' LEFT JOIN pg_index i ON c.oid = i.indrelid AND i.indisprimary = 't' AND a.attnum = ANY(i.indkey) LEFT JOIN pg_attrdef def ON def.adrelid = c.oid AND def.adnum = a.attnum LEFT JOIN spatial_ref_sys srs ON srs.srid = postgis_typmod_srid(a.atttypmod) ORDER BY a.attnum LIMIT 500 OFFSET 0&api_key=foo""" gdal.FileFromMemBuffer(get_full_details_fields_url, '') ds = ogr.Open('CARTO:foo') gdal.PushErrorHandler() lyr_defn = ds.GetLayer(0).GetLayerDefn() gdal.PopErrorHandler() assert lyr_defn.GetFieldCount() == 0 gdal.FileFromMemBuffer( get_full_details_fields_url, """{"rows":[{"attname":"foo"}], "fields":{"attname":{"type":"string"}}}""" ) ds = ogr.Open('CARTO:foo') lyr = ds.GetLayer(0) gdal.PushErrorHandler() lyr_defn = lyr.GetLayerDefn() gdal.PopErrorHandler() assert lyr_defn.GetFieldCount() == 1 gdal.PushErrorHandler() f = lyr.GetFeature(0) gdal.PopErrorHandler() assert f is None gdal.FileFromMemBuffer( get_full_details_fields_url, """{"rows":[{"attname":"strfield", "typname":"varchar", "attnotnull": true, "defaultexpr": "def_value"}, {"attname":"intfield", "typname":"int4"}, {"attname":"doublefield", "typname":"float"}, {"attname":"boolfield", "typname":"bool"}, {"attname":"datetimefield", "typname":"timestamp"}, {"attname":"cartodb_id","typname":"int4","indisprimary":true}, {"attname":"created_at","typname":"date"}, {"attname":"updated_at","typname":"date"}, {"attname":"my_geom","typname":"geometry","dim":3,"srid":4326,"geomtyp":"Point", "srtext":"GEOGCS[\\"WGS 84\\",DATUM[\\"WGS_1984\\",SPHEROID[\\"WGS 84\\",6378137,298.257223563,AUTHORITY[\\"EPSG\\",\\"7030\\"]],AUTHORITY[\\"EPSG\\",\\"6326\\"]],PRIMEM[\\"Greenwich\\",0,AUTHORITY[\\"EPSG\\",\\"8901\\"]],UNIT[\\"degree\\",0.0174532925199433,AUTHORITY[\\"EPSG\\",\\"9122\\"]],AUTHORITY[\\"EPSG\\",\\"4326\\"]]"}, {"attname":"the_geom_webmercator","typname":"geometry"}], "fields":{"attname":{"type":"string"}, "typname":{"type":"string"}, "attlen":{"type":"number"}, "format_type":{"type":"string"}, "attnum":{"type":"number"}, "attnotnull":{"type":"boolean"}, "indisprimary":{"type":"boolean"}, "defaultexpr":{"type":"string"}, "dim":{"type":"number"}, "srid":{"type":"number"}, "geomtyp":{"type":"string"}, "srtext":{"type":"string"}}}""") ds = ogr.Open('CARTO:foo') lyr = ds.GetLayer(0) lyr_defn = lyr.GetLayerDefn() assert lyr_defn.GetFieldCount() == 5 assert (lyr_defn.GetFieldDefn(0).GetName() == 'strfield' and \ lyr_defn.GetFieldDefn(0).GetType() == ogr.OFTString and not \ lyr_defn.GetFieldDefn(0).IsNullable() and \ lyr_defn.GetFieldDefn(0).GetDefault() == 'def_value') assert lyr_defn.GetGeomFieldCount() == 1 assert lyr_defn.GetGeomFieldDefn(0).GetName() == 'my_geom' assert lyr_defn.GetGeomFieldDefn(0).GetType() == ogr.wkbPoint25D assert lyr_defn.GetGeomFieldDefn(0).GetSpatialRef().ExportToWkt().find( '4326') >= 0 gdal.PushErrorHandler() fc = lyr.GetFeatureCount() gdal.PopErrorHandler() assert fc == 0 gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT COUNT(*) FROM "table1"&api_key=foo""", """{}""") gdal.PushErrorHandler() fc = lyr.GetFeatureCount() gdal.PopErrorHandler() assert fc == 0 gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT COUNT(*) FROM "table1"&api_key=foo""", """{"rows":[{"foo":1}], "fields":{"foo":{"type":"number"}}}""") gdal.PushErrorHandler() fc = lyr.GetFeatureCount() gdal.PopErrorHandler() assert fc == 0 gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT COUNT(*) FROM "table1"&api_key=foo""", """{"rows":[{"count":9876543210}], "fields":{"count":{"type":"number"}}}""") assert lyr.GetFeatureCount() == 9876543210 gdal.PushErrorHandler() extent = lyr.GetExtent() gdal.PopErrorHandler() assert extent == (0, 0, 0, 0) gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT ST_Extent("my_geom") FROM "table1"&api_key=foo""", """{"rows":[{"foo":1}], "fields":{"foo":{"type":"number"}}}""") gdal.PushErrorHandler() extent = lyr.GetExtent() gdal.PopErrorHandler() assert extent == (0, 0, 0, 0) gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT ST_Extent("my_geom") FROM "table1"&api_key=foo""", """{"rows":[{"st_extent":""}], "fields":{"st_extent":{"type":"string"}}}""") gdal.ErrorReset() gdal.PushErrorHandler() lyr.GetExtent() gdal.PopErrorHandler() assert gdal.GetLastErrorMsg() != '' gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT ST_Extent("my_geom") FROM "table1"&api_key=foo""", """{"rows":[{"st_extent":"("}], "fields":{"st_extent":{"type":"string"}}}""") gdal.ErrorReset() gdal.PushErrorHandler() lyr.GetExtent() gdal.PopErrorHandler() assert gdal.GetLastErrorMsg() != '' gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT ST_Extent("my_geom") FROM "table1"&api_key=foo""", """{"rows":[{"st_extent":"BOX()"}], "fields":{"st_extent":{"type":"string"}}}""") gdal.ErrorReset() gdal.PushErrorHandler() lyr.GetExtent() gdal.PopErrorHandler() assert gdal.GetLastErrorMsg() != '' gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT ST_Extent("my_geom") FROM "table1"&api_key=foo""", """{"rows":[{"st_extent":"BOX(0,1,2,3)"}], "fields":{"st_extent":{"type":"string"}}}""") assert lyr.GetExtent() == (0.0, 2.0, 1.0, 3.0) gdal.PushErrorHandler() f = lyr.GetFeature(0) gdal.PopErrorHandler() assert f is None gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE "cartodb_id" = 0&api_key=foo""", """""") gdal.PushErrorHandler() f = lyr.GetFeature(0) gdal.PopErrorHandler() assert f is None gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE "cartodb_id" = 0&api_key=foo""", """{"rows":[{"st_extent":"BOX(0,1,2,3)"}], "fields":{"st_extent":{"type":"string"}}}""") f = lyr.GetFeature(0) assert f.GetFID() == -1 and f.IsFieldNull(0) gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE "cartodb_id" = 0&api_key=foo""", """{"rows":[{"cartodb_id":0}], "fields":{"cartodb_id":{"type":"numeric"}}}""") f = lyr.GetFeature(0) assert f.GetFID() == 0 lyr.ResetReading() gdal.PushErrorHandler() f = lyr.GetNextFeature() gdal.PopErrorHandler() assert f is None gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE "cartodb_id" >= 0 ORDER BY "cartodb_id" ASC LIMIT 500&api_key=foo""", """{"rows":[{"cartodb_id":0}], "fields":{"cartodb_id":{"type":"numeric"}}}""") lyr.ResetReading() f = lyr.GetNextFeature() assert f.GetFID() == 0 gdal.PushErrorHandler() f = lyr.GetNextFeature() gdal.PopErrorHandler() assert f is None gdal.SetConfigOption('CARTO_PAGE_SIZE', '2') gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE "cartodb_id" >= 0 ORDER BY "cartodb_id" ASC LIMIT 2&api_key=foo""", """{"rows":[{"cartodb_id":0},{"cartodb_id":10}], "fields":{"cartodb_id":{"type":"numeric"}}}""") lyr.ResetReading() f = lyr.GetNextFeature() assert f.GetFID() == 0 f = lyr.GetNextFeature() assert f.GetFID() == 10 gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE "cartodb_id" >= 11 ORDER BY "cartodb_id" ASC LIMIT 2&api_key=foo""", """{"rows":[{"cartodb_id":12}], "fields":{"cartodb_id":{"type":"numeric"}}}""") f = lyr.GetNextFeature() assert f.GetFID() == 12 gdal.ErrorReset() f = lyr.GetNextFeature() assert f is None and gdal.GetLastErrorMsg() == '' lyr.SetAttributeFilter('strfield is NULL') gdal.PushErrorHandler() fc = lyr.GetFeatureCount() gdal.PopErrorHandler() assert fc == 0 gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE (strfield is NULL) AND "cartodb_id" >= 0 ORDER BY "cartodb_id" ASC LIMIT 2&api_key=foo""", """{"rows":[{"cartodb_id":0}], "fields":{"cartodb_id":{"type":"numeric"}}}""") lyr.ResetReading() f = lyr.GetNextFeature() assert f is not None gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE (strfield is NULL) AND "cartodb_id" >= 1 ORDER BY "cartodb_id" ASC LIMIT 2&api_key=foo""", """{"rows":[], "fields":{"cartodb_id":{"type":"numeric"}}}""") gdal.ErrorReset() f = lyr.GetNextFeature() assert f is None and gdal.GetLastErrorMsg() == '' gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT COUNT(*) FROM "table1" WHERE (strfield is NULL)&api_key=foo""", """{"rows":[{"count":9876543210}], "fields":{"count":{"type":"number"}}}""") assert lyr.GetFeatureCount() == 9876543210 lyr.SetSpatialFilterRect(-180, -90, 180, 90) gdal.PushErrorHandler() fc = lyr.GetFeatureCount() gdal.PopErrorHandler() assert fc == 0 gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE ("my_geom" %26%26 'BOX3D(-180 -90, 180 90)'::box3d) AND (strfield is NULL) AND "cartodb_id" >= 0 ORDER BY "cartodb_id" ASC LIMIT 2&api_key=foo""", """{"rows":[{"cartodb_id":20, "my_geom": "010100000000000000000000400000000000804840" }], "fields":{"cartodb_id":{"type":"numeric"}, "my_geom":{"type":"string"}}}""" ) lyr.ResetReading() f = lyr.GetNextFeature() assert f is not None and f.GetGeometryRef().ExportToWkt() == 'POINT (2 49)' gdal.PushErrorHandler() fc = lyr.GetFeatureCount() gdal.PopErrorHandler() assert fc == 1 gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT COUNT(*) FROM "table1" WHERE ("my_geom" %26%26 'BOX3D(-180 -90, 180 90)'::box3d) AND (strfield is NULL)&api_key=foo""", """{"rows":[{"count":9876543210}], "fields":{"count":{"type":"number"}}}""") assert lyr.GetFeatureCount() == 9876543210 # Not permitted in read-only mode f = ogr.Feature(lyr.GetLayerDefn()) gdal.PushErrorHandler() ds.CreateLayer('foo') ds.DeleteLayer(0) lyr.CreateFeature(f) lyr.SetFeature(f) lyr.DeleteFeature(0) lyr.CreateField(ogr.FieldDefn('foo')) lyr.DeleteField(0) gdal.PopErrorHandler() ds = None gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=DROP FUNCTION IF EXISTS ogr_table_metadata(TEXT,TEXT); CREATE OR REPLACE FUNCTION ogr_table_metadata(schema_name TEXT, table_name TEXT) RETURNS TABLE (attname TEXT, typname TEXT, attlen INT, format_type TEXT, attnum INT, attnotnull BOOLEAN, indisprimary BOOLEAN, defaultexpr TEXT, dim INT, srid INT, geomtyp TEXT, srtext TEXT) AS $$ SELECT a.attname::text, t.typname::text, a.attlen::int, format_type(a.atttypid,a.atttypmod)::text, a.attnum::int, a.attnotnull::boolean, i.indisprimary::boolean, pg_get_expr(def.adbin, c.oid)::text AS defaultexpr, (CASE WHEN t.typname = 'geometry' THEN postgis_typmod_dims(a.atttypmod) ELSE NULL END)::int dim, (CASE WHEN t.typname = 'geometry' THEN postgis_typmod_srid(a.atttypmod) ELSE NULL END)::int srid, (CASE WHEN t.typname = 'geometry' THEN postgis_typmod_type(a.atttypmod) ELSE NULL END)::text geomtyp, srtext FROM pg_class c JOIN pg_attribute a ON a.attnum > 0 AND a.attrelid = c.oid AND c.relname = $2 AND c.relname IN (SELECT CDB_UserTables())JOIN pg_type t ON a.atttypid = t.oid JOIN pg_namespace n ON c.relnamespace=n.oid AND n.nspname = $1 LEFT JOIN pg_index i ON c.oid = i.indrelid AND i.indisprimary = 't' AND a.attnum = ANY(i.indkey) LEFT JOIN pg_attrdef def ON def.adrelid = c.oid AND def.adnum = a.attnum LEFT JOIN spatial_ref_sys srs ON srs.srid = postgis_typmod_srid(a.atttypmod) ORDER BY a.attnum $$ LANGUAGE SQL&api_key=foo""", """""" "") gdal.SetConfigOption('CARTO_PAGE_SIZE', None) ds = ogr.Open('CARTO:foo', update=1) lyr = ds.CreateLayer('MY_LAYER') gdal.ErrorReset() gdal.PushErrorHandler() lyr.GetNextFeature() gdal.PopErrorHandler() assert gdal.GetLastErrorMsg() != '' gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT cdb_cartodbfytable('my_layer')&api_key=foo""", """{"rows":[], "fields":{}}""") ds = None gdal.Unlink( """/vsimem/carto&POSTFIELDS=q=SELECT cdb_cartodbfytable('my_layer')&api_key=foo""" ) ds = gdal.OpenEx('CARTO:foo', gdal.OF_VECTOR | gdal.OF_UPDATE, open_options=['COPY_MODE=NO']) gdal.SetConfigOption('CARTO_MAX_CHUNK_SIZE', '0') sr = osr.SpatialReference() sr.ImportFromEPSG(4326) lyr = ds.CreateLayer('MY_LAYER', srs=sr) fld_defn = ogr.FieldDefn('STRFIELD', ogr.OFTString) fld_defn.SetNullable(0) fld_defn.SetDefault("'DEFAULT VAL'") fld_defn.SetWidth(20) lyr.CreateField(fld_defn) gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=CREATE TABLE "my_layer" ( cartodb_id SERIAL,the_geom GEOMETRY(GEOMETRY, 4326),"strfield" VARCHAR NOT NULL DEFAULT 'DEFAULT VAL',PRIMARY KEY (cartodb_id) );DROP SEQUENCE IF EXISTS "my_layer_cartodb_id_seq" CASCADE;CREATE SEQUENCE "my_layer_cartodb_id_seq" START 1;ALTER SEQUENCE "my_layer_cartodb_id_seq" OWNED BY "my_layer".cartodb_id;ALTER TABLE "my_layer" ALTER COLUMN cartodb_id SET DEFAULT nextval('"my_layer_cartodb_id_seq"')&api_key=foo""", """{"rows":[], "fields":{}}""") f = ogr.Feature(lyr.GetLayerDefn()) gdal.PushErrorHandler() ret = lyr.CreateFeature(f) gdal.PopErrorHandler() assert ret != 0 f = None fld_defn = ogr.FieldDefn('INTFIELD', ogr.OFTInteger) # No server answer with gdaltest.error_handler(): ret = lyr.CreateField(fld_defn) assert ret != 0 gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=ALTER TABLE "my_layer" ADD COLUMN "intfield" INTEGER&api_key=foo""", """{"rows":[], "fields":{}}""") assert lyr.CreateField(fld_defn) == 0 fld_defn = ogr.FieldDefn('boolfield', ogr.OFTInteger) fld_defn.SetSubType(ogr.OFSTBoolean) gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=ALTER TABLE "my_layer" ADD COLUMN "boolfield" BOOLEAN&api_key=foo""", """{"rows":[], "fields":{}}""") assert lyr.CreateField(fld_defn) == 0 # Invalid field with gdaltest.error_handler(): assert lyr.DeleteField(-1) != 0 # No server answer with gdaltest.error_handler(): assert lyr.DeleteField(0) != 0 gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=ALTER TABLE "my_layer" DROP COLUMN "boolfield"&api_key=foo""", """{"rows":[], "fields":{}}""") fld_pos = lyr.GetLayerDefn().GetFieldIndex(fld_defn.GetName()) assert lyr.DeleteField(fld_pos) == 0 gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=ALTER TABLE "my_layer" ADD COLUMN "boolfield" BOOLEAN&api_key=foo""", """{"rows":[], "fields":{}}""") assert lyr.CreateField(fld_defn) == 0 f = ogr.Feature(lyr.GetLayerDefn()) gdal.PushErrorHandler() ret = lyr.CreateFeature(f) gdal.PopErrorHandler() assert ret != 0 f = ogr.Feature(lyr.GetLayerDefn()) f.SetField('strfield', 'foo') f.SetField('intfield', 1) f.SetField('boolfield', 1) f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(2 49)')) gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=INSERT INTO "my_layer" ("strfield", "intfield", "boolfield", "the_geom") VALUES ('foo', 1, 't', '0101000020E610000000000000000000400000000000804840') RETURNING "cartodb_id"&api_key=foo""", """{"rows":[ {"cartodb_id": 1} ], "fields":{"cartodb_id":{"type":"integer"}}}""") ret = lyr.CreateFeature(f) assert ret == 0 and f.GetFID() == 1 f.SetFID(-1) gdal.PushErrorHandler() ret = lyr.SetFeature(f) gdal.PopErrorHandler() assert ret != 0 f.SetFID(3) gdal.PushErrorHandler() ret = lyr.SetFeature(f) gdal.PopErrorHandler() assert ret != 0 gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=UPDATE "my_layer" SET "strfield" = 'foo', "intfield" = 1, "boolfield" = 't', "the_geom" = '0101000020E610000000000000000000400000000000804840' WHERE "cartodb_id" = 3&api_key=foo""", """{"total_rows": 0}""") ret = lyr.SetFeature(f) assert ret == ogr.OGRERR_NON_EXISTING_FEATURE gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=UPDATE "my_layer" SET "strfield" = 'foo', "intfield" = 1, "boolfield" = 't', "the_geom" = '0101000020E610000000000000000000400000000000804840' WHERE "cartodb_id" = 3&api_key=foo""", """{"total_rows": 1}""") ret = lyr.SetFeature(f) assert ret == 0 f = ogr.Feature(lyr.GetLayerDefn()) gdal.PushErrorHandler() ret = lyr.CreateFeature(f) gdal.PopErrorHandler() assert ret != 0 gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=INSERT INTO "my_layer" DEFAULT VALUES RETURNING "cartodb_id"&api_key=foo""", """{"rows":[ {"cartodb_id": 4} ], "fields":{"cartodb_id":{"type":"integer"}}}""") ret = lyr.CreateFeature(f) assert ret == 0 and f.GetFID() == 4 gdal.PushErrorHandler() ret = lyr.DeleteFeature(0) gdal.PopErrorHandler() assert ret != 0 gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=DELETE FROM "my_layer" WHERE "cartodb_id" = 0&api_key=foo""", """{"total_rows": 0}""") ret = lyr.DeleteFeature(0) assert ret == ogr.OGRERR_NON_EXISTING_FEATURE gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=DELETE FROM "my_layer" WHERE "cartodb_id" = 0&api_key=foo""", """{"total_rows": 1}""") ret = lyr.DeleteFeature(0) assert ret == 0 gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT cdb_cartodbfytable('my_layer')&api_key=foo""", """{"rows":[], "fields":{}}""") ds = None gdal.SetConfigOption('CARTO_MAX_CHUNK_SIZE', None) ds = gdal.OpenEx('CARTO:foo', gdal.OF_VECTOR | gdal.OF_UPDATE, open_options=['COPY_MODE=NO']) lyr = ds.GetLayer(0) gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT pg_catalog.pg_get_serial_sequence('table1', 'cartodb_id') AS seq_name&api_key=foo""", """{"rows":[{"seq_name":"table1_cartodb_id_seq0"}],"fields":{"seq_name":{"type":"string"}}}""" ) gdal.FileFromMemBuffer( """/vsimem/carto&POSTFIELDS=q=SELECT nextval('table1_cartodb_id_seq0') AS nextid&api_key=foo""", """{"rows":[{"nextid":11}],"fields":{"nextid":{"type":"number"}}}""") f = ogr.Feature(lyr.GetLayerDefn()) f.SetField('strfield', 'foo') ret = lyr.CreateFeature(f) assert ret == 0 and f.GetFID() == 11 f = ogr.Feature(lyr.GetLayerDefn()) with gdaltest.tempfile( """/vsimem/carto&POSTFIELDS=q=BEGIN;INSERT INTO "table1" ("strfield", "cartodb_id") VALUES ('foo', 11);INSERT INTO "table1" DEFAULT VALUES;COMMIT;&api_key=foo""", """{"rows":[], "fields":{}}"""): ret = lyr.CreateFeature(f) ds = None if ret != 0 or f.GetFID() != 12: f.DumpReadable() pytest.fail() ds = gdal.OpenEx('CARTO:foo', gdal.OF_VECTOR | gdal.OF_UPDATE, open_options=['COPY_MODE=NO']) lyr = ds.GetLayer(0) f = ogr.Feature(lyr.GetLayerDefn()) f.SetFieldNull('strfield') with gdaltest.tempfile( """/vsimem/carto&POSTFIELDS=q=BEGIN;INSERT INTO "table1" ("strfield", "cartodb_id") VALUES (NULL, 11);COMMIT;&api_key=foo""", """{"rows":[], "fields":{}}"""): ret = lyr.CreateFeature(f) ds = None if ret != 0 or f.GetFID() != 11: f.DumpReadable() pytest.fail() # Now remove default value to strfield gdal.FileFromMemBuffer( get_full_details_fields_url, """{"rows":[{"attname":"strfield", "typname":"varchar"}, {"attname":"intfield", "typname":"int4"}, {"attname":"doublefield", "typname":"float"}, {"attname":"boolfield", "typname":"bool"}, {"attname":"datetimefield", "typname":"timestamp"}, {"attname":"cartodb_id","typname":"int4","indisprimary":true}, {"attname":"created_at","typname":"date"}, {"attname":"updated_at","typname":"date"}, {"attname":"my_geom","typname":"geometry","dim":3,"srid":4326,"geomtyp":"Point", "srtext":"GEOGCS[\\"WGS 84\\",DATUM[\\"WGS_1984\\",SPHEROID[\\"WGS 84\\",6378137,298.257223563,AUTHORITY[\\"EPSG\\",\\"7030\\"]],AUTHORITY[\\"EPSG\\",\\"6326\\"]],PRIMEM[\\"Greenwich\\",0,AUTHORITY[\\"EPSG\\",\\"8901\\"]],UNIT[\\"degree\\",0.0174532925199433,AUTHORITY[\\"EPSG\\",\\"9122\\"]],AUTHORITY[\\"EPSG\\",\\"4326\\"]]"}, {"attname":"the_geom_webmercator","typname":"geometry"}], "fields":{"attname":{"type":"string"}, "typname":{"type":"string"}, "attlen":{"type":"number"}, "format_type":{"type":"string"}, "attnum":{"type":"number"}, "attnotnull":{"type":"boolean"}, "indisprimary":{"type":"boolean"}, "defaultexpr":{"type":"string"}, "dim":{"type":"number"}, "srid":{"type":"number"}, "geomtyp":{"type":"string"}, "srtext":{"type":"string"}}}""") ds = gdal.OpenEx('CARTO:foo', gdal.OF_VECTOR | gdal.OF_UPDATE, open_options=['COPY_MODE=NO']) lyr = ds.GetLayer(0) f = ogr.Feature(lyr.GetLayerDefn()) f.SetField('strfield', 'foo') with gdaltest.tempfile( """/vsimem/carto&POSTFIELDS=q=SELECT nextval('table1_cartodb_id_seq') AS nextid&api_key=foo""", """{"rows":[{"nextid":11}],"fields":{"nextid":{"type":"number"}}}""" ): ret = lyr.CreateFeature(f) assert ret == 0 and f.GetFID() == 11 f = ogr.Feature(lyr.GetLayerDefn()) f.SetField('strfield', 'bar') ret = lyr.CreateFeature(f) assert ret == 0 and f.GetFID() == 12 f = ogr.Feature(lyr.GetLayerDefn()) f.SetField('strfield', 'baz') ret = lyr.CreateFeature(f) assert ret == 0 and f.GetFID() == 13 gdal.ErrorReset() with gdaltest.tempfile( """/vsimem/carto&POSTFIELDS=q=BEGIN;INSERT INTO "table1" ("strfield", "cartodb_id") VALUES ('foo', 11);INSERT INTO "table1" ("strfield", "intfield", "doublefield", "boolfield", "datetimefield", "my_geom") VALUES ('bar', NULL, NULL, NULL, NULL, NULL), ('baz', NULL, NULL, NULL, NULL, NULL);COMMIT;&api_key=foo""", """{"rows":[], "fields":{}}"""): ds = None assert gdal.GetLastErrorMsg() == '' ds = gdal.OpenEx('CARTO:foo', gdal.OF_VECTOR | gdal.OF_UPDATE, open_options=['COPY_MODE=NO']) gdal.PushErrorHandler() lyr = ds.CreateLayer('table1') gdal.PopErrorHandler() assert lyr is None with gdaltest.tempfile( """/vsimem/carto&POSTFIELDS=q=BEGIN; DROP TABLE IF EXISTS "table1";CREATE TABLE "table1" ( cartodb_id SERIAL,the_geom Geometry(MULTIPOLYGON,0),PRIMARY KEY (cartodb_id) );DROP SEQUENCE IF EXISTS "table1_cartodb_id_seq" CASCADE;CREATE SEQUENCE "table1_cartodb_id_seq" START 1;ALTER SEQUENCE "table1_cartodb_id_seq" OWNED BY "table1".cartodb_id;ALTER TABLE "table1" ALTER COLUMN cartodb_id SET DEFAULT nextval('"table1_cartodb_id_seq"'); COMMIT;&api_key=foo""", """{"rows":[], "fields":{}}"""): lyr = ds.CreateLayer('table1', geom_type=ogr.wkbPolygon, options=['OVERWRITE=YES', 'CARTODBFY=NO']) f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt('POLYGON((0 0,0 1,1 0,0 0))')) assert lyr.CreateFeature(f) == 0 gdal.ErrorReset() with gdaltest.tempfile( """/vsimem/carto&POSTFIELDS=q=BEGIN;INSERT INTO "table1" ("the_geom") VALUES ('0106000020E61000000100000001030000000100000004000000000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000000000000000000000000000000000000000');COMMIT;&api_key=foo""", """{"rows":[], "fields":{}}"""): ds = None assert gdal.GetLastErrorMsg() == '' ds = gdal.OpenEx('CARTO:foo', gdal.OF_VECTOR | gdal.OF_UPDATE, open_options=['COPY_MODE=NO']) with gdaltest.tempfile( """/vsimem/carto&POSTFIELDS=q=BEGIN; DROP TABLE IF EXISTS "table1";CREATE TABLE "table1" ( cartodb_id SERIAL,the_geom Geometry(MULTIPOLYGON,0),PRIMARY KEY (cartodb_id) );DROP SEQUENCE IF EXISTS "table1_cartodb_id_seq" CASCADE;CREATE SEQUENCE "table1_cartodb_id_seq" START 1;ALTER SEQUENCE "table1_cartodb_id_seq" OWNED BY "table1".cartodb_id;ALTER TABLE "table1" ALTER COLUMN cartodb_id SET DEFAULT nextval('"table1_cartodb_id_seq"'); COMMIT;&api_key=foo""", """{"rows":[], "fields":{}}"""): lyr = ds.CreateLayer('table1', geom_type=ogr.wkbPolygon, options=['OVERWRITE=YES', 'CARTODBFY=NO']) f = ogr.Feature(lyr.GetLayerDefn()) f.SetFID(100) with gdaltest.tempfile( """/vsimem/carto&POSTFIELDS=q=BEGIN;INSERT INTO "table1" ("cartodb_id") VALUES (100);COMMIT;&api_key=foo""", """{"rows":[], "fields":{}}"""): assert lyr.CreateFeature(f) == 0 assert f.GetFID() == 100 ds = None ds = ogr.Open('CARTO:foo', update=1) gdal.PushErrorHandler() ret = ds.DeleteLayer(0) gdal.PopErrorHandler() assert ret != 0 gdal.ErrorReset() ds = gdal.OpenEx('CARTO:foo', gdal.OF_VECTOR | gdal.OF_UPDATE, open_options=['COPY_MODE=YES']) assert ds is not None lyr = ds.GetLayerByName('table1') assert lyr is not None with gdaltest.tempfile( """/vsimem/carto/copyfrom?q=COPY%20"table1"%20("strfield","my_geom","cartodb_id")%20FROM%20STDIN%20WITH%20(FORMAT%20text,%20ENCODING%20UTF8)&api_key=foo&POSTFIELDS=copytest\t0101000020E610000000000000000059400000000000005940\t11\n\\.\n""", """{}"""): with gdaltest.tempfile( """/vsimem/carto/copyfrom?q=COPY%20"table1"%20("intfield","my_geom")%20FROM%20STDIN%20WITH%20(FORMAT%20text,%20ENCODING%20UTF8)&api_key=foo&POSTFIELDS=12\t0101000020E610000000000000000059400000000000005940\n\\.\n""", """{}"""): f = ogr.Feature(lyr.GetLayerDefn()) f.SetField('strfield', 'copytest') f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(100 100)')) assert lyr.CreateFeature(f) == 0 f = ogr.Feature(lyr.GetLayerDefn()) f.SetField('intfield', 12) f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(100 100)')) assert lyr.CreateFeature(f) == 0 ds = None # force flush ds = ogr.Open('CARTO:foo', update=1) gdal.ErrorReset() with gdaltest.tempfile( """/vsimem/carto&POSTFIELDS=q=DROP TABLE "table1"&api_key=foo""", """{"rows":[], "fields":{}}"""): ds.ExecuteSQL('DELLAYER:table1') assert gdal.GetLastErrorMsg() == '' and ds.GetLayerByName('table1') is None with gdaltest.tempfile( '/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0&api_key=foo', """{"rows":[{"current_schema":"my_schema"}],"fields":{"current_schema":{"type":"unknown(19)"}}}""" ): with gdaltest.tempfile( '/vsimem/carto&POSTFIELDS=q=SELECT CDB_UserTables() LIMIT 500 OFFSET 0&api_key=foo', """{"rows":[],"fields":{"cdb_usertables":{"type":"string"}}}""" ): with gdaltest.tempfile( """/vsimem/carto&POSTFIELDS=q=SELECT c.relname FROM pg_class c, pg_namespace n WHERE c.relkind in ('r', 'v') AND c.relname !~ '^pg_' AND c.relnamespace=n.oid AND n.nspname = 'my_schema' LIMIT 500 OFFSET 0&api_key=foo""", """{"rows":[{"relname": "a_layer"}],"fields":{"relname":{"type":"string"}}}""" ): ds = ogr.Open('CARTO:foo') assert ds.GetLayerByName('a_layer') is not None
def test_eeda_2(): gdal.FileFromMemBuffer( '/vsimem/ee/projects/earthengine-public/assets/collection:listImages?pageSize=1', json.dumps({ 'images': [{ 'properties': { 'string_field': 'bar', 'int_field': 1, 'int64_field': 123456789012, 'double_field': 1.23 } }] })) # To please the unregistering of the persistent connection gdal.FileFromMemBuffer('/vsimem/ee/', '') gdal.SetConfigOption('EEDA_BEARER', 'mybearer') gdal.SetConfigOption('EEDA_URL', '/vsimem/ee/') ds = ogr.Open('EEDA:collection') gdal.SetConfigOption('EEDA_URL', None) lyr = ds.GetLayer(0) assert lyr.TestCapability(ogr.OLCStringsAsUTF8) == 1 assert lyr.TestCapability('foo') == 0 assert lyr.GetLayerDefn().GetFieldCount() == 8 + 7 + 4 assert lyr.GetExtent() == (-180.0, 180.0, -90.0, 90.0) assert lyr.GetFeatureCount() == -1 gdal.FileFromMemBuffer( '/vsimem/ee/projects/earthengine-public/assets/collection:listImages', json.dumps({ 'images': [{ 'name': 'projects/earthengine-public/assets/collection/first_feature', 'id': 'collection/first_feature', 'updateTime': '2017-01-04T12:34:56.789Z', 'startTime': '2017-01-02T12:34:56.789Z', 'endTime': '2017-01-03T12:34:56.789Z', 'sizeBytes': 1, 'geometry': { 'type': 'Polygon', 'coordinates': [[[2, 49], [2.1, 49], [2.1, 49.1], [2, 49.1], [2, 49]]] }, 'properties': { 'string_field': 'bar', 'int_field': 1, 'int64_field': 123456789012, 'double_field': 1.23, 'another_prop': 3 }, 'bands': [{ "id": "B1", "dataType": { "precision": "INT", "range": { "max": 255 } }, "grid": { "crsCode": "EPSG:32610", "affineTransform": { "translateX": 499980, "translateY": 4200000, "scaleX": 60, "scaleY": -60 }, "dimensions": { "width": 1830, "height": 1831 } } }] }, { 'name': 'projects/earthengine-public/assets/collection/second_feature' }], 'nextPageToken': 'myToken' })) f = lyr.GetNextFeature() if f.GetField('name') != 'projects/earthengine-public/assets/collection/first_feature' or \ f.GetField('id') != 'collection/first_feature' or \ f.GetField('gdal_dataset') != 'EEDAI:projects/earthengine-public/assets/collection/first_feature' or \ f.GetField('updateTime') != '2017/01/04 12:34:56.789+00' or \ f.GetField('startTime') != '2017/01/02 12:34:56.789+00' or \ f.GetField('endTime') != '2017/01/03 12:34:56.789+00' or \ f.GetField('sizeBytes') != 1 or \ f.GetField('band_count') != 1 or \ f.GetField('band_max_width') != 1830 or \ f.GetField('band_max_height') != 1831 or \ f.GetField('band_min_pixel_size') != 60 or \ f.GetField('band_upper_left_x') != 499980 or \ f.GetField('band_upper_left_y') != 4200000 or \ f.GetField('band_crs') != 'EPSG:32610' or \ f.GetField('string_field') != 'bar' or \ f.GetField('int_field') != 1 or \ f.GetField('int64_field') != 123456789012 or \ f.GetField('double_field') != 1.23 or \ f.GetField('other_properties') != '{ "another_prop": 3 }' or \ f.GetGeometryRef().ExportToWkt() != 'MULTIPOLYGON (((2 49,2.1 49.0,2.1 49.1,2.0 49.1,2 49)))': f.DumpReadable() pytest.fail() f = lyr.GetNextFeature() if f.GetField( 'name' ) != 'projects/earthengine-public/assets/collection/second_feature': f.DumpReadable() pytest.fail() gdal.FileFromMemBuffer( '/vsimem/ee/projects/earthengine-public/assets/collection:listImages?pageToken=myToken', json.dumps({ 'images': [{ 'name': 'projects/earthengine-public/assets/collection/third_feature' }] })) f = lyr.GetNextFeature() if f.GetField( 'name' ) != 'projects/earthengine-public/assets/collection/third_feature': f.DumpReadable() pytest.fail() f = lyr.GetNextFeature() assert f is None lyr.ResetReading() f = lyr.GetNextFeature() if f.GetField( 'name' ) != 'projects/earthengine-public/assets/collection/first_feature': f.DumpReadable() pytest.fail() lyr.SetAttributeFilter('EEDA:raw_filter') gdal.FileFromMemBuffer( '/vsimem/ee/projects/earthengine-public/assets/collection:listImages?filter=raw%5Ffilter', json.dumps({ 'images': [{ 'name': 'projects/earthengine-public/assets/collection/raw_filter' }] })) f = lyr.GetNextFeature() assert f.GetField( 'name') == 'projects/earthengine-public/assets/collection/raw_filter' lyr.SetAttributeFilter(None) lyr.SetAttributeFilter("startTime >= '1980-01-01T00:00:00Z' AND " + "string_field = 'bar' AND " + "int_field > 0 AND " + "int_field < 2 AND " + "int64_field >= 0 AND " + "int64_field <= 9999999999999 AND " + "double_field != 3.5 AND " + "string_field IN ('bar', 'baz') AND " + "NOT( int_field IN (0) OR double_field IN (3.5) )") tmpfile = '/vsimem/ee/projects/earthengine-public/assets/collection:listImages?region=%7B%20%22type%22%3A%20%22Polygon%22%2C%20%22coordinates%22%3A%20%5B%20%5B%20%5B%20%2D180%2E0%2C%20%2D90%2E0%20%5D%2C%20%5B%20%2D180%2E0%2C%2090%2E0%20%5D%2C%20%5B%20180%2E0%2C%2090%2E0%20%5D%2C%20%5B%20180%2E0%2C%20%2D90%2E0%20%5D%2C%20%5B%20%2D180%2E0%2C%20%2D90%2E0%20%5D%20%5D%20%5D%20%7D&filter=%28%28%28string%5Ffield%20%3D%20%22bar%22%20AND%20%28int%5Ffield%20%3E%200%20AND%20int%5Ffield%20%3C%202%29%29%20AND%20%28%28int64%5Ffield%20%3E%3D%200%20AND%20int64%5Ffield%20%3C%3D%209999999999999%29%20AND%20%28double%5Ffield%20%21%3D%203%2E5%20AND%20string%5Ffield%20%3D%20%22bar%22%20OR%20string%5Ffield%20%3D%20%22baz%22%29%29%29%20AND%20%28NOT%20%28int%5Ffield%20%3D%200%20OR%20double%5Ffield%20%3D%203%2E5%29%29%29&startTime=1980%2D01%2D01T00%3A00%3A00Z' with gdaltest.tempfile( tmpfile, json.dumps({ 'images': [{ 'name': 'projects/earthengine-public/assets/collection/filtered_feature', 'updateTime': '2017-01-03T12:34:56.789Z', 'startTime': '2017-01-02T12:34:56.789Z', 'sizeBytes': 1, 'geometry': { 'type': 'Polygon', 'coordinates': [[[2, 49], [2.1, 49], [2.1, 49.1], [2, 49.1], [2, 49]]] }, 'properties': { 'string_field': 'bar', 'int_field': 1, 'int64_field': 123456789012, 'double_field': 1.23, 'another_prop': 3 } }, { 'name': 'projects/earthengine-public/assets/collection/second_feature' }] })): lyr.SetSpatialFilterRect(-180, -90, 180, 90) f = lyr.GetNextFeature() assert f.GetField( 'name' ) == 'projects/earthengine-public/assets/collection/filtered_feature' lyr.SetSpatialFilter(None) # Test time equality with second granularity lyr.SetAttributeFilter( "startTime >= '1980-01-01T00:00:00Z' AND endTime <= '1980-01-02T23:59:59Z'" ) tmpfile = '/vsimem/ee/projects/earthengine-public/assets/collection:listImages?startTime=1980%2D01%2D01T00%3A00%3A00Z&endTime=1980%2D01%2D02T23%3A59%3A59Z' with gdaltest.tempfile( tmpfile, json.dumps({ 'images': [{ 'name': 'projects/earthengine-public/assets/collection/filtered_feature', 'startTime': '1980-01-01T00:00:00Z', 'endTime': '1980-01-02T23:59:59Z' }, { 'name': 'projects/earthengine-public/assets/collection/second_feature' }] })): f = lyr.GetNextFeature() assert f.GetField( 'name' ) == 'projects/earthengine-public/assets/collection/filtered_feature' # Test time equality with day granularity lyr.SetAttributeFilter( "startTime = '1980-01-01' AND endTime = '1980-01-02'") tmpfile = '/vsimem/ee/projects/earthengine-public/assets/collection:listImages?startTime=1980%2D01%2D01T00%3A00%3A00Z&endTime=1980%2D01%2D02T23%3A59%3A59Z' with gdaltest.tempfile( tmpfile, json.dumps({ 'images': [{ 'name': 'projects/earthengine-public/assets/collection/filtered_feature', 'startTime': '1980-01-01T12:00:00Z', 'endTime': '1980-01-02T23:59:59Z' }, { 'name': 'projects/earthengine-public/assets/collection/second_feature' }] })): f = lyr.GetNextFeature() assert f.GetField( 'name' ) == 'projects/earthengine-public/assets/collection/filtered_feature' ds = None gdal.SetConfigOption('EEDA_BEARER', None)
def test_eeda_4(): gdal.SetConfigOption('EEDA_BEARER', 'mybearer') gdal.SetConfigOption('EEDA_URL', '/vsimem/ee/') # User asset ID ("users/**"). tmpfile = '/vsimem/ee/projects/earthengine-legacy/assets/users/foo:listImages?pageSize=1' with gdaltest.tempfile( tmpfile, json.dumps({ 'images': [{ 'name': 'projects/earthengine-legacy/assets/users/foo/bar' }] })): assert ogr.Open('EEDA:users/foo').GetLayer(0) # Project asset ID ("projects/**"). tmpfile = '/vsimem/ee/projects/earthengine-legacy/assets/projects/foo:listImages?pageSize=1' with gdaltest.tempfile( tmpfile, json.dumps({ 'images': [{ 'name': 'projects/earthengine-legacy/assets/projects/foo/bar' }] })): ds = ogr.Open('EEDA:projects/foo') assert ds.GetLayer(0) ds = None # Multi-folder project asset ID ("projects/foo/bar/baz"). tmpfile = '/vsimem/ee/projects/earthengine-legacy/assets/projects/foo/bar/baz:listImages?pageSize=1' with gdaltest.tempfile( tmpfile, json.dumps({ 'images': [{ 'name': 'projects/earthengine-legacy/assets/projects/foo/bar/baz/qux' }] })): ds = ogr.Open('EEDA:projects/foo/bar/baz') assert ds.GetLayer(0) ds = None # Public-catalog asset ID (e.g. "LANDSAT"). tmpfile = '/vsimem/ee/projects/earthengine-public/assets/foo:listImages?pageSize=1' with gdaltest.tempfile( tmpfile, json.dumps({ 'images': [{ 'name': 'projects/earthengine-public/assets/foo/bar' }] })): ds = ogr.Open('EEDA:foo') assert ds.GetLayer(0) ds = None # Asset name ("projects/*/assets/**"). tmpfile = '/vsimem/ee/projects/foo/assets/bar:listImages?pageSize=1' with gdaltest.tempfile( tmpfile, json.dumps({'images': [{ 'name': 'projects/foo/assets/bar/baz' }]})): ds = ogr.Open('EEDA:projects/foo/assets/bar') assert ds.GetLayer(0) ds = None gdal.SetConfigOption('EEDA_BEARER', None) gdal.SetConfigOption('EEDA_URL', None)
def test_ogr_carto_vsimem(): if ogrtest.carto_drv is None: pytest.skip() ogrtest.carto_api_key_ori = gdal.GetConfigOption('CARTO_API_KEY') gdal.SetConfigOption('CARTO_API_URL', '/vsimem/carto') gdal.SetConfigOption('CPL_CURL_ENABLE_VSIMEM', 'YES') gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT postgis_version() LIMIT 500 OFFSET 0&api_key=foo', """{"rows":[{"postgis_version":"2.1 USE_GEOS=1 USE_PROJ=1 USE_STATS=1"}],"time":0.001,"fields":{"postgis_version":{"type":"string"}},"total_rows":1}""") gdal.PushErrorHandler() ds = ogr.Open('CARTO:foo') gdal.PopErrorHandler() assert ds is None gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """Content-Type: text/html\r Error""") gdal.PushErrorHandler() ds = ogr.Open('CARTO:foo') gdal.PopErrorHandler() assert ds is None and gdal.GetLastErrorMsg().find('HTML error page') >= 0 gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """""") ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{""") gdal.PushErrorHandler() ds = ogr.Open('CARTO:foo') gdal.PopErrorHandler() assert ds is None and gdal.GetLastErrorMsg().find('JSON parsing error') >= 0 gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """ "not_expected_json" """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "error" : [ "bla"] }""") gdal.PushErrorHandler() ds = ogr.Open('CARTO:foo') gdal.PopErrorHandler() assert ds is None and gdal.GetLastErrorMsg().find('Error returned by server : bla') >= 0 gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "fields" : null } """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "fields" : "invalid" } """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "fields" : {} } """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "fields" : { "foo": "invalid" } } """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "fields" : { "foo": {} } } """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "fields" : { "foo": { "type" : null } } } """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "fields" : { "foo": { "type" : {} } } } """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{ "fields" : { "foo": { "type" : "string" } } } """) ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{"rows":[ {"field1": "foo", "field2": "bar"} ],"fields":{"field1":{"type":"string"}, "field2":{"type":"string"}}}""") ds = ogr.Open('CARTO:foo') assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{"rows":[],"fields":{"current_schema":{"type":"string"}}}""") gdal.PushErrorHandler() ds = ogr.Open('CARTO:foo') gdal.PopErrorHandler() assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0', """{"rows":[{"current_schema":"public"}],"fields":{"current_schema":{"type":"unknown(19)"}}}""") gdal.PushErrorHandler() ds = ogr.Open('CARTO:foo') gdal.PopErrorHandler() assert ds is None, gdal.GetLastErrorMsg() gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT CDB_UserTables() LIMIT 500 OFFSET 0', """{"rows":[{"cdb_usertables":"table1"}],"fields":{"cdb_usertables":{"type":"string"}}}""") ds = ogr.Open('CARTO:foo') assert ds is not None and ds.GetLayerCount() == 1, gdal.GetLastErrorMsg() gdal.PushErrorHandler() lyr_defn = ds.GetLayer(0).GetLayerDefn() gdal.PopErrorHandler() assert lyr_defn.GetFieldCount() == 0 # Empty layer gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT * FROM "table1" LIMIT 0', """{"rows":[],"fields":{}}""") ds = ogr.Open('CARTO:foo') lyr = ds.GetLayer(0) lyr_defn = lyr.GetLayerDefn() assert lyr_defn.GetFieldCount() == 0 gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT * FROM "table1" LIMIT 500 OFFSET 0', """{"rows":[{}],"fields":{}}}""") f = lyr.GetNextFeature() if f.GetFID() != 0: f.DumpReadable() pytest.fail() # Layer without geometry or primary key gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT * FROM "table1" LIMIT 0', """{"rows":[],"fields":{"strfield":{"type":"string"}, "realfield":{"type":"number"}, "boolfield":{"type":"boolean"}, "datefield":{"type":"date"}}}""") ds = ogr.Open('CARTO:foo') lyr = ds.GetLayer(0) lyr_defn = lyr.GetLayerDefn() assert lyr_defn.GetFieldCount() == 4 assert (lyr_defn.GetFieldDefn(0).GetName() == 'strfield' and \ lyr_defn.GetFieldDefn(0).GetType() == ogr.OFTString) assert (lyr_defn.GetFieldDefn(1).GetName() == 'realfield' and \ lyr_defn.GetFieldDefn(1).GetType() == ogr.OFTReal) assert (lyr_defn.GetFieldDefn(2).GetName() == 'boolfield' and \ lyr_defn.GetFieldDefn(2).GetType() == ogr.OFTInteger and \ lyr_defn.GetFieldDefn(2).GetSubType() == ogr.OFSTBoolean) assert (lyr_defn.GetFieldDefn(3).GetName() == 'datefield' and \ lyr_defn.GetFieldDefn(3).GetType() == ogr.OFTDateTime) gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT "strfield", "realfield", "boolfield", "datefield" FROM "table1" LIMIT 500 OFFSET 0', """{"rows":[{ "strfield": "foo", "realfield": 1.23, "boolfield": true, "datefield": "2015-04-24T12:34:56.123Z" }],"fields":{"strfield":{"type":"string"}, "realfield":{"type":"number"}, "boolfield":{"type":"boolean"}, "datefield":{"type":"date"}}}""") f = lyr.GetNextFeature() if f['strfield'] != 'foo' or f['realfield'] != 1.23 or f['boolfield'] != 1 or \ f['datefield'] != '2015/04/24 12:34:56.123+00': f.DumpReadable() pytest.fail() gdal.SetConfigOption('CARTO_API_KEY', 'foo') gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0&api_key=foo', """{"rows":[{"current_schema":"public"}],"fields":{"current_schema":{"type":"unknown(19)"}}}""") gdal.FileFromMemBuffer('/vsimem/carto&POSTFIELDS=q=SELECT CDB_UserTables() LIMIT 500 OFFSET 0&api_key=foo', """{"rows":[{"cdb_usertables":"table1"}],"fields":{"cdb_usertables":{"type":"string"}}}""") ds = ogr.Open('CARTO:foo') gdal.PushErrorHandler() lyr_defn = ds.GetLayer(0).GetLayerDefn() gdal.PopErrorHandler() assert lyr_defn.GetFieldCount() == 0 get_full_details_fields_url = """/vsimem/carto&POSTFIELDS=q=SELECT a.attname, t.typname, a.attlen, format_type(a.atttypid,a.atttypmod), a.attnum, a.attnotnull, i.indisprimary, pg_get_expr(def.adbin, c.oid) AS defaultexpr, postgis_typmod_dims(a.atttypmod) dim, postgis_typmod_srid(a.atttypmod) srid, postgis_typmod_type(a.atttypmod)::text geomtyp, srtext FROM pg_class c JOIN pg_attribute a ON a.attnum > 0 AND a.attrelid = c.oid AND c.relname = 'table1' JOIN pg_type t ON a.atttypid = t.oid JOIN pg_namespace n ON c.relnamespace=n.oid AND n.nspname= 'public' LEFT JOIN pg_index i ON c.oid = i.indrelid AND i.indisprimary = 't' AND a.attnum = ANY(i.indkey) LEFT JOIN pg_attrdef def ON def.adrelid = c.oid AND def.adnum = a.attnum LEFT JOIN spatial_ref_sys srs ON srs.srid = postgis_typmod_srid(a.atttypmod) ORDER BY a.attnum LIMIT 500 OFFSET 0&api_key=foo""" gdal.FileFromMemBuffer(get_full_details_fields_url, '') ds = ogr.Open('CARTO:foo') gdal.PushErrorHandler() lyr_defn = ds.GetLayer(0).GetLayerDefn() gdal.PopErrorHandler() assert lyr_defn.GetFieldCount() == 0 gdal.FileFromMemBuffer(get_full_details_fields_url, """{"rows":[{"attname":"foo"}], "fields":{"attname":{"type":"string"}}}""") ds = ogr.Open('CARTO:foo') lyr = ds.GetLayer(0) gdal.PushErrorHandler() lyr_defn = lyr.GetLayerDefn() gdal.PopErrorHandler() assert lyr_defn.GetFieldCount() == 1 gdal.PushErrorHandler() f = lyr.GetFeature(0) gdal.PopErrorHandler() assert f is None gdal.FileFromMemBuffer(get_full_details_fields_url, """{"rows":[{"attname":"strfield", "typname":"varchar", "attnotnull": true, "defaultexpr": "def_value"}, {"attname":"intfield", "typname":"int4"}, {"attname":"doublefield", "typname":"float"}, {"attname":"boolfield", "typname":"bool"}, {"attname":"datetimefield", "typname":"timestamp"}, {"attname":"cartodb_id","typname":"int4","indisprimary":true}, {"attname":"created_at","typname":"date"}, {"attname":"updated_at","typname":"date"}, {"attname":"my_geom","typname":"geometry","dim":3,"srid":4326,"geomtyp":"Point", "srtext":"GEOGCS[\\"WGS 84\\",DATUM[\\"WGS_1984\\",SPHEROID[\\"WGS 84\\",6378137,298.257223563,AUTHORITY[\\"EPSG\\",\\"7030\\"]],AUTHORITY[\\"EPSG\\",\\"6326\\"]],PRIMEM[\\"Greenwich\\",0,AUTHORITY[\\"EPSG\\",\\"8901\\"]],UNIT[\\"degree\\",0.0174532925199433,AUTHORITY[\\"EPSG\\",\\"9122\\"]],AUTHORITY[\\"EPSG\\",\\"4326\\"]]"}, {"attname":"the_geom_webmercator","typname":"geometry"}], "fields":{"attname":{"type":"string"}, "typname":{"type":"string"}, "attlen":{"type":"number"}, "format_type":{"type":"string"}, "attnum":{"type":"number"}, "attnotnull":{"type":"boolean"}, "indisprimary":{"type":"boolean"}, "defaultexpr":{"type":"string"}, "dim":{"type":"number"}, "srid":{"type":"number"}, "geomtyp":{"type":"string"}, "srtext":{"type":"string"}}}""") ds = ogr.Open('CARTO:foo') lyr = ds.GetLayer(0) lyr_defn = lyr.GetLayerDefn() assert lyr_defn.GetFieldCount() == 5 assert (lyr_defn.GetFieldDefn(0).GetName() == 'strfield' and \ lyr_defn.GetFieldDefn(0).GetType() == ogr.OFTString and not \ lyr_defn.GetFieldDefn(0).IsNullable() and \ lyr_defn.GetFieldDefn(0).GetDefault() == 'def_value') assert lyr_defn.GetGeomFieldCount() == 1 assert lyr_defn.GetGeomFieldDefn(0).GetName() == 'my_geom' assert lyr_defn.GetGeomFieldDefn(0).GetType() == ogr.wkbPoint25D assert lyr_defn.GetGeomFieldDefn(0).GetSpatialRef().ExportToWkt().find('4326') >= 0 gdal.PushErrorHandler() fc = lyr.GetFeatureCount() gdal.PopErrorHandler() assert fc == 0 gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT COUNT(*) FROM "table1"&api_key=foo""", """{}""") gdal.PushErrorHandler() fc = lyr.GetFeatureCount() gdal.PopErrorHandler() assert fc == 0 gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT COUNT(*) FROM "table1"&api_key=foo""", """{"rows":[{"foo":1}], "fields":{"foo":{"type":"number"}}}""") gdal.PushErrorHandler() fc = lyr.GetFeatureCount() gdal.PopErrorHandler() assert fc == 0 gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT COUNT(*) FROM "table1"&api_key=foo""", """{"rows":[{"count":9876543210}], "fields":{"count":{"type":"number"}}}""") assert lyr.GetFeatureCount() == 9876543210 gdal.PushErrorHandler() extent = lyr.GetExtent() gdal.PopErrorHandler() assert extent == (0, 0, 0, 0) gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT ST_Extent("my_geom") FROM "table1"&api_key=foo""", """{"rows":[{"foo":1}], "fields":{"foo":{"type":"number"}}}""") gdal.PushErrorHandler() extent = lyr.GetExtent() gdal.PopErrorHandler() assert extent == (0, 0, 0, 0) gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT ST_Extent("my_geom") FROM "table1"&api_key=foo""", """{"rows":[{"st_extent":""}], "fields":{"st_extent":{"type":"string"}}}""") gdal.ErrorReset() gdal.PushErrorHandler() lyr.GetExtent() gdal.PopErrorHandler() assert gdal.GetLastErrorMsg() != '' gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT ST_Extent("my_geom") FROM "table1"&api_key=foo""", """{"rows":[{"st_extent":"("}], "fields":{"st_extent":{"type":"string"}}}""") gdal.ErrorReset() gdal.PushErrorHandler() lyr.GetExtent() gdal.PopErrorHandler() assert gdal.GetLastErrorMsg() != '' gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT ST_Extent("my_geom") FROM "table1"&api_key=foo""", """{"rows":[{"st_extent":"BOX()"}], "fields":{"st_extent":{"type":"string"}}}""") gdal.ErrorReset() gdal.PushErrorHandler() lyr.GetExtent() gdal.PopErrorHandler() assert gdal.GetLastErrorMsg() != '' gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT ST_Extent("my_geom") FROM "table1"&api_key=foo""", """{"rows":[{"st_extent":"BOX(0,1,2,3)"}], "fields":{"st_extent":{"type":"string"}}}""") assert lyr.GetExtent() == (0.0, 2.0, 1.0, 3.0) gdal.PushErrorHandler() f = lyr.GetFeature(0) gdal.PopErrorHandler() assert f is None gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE "cartodb_id" = 0&api_key=foo""", """""") gdal.PushErrorHandler() f = lyr.GetFeature(0) gdal.PopErrorHandler() assert f is None gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE "cartodb_id" = 0&api_key=foo""", """{"rows":[{"st_extent":"BOX(0,1,2,3)"}], "fields":{"st_extent":{"type":"string"}}}""") f = lyr.GetFeature(0) assert f.GetFID() == -1 and f.IsFieldNull(0) gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE "cartodb_id" = 0&api_key=foo""", """{"rows":[{"cartodb_id":0}], "fields":{"cartodb_id":{"type":"numeric"}}}""") f = lyr.GetFeature(0) assert f.GetFID() == 0 lyr.ResetReading() gdal.PushErrorHandler() f = lyr.GetNextFeature() gdal.PopErrorHandler() assert f is None gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE "cartodb_id" >= 0 ORDER BY "cartodb_id" ASC LIMIT 500&api_key=foo""", """{"rows":[{"cartodb_id":0}], "fields":{"cartodb_id":{"type":"numeric"}}}""") lyr.ResetReading() f = lyr.GetNextFeature() assert f.GetFID() == 0 gdal.PushErrorHandler() f = lyr.GetNextFeature() gdal.PopErrorHandler() assert f is None gdal.SetConfigOption('CARTO_PAGE_SIZE', '2') gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE "cartodb_id" >= 0 ORDER BY "cartodb_id" ASC LIMIT 2&api_key=foo""", """{"rows":[{"cartodb_id":0},{"cartodb_id":10}], "fields":{"cartodb_id":{"type":"numeric"}}}""") lyr.ResetReading() f = lyr.GetNextFeature() assert f.GetFID() == 0 f = lyr.GetNextFeature() assert f.GetFID() == 10 gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE "cartodb_id" >= 11 ORDER BY "cartodb_id" ASC LIMIT 2&api_key=foo""", """{"rows":[{"cartodb_id":12}], "fields":{"cartodb_id":{"type":"numeric"}}}""") f = lyr.GetNextFeature() assert f.GetFID() == 12 gdal.ErrorReset() f = lyr.GetNextFeature() assert f is None and gdal.GetLastErrorMsg() == '' lyr.SetAttributeFilter('strfield is NULL') gdal.PushErrorHandler() fc = lyr.GetFeatureCount() gdal.PopErrorHandler() assert fc == 0 gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE (strfield is NULL) AND "cartodb_id" >= 0 ORDER BY "cartodb_id" ASC LIMIT 2&api_key=foo""", """{"rows":[{"cartodb_id":0}], "fields":{"cartodb_id":{"type":"numeric"}}}""") lyr.ResetReading() f = lyr.GetNextFeature() assert f is not None gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE (strfield is NULL) AND "cartodb_id" >= 1 ORDER BY "cartodb_id" ASC LIMIT 2&api_key=foo""", """{"rows":[], "fields":{"cartodb_id":{"type":"numeric"}}}""") gdal.ErrorReset() f = lyr.GetNextFeature() assert f is None and gdal.GetLastErrorMsg() == '' gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT COUNT(*) FROM "table1" WHERE (strfield is NULL)&api_key=foo""", """{"rows":[{"count":9876543210}], "fields":{"count":{"type":"number"}}}""") assert lyr.GetFeatureCount() == 9876543210 lyr.SetSpatialFilterRect(-180, -90, 180, 90) gdal.PushErrorHandler() fc = lyr.GetFeatureCount() gdal.PopErrorHandler() assert fc == 0 gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT "cartodb_id", "my_geom", "strfield", "intfield", "doublefield", "boolfield", "datetimefield" FROM "table1" WHERE ("my_geom" %26%26 'BOX3D(-180 -90, 180 90)'::box3d) AND (strfield is NULL) AND "cartodb_id" >= 0 ORDER BY "cartodb_id" ASC LIMIT 2&api_key=foo""", """{"rows":[{"cartodb_id":20, "my_geom": "010100000000000000000000400000000000804840" }], "fields":{"cartodb_id":{"type":"numeric"}, "my_geom":{"type":"string"}}}""") lyr.ResetReading() f = lyr.GetNextFeature() assert f is not None and f.GetGeometryRef().ExportToWkt() == 'POINT (2 49)' gdal.PushErrorHandler() fc = lyr.GetFeatureCount() gdal.PopErrorHandler() assert fc == 1 gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT COUNT(*) FROM "table1" WHERE ("my_geom" %26%26 'BOX3D(-180 -90, 180 90)'::box3d) AND (strfield is NULL)&api_key=foo""", """{"rows":[{"count":9876543210}], "fields":{"count":{"type":"number"}}}""") assert lyr.GetFeatureCount() == 9876543210 # Not permitted in read-only mode f = ogr.Feature(lyr.GetLayerDefn()) gdal.PushErrorHandler() ds.CreateLayer('foo') ds.DeleteLayer(0) lyr.CreateFeature(f) lyr.SetFeature(f) lyr.DeleteFeature(0) lyr.CreateField(ogr.FieldDefn('foo')) lyr.DeleteField(0) gdal.PopErrorHandler() ds = None gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=DROP FUNCTION IF EXISTS ogr_table_metadata(TEXT,TEXT); CREATE OR REPLACE FUNCTION ogr_table_metadata(schema_name TEXT, table_name TEXT) RETURNS TABLE (attname TEXT, typname TEXT, attlen INT, format_type TEXT, attnum INT, attnotnull BOOLEAN, indisprimary BOOLEAN, defaultexpr TEXT, dim INT, srid INT, geomtyp TEXT, srtext TEXT) AS $$ SELECT a.attname::text, t.typname::text, a.attlen::int, format_type(a.atttypid,a.atttypmod)::text, a.attnum::int, a.attnotnull::boolean, i.indisprimary::boolean, pg_get_expr(def.adbin, c.oid)::text AS defaultexpr, (CASE WHEN t.typname = 'geometry' THEN postgis_typmod_dims(a.atttypmod) ELSE NULL END)::int dim, (CASE WHEN t.typname = 'geometry' THEN postgis_typmod_srid(a.atttypmod) ELSE NULL END)::int srid, (CASE WHEN t.typname = 'geometry' THEN postgis_typmod_type(a.atttypmod) ELSE NULL END)::text geomtyp, srtext FROM pg_class c JOIN pg_attribute a ON a.attnum > 0 AND a.attrelid = c.oid AND c.relname = $2 AND c.relname IN (SELECT CDB_UserTables())JOIN pg_type t ON a.atttypid = t.oid JOIN pg_namespace n ON c.relnamespace=n.oid AND n.nspname = $1 LEFT JOIN pg_index i ON c.oid = i.indrelid AND i.indisprimary = 't' AND a.attnum = ANY(i.indkey) LEFT JOIN pg_attrdef def ON def.adrelid = c.oid AND def.adnum = a.attnum LEFT JOIN spatial_ref_sys srs ON srs.srid = postgis_typmod_srid(a.atttypmod) ORDER BY a.attnum $$ LANGUAGE SQL&api_key=foo""", """""""") gdal.SetConfigOption('CARTO_PAGE_SIZE', None) ds = ogr.Open('CARTO:foo', update=1) lyr = ds.CreateLayer('MY_LAYER') gdal.ErrorReset() gdal.PushErrorHandler() lyr.GetNextFeature() gdal.PopErrorHandler() assert gdal.GetLastErrorMsg() != '' gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT cdb_cartodbfytable('my_layer')&api_key=foo""", """{"rows":[], "fields":{}}""") ds = None gdal.Unlink("""/vsimem/carto&POSTFIELDS=q=SELECT cdb_cartodbfytable('my_layer')&api_key=foo""") ds = gdal.OpenEx('CARTO:foo', gdal.OF_VECTOR | gdal.OF_UPDATE, open_options=['COPY_MODE=NO']) gdal.SetConfigOption('CARTO_MAX_CHUNK_SIZE', '0') sr = osr.SpatialReference() sr.ImportFromEPSG(4326) lyr = ds.CreateLayer('MY_LAYER', srs=sr) fld_defn = ogr.FieldDefn('STRFIELD', ogr.OFTString) fld_defn.SetNullable(0) fld_defn.SetDefault("'DEFAULT VAL'") fld_defn.SetWidth(20) lyr.CreateField(fld_defn) gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=CREATE TABLE "my_layer" ( cartodb_id SERIAL,the_geom GEOMETRY(GEOMETRY, 4326),"strfield" VARCHAR NOT NULL DEFAULT 'DEFAULT VAL',PRIMARY KEY (cartodb_id) );DROP SEQUENCE IF EXISTS "my_layer_cartodb_id_seq" CASCADE;CREATE SEQUENCE "my_layer_cartodb_id_seq" START 1;ALTER SEQUENCE "my_layer_cartodb_id_seq" OWNED BY "my_layer".cartodb_id;ALTER TABLE "my_layer" ALTER COLUMN cartodb_id SET DEFAULT nextval('"my_layer_cartodb_id_seq"')&api_key=foo""", """{"rows":[], "fields":{}}""") f = ogr.Feature(lyr.GetLayerDefn()) gdal.PushErrorHandler() ret = lyr.CreateFeature(f) gdal.PopErrorHandler() assert ret != 0 f = None fld_defn = ogr.FieldDefn('INTFIELD', ogr.OFTInteger) # No server answer with gdaltest.error_handler(): ret = lyr.CreateField(fld_defn) assert ret != 0 gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=ALTER TABLE "my_layer" ADD COLUMN "intfield" INTEGER&api_key=foo""", """{"rows":[], "fields":{}}""") assert lyr.CreateField(fld_defn) == 0 fld_defn = ogr.FieldDefn('boolfield', ogr.OFTInteger) fld_defn.SetSubType(ogr.OFSTBoolean) gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=ALTER TABLE "my_layer" ADD COLUMN "boolfield" BOOLEAN&api_key=foo""", """{"rows":[], "fields":{}}""") assert lyr.CreateField(fld_defn) == 0 # Invalid field with gdaltest.error_handler(): assert lyr.DeleteField(-1) != 0 # No server answer with gdaltest.error_handler(): assert lyr.DeleteField(0) != 0 gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=ALTER TABLE "my_layer" DROP COLUMN "boolfield"&api_key=foo""", """{"rows":[], "fields":{}}""") fld_pos = lyr.GetLayerDefn().GetFieldIndex(fld_defn.GetName()) assert lyr.DeleteField(fld_pos) == 0 gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=ALTER TABLE "my_layer" ADD COLUMN "boolfield" BOOLEAN&api_key=foo""", """{"rows":[], "fields":{}}""") assert lyr.CreateField(fld_defn) == 0 f = ogr.Feature(lyr.GetLayerDefn()) gdal.PushErrorHandler() ret = lyr.CreateFeature(f) gdal.PopErrorHandler() assert ret != 0 f = ogr.Feature(lyr.GetLayerDefn()) f.SetField('strfield', 'foo') f.SetField('intfield', 1) f.SetField('boolfield', 1) f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(2 49)')) gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=INSERT INTO "my_layer" ("strfield", "intfield", "boolfield", "the_geom") VALUES ('foo', 1, 't', '0101000020E610000000000000000000400000000000804840') RETURNING "cartodb_id"&api_key=foo""", """{"rows":[ {"cartodb_id": 1} ], "fields":{"cartodb_id":{"type":"integer"}}}""") ret = lyr.CreateFeature(f) assert ret == 0 and f.GetFID() == 1 f.SetFID(-1) gdal.PushErrorHandler() ret = lyr.SetFeature(f) gdal.PopErrorHandler() assert ret != 0 f.SetFID(3) gdal.PushErrorHandler() ret = lyr.SetFeature(f) gdal.PopErrorHandler() assert ret != 0 gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=UPDATE "my_layer" SET "strfield" = 'foo', "intfield" = 1, "boolfield" = 't', "the_geom" = '0101000020E610000000000000000000400000000000804840' WHERE "cartodb_id" = 3&api_key=foo""", """{"total_rows": 0}""") ret = lyr.SetFeature(f) assert ret == ogr.OGRERR_NON_EXISTING_FEATURE gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=UPDATE "my_layer" SET "strfield" = 'foo', "intfield" = 1, "boolfield" = 't', "the_geom" = '0101000020E610000000000000000000400000000000804840' WHERE "cartodb_id" = 3&api_key=foo""", """{"total_rows": 1}""") ret = lyr.SetFeature(f) assert ret == 0 f = ogr.Feature(lyr.GetLayerDefn()) gdal.PushErrorHandler() ret = lyr.CreateFeature(f) gdal.PopErrorHandler() assert ret != 0 gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=INSERT INTO "my_layer" DEFAULT VALUES RETURNING "cartodb_id"&api_key=foo""", """{"rows":[ {"cartodb_id": 4} ], "fields":{"cartodb_id":{"type":"integer"}}}""") ret = lyr.CreateFeature(f) assert ret == 0 and f.GetFID() == 4 gdal.PushErrorHandler() ret = lyr.DeleteFeature(0) gdal.PopErrorHandler() assert ret != 0 gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=DELETE FROM "my_layer" WHERE "cartodb_id" = 0&api_key=foo""", """{"total_rows": 0}""") ret = lyr.DeleteFeature(0) assert ret == ogr.OGRERR_NON_EXISTING_FEATURE gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=DELETE FROM "my_layer" WHERE "cartodb_id" = 0&api_key=foo""", """{"total_rows": 1}""") ret = lyr.DeleteFeature(0) assert ret == 0 gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT cdb_cartodbfytable('my_layer')&api_key=foo""", """{"rows":[], "fields":{}}""") ds = None gdal.SetConfigOption('CARTO_MAX_CHUNK_SIZE', None) ds = gdal.OpenEx('CARTO:foo', gdal.OF_VECTOR | gdal.OF_UPDATE, open_options=['COPY_MODE=NO']) lyr = ds.GetLayer(0) gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT pg_catalog.pg_get_serial_sequence('table1', 'cartodb_id') AS seq_name&api_key=foo""", """{"rows":[{"seq_name":"table1_cartodb_id_seq0"}],"fields":{"seq_name":{"type":"string"}}}""") gdal.FileFromMemBuffer("""/vsimem/carto&POSTFIELDS=q=SELECT nextval('table1_cartodb_id_seq0') AS nextid&api_key=foo""", """{"rows":[{"nextid":11}],"fields":{"nextid":{"type":"number"}}}""") f = ogr.Feature(lyr.GetLayerDefn()) f.SetField('strfield', 'foo') ret = lyr.CreateFeature(f) assert ret == 0 and f.GetFID() == 11 f = ogr.Feature(lyr.GetLayerDefn()) with gdaltest.tempfile("""/vsimem/carto&POSTFIELDS=q=BEGIN;INSERT INTO "table1" ("strfield", "cartodb_id") VALUES ('foo', 11);INSERT INTO "table1" DEFAULT VALUES;COMMIT;&api_key=foo""", """{"rows":[], "fields":{}}"""): ret = lyr.CreateFeature(f) ds = None if ret != 0 or f.GetFID() != 12: f.DumpReadable() pytest.fail() ds = gdal.OpenEx('CARTO:foo', gdal.OF_VECTOR | gdal.OF_UPDATE, open_options=['COPY_MODE=NO']) lyr = ds.GetLayer(0) f = ogr.Feature(lyr.GetLayerDefn()) f.SetFieldNull('strfield') with gdaltest.tempfile("""/vsimem/carto&POSTFIELDS=q=BEGIN;INSERT INTO "table1" ("strfield", "cartodb_id") VALUES (NULL, 11);COMMIT;&api_key=foo""", """{"rows":[], "fields":{}}"""): ret = lyr.CreateFeature(f) ds = None if ret != 0 or f.GetFID() != 11: f.DumpReadable() pytest.fail() # Now remove default value to strfield gdal.FileFromMemBuffer(get_full_details_fields_url, """{"rows":[{"attname":"strfield", "typname":"varchar"}, {"attname":"intfield", "typname":"int4"}, {"attname":"doublefield", "typname":"float"}, {"attname":"boolfield", "typname":"bool"}, {"attname":"datetimefield", "typname":"timestamp"}, {"attname":"cartodb_id","typname":"int4","indisprimary":true}, {"attname":"created_at","typname":"date"}, {"attname":"updated_at","typname":"date"}, {"attname":"my_geom","typname":"geometry","dim":3,"srid":4326,"geomtyp":"Point", "srtext":"GEOGCS[\\"WGS 84\\",DATUM[\\"WGS_1984\\",SPHEROID[\\"WGS 84\\",6378137,298.257223563,AUTHORITY[\\"EPSG\\",\\"7030\\"]],AUTHORITY[\\"EPSG\\",\\"6326\\"]],PRIMEM[\\"Greenwich\\",0,AUTHORITY[\\"EPSG\\",\\"8901\\"]],UNIT[\\"degree\\",0.0174532925199433,AUTHORITY[\\"EPSG\\",\\"9122\\"]],AUTHORITY[\\"EPSG\\",\\"4326\\"]]"}, {"attname":"the_geom_webmercator","typname":"geometry"}], "fields":{"attname":{"type":"string"}, "typname":{"type":"string"}, "attlen":{"type":"number"}, "format_type":{"type":"string"}, "attnum":{"type":"number"}, "attnotnull":{"type":"boolean"}, "indisprimary":{"type":"boolean"}, "defaultexpr":{"type":"string"}, "dim":{"type":"number"}, "srid":{"type":"number"}, "geomtyp":{"type":"string"}, "srtext":{"type":"string"}}}""") ds = gdal.OpenEx('CARTO:foo', gdal.OF_VECTOR | gdal.OF_UPDATE, open_options=['COPY_MODE=NO']) lyr = ds.GetLayer(0) f = ogr.Feature(lyr.GetLayerDefn()) f.SetField('strfield', 'foo') with gdaltest.tempfile("""/vsimem/carto&POSTFIELDS=q=SELECT nextval('table1_cartodb_id_seq') AS nextid&api_key=foo""", """{"rows":[{"nextid":11}],"fields":{"nextid":{"type":"number"}}}"""): ret = lyr.CreateFeature(f) assert ret == 0 and f.GetFID() == 11 f = ogr.Feature(lyr.GetLayerDefn()) f.SetField('strfield', 'bar') ret = lyr.CreateFeature(f) assert ret == 0 and f.GetFID() == 12 f = ogr.Feature(lyr.GetLayerDefn()) f.SetField('strfield', 'baz') ret = lyr.CreateFeature(f) assert ret == 0 and f.GetFID() == 13 gdal.ErrorReset() with gdaltest.tempfile("""/vsimem/carto&POSTFIELDS=q=BEGIN;INSERT INTO "table1" ("strfield", "cartodb_id") VALUES ('foo', 11);INSERT INTO "table1" ("strfield", "intfield", "doublefield", "boolfield", "datetimefield", "my_geom") VALUES ('bar', NULL, NULL, NULL, NULL, NULL), ('baz', NULL, NULL, NULL, NULL, NULL);COMMIT;&api_key=foo""", """{"rows":[], "fields":{}}"""): ds = None assert gdal.GetLastErrorMsg() == '' ds = gdal.OpenEx('CARTO:foo', gdal.OF_VECTOR | gdal.OF_UPDATE, open_options=['COPY_MODE=NO']) gdal.PushErrorHandler() lyr = ds.CreateLayer('table1') gdal.PopErrorHandler() assert lyr is None with gdaltest.tempfile("""/vsimem/carto&POSTFIELDS=q=DROP TABLE "table1"&api_key=foo""", """{"rows":[], "fields":{}}"""): lyr = ds.CreateLayer('table1', geom_type=ogr.wkbPolygon, options=['OVERWRITE=YES', 'CARTODBFY=NO']) f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt('POLYGON((0 0,0 1,1 0,0 0))')) with gdaltest.tempfile("""/vsimem/carto&POSTFIELDS=q=CREATE TABLE "table1" ( cartodb_id SERIAL,the_geom Geometry(MULTIPOLYGON,0),PRIMARY KEY (cartodb_id) );DROP SEQUENCE IF EXISTS "table1_cartodb_id_seq" CASCADE;CREATE SEQUENCE "table1_cartodb_id_seq" START 1;ALTER SEQUENCE "table1_cartodb_id_seq" OWNED BY "table1".cartodb_id;ALTER TABLE "table1" ALTER COLUMN cartodb_id SET DEFAULT nextval('"table1_cartodb_id_seq"')&api_key=foo""", """{"rows":[], "fields":{}}"""): assert lyr.CreateFeature(f) == 0 gdal.ErrorReset() with gdaltest.tempfile("""/vsimem/carto&POSTFIELDS=q=BEGIN;INSERT INTO "table1" ("the_geom") VALUES ('0106000020E61000000100000001030000000100000004000000000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000000000000000000000000000000000000000');COMMIT;&api_key=foo""", """{"rows":[], "fields":{}}"""): ds = None assert gdal.GetLastErrorMsg() == '' ds = gdal.OpenEx('CARTO:foo', gdal.OF_VECTOR | gdal.OF_UPDATE, open_options=['COPY_MODE=NO']) with gdaltest.tempfile("""/vsimem/carto&POSTFIELDS=q=DROP TABLE "table1"&api_key=foo""", """{"rows":[], "fields":{}}"""): lyr = ds.CreateLayer('table1', geom_type=ogr.wkbPolygon, options=['OVERWRITE=YES', 'CARTODBFY=NO']) f = ogr.Feature(lyr.GetLayerDefn()) f.SetFID(100) with gdaltest.tempfile("""/vsimem/carto&POSTFIELDS=q=CREATE TABLE "table1" ( cartodb_id SERIAL,the_geom Geometry(MULTIPOLYGON,0),PRIMARY KEY (cartodb_id) );DROP SEQUENCE IF EXISTS "table1_cartodb_id_seq" CASCADE;CREATE SEQUENCE "table1_cartodb_id_seq" START 1;ALTER SEQUENCE "table1_cartodb_id_seq" OWNED BY "table1".cartodb_id;ALTER TABLE "table1" ALTER COLUMN cartodb_id SET DEFAULT nextval('"table1_cartodb_id_seq"')&api_key=foo""", """{"rows":[], "fields":{}}"""): with gdaltest.tempfile("""/vsimem/carto&POSTFIELDS=q=BEGIN;INSERT INTO "table1" ("cartodb_id") VALUES (100);COMMIT;&api_key=foo""", """{"rows":[], "fields":{}}"""): assert lyr.CreateFeature(f) == 0 assert f.GetFID() == 100 ds = None ds = ogr.Open('CARTO:foo', update=1) gdal.PushErrorHandler() ret = ds.DeleteLayer(0) gdal.PopErrorHandler() assert ret != 0 gdal.ErrorReset() ds = gdal.OpenEx('CARTO:foo', gdal.OF_VECTOR | gdal.OF_UPDATE, open_options=['COPY_MODE=YES']) assert ds is not None lyr = ds.GetLayerByName('table1') assert lyr is not None with gdaltest.tempfile("""/vsimem/carto/copyfrom?q=COPY%20"table1"%20("strfield","my_geom","cartodb_id")%20FROM%20STDIN%20WITH%20(FORMAT%20text,%20ENCODING%20UTF8)&api_key=foo&POSTFIELDS=copytest\t0101000020E610000000000000000059400000000000005940\t11\n\\.\n""","""{}"""): with gdaltest.tempfile("""/vsimem/carto/copyfrom?q=COPY%20"table1"%20("intfield","my_geom")%20FROM%20STDIN%20WITH%20(FORMAT%20text,%20ENCODING%20UTF8)&api_key=foo&POSTFIELDS=12\t0101000020E610000000000000000059400000000000005940\n\\.\n""","""{}"""): f = ogr.Feature(lyr.GetLayerDefn()) f.SetField('strfield', 'copytest') f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(100 100)')) assert lyr.CreateFeature(f) == 0 f = ogr.Feature(lyr.GetLayerDefn()) f.SetField('intfield', 12) f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(100 100)')) assert lyr.CreateFeature(f) == 0 ds = None # force flush ds = ogr.Open('CARTO:foo', update=1) gdal.ErrorReset() with gdaltest.tempfile("""/vsimem/carto&POSTFIELDS=q=DROP TABLE "table1"&api_key=foo""", """{"rows":[], "fields":{}}"""): ds.ExecuteSQL('DELLAYER:table1') assert gdal.GetLastErrorMsg() == '' and ds.GetLayerByName('table1') is None with gdaltest.tempfile('/vsimem/carto&POSTFIELDS=q=SELECT current_schema() LIMIT 500 OFFSET 0&api_key=foo', """{"rows":[{"current_schema":"my_schema"}],"fields":{"current_schema":{"type":"unknown(19)"}}}"""): with gdaltest.tempfile('/vsimem/carto&POSTFIELDS=q=SELECT CDB_UserTables() LIMIT 500 OFFSET 0&api_key=foo', """{"rows":[],"fields":{"cdb_usertables":{"type":"string"}}}"""): with gdaltest.tempfile("""/vsimem/carto&POSTFIELDS=q=SELECT c.relname FROM pg_class c, pg_namespace n WHERE c.relkind in ('r', 'v') AND c.relname !~ '^pg_' AND c.relnamespace=n.oid AND n.nspname = 'my_schema' LIMIT 500 OFFSET 0&api_key=foo""", """{"rows":[{"relname": "a_layer"}],"fields":{"relname":{"type":"string"}}}"""): ds = ogr.Open('CARTO:foo') assert ds.GetLayerByName('a_layer') is not None