1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

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
This commit is contained in:
Olivier Bertrand
2013-02-09 01:08:15 +01:00
parent ec2112f32d
commit 82e746ea1b
18 changed files with 617 additions and 389 deletions

View File

@@ -57,8 +57,6 @@
#include "reldef.h"
#include "tabmysql.h"
#include "valblk.h"
#include "plgcnx.h" // For DB types
#include "resource.h"
#if defined(_CONSOLE)
void PrintResult(PGLOBAL, PSEM, PQRYRES);
@@ -66,250 +64,6 @@ void PrintResult(PGLOBAL, PSEM, PQRYRES);
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
/* -------------- Implementation of the MYSQLDEF class --------------- */
/***********************************************************************/
@@ -1038,12 +792,12 @@ void MYSQLCOL::InitBind(PGLOBAL g)
// if (!((DTVAL*)Value)->IsFormatted())
((DTVAL*)Value)->SetFormat(g, "YYYY-MM-DD hh:mm:ss", 19);
Bind->buffer_type = PLGtoMYSQL(TYPE_STRING);
Bind->buffer_type = PLGtoMYSQL(TYPE_STRING, false);
Bind->buffer = (char *)PlugSubAlloc(g,NULL, 20);
Bind->buffer_length = 20;
Bind->length = &Slen;
} else {
Bind->buffer_type = PLGtoMYSQL(Buf_Type);
Bind->buffer_type = PLGtoMYSQL(Buf_Type, false);
Bind->buffer = (char *)Value->GetTo_Val();
Bind->buffer_length = Value->GetClen();
Bind->length = (IsTypeChar(Buf_Type)) ? &Slen : NULL;