summaryrefslogtreecommitdiff
path: root/storage/connect/myconn.cpp
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2013-02-09 01:08:15 +0100
committerOlivier Bertrand <bertrandop@gmail.com>2013-02-09 01:08:15 +0100
commit82e746ea1bd4f0e91e196863c63af75187bd121a (patch)
tree41f06e7f7f3da8aa3671929498273b10b394d949 /storage/connect/myconn.cpp
parentec2112f32d423aea353feef388ed31e36337de2b (diff)
downloadmariadb-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.cpp248
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 --------------------------- */
/***********************************************************************/