📄 catalog.c
字号:
/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
This file is public domain and comes with NO WARRANTY of any kind */
/*
** CATALOG.C - This is the ODBC sample driver code for
** executing Data Dictionary functions.
*/
#include "myodbc.h"
static MYSQL_ROW fix_fields_copy(STMT FAR *hstmt,MYSQL_ROW row);
static int check_parameters(HSTMT hstmt,UCHAR FAR *szTableQualifier,
SWORD cbTableQualifier,UCHAR FAR *szTableOwner,
SWORD cbTableOwner,UCHAR FAR *szTableName,SWORD *cbTableName,
char *table_name,bool no_wildcards);
// Have DBMS set up result set of Tables.
uint SQLTABLES_order[]={2};
char *SQLTABLES_values[]={"","",NULL,"TABLE","MySQL table"};
char *SQLTABLES_qualifier_values[]={"",NULL,NULL,NULL,NULL};
char *SQLTABLES_owner_values[]={NULL,"",NULL,NULL,NULL};
char *SQLTABLES_type_values[]={NULL,NULL,NULL,"TABLE",NULL};
MYSQL_FIELD SQLTABLES_fields[] = {
{"Table_qualifer","Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
{"Table_owner","Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
{"Table_name","Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,NAME_LEN,0},
{"Table_type","Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,5,0},
{"Remarks","Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,11}};
const uint SQLTABLES_FIELDS=array_elements(SQLTABLES_values);
/*
** This may be changed in the future so that TableQualifier or owner points
** at different databases.
*/
RETCODE SQL_API SQLTables(HSTMT hstmt,
UCHAR FAR *szTableQualifier,SWORD cbTableQualifier,
UCHAR FAR *szTableOwner,SWORD cbTableOwner,
UCHAR FAR *szTableName,SWORD cbTableName,
UCHAR FAR *szTableType,SWORD cbTableType)
{
char Qualifier_buff[NAME_LEN+1],Owner_buff[NAME_LEN+1],Name_buff[NAME_LEN+1],
*type_buff,*TableQualifier,*TableOwner,*TableName,*TableType;
STMT FAR *stmt=(STMT FAR*) hstmt;
DBUG_ENTER("SQLTables");
DBUG_PRINT("enter",("Qualifier: '%s' Owner: '%s' Table: '%s' Type: '%s'",
szTableQualifier ? szTableQualifier : "null",
szTableOwner ? szTableOwner : "null",
szTableName ? szTableName : "null",
szTableType ? szTableType : "null"));
SQLFreeStmt(hstmt,MYSQL_RESET);
if (!(type_buff=my_malloc(szTableType && cbTableType != SQL_NTS ? cbTableType+1 : 1,MYF(0))))
{
DBUG_RETURN(set_error(stmt->dbc,"S1001","Not enough memory",4001));
}
TableQualifier=fix_str((char FAR *) Qualifier_buff,szTableQualifier,
cbTableQualifier);
TableOwner= fix_str((char FAR*) Owner_buff,szTableOwner,cbTableOwner);
TableName= fix_str((char FAR*) Name_buff,szTableName,cbTableName);
TableType= fix_str((char FAR*) type_buff,szTableType,cbTableType);
if (!strcmp(TableQualifier,"%") && !TableOwner[0] && !TableName[0])
{
/* Return set of allowed qualifiers */
DBUG_PRINT("info",("Return set of table qualifiers / Catalog names"));
stmt->result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
stmt->result_array=(MYSQL_ROW) my_memdup((gptr) SQLTABLES_qualifier_values,
sizeof(SQLTABLES_qualifier_values),
MYF(0));
stmt->result->row_count=1;
mysql_link_fields(stmt,SQLTABLES_fields, SQLTABLES_FIELDS);
my_free(type_buff,MYF(0));
DBUG_RETURN(SQL_SUCCESS);
}
if (!TableQualifier[0] && !strcmp(TableOwner,"%") && !TableName[0])
{
/* Return set of allowed Table owners */
DBUG_PRINT("info",("Return set of table owners / Schema names"));
stmt->result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
stmt->result_array=(MYSQL_ROW) my_memdup((gptr) SQLTABLES_owner_values,
sizeof(SQLTABLES_owner_values),
MYF(0));
stmt->result->row_count=1;
mysql_link_fields(stmt,SQLTABLES_fields, SQLTABLES_FIELDS);
my_free(type_buff,MYF(0));
DBUG_RETURN(SQL_SUCCESS);
}
if (!TableQualifier[0] && !TableOwner[0] && !TableName[0] &&
!strcmp(TableType,"%"))
{
/* Return set of TableType qualifiers */
DBUG_PRINT("info",("Return set of table types"));
stmt->result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
stmt->result_array=(MYSQL_ROW) my_memdup((gptr) SQLTABLES_type_values,
sizeof(SQLTABLES_type_values),
MYF(0));
stmt->result->row_count=1;
mysql_link_fields(stmt,SQLTABLES_fields, SQLTABLES_FIELDS);
my_free(type_buff,MYF(0));
DBUG_RETURN(SQL_SUCCESS);
}
/* Return empty set if unknown TableType or if Qualifier or Owner is used */
if ((TableType[0] && !strinstr(TableType,"TABLE")) ||
TableQualifier[0] && strcmp(TableQualifier,"%") &&
strcmp(TableQualifier,stmt->dbc->database) ||
TableOwner[0] && strcmp(TableOwner,"%") &&
strcmp(TableOwner,stmt->dbc->database))
{
DBUG_PRINT("info",("Can't match anything; Returning empty set"));
stmt->result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
stmt->result->row_count=0;
stmt->result_array=(MYSQL_ROW) my_memdup((gptr) SQLTABLES_values,
sizeof(SQLTABLES_values), MYF(0));
mysql_link_fields(stmt,SQLTABLES_fields, SQLTABLES_FIELDS);
my_free(type_buff,MYF(0));
DBUG_RETURN(SQL_SUCCESS);
}
/* This was a normal request for tables. Return matching tables */
if (!(stmt->result=mysql_list_tables(&stmt->dbc->mysql,TableName)))
{
my_free(type_buff,MYF(0));
DBUG_RETURN(set_error(stmt->dbc,"S1000","Could not read table names",0));
DBUG_RETURN(SQL_ERROR);
}
stmt->order= SQLTABLES_order;
stmt->order_count= array_elements(SQLTABLES_order);
stmt->fix_fields= fix_fields_copy;
stmt->array=(MYSQL_ROW) my_memdup((gptr) SQLTABLES_values,
sizeof(SQLTABLES_values),MYF(0));
mysql_link_fields(stmt,SQLTABLES_fields,5);
my_free(type_buff,MYF(0));
DBUG_RETURN(SQL_SUCCESS);
}
static MYSQL_ROW fix_fields_copy(STMT FAR *stmt,MYSQL_ROW row)
{
uint i;
for (i=0 ; i < stmt->order_count; i++)
stmt->array[stmt->order[i]]=row[i];
return stmt->array;
}
// Have DBMS set up result set of Columns.
char SC_type[10],SC_typename[20],SC_precision[10],SC_length[10],SC_scale[10],
SC_nullable[10];
char *SQLCOLUMNS_values[]={"","",NULL,NULL,SC_type,SC_typename,
SC_precision,
SC_length,SC_scale,"10",SC_nullable,"MySQL column"};
MYSQL_FIELD SQLCOLUMNS_fields[] = {
{"Table_cat","MySQL Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
{"Table_schema","MySQL Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
{"Table_name","MySQL Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,NAME_LEN,NOT_NULL_FLAG},
{"Column_name","MySQL Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,NAME_LEN,NOT_NULL_FLAG},
{"Data_type","MySQL Catalog",NULL,FIELD_TYPE_SHORT,5,5,NOT_NULL_FLAG},
{"Type_name","MySQL Catalog",NULL,FIELD_TYPE_VAR_STRING,20,20,NOT_NULL_FLAG},
{"Column_size","MySQL Catalog",NULL,FIELD_TYPE_LONG,11,11},
{"Buffer_length","MySQL Catalog",NULL,FIELD_TYPE_LONG,11,11},
{"Decimal_digits","MySQL Catalog",NULL,FIELD_TYPE_SHORT,2,2},
{"Num_prec_radix","MySQL Catalog",NULL,FIELD_TYPE_SHORT,2,2},
{"Nullable","MySQL Catalog",NULL,FIELD_TYPE_SHORT,5,5,NOT_NULL_FLAG},
{"Remarks","MySQL Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,NAME_LEN}};
const uint SQLCOLUMNS_FIELDS=array_elements(SQLCOLUMNS_values);
RETCODE SQL_API SQLColumns(HSTMT hstmt,
UCHAR FAR *szTableQualifier, SWORD cbTableQualifier,
UCHAR FAR *szTableOwner, SWORD cbTableOwner,
UCHAR FAR *szTableName, SWORD cbTableName,
UCHAR FAR *szColumnName, SWORD cbColumnName)
{
char buff[80],table_name[NAME_LEN+1],column_name[NAME_LEN+1];
ulong transfer_length,precision,display_size;
MYSQL_FIELD *curField;
char **row;
MEM_ROOT *alloc;
STMT FAR *stmt=(STMT FAR*) hstmt;
DBUG_ENTER("SQLColumns");
if (check_parameters(hstmt,szTableQualifier,cbTableQualifier,szTableOwner,
cbTableOwner,szTableName,&cbTableName,table_name,1))
return SQL_ERROR;
if (!(stmt->result=mysql_list_fields(&stmt->dbc->mysql,table_name,
fix_str(column_name,szColumnName,
cbColumnName))))
{
strmov(stmt->dbc->sqlstate,"S1000");
DBUG_RETURN(SQL_ERROR);
}
stmt->result_array= (char**) my_malloc(sizeof(char*)*SQLCOLUMNS_FIELDS*
stmt->result->field_count,
MYF(MY_FAE | MY_ZEROFILL));
/* convert mysql fields to data that odbc wants */
alloc=&stmt->result->field_alloc;
for (row= stmt->result_array ;
(curField = mysql_fetch_field(stmt->result)) ; )
{
int type;
row[0]=""; /* No qualifers */
row[1]=""; /* No owner */
row[2]= curField->table;
row[3]= curField->name;
curField->max_length=curField->length;
type=unireg_to_sql_datatype(stmt,curField,buff,&transfer_length,&precision,&display_size);
row[5]=strdup_root(alloc,buff);
sprintf(buff,"%d",type);
row[4]=strdup_root(alloc,buff);
sprintf(buff,"%ld",precision);
row[6]=strdup_root(alloc,buff);
sprintf(buff,"%ld",transfer_length);
row[7]=strdup_root(alloc,buff);
if (IS_NUM(curField->type))
{
sprintf(buff,"%d",curField->decimals);
row[8]=strdup_root(alloc,buff); /* scale */
row[9]="10";
}
else
{
row[8]=row[9]=NullS;
}
sprintf(buff,"%d",(curField->flags & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == NOT_NULL_FLAG ?
SQL_NO_NULLS : SQL_NULLABLE);
row[10]=strdup_root(alloc,buff);
row[11]="";
row+=SQLCOLUMNS_FIELDS;
}
stmt->result->row_count=stmt->result->field_count;
mysql_link_fields(stmt,SQLCOLUMNS_fields,SQLCOLUMNS_FIELDS);
DBUG_RETURN(SQL_SUCCESS);
}
/* Have DBMS set up result set of Statistics. */
char SS_type[10];
uint SQLSTAT_order[]={2,3,5,7,8,9,10};
char *SQLSTAT_values[]={NULL,NULL,"","",NULL,"",SS_type,"","","","",NULL,NULL};
MYSQL_FIELD SQLSTAT_fields[] = {
{"Table_qualifer","MySQL Stat",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
{"Table_owner","MySQL Stat",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
{"Table_name","MySQL Stat",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,NAME_LEN,NOT_NULL_FLAG},
{"Non_unique","MySQL Stat",NULL,FIELD_TYPE_SHORT,1,1,NOT_NULL_FLAG},
{"Index_qualifer","MySQL Stat",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
{"Index_name","MySQL Stat",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,NAME_LEN},
{"Type","MySQL Stat",NULL,FIELD_TYPE_SHORT,1,1,NOT_NULL_FLAG},
{"Seq_in_index","MySQL Stat",NULL,FIELD_TYPE_SHORT,1,2,NOT_NULL_FLAG},
{"Column_name","MySQL Stat",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,NAME_LEN,NOT_NULL_FLAG},
{"Coallation","MySQL Stat",NULL,FIELD_TYPE_VAR_STRING,1,1},
{"Cardinality","MySQL Stat",NULL,FIELD_TYPE_LONG,11,11},
{"Pages","MySQL Stat",NULL,FIELD_TYPE_LONG,9,9},
{"Filter","MySQL Stat",NULL,FIELD_TYPE_VAR_STRING,10,10},
};
const uint SQLSTAT_FIELDS=array_elements(SQLSTAT_fields);
RETCODE SQL_API SQLStatistics(HSTMT hstmt,
UCHAR FAR *szTableQualifier,
SWORD cbTableQualifier,
UCHAR FAR *szTableOwner,SWORD cbTableOwner,
UCHAR FAR *szTableName,SWORD cbTableName,
UWORD fUnique,UWORD fAccuracy)
{
char buff[100],table_name[NAME_LEN+1];
STMT FAR *stmt=(STMT FAR*) hstmt;
DBUG_ENTER("SQLStatistics");
if (check_parameters(hstmt,szTableQualifier,cbTableQualifier,szTableOwner,
cbTableOwner,szTableName,&cbTableName,table_name,1))
DBUG_RETURN(SQL_ERROR);
remove_escape(table_name);
strxmov(buff,"show keys from ",table_name,NullS);
if (mysql_query(&stmt->dbc->mysql,buff) ||
!(stmt->result=mysql_store_result(&stmt->dbc->mysql)))
{
strmov(stmt->dbc->sqlstate,"S1000");
DBUG_RETURN(SQL_ERROR);
}
int2str(SQL_INDEX_OTHER,SS_type,10);
stmt->order= SQLSTAT_order;
stmt->order_count= array_elements(SQLSTAT_order);
stmt->fix_fields= fix_fields_copy;
stmt->array=(MYSQL_ROW) my_memdup((gptr) SQLSTAT_values,
sizeof(SQLSTAT_values),MYF(0));
if (fUnique == SQL_INDEX_UNIQUE)
{ /* This is too low level... */
MYSQL_ROWS **prev,*pos;
prev= &stmt->result->data->data;
for (pos= *prev ; pos ; pos=pos->next)
{
if (pos->data[1][0] == '0') /* Unlink nonunique index */
{
(*prev)=pos;
prev= &pos->next;
}
else
stmt->result->row_count--;
}
(*prev)=0;
mysql_data_seek(stmt->result,0); /* Restore pointer */
}
mysql_link_fields(stmt,SQLSTAT_fields,SQLSTAT_FIELDS);
DBUG_RETURN(SQL_SUCCESS);
}
// Have DBMS set up result set of TablePrivileges.
RETCODE SQL_API SQLTablePrivileges(HSTMT hstmt,
UCHAR FAR *szTableQualifier,
SWORD cbTableQualifier,
UCHAR FAR *szTableOwner,SWORD cbTableOwner,
UCHAR FAR *szTableName,SWORD cbTableName)
{
DBUG_ENTER("SQLTablePrivileges");
DBUG_RETURN(set_error(((STMT FAR*) hstmt)->dbc,"08002",
"MyODBC doesn't support this yet",4000));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -