diff options
-rw-r--r-- | storage/connect/global.h | 1 | ||||
-rw-r--r-- | storage/connect/ha_connect.cc | 3 | ||||
-rw-r--r-- | storage/connect/plugutil.c | 17 | ||||
-rw-r--r-- | storage/connect/tabmysql.cpp | 144 | ||||
-rw-r--r-- | storage/connect/tabmysql.h | 1 | ||||
-rw-r--r-- | storage/connect/tabtbl.cpp | 20 |
6 files changed, 123 insertions, 63 deletions
diff --git a/storage/connect/global.h b/storage/connect/global.h index 303078f5a18..3702f050501 100644 --- a/storage/connect/global.h +++ b/storage/connect/global.h @@ -244,6 +244,7 @@ DllExport BOOL PlugIsAbsolutePath(LPCSTR path); DllExport void *PlugAllocMem(PGLOBAL, uint); DllExport BOOL PlugSubSet(PGLOBAL, void *, uint); DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t); +DllExport char *PlugDup(PGLOBAL g, const char *str); DllExport void *MakePtr(void *, OFFSET); DllExport void htrc(char const *fmt, ...); diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index e28ac90a9ce..ab002488620 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -666,8 +666,7 @@ char *ha_connect::GetStringOption(char *opname, char *sdef) else if (!stricmp(opname, "Separator")) opval= (char*)options->separator; else if (!stricmp(opname, "Connect")) -// opval= (char*)options->connect; - opval= table->s->connect_string.str; + opval= (tshp) ? tshp->connect_string.str : table->s->connect_string.str; else if (!stricmp(opname, "Qchar")) opval= (char*)options->qchar; else if (!stricmp(opname, "Module")) diff --git a/storage/connect/plugutil.c b/storage/connect/plugutil.c index e8098bb2512..7910f1ea318 100644 --- a/storage/connect/plugutil.c +++ b/storage/connect/plugutil.c @@ -512,6 +512,23 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) } /* end of PlugSubAlloc */ /***********************************************************************/ +/* This routine suballocate a copy of the passed string. */ +/***********************************************************************/ +char *PlugDup(PGLOBAL g, const char *str) + { + char *buf; + size_t len; + + if (str && (len = strlen(str))) { + buf = (char*)PlugSubAlloc(g, NULL, len + 1); + strcpy(buf, str); + } else + buf = NULL; + + return(buf); + } /* end of PlugDup */ + +/***********************************************************************/ /* This routine makes a pointer from an offset to a memory pointer. */ /***********************************************************************/ void *MakePtr(void *memp, OFFSET offset) diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp index 1a19b4cbf33..3af5904eee4 100644 --- a/storage/connect/tabmysql.cpp +++ b/storage/connect/tabmysql.cpp @@ -31,7 +31,10 @@ /* IBM, Borland, GNU or Microsoft C++ Compiler and Linker */ /* */ /************************************************************************/ +#define MYSQL_SERVER 1 #include "my_global.h" +#include "sql_class.h" +#include "sql_servers.h" #if defined(WIN32) //#include <windows.h> #else // !WIN32 @@ -64,7 +67,6 @@ void PrintResult(PGLOBAL, PSEM, PQRYRES); #endif // _CONSOLE extern "C" int trace; -extern MYSQL_PLUGIN_IMPORT uint mysqld_port; /* -------------- Implementation of the MYSQLDEF class --------------- */ @@ -87,6 +89,45 @@ MYSQLDEF::MYSQLDEF(void) } // end of MYSQLDEF constructor /***********************************************************************/ +/* Get connection info from the declared server. */ +/***********************************************************************/ +bool MYSQLDEF::GetServerInfo(PGLOBAL g, const char *server_name) +{ + THD *thd= current_thd; + MEM_ROOT *mem= thd->mem_root; + FOREIGN_SERVER *server, server_buffer; + DBUG_ENTER("GetServerInfo"); + DBUG_PRINT("info", ("server_name %s", server_name)); + + if (!server_name || !strlen(server_name)) { + DBUG_PRINT("info", ("server_name not defined!")); + strcpy(g->Message, "server_name not defined!"); + DBUG_RETURN(true); + } // endif server_name + + // get_server_by_name() clones the server if exists and allocates + // copies of strings in the supplied mem_root + if (!(server= get_server_by_name(mem, server_name, &server_buffer))) { + DBUG_PRINT("info", ("get_server_by_name returned > 0 error condition!")); + /* need to come up with error handling */ + strcpy(g->Message, "get_server_by_name returned > 0 error condition!"); + DBUG_RETURN(true); + } // endif server + + DBUG_PRINT("info", ("get_server_by_name returned server at %lx", + (long unsigned int) server)); + + // TODO: We need to examine which of these can really be NULL + Hostname = PlugDup(g, server->host); + Database = PlugDup(g, server->db); + Username = PlugDup(g, server->username); + Password = PlugDup(g, server->password); + Portnumber = (server->port) ? server->port : GetDefaultPort(); + + DBUG_RETURN(false); +} // end of GetServerInfo + +/***********************************************************************/ /* Parse connection string */ /* */ /* SYNOPSIS */ @@ -135,54 +176,25 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url) if ((!strstr(url, "://") && (!strchr(url, '@')))) { // No :// or @ in connection string. Must be a straight // connection name of either "server" or "server/table" - strcpy(g->Message, "Using Federated server not implemented yet"); - return true; -#if 0 - /* ok, so we do a little parsing, but not completely! */ - share->parsed= FALSE; - /* - If there is a single '/' in the connection string, this means the user is - specifying a table name - */ - - if ((share->table_name= strchr(share->connection_string, '/'))) - { - *share->table_name++= '\0'; - share->table_name_length= strlen(share->table_name); - - DBUG_PRINT("info", - ("internal format, parsed table_name " - "share->connection_string: %s share->table_name: %s", - share->connection_string, share->table_name)); - - /* - there better not be any more '/'s ! - */ - if (strchr(share->table_name, '/')) - goto error; - } - /* - Otherwise, straight server name, use tablename of federatedx table - as remote table name - */ - else - { - /* - Connection specifies everything but, resort to - expecting remote and foreign table names to match - */ - share->table_name= strmake_root(mem_root, table->s->table_name.str, - (share->table_name_length= - table->s->table_name.length)); - DBUG_PRINT("info", - ("internal format, default table_name " - "share->connection_string: %s share->table_name: %s", - share->connection_string, share->table_name)); - } - - if ((error_num= get_connection(mem_root, share))) - goto error; -#endif // 0 + // ok, so we do a little parsing, but not completely! + if ((Tabname= strchr(url, '/'))) { + // If there is a single '/' in the connection string, + // this means the user is specifying a table name + *Tabname++= '\0'; + + // there better not be any more '/'s ! + if (strchr(Tabname, '/')) + return true; + + } else + // Otherwise, straight server name, + // use tablename of federatedx table as remote table name + Tabname= Name; + + if (trace) + htrc("server: %s Tabname: %s", url, Tabname); + + return GetServerInfo(g, url); } else { // URL, parse it char *sport, *scheme = url; @@ -247,7 +259,7 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url) if ((sport = strchr(Hostname, ':'))) *sport++ = 0; - Portnumber = (sport && sport[0]) ? atoi(sport) : mysqld_port; + Portnumber = (sport && sport[0]) ? atoi(sport) : GetDefaultPort(); if (Username[0] == 0) Username = Cat->GetStringCatInfo(g, "User", "*"); @@ -279,12 +291,14 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url) /***********************************************************************/ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) { - char *url = Cat->GetStringCatInfo(g, "Connect", NULL); + char *url; Desc = "MySQL Table"; if (stricmp(am, "MYPRX")) { // Normal case of specific MYSQL table + url = Cat->GetStringCatInfo(g, "Connect", NULL); + if (!url || !*url) { // Not using the connection URL Hostname = Cat->GetStringCatInfo(g, "Host", "localhost"); @@ -293,24 +307,36 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname); Username = Cat->GetStringCatInfo(g, "User", "*"); Password = Cat->GetStringCatInfo(g, "Password", NULL); - Portnumber = Cat->GetIntCatInfo("Port", mysqld_port); + Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort()); } else if (ParseURL(g, url)) return TRUE; Bind = !!Cat->GetIntCatInfo("Bind", 0); Delayed = !!Cat->GetIntCatInfo("Delayed", 0); } else { - // MYSQL access from a PROXY table, not using URL + // MYSQL access from a PROXY table Database = Cat->GetStringCatInfo(g, "Database", "*"); - Tabname = Name; Isview = Cat->GetBoolCatInfo("View", FALSE); - // We must get connection parms from the calling table + // We must get other connection parms from the calling table Remove_tshp(Cat); - Hostname = Cat->GetStringCatInfo(g, "Host", "localhost"); - Username = Cat->GetStringCatInfo(g, "User", "*"); - Password = Cat->GetStringCatInfo(g, "Password", NULL); - Portnumber = Cat->GetIntCatInfo("Port", mysqld_port); + url = Cat->GetStringCatInfo(g, "Connect", NULL); + + if (!url || !*url) { + Hostname = Cat->GetStringCatInfo(g, "Host", "localhost"); + Username = Cat->GetStringCatInfo(g, "User", "*"); + Password = Cat->GetStringCatInfo(g, "Password", NULL); + Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort()); + } else { + char *locdb = Database; + + if (ParseURL(g, url)) + return TRUE; + + Database = locdb; + } // endif url + + Tabname = Name; } // endif am if ((Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL))) diff --git a/storage/connect/tabmysql.h b/storage/connect/tabmysql.h index 24f8c4cdef2..16e2d650229 100644 --- a/storage/connect/tabmysql.h +++ b/storage/connect/tabmysql.h @@ -39,6 +39,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */ virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); virtual PTDB GetTable(PGLOBAL g, MODE m); bool ParseURL(PGLOBAL g, char *url); + bool GetServerInfo(PGLOBAL g, const char *server_name); protected: // Members diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp index 89acc53fd4a..6b90b3861aa 100644 --- a/storage/connect/tabtbl.cpp +++ b/storage/connect/tabtbl.cpp @@ -109,11 +109,12 @@ TBLDEF::TBLDEF(void) /**************************************************************************/ bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) { - char *tablist, *dbname; + char *tablist, *dbname, *def = NULL; Desc = "Table list table"; tablist = Cat->GetStringCatInfo(g, "Tablist", ""); dbname = Cat->GetStringCatInfo(g, "Dbname", "*"); + def = Cat->GetStringCatInfo(g, "Srcdef", NULL); Ntables = 0; if (*tablist) { @@ -134,7 +135,7 @@ bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) } // endif p // Allocate the TBLIST block for that table - tbl = new(g) XTAB(pn); + tbl = new(g) XTAB(pn, def); tbl->SetQualifier(pdb); if (trace) @@ -231,16 +232,28 @@ PCOL TDBTBL::InsertSpecialColumn(PGLOBAL g, PCOL scp) bool TDBTBL::InitTableList(PGLOBAL g) { int n; + uint sln; + char *scs; PTABLE tp, tabp; PCOL colp; PTBLDEF tdp = (PTBLDEF)To_Def; + PCATLG cat = To_Def->GetCat(); + PHC hc = ((MYCAT*)cat)->GetHandler(); + scs = hc->get_table()->s->connect_string.str; + sln = hc->get_table()->s->connect_string.length; // PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath()); for (n = 0, tp = tdp->Tablep; tp; tp = tp->GetNext()) { if (TestFil(g, To_Filter, tp)) { tabp = new(g) XTAB(tp); + if (tabp->GetSrc()) { + // Table list is a list of connections + hc->get_table()->s->connect_string.str = (char*)tabp->GetName(); + hc->get_table()->s->connect_string.length = strlen(tabp->GetName()); + } // endif Src + // Get the table description block of this table if (!(Tdbp = GetSubTable(g, tabp))) { if (++Nbc > Maxerr) @@ -269,6 +282,9 @@ bool TDBTBL::InitTableList(PGLOBAL g) } // endfor tp + hc->get_table()->s->connect_string.str = scs; + hc->get_table()->s->connect_string.length = sln; + //NumTables = n; To_Filter = NULL; // To avoid doing it several times return FALSE; |