int OGRAmigoCloudDataSource::Open( const char * pszFilename, char** papszOpenOptionsIn, int bUpdateIn ) { bReadWrite = CPL_TO_BOOL(bUpdateIn); pszName = CPLStrdup( pszFilename ); if( CSLFetchNameValue(papszOpenOptionsIn, "PROJECTID") ) pszProjetctId = CPLStrdup(CSLFetchNameValue(papszOpenOptionsIn, "PROJECTID")); else { pszProjetctId = CPLStrdup(pszFilename + strlen("AMIGOCLOUD:")); char* pchSpace = strchr(pszProjetctId, ' '); if( pchSpace ) *pchSpace = '\0'; if( pszProjetctId[0] == 0 ) { CPLError(CE_Failure, CPLE_AppDefined, "Missing projetc id"); return FALSE; } } osAPIKey = CSLFetchNameValueDef(papszOpenOptionsIn, "API_KEY", CPLGetConfigOption("AMIGOCLOUD_API_KEY", "")); CPLString osDatasets = OGRAMIGOCLOUDGetOptionValue(pszFilename, "datasets"); bUseHTTPS = CPLTestBool(CPLGetConfigOption("AMIGOCLOUD_HTTPS", "YES")); OGRLayer* poSchemaLayer = ExecuteSQLInternal("SELECT current_schema()"); if( poSchemaLayer ) { OGRFeature* poFeat = poSchemaLayer->GetNextFeature(); if( poFeat ) { if( poFeat->GetFieldCount() == 1 ) { osCurrentSchema = poFeat->GetFieldAsString(0); } delete poFeat; } ReleaseResultSet(poSchemaLayer); } if( osCurrentSchema.size() == 0 ) return FALSE; if (osDatasets.size() != 0) { char** papszTables = CSLTokenizeString2(osDatasets, ",", 0); for(int i=0;papszTables && papszTables[i];i++) { papoLayers = (OGRAmigoCloudTableLayer**) CPLRealloc( papoLayers, (nLayers + 1) * sizeof(OGRAmigoCloudTableLayer*)); papoLayers[nLayers ++] = new OGRAmigoCloudTableLayer(this, papszTables[i]); } CSLDestroy(papszTables); return TRUE; } return TRUE; }
int OGRCARTODataSource::Open( const char * pszFilename, char** papszOpenOptionsIn, int bUpdateIn ) { bReadWrite = bUpdateIn; bBatchInsert = CPLTestBool(CSLFetchNameValueDef(papszOpenOptionsIn, "BATCH_INSERT", "YES")); pszName = CPLStrdup( pszFilename ); if( CSLFetchNameValue(papszOpenOptionsIn, "ACCOUNT") ) pszAccount = CPLStrdup(CSLFetchNameValue(papszOpenOptionsIn, "ACCOUNT")); else { if( STARTS_WITH_CI(pszFilename, "CARTODB:") ) pszAccount = CPLStrdup(pszFilename + strlen("CARTODB:")); else pszAccount = CPLStrdup(pszFilename + strlen("CARTO:")); char* pchSpace = strchr(pszAccount, ' '); if( pchSpace ) *pchSpace = '\0'; if( pszAccount[0] == 0 ) { CPLError(CE_Failure, CPLE_AppDefined, "Missing account name"); return FALSE; } } osAPIKey = CSLFetchNameValueDef(papszOpenOptionsIn, "API_KEY", CPLGetConfigOption("CARTO_API_KEY", CPLGetConfigOption("CARTODB_API_KEY", ""))); CPLString osTables = OGRCARTOGetOptionValue(pszFilename, "tables"); /*if( osTables.size() == 0 && osAPIKey.size() == 0 ) { CPLError(CE_Failure, CPLE_AppDefined, "When not specifying tables option, CARTO_API_KEY must be defined"); return FALSE; }*/ bUseHTTPS = CPLTestBool(CPLGetConfigOption("CARTO_HTTPS", CPLGetConfigOption("CARTODB_HTTPS", "YES"))); OGRLayer* poSchemaLayer = ExecuteSQLInternal("SELECT current_schema()"); if( poSchemaLayer ) { OGRFeature* poFeat = poSchemaLayer->GetNextFeature(); if( poFeat ) { if( poFeat->GetFieldCount() == 1 ) { osCurrentSchema = poFeat->GetFieldAsString(0); } delete poFeat; } ReleaseResultSet(poSchemaLayer); } if( osCurrentSchema.size() == 0 ) return FALSE; /* -------------------------------------------------------------------- */ /* Find out PostGIS version */ /* -------------------------------------------------------------------- */ if( bReadWrite ) { OGRLayer* poPostGISVersionLayer = ExecuteSQLInternal("SELECT postgis_version()"); if( poPostGISVersionLayer ) { OGRFeature* poFeat = poPostGISVersionLayer->GetNextFeature(); if( poFeat ) { if( poFeat->GetFieldCount() == 1 ) { const char* pszVersion = poFeat->GetFieldAsString(0); nPostGISMajor = atoi(pszVersion); const char* pszDot = strchr(pszVersion, '.'); nPostGISMinor = 0; if( pszDot ) nPostGISMinor = atoi(pszDot + 1); } delete poFeat; } ReleaseResultSet(poPostGISVersionLayer); } } if( osAPIKey.size() && bUpdateIn ) { ExecuteSQLInternal( "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"); } if (osTables.size() != 0) { char** papszTables = CSLTokenizeString2(osTables, ",", 0); for(int i=0;papszTables && papszTables[i];i++) { papoLayers = (OGRCARTOTableLayer**) CPLRealloc( papoLayers, (nLayers + 1) * sizeof(OGRCARTOTableLayer*)); papoLayers[nLayers ++] = new OGRCARTOTableLayer(this, papszTables[i]); } CSLDestroy(papszTables); return TRUE; } OGRLayer* poTableListLayer = ExecuteSQLInternal("SELECT CDB_UserTables()"); if( poTableListLayer ) { OGRFeature* poFeat; while( (poFeat = poTableListLayer->GetNextFeature()) != NULL ) { if( poFeat->GetFieldCount() == 1 ) { papoLayers = (OGRCARTOTableLayer**) CPLRealloc( papoLayers, (nLayers + 1) * sizeof(OGRCARTOTableLayer*)); papoLayers[nLayers ++] = new OGRCARTOTableLayer( this, poFeat->GetFieldAsString(0)); } delete poFeat; } ReleaseResultSet(poTableListLayer); } else if( osCurrentSchema == "public" ) return FALSE; /* There's currently a bug with CDB_UserTables() on multi-user accounts */ if( nLayers == 0 && osCurrentSchema != "public" ) { CPLString osSQL; osSQL.Printf("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 = '%s'", OGRCARTOEscapeLiteral(osCurrentSchema).c_str()); poTableListLayer = ExecuteSQLInternal(osSQL); if( poTableListLayer ) { OGRFeature* poFeat; while( (poFeat = poTableListLayer->GetNextFeature()) != NULL ) { if( poFeat->GetFieldCount() == 1 ) { papoLayers = (OGRCARTOTableLayer**) CPLRealloc( papoLayers, (nLayers + 1) * sizeof(OGRCARTOTableLayer*)); papoLayers[nLayers ++] = new OGRCARTOTableLayer( this, poFeat->GetFieldAsString(0)); } delete poFeat; } ReleaseResultSet(poTableListLayer); } else return FALSE; } return TRUE; }
int OGRAmigoCloudDataSource::Open( const char * pszFilename, char** papszOpenOptionsIn, int bUpdateIn ) { bReadWrite = CPL_TO_BOOL(bUpdateIn); pszName = CPLStrdup( pszFilename ); pszProjectId = CPLStrdup(pszFilename + strlen("AMIGOCLOUD:")); char* pchSpace = strchr(pszProjectId, ' '); if( pchSpace ) *pchSpace = '\0'; if( pszProjectId[0] == 0 ) { CPLError(CE_Failure, CPLE_AppDefined, "Missing project id"); return FALSE; } osAPIKey = CSLFetchNameValueDef(papszOpenOptionsIn, "AMIGOCLOUD_API_KEY", CPLGetConfigOption("AMIGOCLOUD_API_KEY", "")); if (osAPIKey.empty()) { osAPIKey = OGRAMIGOCLOUDGetOptionValue(pszFilename, "AMIGOCLOUD_API_KEY"); } if (osAPIKey.empty()) { CPLError(CE_Failure, CPLE_AppDefined, "AMIGOCLOUD_API_KEY is not defined.\n"); return FALSE; } OGRLayer* poSchemaLayer = ExecuteSQLInternal("SELECT current_schema()"); if( poSchemaLayer ) { OGRFeature* poFeat = poSchemaLayer->GetNextFeature(); if( poFeat ) { if( poFeat->GetFieldCount() == 1 ) { osCurrentSchema = poFeat->GetFieldAsString(0); } delete poFeat; } ReleaseResultSet(poSchemaLayer); } if( osCurrentSchema.empty() ) return FALSE; CPLString osDatasets = OGRAMIGOCLOUDGetOptionValue(pszFilename, "datasets"); if (!osDatasets.empty()) { char** papszTables = CSLTokenizeString2(osDatasets, ",", 0); for(int i=0;papszTables && papszTables[i];i++) { papoLayers = (OGRAmigoCloudTableLayer**) CPLRealloc( papoLayers, (nLayers + 1) * sizeof(OGRAmigoCloudTableLayer*)); papoLayers[nLayers ++] = new OGRAmigoCloudTableLayer(this, papszTables[i]); } CSLDestroy(papszTables); // If OVERWRITE: YES, truncate the layer. if( nLayers==1 && CPLFetchBool(papszOpenOptionsIn, "OVERWRITE", false) ) { TruncateDataset(papoLayers[0]->GetTableName()); } return TRUE; } else { // If 'datasets' word is in the filename, but no dataset id specified, // print the list of available datasets if(std::string(pszFilename).find("datasets") != std::string::npos) ListDatasets(); } return TRUE; }
int OGRMySQLDataSource::Open( const char * pszNewName, char** papszOpenOptionsIn, int bUpdate ) { CPLAssert( nLayers == 0 ); /* -------------------------------------------------------------------- */ /* Use options process to get .my.cnf file contents. */ /* -------------------------------------------------------------------- */ int nPort = 0; char **papszTableNames=nullptr; std::string oHost, oPassword, oUser, oDB; CPLString osNewName(pszNewName); const char* apszOpenOptions[] = { "dbname", "port", "user", "password", "host", "tables" }; for(int i=0; i <(int)(sizeof(apszOpenOptions)/sizeof(char*));i++) { const char* pszVal = CSLFetchNameValue(papszOpenOptionsIn, apszOpenOptions[i]); if( pszVal ) { if( osNewName.back() != ':' ) osNewName += ","; if( i > 0 ) { osNewName += apszOpenOptions[i]; osNewName += "="; } if( EQUAL(apszOpenOptions[i], "tables") ) { for( ; *pszVal; ++pszVal ) { if( *pszVal == ',' ) osNewName += ";"; else osNewName += *pszVal; } } else osNewName += pszVal; } } /* -------------------------------------------------------------------- */ /* Parse out connection information. */ /* -------------------------------------------------------------------- */ char **papszItems = CSLTokenizeString2( osNewName+6, ",", CSLT_HONOURSTRINGS ); if( CSLCount(papszItems) < 1 ) { CSLDestroy( papszItems ); CPLError( CE_Failure, CPLE_AppDefined, "MYSQL: request missing databasename." ); return FALSE; } oDB = papszItems[0]; for( int i = 1; papszItems[i] != nullptr; i++ ) { if( STARTS_WITH_CI(papszItems[i], "user="******"password="******"host=") ) oHost = papszItems[i] + 5; else if( STARTS_WITH_CI(papszItems[i], "port=") ) nPort = atoi(papszItems[i] + 5); else if( STARTS_WITH_CI(papszItems[i], "tables=") ) { CSLDestroy(papszTableNames); papszTableNames = CSLTokenizeStringComplex( papszItems[i] + 7, ";", FALSE, FALSE ); } else CPLError( CE_Warning, CPLE_AppDefined, "'%s' in MYSQL datasource definition not recognised and ignored.", papszItems[i] ); } CSLDestroy( papszItems ); /* -------------------------------------------------------------------- */ /* Try to establish connection. */ /* -------------------------------------------------------------------- */ hConn = mysql_init( nullptr ); if( hConn == nullptr ) { CPLError( CE_Failure, CPLE_AppDefined, "mysql_init() failed." ); } /* -------------------------------------------------------------------- */ /* Set desired options on the connection: charset and timeout. */ /* -------------------------------------------------------------------- */ if( hConn ) { const char *pszTimeoutLength = CPLGetConfigOption( "MYSQL_TIMEOUT", "0" ); unsigned int timeout = atoi(pszTimeoutLength); mysql_options(hConn, MYSQL_OPT_CONNECT_TIMEOUT, (char*)&timeout); mysql_options(hConn, MYSQL_SET_CHARSET_NAME, "utf8" ); } /* -------------------------------------------------------------------- */ /* Perform connection. */ /* -------------------------------------------------------------------- */ if( hConn && mysql_real_connect( hConn, oHost.length() ? oHost.c_str() : nullptr, oUser.length() ? oUser.c_str() : nullptr, oPassword.length() ? oPassword.c_str() : nullptr, oDB.length() ? oDB.c_str() : nullptr, nPort, nullptr, CLIENT_INTERACTIVE ) == nullptr ) { CPLError( CE_Failure, CPLE_AppDefined, "MySQL connect failed for: %s\n%s", pszNewName + 6, mysql_error( hConn ) ); mysql_close( hConn ); hConn = nullptr; } if( hConn == nullptr ) { CSLDestroy( papszTableNames ); return FALSE; } else { // Enable automatic reconnection #if defined(LIBMYSQL_VERSION_ID) && (LIBMYSQL_VERSION_ID >= 80000) bool reconnect = 1; #else my_bool reconnect = 1; #endif // Must be called after mysql_real_connect() on MySQL < 5.0.19 // and at any point on more recent versions. mysql_options(hConn, MYSQL_OPT_RECONNECT, &reconnect); } pszName = CPLStrdup( pszNewName ); bDSUpdate = bUpdate; /* -------------------------------------------------------------------- */ /* Check version. */ /* -------------------------------------------------------------------- */ auto versionLyr = ExecuteSQL("SELECT VERSION()", nullptr, nullptr); if( versionLyr ) { auto versionFeat = versionLyr->GetNextFeature(); if( versionFeat ) { const char* pszVersion = versionFeat->GetFieldAsString(0); m_nMajor = atoi(pszVersion); const char* pszDot = strchr(pszVersion, '.'); if( pszDot ) m_nMinor = atoi(pszDot+1); m_bIsMariaDB = strstr(pszVersion, "MariaDB") != nullptr; } delete versionFeat; ReleaseResultSet(versionLyr); } /* -------------------------------------------------------------------- */ /* Get a list of available tables. */ /* -------------------------------------------------------------------- */ if( papszTableNames == nullptr ) { MYSQL_RES *hResultSet; MYSQL_ROW papszRow; if( mysql_query( hConn, "SHOW TABLES" ) ) { ReportError( "SHOW TABLES Failed" ); return FALSE; } hResultSet = mysql_store_result( hConn ); if( hResultSet == nullptr ) { ReportError( "mysql_store_result() failed on SHOW TABLES result."); return FALSE; } while( (papszRow = mysql_fetch_row( hResultSet )) != nullptr ) { if( papszRow[0] == nullptr ) continue; if( EQUAL(papszRow[0],"spatial_ref_sys") || EQUAL(papszRow[0],"geometry_columns") ) continue; papszTableNames = CSLAddString(papszTableNames, papszRow[0] ); } mysql_free_result( hResultSet ); } /* -------------------------------------------------------------------- */ /* Get the schema of the available tables. */ /* -------------------------------------------------------------------- */ for( int iRecord = 0; papszTableNames != nullptr && papszTableNames[iRecord] != nullptr; iRecord++ ) { // FIXME: This should be fixed to deal with tables // for which we can't open because the name is bad/ OpenTable( papszTableNames[iRecord], bUpdate ); } CSLDestroy( papszTableNames ); return nLayers > 0 || bUpdate; }