summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2013-02-22 17:26:08 +0100
committerOlivier Bertrand <bertrandop@gmail.com>2013-02-22 17:26:08 +0100
commitb535cb987400642e0a6171e54d49fca52efadcf1 (patch)
tree21c1c4e1c2c30fa97ece3da66f6f600c5d7eca50 /storage
parent62fbaf96a00a639a1238fd885f88a0e521191a30 (diff)
downloadmariadb-git-b535cb987400642e0a6171e54d49fca52efadcf1.tar.gz
- 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
Diffstat (limited to 'storage')
-rw-r--r--storage/connect/ha_connect.cc44
-rw-r--r--storage/connect/tabmysql.cpp208
-rw-r--r--storage/connect/tabmysql.h8
3 files changed, 239 insertions, 21 deletions
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index ea51697af7e..e4de80cb94f 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -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;
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index f4fa584c117..35a584938ad 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -1,7 +1,7 @@
/************* TabMySQL C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: TABMYSQL */
/* ------------- */
-/* Version 1.6 */
+/* Version 1.7 */
/* */
/* AUTHOR: */
/* ------- */
@@ -83,18 +83,210 @@ MYSQLDEF::MYSQLDEF(void)
} // 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;
diff --git a/storage/connect/tabmysql.h b/storage/connect/tabmysql.h
index c3f0aaeb12e..367caf010fb 100644
--- a/storage/connect/tabmysql.h
+++ b/storage/connect/tabmysql.h
@@ -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
/***********************************************************************/