?? ogrmysqldatasource.cpp
字號:
/****************************************************************************** * $Id: ogrmysqldatasource.cpp 10646 2007-01-18 02:38:10Z warmerdam $ * * Project: OpenGIS Simple Features Reference Implementation * Purpose: Implements OGRMySQLDataSource class. * Author: Frank Warmerdam, warmerdam@pobox.com * Author: Howard Butler, hobu@hobu.net * ****************************************************************************** * Copyright (c) 2004, Frank Warmerdam <warmerdam@pobox.com> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************/#include <string>#include "ogr_mysql.h"#include <my_sys.h>#include "cpl_conv.h"#include "cpl_string.h"CPL_CVSID("$Id: ogrmysqldatasource.cpp 10646 2007-01-18 02:38:10Z warmerdam $");/************************************************************************//* OGRMySQLDataSource() *//************************************************************************/OGRMySQLDataSource::OGRMySQLDataSource(){ pszName = NULL; papoLayers = NULL; nLayers = 0; hConn = 0; nSoftTransactionLevel = 0; nKnownSRID = 0; panSRID = NULL; papoSRS = NULL; poLongResultLayer = NULL;}/************************************************************************//* ~OGRMySQLDataSource() *//************************************************************************/OGRMySQLDataSource::~OGRMySQLDataSource(){ int i; InterruptLongResult(); CPLFree( pszName ); for( i = 0; i < nLayers; i++ ) delete papoLayers[i]; CPLFree( papoLayers ); if( hConn != NULL ) mysql_close( hConn ); for( i = 0; i < nKnownSRID; i++ ) { if( papoSRS[i] != NULL ) papoSRS[i]->Release(); } CPLFree( panSRID ); CPLFree( papoSRS );}/************************************************************************//* ReportError() *//************************************************************************/void OGRMySQLDataSource::ReportError( const char *pszDescription ){ if( pszDescription ) CPLError( CE_Failure, CPLE_AppDefined, "MySQL error message:%s Description: %s", mysql_error( hConn ), pszDescription ); else CPLError( CE_Failure, CPLE_AppDefined, "%s", mysql_error( hConn ) );}/************************************************************************//* Open() *//************************************************************************/int OGRMySQLDataSource::Open( const char * pszNewName, int bUpdate, int bTestOpen ){ CPLAssert( nLayers == 0 );/* -------------------------------------------------------------------- *//* Verify MySQL prefix. *//* -------------------------------------------------------------------- */ if( !EQUALN(pszNewName,"MYSQL:",6) ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_AppDefined, "%s does not conform to MySQL naming convention," " MYSQL:dbname[, user=..][,password=..][,host=..][,port=..][tables=table;table;...]", pszNewName ); return FALSE; } /* -------------------------------------------------------------------- *//* Use options process to get .my.cnf file contents. *//* -------------------------------------------------------------------- */ int nPort = 0, i; char **papszTableNames=NULL; std::string oHost, oPassword, oUser, oDB; char *apszArgv[2] = { "org", NULL }; char **papszArgv = apszArgv; int nArgc = 1; const char *client_groups[] = {"client", "ogr", NULL }; my_init(); // I hope there is no problem with calling this multiple times! load_defaults( "my", client_groups, &nArgc, &papszArgv ); for( i = 0; i < nArgc; i++ ) { if( EQUALN(papszArgv[i],"--user=",7) ) oUser = papszArgv[i] + 7; else if( EQUALN(papszArgv[i],"--host=",7) ) oHost = papszArgv[i] + 7; else if( EQUALN(papszArgv[i],"--password=",11) ) oPassword = papszArgv[i] + 11; else if( EQUALN(papszArgv[i],"--port=",7) ) nPort = atoi(papszArgv[i] + 7); } // cleanup free_defaults( papszArgv );/* -------------------------------------------------------------------- *//* Parse out connection information. *//* -------------------------------------------------------------------- */ char **papszItems = CSLTokenizeString2( pszNewName+6, ",", CSLT_HONOURSTRINGS ); if( CSLCount(papszItems) < 1 ) { CSLDestroy( papszItems ); CPLError( CE_Failure, CPLE_AppDefined, "MYSQL: request missing databasename." ); return FALSE; } oDB = papszItems[0]; for( i = 1; papszItems[i] != NULL; i++ ) { if( EQUALN(papszItems[i],"user=",5) ) oUser = papszItems[i] + 5; else if( EQUALN(papszItems[i],"password=",9) ) oPassword = papszItems[i] + 9; else if( EQUALN(papszItems[i],"host=",5) ) oHost = papszItems[i] + 5; else if( EQUALN(papszItems[i],"port=",5) ) nPort = atoi(papszItems[i] + 5); else if( EQUALN(papszItems[i],"tables=",7) ) { 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( NULL );/* -------------------------------------------------------------------- *//* Set the timeout for the connection if the users has specified. *//* -------------------------------------------------------------------- */ const char *pszTimeoutLength = CPLGetConfigOption( "MYSQL_TIMEOUT", "0" ); unsigned int timeout = atoi(pszTimeoutLength); mysql_options(hConn, MYSQL_OPT_CONNECT_TIMEOUT, (char*)&timeout); if( hConn == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "mysql_init() failed." ); } if( hConn && mysql_real_connect( hConn, oHost.length() ? oHost.c_str() : NULL, oUser.length() ? oUser.c_str() : NULL, oPassword.length() ? oPassword.c_str() : NULL, oDB.length() ? oDB.c_str() : NULL, nPort, NULL, CLIENT_INTERACTIVE ) == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "MySQL connect failed for: %s\n%s", pszNewName + 6, mysql_error( hConn ) ); mysql_close( hConn ); hConn = NULL; } if( hConn == NULL ) { CSLDestroy( papszTableNames ); return FALSE; } pszName = CPLStrdup( pszNewName ); bDSUpdate = bUpdate;/* -------------------------------------------------------------------- *//* Get a list of available tables. *//* -------------------------------------------------------------------- */ if( papszTableNames == NULL ) { 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 == NULL ) { ReportError( "mysql_store_result() failed on SHOW TABLES result."); return FALSE; } while( (papszRow = mysql_fetch_row( hResultSet )) != NULL ) { if( papszRow[0] == NULL ) 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. *//* -------------------------------------------------------------------- */ int iRecord; for( iRecord = 0; papszTableNames != NULL && papszTableNames[iRecord] != NULL; 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, FALSE ); } CSLDestroy( papszTableNames ); return nLayers > 0 || bUpdate;}/************************************************************************//* OpenTable() *//************************************************************************/int OGRMySQLDataSource::OpenTable( const char *pszNewName, int bUpdate, int bTestOpen ){/* -------------------------------------------------------------------- *//* Create the layer object. *//* -------------------------------------------------------------------- */ OGRMySQLTableLayer *poLayer; OGRErr eErr; poLayer = new OGRMySQLTableLayer( this, pszNewName, bUpdate ); eErr = poLayer->Initialize(pszNewName); if (eErr == OGRERR_FAILURE) return FALSE;/* -------------------------------------------------------------------- *//* Add layer to data source layer list. *//* -------------------------------------------------------------------- */ papoLayers = (OGRMySQLLayer **) CPLRealloc( papoLayers, sizeof(OGRMySQLLayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; return TRUE;}/************************************************************************//* TestCapability() *//************************************************************************/int OGRMySQLDataSource::TestCapability( const char * pszCap ){ if( EQUAL(pszCap, ODsCCreateLayer) ) return TRUE; if( EQUAL(pszCap, ODsCDeleteLayer)) return TRUE; else return FALSE;}/************************************************************************//* GetLayer() *//************************************************************************/OGRLayer *OGRMySQLDataSource::GetLayer( int iLayer ){ if( iLayer < 0 || iLayer >= nLayers ) return NULL; else return papoLayers[iLayer];}/************************************************************************//* InitializeMetadataTables() *//* *//* Create the metadata tables (SPATIAL_REF_SYS and *//* GEOMETRY_COLUMNS). This method "does no harm" if the tables *//* exist and can be called at will. *//************************************************************************/OGRErr OGRMySQLDataSource::InitializeMetadataTables(){
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -