Commit b535cb98 authored by Olivier Bertrand's avatar Olivier Bertrand

- Add the support of URL connection string fo MYSQL tables

  Federated servers are not yet supported.

modified:
  storage/connect/ha_connect.cc
  storage/connect/tabmysql.cpp
  storage/connect/tabmysql.h
parent 62fbaf96
......@@ -117,7 +117,8 @@
#include "odbccat.h"
#endif // ODBC_SUPPORT
#if defined(MYSQL_SUPPORT)
#include "myconn.h"
#include "xtable.h"
#include "tabmysql.h"
#endif // MYSQL_SUPPORT
#include "filamdbf.h"
#include "tabfmt.h"
......@@ -832,8 +833,10 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
if (!opval) {
if (sdef && !strcmp(sdef, "*")) {
// Return the handler default value
if (!stricmp(opname, "Database"))
if (!stricmp(opname, "Dbname") || !stricmp(opname, "Database"))
opval= (char*)GetDBName(NULL); // Current database
else
opval= sdef; // Caller default
} else
opval= sdef; // Caller default
......@@ -3405,12 +3408,6 @@ bool ha_connect::pre_create(THD *thd, HA_CREATE_INFO *create_info,
pov= new(mem) engine_option_value(*name, *val, false, &start, &end);
} // endif ttp
// Test whether columns must be specified
if (alter_info->create_list.elements)
return false;
dbf= ttp == TAB_DBF;
if (!tab && !(fnc & (FNC_TABLE | FNC_COL)))
tab= (char*)create_info->alias;
......@@ -3438,10 +3435,33 @@ bool ha_connect::pre_create(THD *thd, HA_CREATE_INFO *create_info,
break;
#if defined(MYSQL_SUPPORT)
case TAB_MYSQL:
if (!user)
ok= true;
if ((dsn= create_info->connect_string.str)) {
PDBUSER dup= PlgGetUser(g);
PCATLG cat= (dup) ? dup->Catalog : NULL;
PMYDEF mydef= new(g) MYSQLDEF();
dsn= (char*)PlugSubAlloc(g, NULL, strlen(dsn) + 1);
strncpy(dsn, create_info->connect_string.str,
create_info->connect_string.length);
dsn[create_info->connect_string.length] = 0;
mydef->Name= (char*)create_info->alias;
mydef->Cat= cat;
if (!mydef->ParseURL(g, dsn)) {
host= mydef->Hostname;
user= mydef->Username;
pwd= mydef->Password;
db= mydef->Database;
tab= mydef->Tabname;
port= mydef->Portnumber;
} else
ok= false;
} else if (!user)
user= "root"; // Avoid crash
ok= true;
break;
#endif // MYSQL_SUPPORT
#if defined(WIN32)
......@@ -3460,6 +3480,10 @@ bool ha_connect::pre_create(THD *thd, HA_CREATE_INFO *create_info,
ok= false;
} // endif supfnc
// Test whether columns must be specified
if (alter_info->create_list.elements)
return false;
if (ok) {
char *length, *decimals, *cnm, *rem;
int i, len, dec, typ;
......
/************* TabMySQL C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: TABMYSQL */
/* ------------- */
/* Version 1.6 */
/* Version 1.7 */
/* */
/* AUTHOR: */
/* ------- */
......@@ -82,19 +82,211 @@ MYSQLDEF::MYSQLDEF(void)
Delayed = FALSE;
} // end of MYSQLDEF constructor
/***********************************************************************/
/* Parse connection string */
/* */
/* SYNOPSIS */
/* ParseURL() */
/* url The connection string to parse */
/* */
/* DESCRIPTION */
/* Populates the table with information about the connection */
/* to the foreign database that will serve as the data source. */
/* This string must be specified (currently) in the "CONNECTION" */
/* field, listed in the CREATE TABLE statement. */
/* */
/* This string MUST be in the format of any of these: */
/* */
/* CONNECTION="scheme://user:pwd@host:port/database/table" */
/* CONNECTION="scheme://user@host/database/table" */
/* CONNECTION="scheme://user@host:port/database/table" */
/* CONNECTION="scheme://user:pwd@host/database/table" */
/* */
/* _OR_ */
/* */
/* CONNECTION="connection name" (NIY) */
/* */
/* An Example: */
/* */
/* CREATE TABLE t1 (id int(32)) */
/* ENGINE="FEDERATEDX" */
/* CONNECTION="mysql://joe:pwd@192.168.1.111:9308/dbname/tabname"; */
/* */
/* CREATE TABLE t2 ( */
/* id int(4) NOT NULL auto_increment, */
/* name varchar(32) NOT NULL, */
/* PRIMARY KEY(id) */
/* ) ENGINE="FEDERATEDX" CONNECTION="my_conn"; (NIY) */
/* */
/* 'password' and 'port' are both optional. */
/* */
/* RETURN VALUE */
/* false success */
/* true error */
/* */
/***********************************************************************/
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
} else {
// URL, parse it
char *sport, *scheme = url;
if (!(Username = strstr(url, "://"))) {
strcpy(g->Message, "Connection is not an URL");
return true;
} // endif User
scheme[Username - scheme] = 0;
if (stricmp(scheme, "mysql")) {
strcpy(g->Message, "scheme must be mysql");
return true;
} // endif scheme
Username += 3;
if (!(Hostname = strchr(Username, '@'))) {
strcpy(g->Message, "No host specified in URL");
return true;
} else
*Hostname++ = 0; // End Username
if ((Password = strchr(Username, ':'))) {
*Password++ = 0; // End username
// Make sure there isn't an extra / or @
if ((strchr(Password, '/') || strchr(Hostname, '@'))) {
strcpy(g->Message, "Syntax error in URL");
return true;
} // endif
// Found that if the string is:
// user:@hostname:port/db/table
// Then password is a null string, so set to NULL
if ((Password[0] == 0))
Password = NULL;
} // endif password
// Make sure there isn't an extra / or @ */
if ((strchr(Username, '/')) || (strchr(Hostname, '@'))) {
strcpy(g->Message, "Syntax error in URL");
return true;
} // endif
if ((Database = strchr(Hostname, '/'))) {
*Database++ = 0;
if ((Tabname = strchr(Database, '/')))
*Tabname++ = 0;
// Make sure there's not an extra /
if ((strchr(Tabname, '/'))) {
strcpy(g->Message, "Syntax error in URL");
return true;
} // endif /
} // endif database
if ((sport = strchr(Hostname, ':')))
*sport++ = 0;
Portnumber = (sport && sport[0]) ? atoi(sport) : MYSQL_PORT;
if (Hostname[0] == 0)
Hostname = "localhost";
if (!Database || !*Database)
Database = Cat->GetStringCatInfo(g, Name, "Database", "*");
if (!Tabname || !*Tabname)
Tabname = Name;
} // endif URL
#if 0
if (!share->port)
if (!share->hostname || strcmp(share->hostname, my_localhost) == 0)
share->socket= (char *) MYSQL_UNIX_ADDR;
else
share->port= MYSQL_PORT;
#endif // 0
return false;
} // end of ParseURL
/***********************************************************************/
/* DefineAM: define specific AM block values from XCV file. */
/***********************************************************************/
bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
char *url;
Desc = "MySQL Table";
Hostname = Cat->GetStringCatInfo(g, Name, "Host", "localhost");
Database = Cat->GetStringCatInfo(g, Name, "Database", "*");
Tabname = Cat->GetStringCatInfo(g, Name, "Name", Name); // Deprecated
Tabname = Cat->GetStringCatInfo(g, Name, "Tabname", Tabname);
Username = Cat->GetStringCatInfo(g, Name, "User", "root");
Password = Cat->GetStringCatInfo(g, Name, "Password", NULL);
Portnumber = Cat->GetIntCatInfo(Name, "Port", MYSQL_PORT);
if (!(url = Cat->GetStringCatInfo(g, Name, "Connect", NULL))) {
// Not using the connection URL
Hostname = Cat->GetStringCatInfo(g, Name, "Host", "localhost");
Database = Cat->GetStringCatInfo(g, Name, "Database", "*");
Tabname = Cat->GetStringCatInfo(g, Name, "Name", Name); // Deprecated
Tabname = Cat->GetStringCatInfo(g, Name, "Tabname", Tabname);
Username = Cat->GetStringCatInfo(g, Name, "User", "root");
Password = Cat->GetStringCatInfo(g, Name, "Password", NULL);
Portnumber = Cat->GetIntCatInfo(Name, "Port", MYSQL_PORT);
} else if (ParseURL(g, url))
return TRUE;
Bind = !!Cat->GetIntCatInfo(Name, "Bind", 0);
Delayed = !!Cat->GetIntCatInfo(Name, "Delayed", 0);
return FALSE;
......
......@@ -19,6 +19,7 @@ typedef class MYSQLCOL *PMYCOL;
class MYSQLDEF : public TABDEF {/* Logical table description */
friend class TDBMYSQL;
friend class TDBMCL;
friend class ha_connect;
public:
// Constructor
MYSQLDEF(void);
......@@ -36,6 +37,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
// Methods
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m);
bool ParseURL(PGLOBAL g, char *url);
protected:
// Members
......@@ -44,9 +46,9 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
PSZ Tabname; /* External table name */
PSZ Username; /* User logon name */
PSZ Password; /* Password logon info */
int Portnumber; /* MySQL port number (0 = default) */
bool Bind; /* Use prepared statement on insert */
bool Delayed; /* Delayed insert */
int Portnumber; /* MySQL port number (0 = default) */
bool Bind; /* Use prepared statement on insert */
bool Delayed; /* Delayed insert */
}; // end of MYSQLDEF
/***********************************************************************/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment