diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2013-02-09 01:08:15 +0100 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2013-02-09 01:08:15 +0100 |
commit | 82e746ea1bd4f0e91e196863c63af75187bd121a (patch) | |
tree | 41f06e7f7f3da8aa3671929498273b10b394d949 /storage/connect/myconn.cpp | |
parent | ec2112f32d423aea353feef388ed31e36337de2b (diff) | |
download | mariadb-git-82e746ea1bd4f0e91e196863c63af75187bd121a.tar.gz |
Put almost all function prototypes in header files that are
included by the program using them.
Continuing implementing the "catalog" tables (ex "info").
Already existing were the ODBC data source table and the
WMI column info table.
A common way to handle them will permit to develop many
other such tables. Implemented:
The ODBC column catalog table.
The ODBC tables catalog table.
The ODBC drivers catalog table.
The INFO table option is replaced by the CATFUNC string option
whode first letter specifies the information to retrieve:
C: Columns (of a table)
T: Tables (of a database)
S: Data sources
D: Drivers
Modified:
ha_connect.cc
odbconn.cpp
odbconn.h
tabodbc.h
tabodbc.cpp
rcmsg.c
tabfmt.h
tabmysql.cpp
tabwmi.cpp
tabwmi.h
resource.h
myconn.h
filamdbf.h
connect.cc
connect.h
Added:
myutil.h
Diffstat (limited to 'storage/connect/myconn.cpp')
-rw-r--r-- | storage/connect/myconn.cpp | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp index 1d0071b1851..d8e7a4425de 100644 --- a/storage/connect/myconn.cpp +++ b/storage/connect/myconn.cpp @@ -39,6 +39,8 @@ #include "global.h" #include "plgdbsem.h" +#include "plgcnx.h" // For DB types +#include "resource.h" #include "value.h" #include "valblk.h" #define DLL_EXPORT // Items are exported from this DLL @@ -59,6 +61,252 @@ static char *server_groups[] = { }; #endif // EMBEDDED +extern "C" int trace; + +/**************************************************************************/ +/* Allocate the result structure that will contain result data. */ +/**************************************************************************/ +PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids, + int *dbtype, int *buftyp, unsigned int *length, + bool blank = true, bool nonull = true); + +/************************************************************************/ +/* MyColumns: constructs the result blocks containing all columns */ +/* of a MySQL table that will be retrieved by GetData commands. */ +/* key = TRUE when called from Create Table to get key informations. */ +/************************************************************************/ +PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, + const char *user, const char *pwd, + const char *table, const char *colpat, + int port, bool key) + { + static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, DB_INT, + DB_INT, DB_SHORT, DB_CHAR, DB_CHAR}; + static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, + TYPE_INT, TYPE_SHORT, TYPE_STRING, TYPE_STRING}; + static unsigned int length[] = {0, 4, 16, 4, 4, 4, 0, 0}; + char *fld, *fmt, cmd[128]; + int i, n, nf, ncol = sizeof(dbtype) / sizeof(int); + int len, type, prec, rc, k = 0; + PQRYRES qrp; + PCOLRES crp; + MYSQLC myc; + + /**********************************************************************/ + /* Open the connection with the MySQL server. */ + /**********************************************************************/ + if (myc.Open(g, host, db, user, pwd, port)) + return NULL; + + /**********************************************************************/ + /* Do an evaluation of the result size. */ + /**********************************************************************/ + sprintf(cmd, "SHOW FULL COLUMNS FROM %s", table); + strcat(strcat(cmd, " FROM "), (db) ? db : PlgGetUser(g)->DBName); + + if (colpat) + strcat(strcat(cmd, " LIKE "), colpat); + + if (trace) + htrc("MyColumns: cmd='%s'\n", cmd); + + if ((n = myc.GetResultSize(g, cmd)) < 0) { + myc.Close(); + return NULL; + } // endif n + + /**********************************************************************/ + /* Get the size of the name columns. */ + /* Note that because the length is 0 for the last 2 columns (comment */ + /* and date format) they will be STRBLK instead of CHRBLK. */ + /**********************************************************************/ + length[0] = myc.GetFieldLength(0); + + if (!key) // We are not called from Create table + ncol--; // No date format column + + /**********************************************************************/ + /* Allocate the structures used to refer to the result set. */ + /**********************************************************************/ + qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3, + dbtype, buftyp, length); + + /**********************************************************************/ + /* Now get the results into blocks. */ + /**********************************************************************/ + for (i = 0; i < n; i++) { + if ((rc = myc.Fetch(g, -1) == RC_FX)) + return NULL; + else if (rc == RC_NF) + break; + + // Get column name + fld = myc.GetCharField(0); + crp = qrp->Colresp; + crp->Kdata->SetValue(fld, i); + + // Get type, type name, and precision + fld = myc.GetCharField(1); + prec = 0; + len = 256; // Default for text or blob + + if ((nf = sscanf(fld, "%[^(](%d,%d", cmd, &len, &prec)) < 1) { + sprintf(g->Message, MSG(BAD_FIELD_TYPE), fld); + return NULL; + } else + qrp->Nblin++; + + if ((type = MYSQLtoPLG(cmd)) == TYPE_ERROR) { + sprintf(g->Message, "Unsupported column type %s", cmd); + return NULL; + } // endif type + + crp = crp->Next; + crp->Kdata->SetValue(type, i); + crp = crp->Next; + crp->Kdata->SetValue(cmd, i); + + if (key && type == TYPE_DATE) { + // When creating tables we do need info about date columns + fmt = MyDateFmt(cmd); + len = strlen(fmt); + } else + fmt = NULL; + + crp = crp->Next; + crp->Name = "Length"; + crp->Kdata->SetValue(len, i); + crp = crp->Next; + crp->Name = "Key"; + + if (key) { + // Creating a table, we need key info + fld = myc.GetCharField(4); + crp->Kdata->SetValue((stricmp(fld, "PRI")) ? 0 : ++k, i); + } else + crp->Kdata->SetValue(len, i); + + crp = crp->Next; + crp->Name = "Prec"; + crp->Kdata->SetValue(prec, i); + + // Get comment field + crp = crp->Next; + crp->Name = "Comment"; + fld = myc.GetCharField(8); + + if (fld && strlen(fld)) + crp->Kdata->SetValue(fld, i); + else + crp->Kdata->Reset(i); + + if (key) { + crp = crp->Next; + crp->Name = "Date_Fmt"; + + if (fmt) + crp->Kdata->SetValue(fmt, i); + else + crp->Kdata->Reset(i); + + } // endif key + + } // endfor i + + if (k > 1) { + // Multicolumn primary key + PVBLK vbp = qrp->Colresp->Next->Next->Next->Next->Kdata; + + for (i = 0; i < n; i++) + if (vbp->GetIntValue(i)) + vbp->SetValue(k, i); + + } // endif k + + /**********************************************************************/ + /* Close MySQL connection. */ + /**********************************************************************/ + myc.Close(); + + /**********************************************************************/ + /* Return the result pointer for use by GetData routines. */ + /**********************************************************************/ + return qrp; + } // end of MyColumns + +#if 0 +/**************************************************************************/ +/* SemMySQLColumns: analyze a MySQL table for column format. */ +/**************************************************************************/ +void SemMySQLColumns(PGLOBAL g, PSEM semp) + { + PQRYRES qrp; + PPARM pp, parmp = semp->Parmp; + + /*********************************************************************/ + /* Test passed parameters. */ + /*********************************************************************/ + sprintf(g->Message, MSG(BAD_PARAMETERS), semp->Name); + semp->Value = g->Message; + semp->Type = TYPE_ERROR; + + if (!parmp || parmp->Type != TYPE_LIST) + return; + + /*********************************************************************/ + /* Analyze the table specifications. */ + /*********************************************************************/ + PSZ host, db, user, pwd, table; + int port = 0; + + host = db = user = pwd = table = NULL; + + for (pp = (PPARM)parmp->Value; pp; pp = pp->Next) + switch (pp->Type) { + case TYPE_STRING: + switch (pp->Domain) { + case 5: table = (PSZ)pp->Value; break; + case 7: db = (PSZ)pp->Value; break; + case 30: host = (PSZ)pp->Value; break; + case 31: user = (PSZ)pp->Value; break; + case 32: pwd = (PSZ)pp->Value; break; + default: + return; + } // endswitch Domain + + break; + case TYPE_INT: + if (pp->Domain == 33) + port = (int)*(int*)pp->Value; + else + return; + + break; + default: + return; + } // endswitch Type + + /************************************************************************/ + /* Get and store the result pointer for use by GetData routines. */ + /************************************************************************/ + if (!(qrp = MyColumns(g, host, db, user, pwd, table, NULL, port, TRUE))) + return; // Error in MyColumns + + PlgGetUser(g)->Result = qrp; + +#if defined(_CONSOLE) + PrintResult(g, semp, qrp); +#else + /************************************************************************/ + /* Make as result the qryresult description block. */ + /************************************************************************/ + semp->Type = TYPE_QRYRES; + semp->Domain = 0; + semp->Value = qrp; +#endif // _CONSOLE + } // end of SemMySQLColumns +#endif // 0 + /* -------------------------- Class MYSQLC --------------------------- */ /***********************************************************************/ |