diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2013-02-22 17:26:08 +0100 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2013-02-22 17:26:08 +0100 |
commit | b535cb987400642e0a6171e54d49fca52efadcf1 (patch) | |
tree | 21c1c4e1c2c30fa97ece3da66f6f600c5d7eca50 /storage | |
parent | 62fbaf96a00a639a1238fd885f88a0e521191a30 (diff) | |
download | mariadb-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.cc | 44 | ||||
-rw-r--r-- | storage/connect/tabmysql.cpp | 208 | ||||
-rw-r--r-- | storage/connect/tabmysql.h | 8 |
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 /***********************************************************************/ |