diff options
-rw-r--r-- | storage/connect/filamdbf.cpp | 74 | ||||
-rw-r--r-- | storage/connect/ha_connect.cc | 165 | ||||
-rw-r--r-- | storage/connect/mycat.cc | 79 | ||||
-rw-r--r-- | storage/connect/myconn.cpp | 225 | ||||
-rw-r--r-- | storage/connect/myconn.h | 2 | ||||
-rw-r--r-- | storage/connect/odbconn.cpp | 54 | ||||
-rw-r--r-- | storage/connect/plgdbsem.h | 28 | ||||
-rw-r--r-- | storage/connect/plgdbutl.cpp | 85 | ||||
-rw-r--r-- | storage/connect/reldef.cpp | 2 | ||||
-rw-r--r-- | storage/connect/reldef.h | 1 | ||||
-rw-r--r-- | storage/connect/tabdos.cpp | 14 | ||||
-rw-r--r-- | storage/connect/tabdos.h | 1 | ||||
-rw-r--r-- | storage/connect/tabfix.h | 19 | ||||
-rw-r--r-- | storage/connect/tabfmt.cpp | 141 | ||||
-rw-r--r-- | storage/connect/tabfmt.h | 37 | ||||
-rw-r--r-- | storage/connect/table.cpp | 181 | ||||
-rw-r--r-- | storage/connect/tabmysql.cpp | 31 | ||||
-rw-r--r-- | storage/connect/tabmysql.h | 29 | ||||
-rw-r--r-- | storage/connect/tabodbc.cpp | 252 | ||||
-rw-r--r-- | storage/connect/tabodbc.h | 101 | ||||
-rw-r--r-- | storage/connect/tabwmi.cpp | 452 | ||||
-rw-r--r-- | storage/connect/tabwmi.h | 79 | ||||
-rw-r--r-- | storage/connect/xtable.h | 71 |
23 files changed, 937 insertions, 1186 deletions
diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp index e8aace3fc06..29cfb70c116 100644 --- a/storage/connect/filamdbf.cpp +++ b/storage/connect/filamdbf.cpp @@ -48,8 +48,6 @@ /***********************************************************************/ #include "global.h" #include "plgdbsem.h" -//#include "catalog.h" -//#include "kindex.h" #include "filamdbf.h" #include "tabdos.h" #include "valblk.h" @@ -65,12 +63,6 @@ #define DBFTYPE 3 /* value of bits 0 and 1 if .dbf */ #define EOH 0x0D /* end-of-header marker in .dbf file */ -/****************************************************************************/ -/* Catalog utility function. */ -/****************************************************************************/ -PQRYRES PlgAllocResult(PGLOBAL, int, int, int, int *, int *, - unsigned int *, bool blank = true, bool nonull = false); - extern "C" int trace; // The general trace value /****************************************************************************/ @@ -186,10 +178,12 @@ static int dbfhead(PGLOBAL g, FILE *file, PSZ fn, DBFHEADER *buf) /****************************************************************************/ PQRYRES DBFColumns(PGLOBAL g, char *fn, BOOL info) { - static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, - DB_INT, DB_INT, DB_SHORT}; - static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, - TYPE_INT, TYPE_INT, TYPE_SHORT}; + static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, + DB_INT, DB_INT, DB_SHORT}; + static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, + TYPE_INT, TYPE_INT, TYPE_SHORT}; + static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, + FLD_PREC, FLD_LENGTH, FLD_SCALE}; static unsigned int length[] = {11, 6, 8, 10, 10, 6}; char buf[2], filename[_MAX_PATH]; int ncol = sizeof(dbtype) / sizeof(int); @@ -204,35 +198,41 @@ PQRYRES DBFColumns(PGLOBAL g, char *fn, BOOL info) if (trace) htrc("DBFColumns: File %s\n", SVP(fn)); - if (!fn) { - strcpy(g->Message, MSG(MISSING_FNAME)); - return NULL; - } // endif fn + if (!info) { + if (!fn) { + strcpy(g->Message, MSG(MISSING_FNAME)); + return NULL; + } // endif fn - /**************************************************************************/ - /* Open the input file. */ - /**************************************************************************/ - PlugSetPath(filename, fn, PlgGetDataPath(g)); + /************************************************************************/ + /* Open the input file. */ + /************************************************************************/ + PlugSetPath(filename, fn, PlgGetDataPath(g)); - if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "rb"))) - return NULL; + if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "rb"))) + return NULL; - /**************************************************************************/ - /* Get the first 32 bytes of the header. */ - /**************************************************************************/ - if ((rc = dbfhead(g, infile, filename, &mainhead)) == RC_FX) { - fclose(infile); - return NULL; - } // endif dbfhead + /************************************************************************/ + /* Get the first 32 bytes of the header. */ + /************************************************************************/ + if ((rc = dbfhead(g, infile, filename, &mainhead)) == RC_FX) { + fclose(infile); + return NULL; + } // endif dbfhead + + /************************************************************************/ + /* Allocate the structures used to refer to the result set. */ + /************************************************************************/ + fields = mainhead.Fields; + } else + fields = 0; - /**************************************************************************/ - /* Allocate the structures used to refer to the result set. */ - /**************************************************************************/ -//fields = (mainhead.Headlen - 33) / 32; - fields = mainhead.Fields; qrp = PlgAllocResult(g, ncol, fields, IDS_COLUMNS + 3, - dbtype, buftyp, length); - qrp->Info = info || (rc == RC_INFO); + dbtype, buftyp, fldtyp, length, true, false); +//qrp->Info = info || (rc == RC_INFO); + + if (info) + return qrp; if (trace) { htrc("Structure of %s\n", filename); @@ -316,6 +316,7 @@ PQRYRES DBFColumns(PGLOBAL g, char *fn, BOOL info) qrp->Nblin = field; fclose(infile); +#if 0 if (info) { /************************************************************************/ /* Prepare return message for dbfinfo command. */ @@ -330,6 +331,7 @@ PQRYRES DBFColumns(PGLOBAL g, char *fn, BOOL info) strcat(g->Message, buf); } // endif info +#endif // 0 /**************************************************************************/ /* Return the result pointer for use by GetData routines. */ diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index f8dff85dd71..4d1ee88c8a1 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -138,10 +138,6 @@ #define my_strlwr(p) my_casedn_str(default_charset_info, (p)); #define my_stricmp(a,b) my_strcasecmp(default_charset_info, (a), (b)) -#if defined (WIN32) -typedef struct _WMIutil *PWMIUT; /* Used to call WMIColumns */ -#endif - #ifdef LIBXML2_SUPPORT void XmlInitParserLib(void); void XmlCleanupParserLib(void); @@ -1379,9 +1375,6 @@ int ha_connect::MakeRecord(char *buf) // This is for variable_length rows memset(buf, 0, table->s->null_bytes); - // store needs a charset, why not this one? - charset= table->s->table_charset; - // When sorting read_set selects all columns, so we use def_read_set map= (const MY_BITMAP *)&table->def_read_set; @@ -1389,6 +1382,9 @@ int ha_connect::MakeRecord(char *buf) for (field= table->field; *field && !rc; field++) { fp= *field; + // Default charset + charset= table->s->table_charset; + #if defined(MARIADB) if (fp->vcol_info && !fp->stored_in_db) continue; // This is a virtual column @@ -1409,28 +1405,35 @@ int ha_connect::MakeRecord(char *buf) value= colp->GetValue(); // All this could be better optimized - if (value->GetType() == TYPE_DATE) { - if (!sdval) - sdval= AllocateValue(xp->g, TYPE_STRING, 20); - - switch (fp->type()) { - case MYSQL_TYPE_DATE: - fmt= "%Y-%m-%d"; - break; - case MYSQL_TYPE_TIME: - fmt= "%H:%M:%S"; - break; - default: - fmt= "%Y-%m-%d %H:%M:%S"; - } // endswitch type - - // Get date in the format required by MySQL fields - value->FormatValue(sdval, fmt); - p= sdval->GetCharValue(); - } else if (value->GetType() == TYPE_FLOAT) - p= NULL; - else - p= value->GetCharString(val); + switch (value->GetType()) { + case TYPE_DATE: + if (!sdval) + sdval= AllocateValue(xp->g, TYPE_STRING, 20); + + switch (fp->type()) { + case MYSQL_TYPE_DATE: + fmt= "%Y-%m-%d"; + break; + case MYSQL_TYPE_TIME: + fmt= "%H:%M:%S"; + break; + default: + fmt= "%Y-%m-%d %H:%M:%S"; + } // endswitch type + + // Get date in the format required by MySQL fields + value->FormatValue(sdval, fmt); + p= sdval->GetCharValue(); + break; + case TYPE_FLOAT: + p= NULL; + break; + case TYPE_STRING: + charset= fp->charset(); + // Passthru + default: + p= value->GetCharString(val); + } // endswitch Type if (p) { if (fp->store(p, strlen(p), charset, CHECK_FIELD_WARN)) { @@ -3253,17 +3256,20 @@ bool ha_connect::add_fields(THD *thd, void *alt_info, */ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info) { - char ttp= '?', spc= ',', qch= 0, fnc= 0; - const char *typn= "DOS"; + char ttp= '?', spc= ',', qch= 0, fnc= '*'; + const char *typn= "?"; const char *user; - char *fn, *dsn, *tab, *db, *host, *pwd, *prt, *sep; + char *fn, *dsn, *tab, *db, *host, *pwd, *prt, *sep, *csn; #if defined(WIN32) char *nsp= NULL, *cls= NULL; #endif // WIN32 + char *supfnc = "*C"; int port= MYSQL_PORT, hdr= 0, mxr= 0; + uint tm; bool b= false, ok= false, dbf= false; LEX_STRING *comment, *name; HA_CREATE_INFO *create_info= (HA_CREATE_INFO *)crt_info; + CHARSET_INFO *cs; engine_option_value *pov; PQRYRES qrp; PCOLRES crp; @@ -3325,6 +3331,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info) else ok= true; + supfnc = "*CTSD"; break; #endif // ODBC_SUPPORT case 'A': // DBF @@ -3354,6 +3361,13 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info) sprintf(g->Message, "Cannot get column info for table type %s", typn); } // endif ttp + // Check for supported catalog function + if (ok && !strchr(supfnc, fnc)) { + sprintf(g->Message, "Unsupported catalog function %c for table type %s", + fnc, typn); + ok= false; + } // endif supfnc + if (ok) { char *length, *decimals, *cnm, *rem; int i, len, dec; @@ -3368,7 +3382,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info) switch (ttp) { case 'A': - qrp= DBFColumns(g, fn, false); + qrp= DBFColumns(g, fn, fnc == 'C'); break; #if defined(ODBC_SUPPORT) case 'O': @@ -3394,15 +3408,16 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info) #endif // ODBC_SUPPORT #if defined(MYSQL_SUPPORT) case 'Y': - qrp= MyColumns(g, host, db, user, pwd, tab, NULL, port, false); + qrp= MyColumns(g, host, db, user, pwd, tab, + NULL, port, false, fnc == 'C'); break; #endif // MYSQL_SUPPORT case 'C': - qrp= CSVColumns(g, fn, spc, qch, hdr, mxr); + qrp= CSVColumns(g, fn, spc, qch, hdr, mxr, fnc == 'C'); break; #if defined(WIN32) case 'W': - qrp= WMIColumns(g, nsp, cls, NULL); + qrp= WMIColumns(g, nsp, cls, fnc == 'C'); break; #endif // WIN32 } // endswitch ttp @@ -3412,7 +3427,8 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info) return true; } // endif qrp - if (fnc) { + if (fnc && fnc != '*') { + // Catalog table for (crp=qrp->Colresp; !b && crp; crp= crp->Next) { cnm= encode(g, crp->Name); name= thd->make_lex_string(NULL, cnm, strlen(cnm), true); @@ -3425,39 +3441,60 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info) // Now add the field b= add_fields(thd, alt_info, name, type, length, decimals, - 0, comment, NULL, NULL, NULL); + NOT_NULL_FLAG, comment, NULL, NULL, NULL); } // endfor crp - } else + } else // Not a catalog table for (i= 0; !b && i < qrp->Nblin; i++) { - crp= qrp->Colresp; // Column Name - cnm= encode(g, crp->Kdata->GetCharValue(i)); - name= thd->make_lex_string(NULL, cnm, strlen(cnm), true); - crp= crp->Next; // Data Type - type= PLGtoMYSQL(crp->Kdata->GetIntValue(i), true); - crp= crp->Next; // Type Name - crp= crp->Next; // Precision (length) - len= crp->Kdata->GetIntValue(i); - length= (char*)PlugSubAlloc(g, NULL, 8); - sprintf(length, "%d", len); - crp= crp->Next; // Length - crp= crp->Next; // Scale (precision) - - if ((dec= crp->Kdata->GetIntValue(i))) { - decimals= (char*)PlugSubAlloc(g, NULL, 8); - sprintf(decimals, "%d", dec); - } else - decimals= NULL; - - if ((crp= crp->Next) && // Remark (comment) - (rem= crp->Kdata->GetCharValue(i))) - comment= thd->make_lex_string(NULL, rem, strlen(rem), true); - else - comment= thd->make_lex_string(NULL, "", 0, true); + rem= ""; + length= ""; + decimals= NULL; + tm= NOT_NULL_FLAG; + cs= NULL; + + for (crp= qrp->Colresp; crp; crp= crp->Next) + switch (crp->Fld) { + case FLD_NAME: + cnm= encode(g, crp->Kdata->GetCharValue(i)); + name= thd->make_lex_string(NULL, cnm, strlen(cnm), true); + break; + case FLD_TYPE: + type= PLGtoMYSQL(crp->Kdata->GetIntValue(i), true); + break; + case FLD_PREC: + len= crp->Kdata->GetIntValue(i); + length= (char*)PlugSubAlloc(g, NULL, 8); + sprintf(length, "%d", len); + break; + case FLD_SCALE: + if ((dec= crp->Kdata->GetIntValue(i))) { + decimals= (char*)PlugSubAlloc(g, NULL, 8); + sprintf(decimals, "%d", dec); + } else + decimals= NULL; + + break; + case FLD_NULL: + if (crp->Kdata->GetIntValue(i)) + tm= 0; // Nullable + + break; + case FLD_REM: + rem= crp->Kdata->GetCharValue(i); + break; +// case FLD_CHARSET: + // No good because remote table is already translated +// if (*(csn= crp->Kdata->GetCharValue(i))) +// cs= get_charset_by_name(csn, 0); + +// break; + } // endswitch Fld + + comment= thd->make_lex_string(NULL, rem, strlen(rem), true); // Now add the field b= add_fields(thd, alt_info, name, type, length, decimals, - 0, comment, NULL, NULL, NULL); + tm, comment, cs, NULL, NULL); } // endfor i return b; diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc index 4865711e3a4..bbf38fa0374 100644 --- a/storage/connect/mycat.cc +++ b/storage/connect/mycat.cc @@ -100,84 +100,9 @@ extern int xtrace; /**************************************************************************/ //bool PlugCheckPattern(PGLOBAL, LPCSTR, LPCSTR); //#if !defined(WIN32) -extern "C" int GetRcString(int id, char *buf, int bufsize); //#endif // !WIN32 //void ptrc(char const *fmt, ...); -/**************************************************************************/ -/* 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 = false, bool nonull = false) - { - char cname[NAM_LEN+1]; - int i; - PCOLRES *pcrp, crp; - PQRYRES qrp; - - /************************************************************************/ - /* Allocate the structure used to contain the result set. */ - /************************************************************************/ - qrp = (PQRYRES)PlugSubAlloc(g, NULL, sizeof(QRYRES)); - pcrp = &qrp->Colresp; - qrp->Continued = false; - qrp->Truncated = false; - qrp->Info = false; - qrp->Suball = true; - qrp->Maxres = maxres; - qrp->Maxsize = 0; - qrp->Nblin = 0; - qrp->Nbcol = 0; // will be ncol - qrp->Cursor = 0; - qrp->BadLines = 0; - - for (i = 0; i < ncol; i++) { - *pcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES)); - crp = *pcrp; - pcrp = &crp->Next; - crp->Colp = NULL; - crp->Ncol = ++qrp->Nbcol; - crp->Type = buftyp[i]; - crp->Length = length[i]; - crp->Clen = GetTypeSize(crp->Type, length[i]); - crp->Prec = 0; - crp->DBtype = dbtype[i]; - - if (ids > 0) { -#if defined(XMSG) - // Get header from message file - strncpy(cname, PlugReadMessage(g, ids + crp->Ncol, NULL), NAM_LEN); - cname[NAM_LEN] = 0; // for truncated long names -//#elif defined(WIN32) - // Get header from ressource file -// LoadString(s_hModule, ids + crp->Ncol, cname, sizeof(cname)); -#else // !WIN32 - GetRcString(ids + crp->Ncol, cname, sizeof(cname)); -#endif // !WIN32 - crp->Name = (PSZ)PlugSubAlloc(g, NULL, strlen(cname) + 1); - strcpy(crp->Name, cname); - } else - crp->Name = NULL; // Will be set by caller - - // Allocate the Value Block that will contain data - if (crp->Length || nonull) - crp->Kdata = AllocValBlock(g, NULL, crp->Type, maxres, - crp->Length, 0, true, blank); - else - crp->Kdata = NULL; - - if (g->Trace) - htrc("Column(%d) %s type=%d len=%d value=%p\n", - crp->Ncol, crp->Name, crp->Type, crp->Length, crp->Kdata); - - } // endfor i - - *pcrp = NULL; - - return qrp; - } // end of PlgAllocResult - /***********************************************************************/ /* Get a unique char identifier for types. The letter used are: */ /* ABCDEF..I.KLM.O..R.T.VWXY.. */ @@ -345,14 +270,14 @@ char *MYCAT::GetStringCatInfo(PGLOBAL g, PSZ name, PSZ what, PSZ sdef) /***********************************************************************/ int MYCAT::GetColCatInfo(PGLOBAL g, PTABDEF defp) { - char *type= GetStringCatInfo(g, NULL, "Type", "DOS"); + char tc, *type= GetStringCatInfo(g, NULL, "Type", "DOS"); int i, loff, poff, nof, nlg; void *field= NULL; PCOLDEF cdp, lcdp= NULL, tocols= NULL; PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO)); // Get a unique char identifier for type - char tc= GetTypeID(type); + tc= (!defp->Catfunc) ? GetTypeID(type) : 0; // Take care of the column definitions i= poff= nof= nlg= 0; diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp index d8e7a4425de..b4347f11094 100644 --- a/storage/connect/myconn.cpp +++ b/storage/connect/myconn.cpp @@ -1,11 +1,11 @@ /************** MyConn C++ Program Source Code File (.CPP) **************/ /* PROGRAM NAME: MYCONN */ /* ------------- */ -/* Version 1.5 */ +/* Version 1.6 */ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2007-2012 */ +/* (C) Copyright to the author Olivier BERTRAND 2007-2013 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -63,13 +63,6 @@ static char *server_groups[] = { 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. */ @@ -78,13 +71,18 @@ PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids, 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) + int port, bool key, bool info) { - 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}; + static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, DB_INT, + DB_CHAR, DB_SHORT, DB_SHORT, DB_SHORT, + DB_CHAR, DB_CHAR, DB_CHAR}; + static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, + TYPE_STRING, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, + TYPE_STRING, TYPE_STRING, TYPE_STRING}; + static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC, + FLD_KEY, FLD_SCALE, FLD_RADIX, FLD_NULL, + FLD_REM, FLD_NO, FLD_CHARSET}; + static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 256, 32, 32}; char *fld, *fmt, cmd[128]; int i, n, nf, ncol = sizeof(dbtype) / sizeof(int); int len, type, prec, rc, k = 0; @@ -92,44 +90,59 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, PCOLRES crp; MYSQLC myc; - /**********************************************************************/ - /* Open the connection with the MySQL server. */ - /**********************************************************************/ - if (myc.Open(g, host, db, user, pwd, port)) - return NULL; + if (!info) { + /********************************************************************/ + /* 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); + /********************************************************************/ + /* 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 (colpat) + strcat(strcat(cmd, " LIKE "), colpat); - if (trace) - htrc("MyColumns: cmd='%s'\n", cmd); + if (trace) + htrc("MyColumns: cmd='%s'\n", cmd); - if ((n = myc.GetResultSize(g, cmd)) < 0) { - myc.Close(); - return NULL; - } // endif n + 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); + /********************************************************************/ + /* Get the size of the name columns. */ + /********************************************************************/ + length[0] = myc.GetFieldLength(0); + } else { + n = 0; + length[0] = 128; + } // endif info - if (!key) // We are not called from Create table - ncol--; // No date format column +//if (!key) // We are not called from Create table +// ncol--; // No date format column yet /**********************************************************************/ /* Allocate the structures used to refer to the result set. */ /**********************************************************************/ qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3, - dbtype, buftyp, length); + dbtype, buftyp, fldtyp, length, true, true); + + // Some columns must be renamed + for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next) + switch (++i) { + case 4: crp->Name = "Length"; break; + case 5: crp->Name = "Key"; break; + case 10: crp->Name = "Date_fmt"; break; + case 11: crp->Name = "Collation"; break; + } // endswitch i + + if (info) + return qrp; /**********************************************************************/ /* Now get the results into blocks. */ @@ -142,7 +155,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, // Get column name fld = myc.GetCharField(0); - crp = qrp->Colresp; + crp = qrp->Colresp; // Column_Name crp->Kdata->SetValue(fld, i); // Get type, type name, and precision @@ -161,56 +174,45 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, return NULL; } // endif type - crp = crp->Next; + crp = crp->Next; // Data_Type crp->Kdata->SetValue(type, i); - crp = crp->Next; + crp = crp->Next; // Type_Name crp->Kdata->SetValue(cmd, i); - if (key && type == TYPE_DATE) { + if (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 = crp->Next; // Precision 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; // was Length + fld = myc.GetCharField(4); + crp->Kdata->SetValue(fld, i); - crp = crp->Next; - crp->Name = "Prec"; + crp = crp->Next; // Scale crp->Kdata->SetValue(prec, i); - // Get comment field - crp = crp->Next; - crp->Name = "Comment"; - fld = myc.GetCharField(8); + crp = crp->Next; // Radix + crp->Kdata->SetValue(0, i); - if (fld && strlen(fld)) - crp->Kdata->SetValue(fld, i); - else - crp->Kdata->Reset(i); + crp = crp->Next; // Nullable + fld = myc.GetCharField(3); + crp->Kdata->SetValue((toupper(*fld) == 'Y') ? 1 : 0, i); - if (key) { - crp = crp->Next; - crp->Name = "Date_Fmt"; - - if (fmt) - crp->Kdata->SetValue(fmt, i); - else - crp->Kdata->Reset(i); + crp = crp->Next; // Remark + fld = myc.GetCharField(8); + crp->Kdata->SetValue(fld, i); - } // endif key + crp = crp->Next; // New + crp->Kdata->SetValue((fmt) ? fmt : "", i); + crp = crp->Next; // New (charset) + fld = myc.GetCharField(2); + crp->Kdata->SetValue(fld, i); } // endfor i if (k > 1) { @@ -234,79 +236,6 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, 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 --------------------------- */ /***********************************************************************/ diff --git a/storage/connect/myconn.h b/storage/connect/myconn.h index fc462aaa22a..1aab55f1e01 100644 --- a/storage/connect/myconn.h +++ b/storage/connect/myconn.h @@ -38,7 +38,7 @@ typedef class MYSQLC *PMYC; 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); + int port, bool key, bool info); /* -------------------------- MYCONN class --------------------------- */ diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp index d9e3e3f4d58..0519a8141e6 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -171,13 +171,6 @@ int TranslateSQLType(int stp, int prec, int& len) HENV ODBConn::m_henv = SQL_NULL_HENV; int ODBConn::m_nAlloc = 0; // per-Appl reference to HENV above -/**************************************************************************/ -/* 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); - /***********************************************************************/ /* Allocate the structure used to refer to the result set. */ /***********************************************************************/ @@ -235,14 +228,18 @@ void ResetNullValues(CATPARM *cap) PQRYRES ODBCColumns(PGLOBAL g, ODBConn *ocp, char *dsn, char *table, char *colpat) { - static int dbtype[] = {DB_CHAR, DB_CHAR, - DB_CHAR, DB_SHORT, DB_CHAR, - DB_INT, DB_INT, DB_SHORT, - DB_SHORT, DB_SHORT, DB_CHAR}; - static int buftyp[] = {TYPE_STRING, TYPE_STRING, - TYPE_STRING, TYPE_SHORT, TYPE_STRING, - TYPE_INT, TYPE_INT, TYPE_SHORT, - TYPE_SHORT, TYPE_SHORT, TYPE_STRING}; + static int dbtype[] = {DB_CHAR, DB_CHAR, + DB_CHAR, DB_SHORT, DB_CHAR, + DB_INT, DB_INT, DB_SHORT, + DB_SHORT, DB_SHORT, DB_CHAR}; + static int buftyp[] = {TYPE_STRING, TYPE_STRING, + TYPE_STRING, TYPE_SHORT, TYPE_STRING, + TYPE_INT, TYPE_INT, TYPE_SHORT, + TYPE_SHORT, TYPE_SHORT, TYPE_STRING}; + static XFLD fldtyp[] = {FLD_NO, FLD_NO, + FLD_NAME, FLD_TYPE, FLD_TYPENAME, + FLD_PREC, FLD_LENGTH, FLD_SCALE, + FLD_RADIX, FLD_NULL, FLD_REM}; static unsigned int length[] = {0, 0, 0, 6, 20, 10, 10, 6, 6, 6, 128}; int n, ncol = 11; int maxres; @@ -277,7 +274,7 @@ PQRYRES ODBCColumns(PGLOBAL g, ODBConn *ocp, char *dsn, char *table, /* Allocate the structures used to refer to the result set. */ /************************************************************************/ qrp = PlgAllocResult(g, ncol, maxres, IDS_COLUMNS + 1, - dbtype, buftyp, length); + dbtype, buftyp, NULL, length, true, true); if (!ocp) // Info table return qrp; @@ -313,8 +310,8 @@ PQRYRES ODBCColumns(PGLOBAL g, ODBConn *ocp, char *dsn, char *table, /**************************************************************************/ PQRYRES MyODBCCols(PGLOBAL g, char *dsn, char *tab, bool info) { - int type, len, prec; - PCOLRES crpt, crpl, crpp; +// int i, type, len, prec; +// PCOLRES crp, crpt, crpl, crpp; PQRYRES qrp; ODBConn *ocp; @@ -342,6 +339,7 @@ PQRYRES MyODBCCols(PGLOBAL g, char *dsn, char *tab, bool info) if (ocp) ocp->Close(); +#if 0 if (!qrp) return NULL; // Error in ODBCColumns @@ -371,7 +369,13 @@ PQRYRES MyODBCCols(PGLOBAL g, char *dsn, char *tab, bool info) } // endfor i crpp->Next = crpp->Next->Next->Next; // Should be Remark - qrp->Nbcol = 7; // Was 11, skipped 4 + + // Renumber crp's for flag comparison + for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next) + crp->Ncol = ++i; + + qrp->Nbcol = i; // Should be 7; was 11, skipped 4 +#endif // 0 return qrp; } // end of MyODBCCols @@ -410,7 +414,8 @@ PQRYRES ODBCDataSources(PGLOBAL g, bool info) /************************************************************************/ /* Allocate the structures used to refer to the result set. */ /************************************************************************/ - qrp = PlgAllocResult(g, ncol, maxres, IDS_DSRC, dbtype, buftyp, length); + qrp = PlgAllocResult(g, ncol, maxres, IDS_DSRC, + dbtype, buftyp, NULL, length, true, true); /************************************************************************/ /* Now get the results into blocks. */ @@ -455,7 +460,8 @@ PQRYRES ODBCDrivers(PGLOBAL g, bool info) /************************************************************************/ /* Allocate the structures used to refer to the result set. */ /************************************************************************/ - qrp = PlgAllocResult(g, ncol, maxres, IDS_DRIVER, dbtype, buftyp, length); + qrp = PlgAllocResult(g, ncol, maxres, IDS_DRIVER, + dbtype, buftyp, NULL, length, true, true); /************************************************************************/ /* Now get the results into blocks. */ @@ -521,7 +527,7 @@ PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *tabpat, bool info) /* Allocate the structures used to refer to the result set. */ /************************************************************************/ qrp = PlgAllocResult(g, ncol, maxres, IDS_TABLES + 1, - dbtype, buftyp, length); + dbtype, buftyp, NULL, length, true, true); if (info) return qrp; @@ -606,7 +612,7 @@ PQRYRES ODBCPrimaryKeys(PGLOBAL g, ODBConn *op, char *dsn, char *table) /* Allocate the structure used to refer to the result set. */ /************************************************************************/ qrp = PlgAllocResult(g, ncol, maxres, IDS_PKEY + 1, - dbtype, buftyp, length); + dbtype, buftyp, NULL, length, true, true); #ifdef DEBTRACE htrc("Getting pkey results ncol=%d\n", qrp->Nbcol); @@ -693,7 +699,7 @@ PQRYRES ODBCStatistics(PGLOBAL g, ODBConn *op, char *dsn, char *pat, /* Allocate the structure used to refer to the result set. */ /************************************************************************/ qrp = PlgAllocResult(g, ncol, maxres, IDS_STAT + 1, - dbtype, buftyp, length); + dbtype, buftyp, NULL, length, true, true); #ifdef DEBTRACE htrc("Getting stat results ncol=%d\n", qrp->Nbcol); diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h index 0a412972ce1..7a8e13fa4c5 100644 --- a/storage/connect/plgdbsem.h +++ b/storage/connect/plgdbsem.h @@ -96,6 +96,7 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */ TYPE_AM_DMY = 172, /* DMY Dummy tables am type no */ TYPE_AM_SET = 180, /* SET Set tables am type no */ TYPE_AM_MYSQL = 192, /* MYSQL access method type no */ + TYPE_AM_CAT = 193, /* Catalog access method type no */ TYPE_AM_OUT = 200}; /* Output relations (storage) */ enum RECFM {RECFM_NAF = -2, /* Not a file */ @@ -441,6 +442,25 @@ typedef struct _tabs { } TABS; /***********************************************************************/ +/* Following definitions are used to define table fields (columns). */ +/***********************************************************************/ +enum XFLD {FLD_NO = 0, /* Not a field definition item */ + FLD_NAME = 1, /* Field name */ + FLD_TYPE = 2, /* Field type */ + FLD_TYPENAME = 3, /* Field type name */ + FLD_PREC = 4, /* Field precision (length?) */ + FLD_LENGTH = 5, /* Field length (?) */ + FLD_SCALE = 6, /* Field scale (precision) */ + FLD_RADIX = 7, /* Field radix */ + FLD_NULL = 8, /* Field nullable property */ + FLD_REM = 9, /* Field comment (remark) */ + FLD_CHARSET = 10, /* Field collation */ + FLD_KEY = 11, /* Field key property */ + FLD_DEFAULT = 12, /* Field default value */ + FLD_PRIV = 13, /* Field priviledges */ + FLD_DATEFMT = 14}; /* Field date format */ + +/***********************************************************************/ /* Result of last SQL noconv query. */ /***********************************************************************/ typedef struct _qryres { @@ -470,6 +490,7 @@ typedef struct _colres { int Clen; /* Data individual internal size */ int Length; /* Data individual print length */ int Prec; /* Precision */ + XFLD Fld; /* Type of field info */ } COLRES; #if defined(WIN32) && !defined(NOEX) @@ -491,6 +512,13 @@ void AddPointer(PTABS, void *); PDTP MakeDateFormat(PGLOBAL, PSZ, bool, bool, int); int ExtractDate(char *, PDTP, int, int val[6]); +/**************************************************************************/ +/* Allocate the result structure that will contain result data. */ +/**************************************************************************/ +PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids, + int *dbtype, int *buftyp, XFLD *fldtyp, + unsigned int *length, bool blank, bool nonull); + /***********************************************************************/ /* Exported utility routines. */ /***********************************************************************/ diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp index e980926c820..2e0564e8735 100644 --- a/storage/connect/plgdbutl.cpp +++ b/storage/connect/plgdbutl.cpp @@ -1,11 +1,11 @@ /********** PlgDBUtl Fpe C++ Program Source Code File (.CPP) ***********/ /* PROGRAM NAME: PLGDBUTL */ /* ------------- */ -/* Version 3.7 */ +/* Version 3.8 */ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 1998-2012 */ +/* (C) Copyright to the author Olivier BERTRAND 1998-2013 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -66,6 +66,7 @@ #include "colblk.h" #include "xtable.h" // header of TBX, TDB and TDBASE classes #include "tabcol.h" // header of XTAB and COLUMN classes +#include "valblk.h" /***********************************************************************/ /* Macro or external routine definition */ @@ -128,6 +129,7 @@ void CloseXMLFile(PGLOBAL, PFBLOCK, bool); void CloseXML2File(PGLOBAL, PFBLOCK, bool); #endif // LIBXML2_SUPPORT +extern "C" int GetRcString(int id, char *buf, int bufsize); /***********************************************************************/ /* Routines for file IO with error reporting to g->Message */ @@ -262,6 +264,85 @@ void ptrc(char const *fmt, ...) } // end of ptrc #endif // 0 +/**************************************************************************/ +/* Allocate the result structure that will contain result data. */ +/**************************************************************************/ +PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids, + int *dbtype, int *buftyp, XFLD *fldtyp, + unsigned int *length, bool blank, bool nonull) + { + char cname[NAM_LEN+1]; + int i; + PCOLRES *pcrp, crp; + PQRYRES qrp; + + /************************************************************************/ + /* Allocate the structure used to contain the result set. */ + /************************************************************************/ + qrp = (PQRYRES)PlugSubAlloc(g, NULL, sizeof(QRYRES)); + pcrp = &qrp->Colresp; + qrp->Continued = false; + qrp->Truncated = false; + qrp->Info = false; + qrp->Suball = true; + qrp->Maxres = maxres; + qrp->Maxsize = 0; + qrp->Nblin = 0; + qrp->Nbcol = 0; // will be ncol + qrp->Cursor = 0; + qrp->BadLines = 0; + + for (i = 0; i < ncol; i++) { + *pcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES)); + crp = *pcrp; + pcrp = &crp->Next; + crp->Colp = NULL; + crp->Ncol = ++qrp->Nbcol; + crp->Type = buftyp[i]; + crp->Length = length[i]; + crp->Clen = GetTypeSize(crp->Type, length[i]); + crp->Prec = 0; + crp->DBtype = dbtype[i]; + + if (ids > 0) { +#if defined(XMSG) + // Get header from message file + strncpy(cname, PlugReadMessage(g, ids + crp->Ncol, NULL), NAM_LEN); + cname[NAM_LEN] = 0; // for truncated long names +//#elif defined(WIN32) + // Get header from ressource file +// LoadString(s_hModule, ids + crp->Ncol, cname, sizeof(cname)); +#else // !WIN32 + GetRcString(ids + crp->Ncol, cname, sizeof(cname)); +#endif // !WIN32 + crp->Name = (PSZ)PlugSubAlloc(g, NULL, strlen(cname) + 1); + strcpy(crp->Name, cname); + } else + crp->Name = NULL; // Will be set by caller + + if (fldtyp) + crp->Fld = fldtyp[i]; + else + crp->Fld = FLD_NO; + + // Allocate the Value Block that will contain data + if (crp->Length || nonull) + crp->Kdata = AllocValBlock(g, NULL, crp->Type, maxres, + crp->Length, 0, true, blank); + else + crp->Kdata = NULL; + + if (g->Trace) + htrc("Column(%d) %s type=%d len=%d value=%p\n", + crp->Ncol, crp->Name, crp->Type, crp->Length, crp->Kdata); + + } // endfor i + + *pcrp = NULL; + + return qrp; + } // end of PlgAllocResult + /***********************************************************************/ /* Allocate and initialize the new DB User Block. */ /***********************************************************************/ diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp index bf129a2f54a..4f99b2da6d6 100644 --- a/storage/connect/reldef.cpp +++ b/storage/connect/reldef.cpp @@ -74,6 +74,7 @@ TABDEF::TABDEF(void) { Owner = NULL; Desc = NULL; + Catfunc = 0; Card = 0; Elemt = 0; Sort = 0; @@ -95,6 +96,7 @@ bool TABDEF::Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am) Name = (PSZ)PlugSubAlloc(g, memp, strlen(name) + 1); strcpy(Name, name); Cat = cat; + Catfunc = toupper(*Cat->GetStringCatInfo(g, Name, "Catfunc", "")); Elemt = cat->GetIntCatInfo(name, "Elements", 0); Multiple = cat->GetIntCatInfo(name, "Multiple", 0); Degree = cat->GetIntCatInfo(name, "Degree", 0); diff --git a/storage/connect/reldef.h b/storage/connect/reldef.h index ac006f5c7e9..8f14d28599f 100644 --- a/storage/connect/reldef.h +++ b/storage/connect/reldef.h @@ -85,6 +85,7 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */ // Members PSZ Owner; /* Table owner (for ODBC) */ PSZ Desc; /* Table description */ + char Catfunc; /* Catalog function */ int Card; /* (max) number of rows in table */ int Elemt; /* Number of rows in blocks or rowset */ int Sort; /* Table already sorted ??? */ diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp index 5218a322ea6..930048346b9 100644 --- a/storage/connect/tabdos.cpp +++ b/storage/connect/tabdos.cpp @@ -297,12 +297,16 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode) /* Column blocks will be allocated only when needed. */ /*********************************************************************/ if (Recfm == RECFM_DBF) { - if (map) - txfp = new(g) DBMFAM(this); - else - txfp = new(g) DBFFAM(this); + if (!Catfunc) { + if (map) + txfp = new(g) DBMFAM(this); + else + txfp = new(g) DBFFAM(this); + + tdbp = new(g) TDBFIX(this, txfp); + } else // Catfunc should be 'C' + tdbp = new(g) TDBDCL(this); - tdbp = new(g) TDBFIX(this, txfp); } else if (Recfm != RECFM_VAR && Compressed < 2) { if (Huge) txfp = new(g) BGXFAM(this); diff --git a/storage/connect/tabdos.h b/storage/connect/tabdos.h index a1c5b0660cd..2f1f0a5ecf9 100644 --- a/storage/connect/tabdos.h +++ b/storage/connect/tabdos.h @@ -34,6 +34,7 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */ virtual const char *GetType(void) {return "DOS";} virtual PIXDEF GetIndx(void) {return To_Indx;} virtual void SetIndx(PIXDEF xdp) {To_Indx = xdp;} + PSZ GetFn(void) {return Fn;} PSZ GetOfn(void) {return Ofn;} void SetBlock(int block) {Block = block;} int GetBlock(void) {return Block;} diff --git a/storage/connect/tabfix.h b/storage/connect/tabfix.h index 0a4f9fc4872..bcd171b37bb 100644 --- a/storage/connect/tabfix.h +++ b/storage/connect/tabfix.h @@ -8,6 +8,7 @@ #ifndef __TABFIX__ #define __TABFIX__ #include "tabdos.h" /* Base class declares */ +#include "filamdbf.h" typedef class FIXCOL *PFIXCOL; typedef class BINCOL *PBINCOL; @@ -77,4 +78,22 @@ class DllExport BINCOL : public DOSCOL { // Members char Fmt; // The column numeric format }; // end of class BINCOL + +/***********************************************************************/ +/* This is the class declaration for the DBF columns catalog table. */ +/***********************************************************************/ +class TDBDCL : public TDBCAT { + public: + // Constructor + TDBDCL(PDOSDEF tdp) : TDBCAT(tdp) {Fn = tdp->GetFn();} + + protected: + // Specific routines + virtual PQRYRES GetResult(PGLOBAL g) {return DBFColumns(g, Fn, false);} + + // Members + char *Fn; // The DBF file (path) name + }; // end of class TDBOCL + + #endif // __TABFIX__ diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp index 9b4589a71a7..6834ca5ea28 100644 --- a/storage/connect/tabfmt.cpp +++ b/storage/connect/tabfmt.cpp @@ -1,7 +1,7 @@ /************* TabFmt C++ Program Source Code File (.CPP) **************/ /* PROGRAM NAME: TABFMT */ /* ------------- */ -/* Version 3.7 */ +/* Version 3.8 */ /* */ /* COPYRIGHT: */ /* ---------- */ @@ -68,24 +68,21 @@ extern "C" int trace; /***********************************************************************/ -/* CSV Catalog utility functions. */ -/***********************************************************************/ -PQRYRES PlgAllocResult(PGLOBAL, int, int, int, int *, int *, - unsigned int *, bool blank = true, bool nonull = false); - -/***********************************************************************/ /* CSVColumns: constructs the result blocks containing the description */ /* of all the columns of a CSV file that will be retrieved by #GetData.*/ /* Note: the algorithm to set the type is based on the internal values */ /* of types (TYPE_STRING < TYPE_FLOAT < TYPE_INT) (1 < 2 < 7). */ /* If these values are changed, this will have to be revisited. */ /***********************************************************************/ -PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, int hdr, int mxr) +PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, + int hdr, int mxr, bool info) { - static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, - DB_INT, DB_INT, DB_SHORT}; - static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, - TYPE_INT, TYPE_INT, TYPE_SHORT}; + static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, + DB_INT, DB_INT, DB_SHORT}; + static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, + TYPE_INT, TYPE_INT, TYPE_SHORT}; + static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, + FLD_PREC, FLD_LENGTH, FLD_SCALE}; static unsigned int length[] = {6, 6, 8, 10, 10, 6}; char *p, *colname[MAXCOL], dechar, filename[_MAX_PATH], buf[4096]; int i, imax, hmax, n, nerr, phase, blank, digit, dec, type; @@ -96,9 +93,15 @@ PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, int hdr, int mxr) PQRYRES qrp; PCOLRES crp; + if (info) { + imax = 0; + length[0] = 128; + goto skipit; + } // endif info + // num_max = atoi(p+1); // Max num of record to test #if defined(WIN32) - if (strnicmp(setlocale(LC_NUMERIC, NULL), "French", 6)) + if (sep == ',' || strnicmp(setlocale(LC_NUMERIC, NULL), "French", 6)) dechar = '.'; else dechar = ','; @@ -328,6 +331,7 @@ PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, int hdr, int mxr) fclose(infile); + skipit: if (trace) htrc("CSVColumns: imax=%d hmax=%d len=%d\n", imax, hmax, length[0]); @@ -336,9 +340,12 @@ PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, int hdr, int mxr) /* Allocate the structures used to refer to the result set. */ /*********************************************************************/ qrp = PlgAllocResult(g, ncol, imax, IDS_COLUMNS + 3, - dbtype, buftyp, length); + dbtype, buftyp, fldtyp, length, true, false); qrp->Nblin = imax; + if (info) + return qrp; + /*********************************************************************/ /* Now get the results into blocks. */ /*********************************************************************/ @@ -398,11 +405,12 @@ bool CSVDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) char buf[8]; // Double check correctness of offset values - for (PCOLDEF cdp = To_Cols; cdp; cdp = cdp->GetNext()) - if (cdp->GetOffset() < 1) { - strcpy(g->Message, MSG(BAD_OFFSET_VAL)); - return true; - } // endif Offset + if (!Catfunc) + for (PCOLDEF cdp = To_Cols; cdp; cdp = cdp->GetNext()) + if (cdp->GetOffset() < 1) { + strcpy(g->Message, MSG(BAD_OFFSET_VAL)); + return true; + } // endif Offset // Call DOSDEF DefineAM with am=CSV so FMT is not confused with FIX if (DOSDEF::DefineAM(g, "CSV", poff)) @@ -431,47 +439,52 @@ bool CSVDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) /***********************************************************************/ PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode) { - USETEMP tmp = PlgGetUser(g)->UseTemp; - bool map = Mapped && mode != MODE_INSERT && - !(tmp != TMP_NO && mode == MODE_UPDATE) && - !(tmp == TMP_FORCE && - (mode == MODE_UPDATE || mode == MODE_DELETE)); - PTXF txfp; PTDBASE tdbp; - /*********************************************************************/ - /* Allocate a file processing class of the proper type. */ - /*********************************************************************/ - if (map) { - // Should be now compatible with UNIX - txfp = new(g) MAPFAM(this); - } else if (Compressed) { + if (Catfunc != 'C') { + USETEMP tmp = PlgGetUser(g)->UseTemp; + bool map = Mapped && mode != MODE_INSERT && + !(tmp != TMP_NO && mode == MODE_UPDATE) && + !(tmp == TMP_FORCE && + (mode == MODE_UPDATE || mode == MODE_DELETE)); + PTXF txfp; + + /*******************************************************************/ + /* Allocate a file processing class of the proper type. */ + /*******************************************************************/ + if (map) { + // Should be now compatible with UNIX + txfp = new(g) MAPFAM(this); + } else if (Compressed) { #if defined(ZIP_SUPPORT) - if (Compressed == 1) - txfp = new(g) ZIPFAM(this); - else { - strcpy(g->Message, "Compress 2 not supported yet"); -// txfp = new(g) ZLBFAM(defp); - return NULL; - } // endelse + if (Compressed == 1) + txfp = new(g) ZIPFAM(this); + else { + strcpy(g->Message, "Compress 2 not supported yet"); +// txfp = new(g) ZLBFAM(defp); + return NULL; + } // endelse #else // !ZIP_SUPPORT - strcpy(g->Message, "Compress not supported"); - return NULL; + strcpy(g->Message, "Compress not supported"); + return NULL; #endif // !ZIP_SUPPORT - } else - txfp = new(g) DOSFAM(this); + } else + txfp = new(g) DOSFAM(this); - /*********************************************************************/ - /* Allocate a TDB of the proper type. */ - /* Column blocks will be allocated only when needed. */ - /*********************************************************************/ - if (!Fmtd) - tdbp = new(g) TDBCSV(this, txfp); - else - tdbp = new(g) TDBFMT(this, txfp); + /*******************************************************************/ + /* Allocate a TDB of the proper type. */ + /* Column blocks will be allocated only when needed. */ + /*******************************************************************/ + if (!Fmtd) + tdbp = new(g) TDBCSV(this, txfp); + else + tdbp = new(g) TDBFMT(this, txfp); - if (Multiple) - tdbp = new(g) TDBMUL(tdbp); + if (Multiple) + tdbp = new(g) TDBMUL(tdbp); + + } else + tdbp = new(g)TDBCCL(this); return tdbp; } // end of GetTable @@ -1389,4 +1402,26 @@ void CSVCOL::WriteColumn(PGLOBAL g) } // end of WriteColumn +/* ---------------------------TDBCCL class --------------------------- */ + +/***********************************************************************/ +/* TDBCCL class constructor. */ +/***********************************************************************/ +TDBCCL::TDBCCL(PCSVDEF tdp) : TDBCAT(tdp) + { + Fn = tdp->GetFn(); + Hdr = tdp->Header; + Mxr = tdp->Maxerr; + Qtd = tdp->Quoted; + Sep = tdp->Sep; + } // end of TDBCCL constructor + +/***********************************************************************/ +/* GetResult: Get the list the CSV file columns. */ +/***********************************************************************/ +PQRYRES TDBCCL::GetResult(PGLOBAL g) + { + return CSVColumns(g, Fn, Sep, Qtd, Hdr, Mxr, false); + } // end of GetResult + /* ------------------------ End of TabFmt ---------------------------- */ diff --git a/storage/connect/tabfmt.h b/storage/connect/tabfmt.h index 95486a09881..05b9d6445c6 100644 --- a/storage/connect/tabfmt.h +++ b/storage/connect/tabfmt.h @@ -1,7 +1,7 @@ /*************** TabFmt H Declares Source Code File (.H) ***************/ -/* Name: TABFMT.H Version 2.2 */ +/* Name: TABFMT.H Version 2.3 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2001-2012 */ +/* (C) Copyright to the author Olivier BERTRAND 2001-2013 */ /* */ /* This file contains the CSV and FMT classes declares. */ /***********************************************************************/ @@ -14,14 +14,15 @@ typedef class TDBFMT *PTDBFMT; /***********************************************************************/ /* Functions used externally. */ /***********************************************************************/ -PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, int hdr, int mxr); +PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, + int hdr, int mxr, bool info); /***********************************************************************/ /* CSV table. */ /***********************************************************************/ class DllExport CSVDEF : public DOSDEF { /* Logical table description */ friend class TDBCSV; -//friend class TDBMCV; + friend class TDBCCL; public: // Constructor CSVDEF(void); @@ -160,10 +161,30 @@ class TDBFMT : public TDBCSV { protected: // Members - PSZ *FldFormat; // Field read format - void *To_Fld; // To field test buffer - int *FmtTest; // Test on ending by %n or %m - int Linenum; // Last read line + PSZ *FldFormat; // Field read format + void *To_Fld; // To field test buffer + int *FmtTest; // Test on ending by %n or %m + int Linenum; // Last read line }; // end of class TDBFMT +/***********************************************************************/ +/* This is the class declaration for the CSV catalog table. */ +/***********************************************************************/ +class TDBCCL : public TDBCAT { + public: + // Constructor + TDBCCL(PCSVDEF tdp); + + protected: + // Specific routines + virtual PQRYRES GetResult(PGLOBAL g); + + // Members + char *Fn; // The CSV file (path) name + bool Hdr; // true if first line contains headers + int Mxr; // Maximum number of bad records + int Qtd; // Quoting level for quoted fields + char Sep; // Separator for standard CSV files + }; // end of class TDBCCL + /* ------------------------- End of TabFmt.H ------------------------- */ diff --git a/storage/connect/table.cpp b/storage/connect/table.cpp index 77c2fd4df3b..0c8e86c0457 100644 --- a/storage/connect/table.cpp +++ b/storage/connect/table.cpp @@ -1,7 +1,7 @@ /************** Table C++ Functions Source Code File (.CPP) ************/ -/* Name: TABLE.CPP Version 2.5 */ +/* Name: TABLE.CPP Version 2.6 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 1999-2012 */ +/* (C) Copyright to the author Olivier BERTRAND 1999-2013 */ /* */ /* This file contains the TBX, TDB and OPJOIN classes functions. */ /***********************************************************************/ @@ -425,3 +425,180 @@ void TDBASE::MarkDB(PGLOBAL g, PTDB tdb2) htrc("DOS MarkDB: tdbp=%p tdb2=%p\n", this, tdb2); } // end of MarkDB + +/* ---------------------------TDBCAT class --------------------------- */ + +/***********************************************************************/ +/* Implementation of the TDBCAT class. */ +/***********************************************************************/ +TDBCAT::TDBCAT(PTABDEF tdp) : TDBASE(tdp) + { + Qrp = NULL; + Init = false; + N = -1; + } // end of TDBCAT constructor + +/***********************************************************************/ +/* Allocate CAT column description block. */ +/***********************************************************************/ +PCOL TDBCAT::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) + { + PCATCOL colp; + + colp = (PCATCOL)new(g) CATCOL(cdp, this, n); + + if (cprec) { + colp->SetNext(cprec->GetNext()); + cprec->SetNext(colp); + } else { + colp->SetNext(Columns); + Columns = colp; + } // endif cprec + + return colp; + } // end of MakeCol + +/***********************************************************************/ +/* Initialize: Get the result query block. */ +/***********************************************************************/ +bool TDBCAT::Initialize(PGLOBAL g) + { + if (Init) + return false; + + if (!(Qrp = GetResult(g))) + return true; + + Init = true; + return false; + } // end of Initialize + +/***********************************************************************/ +/* CAT: Get the number of properties. */ +/***********************************************************************/ +int TDBCAT::GetMaxSize(PGLOBAL g) + { + if (MaxSize < 0) { + if (Initialize(g)) + return -1; + + MaxSize = Qrp->Nblin; + } // endif MaxSize + + return MaxSize; + } // end of GetMaxSize + +/***********************************************************************/ +/* CAT Access Method opening routine. */ +/***********************************************************************/ +bool TDBCAT::OpenDB(PGLOBAL g) + { + if (Use == USE_OPEN) { + /*******************************************************************/ + /* Table already open. */ + /*******************************************************************/ + N = -1; + return false; + } // endif use + + if (Mode != MODE_READ) { + /*******************************************************************/ + /* ODBC Info tables cannot be modified. */ + /*******************************************************************/ + strcpy(g->Message, "CAT tables are read only"); + return true; + } // endif Mode + + /*********************************************************************/ + /* Initialize the ODBC processing. */ + /*********************************************************************/ + if (Initialize(g)) + return true; + + return InitCol(g); + } // end of OpenDB + +/***********************************************************************/ +/* Initialize columns. */ +/***********************************************************************/ +bool TDBCAT::InitCol(PGLOBAL g) + { + PCATCOL colp; + PCOLRES crp; + + for (colp = (PCATCOL)Columns; colp; colp = (PCATCOL)colp->GetNext()) { + for (crp = Qrp->Colresp; crp; crp = crp->Next) + if ((colp->Flag == crp->Ncol) || + (!colp->Flag && !stricmp(colp->Name, crp->Name))) { + colp->Crp = crp; + break; + } // endif Flag + + + if (!colp->Crp /*&& !colp->GetValue()->IsConstant()*/) { + sprintf(g->Message, "Invalid flag %d for column %s", + colp->Flag, colp->Name); + return true; + } // endif Crp + + } // endfor colp + + return false; + } // end of InitCol + +/***********************************************************************/ +/* Data Base read routine for CAT access method. */ +/***********************************************************************/ +int TDBCAT::ReadDB(PGLOBAL g) + { + return (++N < Qrp->Nblin) ? RC_OK : RC_EF; + } // end of ReadDB + +/***********************************************************************/ +/* WriteDB: Data Base write routine for CAT access methods. */ +/***********************************************************************/ +int TDBCAT::WriteDB(PGLOBAL g) + { + strcpy(g->Message, "CAT tables are read only"); + return RC_FX; + } // end of WriteDB + +/***********************************************************************/ +/* Data Base delete line routine for CAT access methods. */ +/***********************************************************************/ +int TDBCAT::DeleteDB(PGLOBAL g, int irc) + { + strcpy(g->Message, "Delete not enabled for CAT tables"); + return RC_FX; + } // end of DeleteDB + +/***********************************************************************/ +/* Data Base close routine for WMI access method. */ +/***********************************************************************/ +void TDBCAT::CloseDB(PGLOBAL g) + { + // Nothing to do + } // end of CloseDB + +// ------------------------ CATCOL functions ---------------------------- + +/***********************************************************************/ +/* CATCOL public constructor. */ +/***********************************************************************/ +CATCOL::CATCOL(PCOLDEF cdp, PTDB tdbp, int n) + : COLBLK(cdp, tdbp, n) + { + Tdbp = (PTDBCAT)tdbp; + Crp = NULL; + Flag = cdp->GetOffset(); + } // end of WMICOL constructor + +/***********************************************************************/ +/* Read the next Data Source elements. */ +/***********************************************************************/ +void CATCOL::ReadColumn(PGLOBAL g) + { + // Get the value of the Name or Description property + Value->SetValue_pvblk(Crp->Kdata, Tdbp->N); + } // end of ReadColumn + diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp index a63526f1e8d..27489f4635e 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.5 */ +/* Version 1.6 */ /* */ /* AUTHOR: */ /* ------- */ @@ -105,7 +105,11 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) /***********************************************************************/ PTDB MYSQLDEF::GetTable(PGLOBAL g, MODE m) { - return new(g) TDBMYSQL(this); + if (Catfunc == 'C') + return new(g) TDBMCL(this); + else + return new(g) TDBMYSQL(this); + } // end of GetTable /* ------------------------------------------------------------------- */ @@ -859,3 +863,26 @@ void MYSQLCOL::WriteColumn(PGLOBAL g) } // endif Prep } // end of WriteColumn + +/* ---------------------------TDBMCL class --------------------------- */ + +/***********************************************************************/ +/* TDBMCL class constructor. */ +/***********************************************************************/ +TDBMCL::TDBMCL(PMYDEF tdp) : TDBCAT(tdp) + { + Host = tdp->Hostname; + Db = tdp->Database; + Tab = tdp->Tabname; + User = tdp->Username; + Pwd = tdp->Password; + Port = tdp->Portnumber; + } // end of TDBMCL constructor + +/***********************************************************************/ +/* GetResult: Get the list the MYSQL table columns. */ +/***********************************************************************/ +PQRYRES TDBMCL::GetResult(PGLOBAL g) + { + return MyColumns(g, Host, Db, User, Pwd, Tab, NULL, Port, false, false); + } // end of GetResult diff --git a/storage/connect/tabmysql.h b/storage/connect/tabmysql.h index 68fb9d89f24..abfdeeb13a3 100644 --- a/storage/connect/tabmysql.h +++ b/storage/connect/tabmysql.h @@ -1,4 +1,4 @@ -// TDBMYSQL.H Olivier Bertrand 2007-2012 +// TDBMYSQL.H Olivier Bertrand 2007-2013 #include "myconn.h" // MySQL connection declares typedef class MYSQLDEF *PMYDEF; @@ -18,6 +18,7 @@ typedef class MYSQLCOL *PMYCOL; /***********************************************************************/ class MYSQLDEF : public TABDEF {/* Logical table description */ friend class TDBMYSQL; + friend class TDBMCL; public: // Constructor MYSQLDEF(void); @@ -104,7 +105,7 @@ class TDBMYSQL : public TDBASE { int AftRows; // The number of affected rows int N; // The current table index int Port; // MySQL port number (0 = default) - int Nparm; // The number of statement parameters + int Nparm; // The number of statement parameters }; // end of class TDBMYSQL /***********************************************************************/ @@ -132,12 +133,28 @@ class MYSQLCOL : public COLBLK { // Members MYSQL_BIND *Bind; // This column bind structure pointer - PVAL To_Val; // To value used for Update/Insert + PVAL To_Val; // To value used for Update/Insert unsigned long Slen; // Bind string lengh int Rank; // Rank (position) number in the query }; // end of class MYSQLCOL +/***********************************************************************/ +/* This is the class declaration for the MYSQL column catalog table. */ +/***********************************************************************/ +class TDBMCL : public TDBCAT { + public: + // Constructor + TDBMCL(PMYDEF tdp); -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); + protected: + // Specific routines + virtual PQRYRES GetResult(PGLOBAL g); + + // Members + PSZ Host; // Host machine to use + PSZ Db; // Database to be used by server + PSZ Tab; // External table name + PSZ User; // User logon name + PSZ Pwd; // Password logon info + int Port; // MySQL port number (0 = default) + }; // end of class TDBMCL diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp index 7b8c62e3e53..55475852a62 100644 --- a/storage/connect/tabodbc.cpp +++ b/storage/connect/tabodbc.cpp @@ -89,7 +89,6 @@ extern int num_read, num_there, num_eq[2]; // Statistics ODBCDEF::ODBCDEF(void) { Connect = Tabname = Tabowner = Tabqual = Qchar = NULL; - Catfunc = 0; Catver = Options = 0; } // end of ODBCDEF constructor @@ -101,7 +100,6 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) int dop = ODBConn::noOdbcDialog; // Default for options Desc = Connect = Cat->GetStringCatInfo(g, Name, "Connect", ""); - Catfunc = toupper(*Cat->GetStringCatInfo(g, Name, "Catfunc", "")); Tabname = Cat->GetStringCatInfo(g, Name, "Name", Catfunc == 'T' ? NULL : Name); Tabname = Cat->GetStringCatInfo(g, Name, "Tabname", Tabname); @@ -905,259 +903,53 @@ void ODBCCOL::WriteColumn(PGLOBAL g) } // end of WriteColumn -/* ---------------------------TDBOIF class --------------------------- */ - -/***********************************************************************/ -/* Implementation of the TDBOIF class. */ -/***********************************************************************/ -TDBOIF::TDBOIF(PODEF tdp) : TDBASE(tdp) - { - Qrp = NULL; - ID = 0; - NC = 0; - Init = false; - N = -1; - } // end of TDBOIF constructor - -/***********************************************************************/ -/* Allocate OIF column description block. */ -/***********************************************************************/ -PCOL TDBOIF::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) - { - POIFCOL colp; - - colp = (POIFCOL)new(g) OIFCOL(cdp, this, n); - - if (cprec) { - colp->SetNext(cprec->GetNext()); - cprec->SetNext(colp); - } else { - colp->SetNext(Columns); - Columns = colp; - } // endif cprec - - for (int i = 1; !colp->Flag && i <= NC; i++) - if (!stricmp(colp->Name, GetMsgid(ID + i))) - colp->Flag = i; - - return colp; - } // end of MakeCol - -/***********************************************************************/ -/* OIF: Get the number of properties. */ -/***********************************************************************/ -int TDBOIF::GetMaxSize(PGLOBAL g) - { - if (MaxSize < 0) { - if (Initialize(g)) - return -1; - - MaxSize = Qrp->Nblin; - } // endif MaxSize - - return MaxSize; - } // end of GetMaxSize - -/***********************************************************************/ -/* OIF Access Method opening routine. */ -/***********************************************************************/ -bool TDBOIF::OpenDB(PGLOBAL g) - { - if (Use == USE_OPEN) { - /*******************************************************************/ - /* Table already open. */ - /*******************************************************************/ - N = -1; - return false; - } // endif use - - if (Mode != MODE_READ) { - /*******************************************************************/ - /* ODBC Info tables cannot be modified. */ - /*******************************************************************/ - strcpy(g->Message, "OIF tables are read only"); - return true; - } // endif Mode - - /*********************************************************************/ - /* Initialize the ODBC processing. */ - /*********************************************************************/ - if (Initialize(g)) - return true; - - return InitCol(g); - } // end of OpenDB - -/***********************************************************************/ -/* Initialize columns. */ -/***********************************************************************/ -bool TDBOIF::InitCol(PGLOBAL g) - { - POIFCOL colp; - PCOLRES crp; - - for (colp = (POIFCOL)Columns; colp; colp = (POIFCOL)colp->GetNext()) { - for (crp = Qrp->Colresp; crp; crp = crp->Next) - if (colp->Flag == crp->Ncol) { - colp->Crp = crp; - break; - } // endif Flag - - if (!colp->Crp) { - sprintf(g->Message, "Invalid flag %d for column %s", - colp->Flag, colp->Name); - return true; - } // endif Crp - - } // endfor colp - - return false; - } // end of InitCol - -/***********************************************************************/ -/* Data Base read routine for OIF access method. */ -/***********************************************************************/ -int TDBOIF::ReadDB(PGLOBAL g) - { - return (++N < Qrp->Nblin) ? RC_OK : RC_EF; - } // end of ReadDB - -/***********************************************************************/ -/* WriteDB: Data Base write routine for OIF access methods. */ -/***********************************************************************/ -int TDBOIF::WriteDB(PGLOBAL g) - { - strcpy(g->Message, "OIF tables are read only"); - return RC_FX; - } // end of WriteDB - -/***********************************************************************/ -/* Data Base delete line routine for OIF access methods. */ -/***********************************************************************/ -int TDBOIF::DeleteDB(PGLOBAL g, int irc) - { - strcpy(g->Message, "Delete not enabled for OIF tables"); - return RC_FX; - } // end of DeleteDB - -/***********************************************************************/ -/* Data Base close routine for WMI access method. */ -/***********************************************************************/ -void TDBOIF::CloseDB(PGLOBAL g) - { - // Nothing to do - } // end of CloseDB - -// ------------------------ OIFCOL functions ---------------------------- - -/***********************************************************************/ -/* OIFCOL public constructor. */ -/***********************************************************************/ -OIFCOL::OIFCOL(PCOLDEF cdp, PTDB tdbp, int n) - : COLBLK(cdp, tdbp, n) - { - Tdbp = (PTDBOIF)tdbp; - Crp = NULL; - Flag = cdp->GetOffset(); - } // end of WMICOL constructor - -/***********************************************************************/ -/* Read the next Data Source elements. */ -/***********************************************************************/ -void OIFCOL::ReadColumn(PGLOBAL g) - { - // Get the value of the Name or Description property - Value->SetValue_pvblk(Crp->Kdata, Tdbp->N); - } // end of ReadColumn - /* ---------------------------TDBSRC class --------------------------- */ /***********************************************************************/ -/* Initialize: Get the list of ODBC data sources. */ +/* GetResult: Get the list of ODBC data sources. */ /***********************************************************************/ -bool TDBSRC::Initialize(PGLOBAL g) +PQRYRES TDBSRC::GetResult(PGLOBAL g) { - if (Init) - return false; - - if (!(Qrp = ODBCDataSources(g, false))) - return true; - - Init = true; - return false; - } // end of Initialize + return ODBCDataSources(g, false); + } // end of GetResult /* ---------------------------TDBDRV class --------------------------- */ /***********************************************************************/ -/* Initialize: Get the list of ODBC drivers. */ +/* GetResult: Get the list of ODBC drivers. */ /***********************************************************************/ -bool TDBDRV::Initialize(PGLOBAL g) +PQRYRES TDBDRV::GetResult(PGLOBAL g) { - if (Init) - return false; - - if (!(Qrp = ODBCDrivers(g, false))) - return true; + return ODBCDrivers(g, false); + } // end of GetResult - Init = true; - return false; - } // end of Initialize - -/* ---------------------------TDBOCL class --------------------------- */ +/* ---------------------------TDBOTB class --------------------------- */ /***********************************************************************/ -/* TDBOCL class constructor. */ +/* TDBOTB class constructor. */ /***********************************************************************/ -TDBOCL::TDBOCL(PODEF tdp) : TDBOIF(tdp) +TDBOTB::TDBOTB(PODEF tdp) : TDBCAT(tdp) { - ID = IDS_COLUMNS + 1; - NC = 11; Dsn = tdp->GetConnect(); - Tabn = tdp->GetTabname(); - } // end of TDBOCL constructor + Tab = tdp->GetTabname(); + } // end of TDBOTB constructor /***********************************************************************/ -/* Initialize: Get the list of ODBC table columns. */ +/* GetResult: Get the list of ODBC tables. */ /***********************************************************************/ -bool TDBOCL::Initialize(PGLOBAL g) +PQRYRES TDBOTB::GetResult(PGLOBAL g) { - if (Init) - return false; + return ODBCTables(g, Dsn, Tab, false); + } // end of GetResult - if (!(Qrp = MyODBCCols(g, Dsn, Tabn, false))) - return true; - - Init = true; - return false; - } // end of Initialize - -/* ---------------------------TDBOTB class --------------------------- */ - -/***********************************************************************/ -/* TDBOCL class constructor. */ -/***********************************************************************/ -TDBOTB::TDBOTB(PODEF tdp) : TDBOIF(tdp) - { - ID = IDS_TABLES + 1; - NC = 4; - Dsn = tdp->GetConnect(); - Tabpat = tdp->GetTabname(); - } // end of TDBOCL constructor +/* ---------------------------TDBOCL class --------------------------- */ /***********************************************************************/ -/* Initialize: Get the list of ODBC tables. */ +/* GetResult: Get the list of ODBC table columns. */ /***********************************************************************/ -bool TDBOTB::Initialize(PGLOBAL g) +PQRYRES TDBOCL::GetResult(PGLOBAL g) { - if (Init) - return false; - - if (!(Qrp = ODBCTables(g, Dsn, Tabpat, false))) - return true; - - Init = true; - return false; - } // end of Initialize + return MyODBCCols(g, Dsn, Tab, false); + } // end of GetResult /* ------------------------ End of Tabodbc --------------------------- */ diff --git a/storage/connect/tabodbc.h b/storage/connect/tabodbc.h index f31c005e3d8..645426eef78 100644 --- a/storage/connect/tabodbc.h +++ b/storage/connect/tabodbc.h @@ -44,7 +44,6 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */ PSZ Tabowner; /* External table owner */ PSZ Tabqual; /* External table qualifier */ PSZ Qchar; /* Identifier quoting character */ - char Catfunc; /* Catalog function */ int Catver; /* ODBC version for catalog functions */ int Options; /* Open connection options */ }; // end of ODBCDEF @@ -164,127 +163,63 @@ class ODBCCOL : public COLBLK { }; // end of class ODBCCOL /***********************************************************************/ -/* This is the base class declaration for the ODBC info tables. */ -/***********************************************************************/ -class TDBOIF : public TDBASE { - friend class OIFCOL; - public: - // Constructor - TDBOIF(PODEF tdp); - - // Implementation - virtual AMT GetAmType(void) {return TYPE_AM_ODBC;} - - // Methods - virtual int GetRecpos(void) {return N;} - virtual int GetProgCur(void) {return N;} - virtual int RowNumber(PGLOBAL g, bool b = false) {return N + 1;} - - // Database routines - virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); - virtual int GetMaxSize(PGLOBAL g); - virtual bool OpenDB(PGLOBAL g); - virtual int ReadDB(PGLOBAL g); - virtual int WriteDB(PGLOBAL g); - virtual int DeleteDB(PGLOBAL g, int irc); - virtual void CloseDB(PGLOBAL g); - - protected: - // Specific routines - virtual bool Initialize(PGLOBAL g) = 0; - bool InitCol(PGLOBAL g); - - // Members - PQRYRES Qrp; - int ID; // Base of Column names - int NC; // Number of valid flags - int N; // Row number - bool Init; - }; // end of class TDBOIF - -/***********************************************************************/ -/* Class OIFCOL: ODBC info column. */ -/***********************************************************************/ -class OIFCOL : public COLBLK { - friend class TDBOIF; - public: - // Constructors - OIFCOL(PCOLDEF cdp, PTDB tdbp, int n); - - // Implementation - virtual int GetAmType(void) {return TYPE_AM_ODBC;} - - // Methods - virtual void ReadColumn(PGLOBAL g); - - protected: - OIFCOL(void) {} // Default constructor not to be used - - // Members - PTDBOIF Tdbp; // Points to ODBC table block - PCOLRES Crp; // The column data array - int Flag; - }; // end of class OIFCOL - -/***********************************************************************/ /* This is the class declaration for the Data Sources catalog table. */ /***********************************************************************/ -class TDBSRC : public TDBOIF { +class TDBSRC : public TDBCAT { public: // Constructor - TDBSRC(PODEF tdp) : TDBOIF(tdp) {ID = IDS_DSRC; NC = 2;} + TDBSRC(PODEF tdp) : TDBCAT(tdp) {} protected: // Specific routines - virtual bool Initialize(PGLOBAL g); + virtual PQRYRES GetResult(PGLOBAL g); }; // end of class TDBSRC /***********************************************************************/ /* This is the class declaration for the Drivers catalog table. */ /***********************************************************************/ -class TDBDRV : public TDBOIF { +class TDBDRV : public TDBCAT { public: // Constructor - TDBDRV(PODEF tdp) : TDBOIF(tdp) {ID = IDS_DRIVER; NC = 2;} + TDBDRV(PODEF tdp) : TDBCAT(tdp) {} protected: // Specific routines - virtual bool Initialize(PGLOBAL g); + virtual PQRYRES GetResult(PGLOBAL g); }; // end of class TDBDRV /***********************************************************************/ -/* This is the class declaration for the columns catalog table. */ +/* This is the class declaration for the tables catalog table. */ /***********************************************************************/ -class TDBOCL : public TDBOIF { +class TDBOTB : public TDBCAT { public: // Constructor - TDBOCL(PODEF tdp); + TDBOTB(PODEF tdp); protected: // Specific routines - virtual bool Initialize(PGLOBAL g); + virtual PQRYRES GetResult(PGLOBAL g); // Members char *Dsn; // Points to connection string - char *Tabn; // Points to ODBC table name - }; // end of class TDBOCL + char *Tab; // Points to ODBC table name or pattern + }; // end of class TDBOTB /***********************************************************************/ -/* This is the class declaration for the tables catalog table. */ +/* This is the class declaration for the columns catalog table. */ /***********************************************************************/ -class TDBOTB : public TDBOIF { +class TDBOCL : public TDBOTB { public: // Constructor - TDBOTB(PODEF tdp); + TDBOCL(PODEF tdp) : TDBOTB(tdp) {} protected: // Specific routines - virtual bool Initialize(PGLOBAL g); + virtual PQRYRES GetResult(PGLOBAL g); // Members - char *Dsn; // Points to connection string - char *Tabpat; // Points to ODBC table pattern - }; // end of class TDBOTB + }; // end of class TDBOCL + #endif // !NODBC diff --git a/storage/connect/tabwmi.cpp b/storage/connect/tabwmi.cpp index e98dfd0cde0..e6a02e1871f 100644 --- a/storage/connect/tabwmi.cpp +++ b/storage/connect/tabwmi.cpp @@ -23,13 +23,6 @@ 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); - /* ------------------- Functions WMI Column info --------------------- */ /***********************************************************************/ @@ -140,82 +133,90 @@ PWMIUT InitWMI(PGLOBAL g, char *nsp, char *classname) /* WMIColumns: constructs the result blocks containing the description */ /* of all the columns of a WMI table of a specified class. */ /***********************************************************************/ -PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *classname, PWMIUT wp) +PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *cls, bool info) { - static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, - DB_INT, DB_INT, DB_SHORT}; - static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, - TYPE_INT, TYPE_INT, TYPE_SHORT}; + static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, + DB_INT, DB_INT, DB_SHORT}; + static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, + TYPE_INT, TYPE_INT, TYPE_SHORT}; + static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, + FLD_PREC, FLD_LENGTH, FLD_SCALE}; static unsigned int len, length[] = {0, 6, 8, 10, 10, 6}; int i = 0, n = 0, ncol = sizeof(dbtype) / sizeof(int); int lng, typ, prec; LONG low, upp; - BOOL b1, b2 = TRUE; BSTR propname; VARIANT val; CIMTYPE type; HRESULT res; + PWMIUT wp; SAFEARRAY *prnlist = NULL; PQRYRES qrp = NULL; PCOLRES crp; - /*********************************************************************/ - /* Initialize WMI if not done yet. */ - /*********************************************************************/ - if ((b1 = !wp) && !(wp = InitWMI(g, nsp, classname))) - return NULL; - - /*********************************************************************/ - /* Get the number of properties to return. */ - /*********************************************************************/ - res = wp->Cobj->Get(bstr_t("__Property_Count"), 0, &val, NULL, NULL); - - if (FAILED(res)) { - sprintf(g->Message, "failed Get(__Property_Count) res=%d\n", res); - goto err; - } // endif res - - if (!(n = val.lVal)) { - sprintf(g->Message, "Class %s in %s has no properties\n", - classname, nsp); - goto err; - } // endif res + if (!info) { + /*******************************************************************/ + /* Initialize WMI if not done yet. */ + /*******************************************************************/ + if (!(wp = InitWMI(g, nsp, cls))) + return NULL; - /*********************************************************************/ - /* Get max property name length. */ - /*********************************************************************/ - res = wp->Cobj->GetNames(NULL, - WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY, - NULL, &prnlist); + /*******************************************************************/ + /* Get the number of properties to return. */ + /*******************************************************************/ + res = wp->Cobj->Get(bstr_t("__Property_Count"), 0, &val, NULL, NULL); - if (FAILED(res)) { - sprintf(g->Message, "failed GetNames res=%d\n", res); - goto err; - } // endif res + if (FAILED(res)) { + sprintf(g->Message, "failed Get(__Property_Count) res=%d\n", res); + goto err; + } // endif res - res = SafeArrayGetLBound(prnlist, 1, &low); - res = SafeArrayGetUBound(prnlist, 1, &upp); + if (!(n = val.lVal)) { + sprintf(g->Message, "Class %s in %s has no properties\n", + cls, nsp); + goto err; + } // endif res - for (long i = low; i <= upp; i++) { - // Get this property name. - res = SafeArrayGetElement(prnlist, &i, &propname); + /*******************************************************************/ + /* Get max property name length. */ + /*******************************************************************/ + res = wp->Cobj->GetNames(NULL, + WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY, + NULL, &prnlist); if (FAILED(res)) { - sprintf(g->Message, "failed GetArrayElement res=%d\n", res); + sprintf(g->Message, "failed GetNames res=%d\n", res); goto err; } // endif res - len = (unsigned)SysStringLen(propname); - length[0] = max(length[0], len); - } // enfor i + res = SafeArrayGetLBound(prnlist, 1, &low); + res = SafeArrayGetUBound(prnlist, 1, &upp); + + for (long i = low; i <= upp; i++) { + // Get this property name. + res = SafeArrayGetElement(prnlist, &i, &propname); + + if (FAILED(res)) { + sprintf(g->Message, "failed GetArrayElement res=%d\n", res); + goto err; + } // endif res + + len = (unsigned)SysStringLen(propname); + length[0] = max(length[0], len); + } // enfor i - res = SafeArrayDestroy(prnlist); + res = SafeArrayDestroy(prnlist); + } else + length[0] = 128; /*********************************************************************/ /* Allocate the structures used to refer to the result set. */ /*********************************************************************/ qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3, - dbtype, buftyp, length); + dbtype, buftyp, fldtyp, length, true, true); + + if (info) + return qrp; /*********************************************************************/ /* Now get the results into blocks. */ @@ -309,16 +310,13 @@ PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *classname, PWMIUT wp) } // endfor i qrp->Nblin = i; - b2 = b1; err: - if (b2) { - // Cleanup - wp->Cobj->Release(); - wp->Svc->Release(); - wp->Svc = NULL; // MUST be set to NULL (why?) - CoUninitialize(); - } // endif b + // Cleanup + wp->Cobj->Release(); + wp->Svc->Release(); + wp->Svc = NULL; // MUST be set to NULL (why?) + CoUninitialize(); /*********************************************************************/ /* Return the result pointer for use by GetData routines. */ @@ -346,7 +344,7 @@ bool WMIDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) Wclass = strcat(strcpy(p, "Win32_"), Wclass); } // endif Wclass - if (!(Info = Cat->GetBoolCatInfo(Name, "Info", false))) + if (!Catfunc) Ems = Cat->GetIntCatInfo(Name, "Estimate", 100); return false; @@ -357,17 +355,19 @@ bool WMIDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) /***********************************************************************/ PTDB WMIDEF::GetTable(PGLOBAL g, MODE m) { - if (Info) - return new(g) TDBWCL(this); - else + if (!Catfunc) return new(g) TDBWMI(this); + else if (Catfunc == 'C') + return new(g) TDBWCL(this); + sprintf(g->Message, "Bad catfunc %c for WMI", Catfunc); + return NULL; } // end of GetTable /* ------------------------------------------------------------------- */ /***********************************************************************/ -/* Implementation of the TDBWMI class. */ +/* Implementation of the TDBWMI class. */ /***********************************************************************/ TDBWMI::TDBWMI(PWMIDEF tdp) : TDBASE(tdp) { @@ -826,320 +826,20 @@ void WMICOL::ReadColumn(PGLOBAL g) /* ---------------------------TDBWCL class --------------------------- */ /***********************************************************************/ -/* Implementation of the TDBWCL class. */ +/* TDBWCL class constructor. */ /***********************************************************************/ -TDBWCL::TDBWCL(PWMIDEF tdp) : TDBASE(tdp) +TDBWCL::TDBWCL(PWMIDEF tdp) : TDBCAT(tdp) { - Svc = NULL; - ClsObj = NULL; - Propname = NULL; - Nspace = tdp->Nspace; - Wclass = tdp->Wclass; - Init = false; - Done = false; - Res = 0; - N = -1; - Lng = 0; - Typ = 0; - Prec = 0; + Nsp = tdp->Nspace; + Cls = tdp->Wclass; } // end of TDBWCL constructor /***********************************************************************/ -/* Allocate WCL column description block. */ -/***********************************************************************/ -PCOL TDBWCL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) - { - PWCLCOL colp; - - colp = (PWCLCOL)new(g) WCLCOL(cdp, this, n); - - if (cprec) { - colp->SetNext(cprec->GetNext()); - cprec->SetNext(colp); - } else { - colp->SetNext(Columns); - Columns = colp; - } // endif cprec - - if (!colp->Flag) { - if (!stricmp(colp->Name, "Column_Name")) - colp->Flag = 1; - else if (!stricmp(colp->Name, "Data_Type")) - colp->Flag = 2; - else if (!stricmp(colp->Name, "Type_Name")) - colp->Flag = 3; - else if (!stricmp(colp->Name, "Precision")) - colp->Flag = 4; - else if (!stricmp(colp->Name, "Length")) - colp->Flag = 5; - else if (!stricmp(colp->Name, "Scale")) - colp->Flag = 6; - - } // endif Flag - - return colp; - } // end of MakeCol - -/***********************************************************************/ -/* Initialize: Initialize WMI operations. */ +/* GetResult: Get the list of the WMI class properties. */ /***********************************************************************/ -bool TDBWCL::Initialize(PGLOBAL g) +PQRYRES TDBWCL::GetResult(PGLOBAL g) { - if (Init) - return false; - - // Initialize COM. - Res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - - if (FAILED(Res)) { - sprintf(g->Message, "Failed to initialize COM library. " - "Error code = %p", Res); - return true; // Program has failed. - } // endif Res - - // Obtain the initial locator to Windows Management - // on a particular host computer. - IWbemLocator *loc; // Initial Windows Management locator - - Res = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, - IID_IWbemLocator, (LPVOID*) &loc); - - if (FAILED(Res)) { - sprintf(g->Message, "Failed to create Locator. " - "Error code = %p", Res); - CoUninitialize(); - return true; // Program has failed. - } // endif Res - - // Connect to the specified namespace with the - // current user and obtain pointer to Svc - // to make IWbemServices calls. - Res = loc->ConnectServer(_bstr_t(Nspace), - NULL, NULL,0, NULL, 0, 0, &Svc); - - if (FAILED(Res)) { - sprintf(g->Message, "Could not connect. Error code = %p", Res); - loc->Release(); - CoUninitialize(); - return true; // Program has failed. - } // endif hres - - loc->Release(); // Not used anymore + return WMIColumns(g, Nsp, Cls, false); + } // end of GetResult - // Perform a full class object retrieval - Res = Svc->GetObject(bstr_t(Wclass), 0, 0, &ClsObj, 0); - if (FAILED(Res)) { - sprintf(g->Message, "failed GetObject %s in %s\n", Wclass, Nspace); - Svc->Release(); - Svc = NULL; // MUST be set to NULL (why?) - return true; - } // endif res - - Init = true; - return false; - } // end of Initialize - -/***********************************************************************/ -/* WCL: Get the number of properties. */ -/***********************************************************************/ -int TDBWCL::GetMaxSize(PGLOBAL g) - { - if (MaxSize < 0) { - VARIANT val; - - if (Initialize(g)) - return -1; - - Res = ClsObj->Get(bstr_t("__Property_Count"), 0, &val, NULL, NULL); - - if (FAILED(Res)) { - sprintf(g->Message, "failed Get(Property_Count) res=%d\n", Res); - return -1; - } // endif Res - - MaxSize = val.lVal; - } // endif MaxSize - - return MaxSize; - } // end of GetMaxSize - -/***********************************************************************/ -/* WCL Access Method opening routine. */ -/***********************************************************************/ -bool TDBWCL::OpenDB(PGLOBAL g) - { - if (Use == USE_OPEN) { - /*******************************************************************/ - /* Table already open. */ - /*******************************************************************/ - ClsObj->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY); - N = 0; - return false; - } // endif use - - if (Mode != MODE_READ) { - /*******************************************************************/ - /* WMI tables cannot be modified. */ - /*******************************************************************/ - strcpy(g->Message, "WCL tables are read only"); - return true; - } // endif Mode - - /*********************************************************************/ - /* Initialize the WMI processing. */ - /*********************************************************************/ - if (Initialize(g)) - return true; - - Res = ClsObj->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY); - - if (FAILED(Res)) { - sprintf(g->Message, "failed BeginEnumeration hr=%d\n", Res); - return NULL; - } // endif hr - - return false; - } // end of OpenDB - -/***********************************************************************/ -/* Data Base read routine for WCL access method. */ -/***********************************************************************/ -int TDBWCL::ReadDB(PGLOBAL g) - { - VARIANT val; - CIMTYPE type; - - Res = ClsObj->Next(0, &Propname, &val, &type, NULL); - - if (FAILED(Res)) { - sprintf(g->Message, "failed getting Next hr=%d\n", Res); - return RC_FX; - } else if (Res == WBEM_S_NO_MORE_DATA) { - VariantClear(&val); - return RC_EF; - } // endif res - - Prec = 0; - - switch (type) { - case CIM_STRING: - Typ = TYPE_STRING; - Lng = 255; - Prec = 1; // Case insensitive - break; - case CIM_SINT32: - case CIM_UINT32: - case CIM_BOOLEAN: - Typ = TYPE_INT; - Lng = 9; - break; - case CIM_SINT8: - case CIM_UINT8: - case CIM_SINT16: - case CIM_UINT16: - Typ = TYPE_SHORT; - Lng = 6; - break; - case CIM_REAL64: - case CIM_REAL32: - Prec = 2; - case CIM_SINT64: - case CIM_UINT64: - Typ = TYPE_FLOAT; - Lng = 15; - break; - case CIM_DATETIME: - Typ = TYPE_DATE; - Lng = 19; - break; - case CIM_CHAR16: - Typ = TYPE_STRING; - Lng = 16; - break; - case CIM_EMPTY: - Typ = TYPE_STRING; - Lng = 24; // ??? - break; - default: - return RC_NF; - } // endswitch type - - N++; - return RC_OK; - } // end of ReadDB - -/***********************************************************************/ -/* WriteDB: Data Base write routine for WCL access methods. */ -/***********************************************************************/ -int TDBWCL::WriteDB(PGLOBAL g) - { - strcpy(g->Message, "WCL tables are read only"); - return RC_FX; - } // end of WriteDB - -/***********************************************************************/ -/* Data Base delete line routine for WCL access methods. */ -/***********************************************************************/ -int TDBWCL::DeleteDB(PGLOBAL g, int irc) - { - strcpy(g->Message, "Delete not enabled for WCL tables"); - return RC_FX; - } // end of DeleteDB - -/***********************************************************************/ -/* Data Base close routine for WMI access method. */ -/***********************************************************************/ -void TDBWCL::CloseDB(PGLOBAL g) - { - // Cleanup - if (ClsObj) - ClsObj->Release(); - - if (Svc) - Svc->Release(); - - CoUninitialize(); - } // end of CloseDB - -// ------------------------ WCLCOL functions ---------------------------- - -/***********************************************************************/ -/* WCLCOL public constructor. */ -/***********************************************************************/ -WCLCOL::WCLCOL(PCOLDEF cdp, PTDB tdbp, int n) - : COLBLK(cdp, tdbp, n) - { - Tdbp = (PTDBWCL)tdbp; - Flag = cdp->GetOffset(); - Res = 0; - } // end of WMICOL constructor - -/***********************************************************************/ -/* Read the next WCL elements. */ -/***********************************************************************/ -void WCLCOL::ReadColumn(PGLOBAL g) - { - // Get the value of the Name property - switch (Flag) { - case 1: - Value->SetValue_psz(_com_util::ConvertBSTRToString(Tdbp->Propname)); - break; - case 2: - Value->SetValue(Tdbp->Typ); - break; - case 3: - Value->SetValue_psz(GetTypeName(Tdbp->Typ)); - break; - case 4: - case 5: - Value->SetValue(Tdbp->Lng); - break; - case 6: - Value->SetValue(Tdbp->Prec); - break; - default: - Value->Reset(); - } // endswitch Flag - - } // end of ReadColumn diff --git a/storage/connect/tabwmi.h b/storage/connect/tabwmi.h index 853f2174434..9df57e7c579 100644 --- a/storage/connect/tabwmi.h +++ b/storage/connect/tabwmi.h @@ -27,7 +27,7 @@ typedef struct _WMIutil { /***********************************************************************/ /* Functions used externally. */ /***********************************************************************/ -PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *classname, PWMIUT wp); +PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *cls, bool info); /* -------------------------- WMI classes ---------------------------- */ @@ -37,10 +37,10 @@ PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *classname, PWMIUT wp); class WMIDEF : public TABDEF { /* Logical table description */ friend class TDBWMI; friend class TDBWCL; + friend class TDBWCX; public: // Constructor - WMIDEF(void) - {Pseudo = 3; Nspace = NULL; Wclass = NULL; Ems = 0; Info = false;} + WMIDEF(void) {Pseudo = 3; Nspace = NULL; Wclass = NULL; Ems = 0;} // Implementation virtual const char *GetType(void) {return "WMI";} @@ -55,7 +55,6 @@ class WMIDEF : public TABDEF { /* Logical table description */ char *Nspace; char *Wclass; int Ems; - bool Info; }; // end of WMIDEF /***********************************************************************/ @@ -99,13 +98,13 @@ class TDBWMI : public TDBASE { char *Wclass; // Class name char *ObjPath; // Used for direct access char *Kvp; // Itou - int Ems; // Estimated max size + int Ems; // Estimated max size PCOL Kcol; // Key column HRESULT Res; PVBLK Vbp; bool Init; bool Done; - ULONG Rc; + ULONG Rc; int N; // Row number }; // end of class TDBWMI @@ -129,76 +128,24 @@ class WMICOL : public COLBLK { // Members PTDBWMI Tdbp; // Points to WMI table block - VARIANT Prop; // Property value - CIMTYPE Ctype; // CIM Type + VARIANT Prop; // Property value + CIMTYPE Ctype; // CIM Type HRESULT Res; }; // end of class WMICOL /***********************************************************************/ -/* This is the class declaration for the WCL table. */ +/* This is the class declaration for the WMI catalog table. */ /***********************************************************************/ -class TDBWCL : public TDBASE { - friend class WCLCOL; +class TDBWCL : public TDBCAT { public: // Constructor TDBWCL(PWMIDEF tdp); - // Implementation - virtual AMT GetAmType(void) {return TYPE_AM_WMI;} - - // Methods - virtual int GetRecpos(void) {return N;} - virtual int GetProgCur(void) {return N;} - virtual int RowNumber(PGLOBAL g, bool b = false) {return N + 1;} - - // Database routines - virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); - virtual int GetMaxSize(PGLOBAL g); - virtual bool OpenDB(PGLOBAL g); - virtual int ReadDB(PGLOBAL g); - virtual int WriteDB(PGLOBAL g); - virtual int DeleteDB(PGLOBAL g, int irc); - virtual void CloseDB(PGLOBAL g); - protected: - // Specific routines - bool Initialize(PGLOBAL g); + // Specific routines + virtual PQRYRES GetResult(PGLOBAL g); // Members - IWbemServices *Svc; // IWbemServices pointer - IWbemClassObject *ClsObj; - BSTR Propname; - char *Nspace; // Namespace - char *Wclass; // Class name - HRESULT Res; - bool Init; - bool Done; - int N; // Row number - int Lng; - int Typ; - int Prec; + char *Nsp; // Name space + char *Cls; // Class }; // end of class TDBWCL - -/***********************************************************************/ -/* Class WMICOL: WMI Address column. */ -/***********************************************************************/ -class WCLCOL : public COLBLK { - friend class TDBWCL; - public: - // Constructors - WCLCOL(PCOLDEF cdp, PTDB tdbp, int n); - - // Implementation - virtual int GetAmType(void) {return TYPE_AM_WMI;} - - // Methods - virtual void ReadColumn(PGLOBAL g); - - protected: - WCLCOL(void) {} // Default constructor not to be used - - // Members - PTDBWCL Tdbp; // Points to WMI table block - HRESULT Res; - int Flag; - }; // end of class WCLCOL diff --git a/storage/connect/xtable.h b/storage/connect/xtable.h index 73af45c7e0a..6932fe7337a 100644 --- a/storage/connect/xtable.h +++ b/storage/connect/xtable.h @@ -15,9 +15,12 @@ /***********************************************************************/ #include "assert.h" #include "block.h" +#include "colblk.h" //pedef class INDEXDEF *PIXDEF; -typedef char *PFIL; // Specific to CONNECT +typedef char *PFIL; // Specific to CONNECT +typedef class TDBCAT *PTDBCAT; +typedef class CATCOL *PCATCOL; /***********************************************************************/ /* Definition of class TBX (pure virtual class for TDB and OPJOIN) */ @@ -170,8 +173,8 @@ class DllExport TDBASE : public TDB { virtual bool IsReadOnly(void) {return Read_Only;} virtual int GetProgMax(PGLOBAL g) {return GetMaxSize(g);} virtual int GetProgCur(void) {return GetRecpos();} - virtual PSZ GetFile(PGLOBAL g) {return "Not a file";} - virtual int GetRemote(void) {return 0;} + virtual PSZ GetFile(PGLOBAL g) {return "Not a file";} + virtual int GetRemote(void) {return 0;} virtual void SetFile(PGLOBAL g, PSZ fn) {} virtual void ResetDB(void) {} virtual void ResetSize(void) {MaxSize = -1;} @@ -198,4 +201,66 @@ class DllExport TDBASE : public TDB { bool Read_Only; // True for read only tables }; // end of class TDBASE +/***********************************************************************/ +/* The abstract base class declaration for the catalog tables. */ +/***********************************************************************/ +class TDBCAT : public TDBASE { + friend class CATCOL; + public: + // Constructor + TDBCAT(PTABDEF tdp); + + // Implementation + virtual AMT GetAmType(void) {return TYPE_AM_CAT;} + + // Methods + virtual int GetRecpos(void) {return N;} + virtual int GetProgCur(void) {return N;} + virtual int RowNumber(PGLOBAL g, bool b = false) {return N + 1;} + + // Database routines + virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); + virtual int GetMaxSize(PGLOBAL g); + virtual bool OpenDB(PGLOBAL g); + virtual int ReadDB(PGLOBAL g); + virtual int WriteDB(PGLOBAL g); + virtual int DeleteDB(PGLOBAL g, int irc); + virtual void CloseDB(PGLOBAL g); + + protected: + // Specific routines + virtual PQRYRES GetResult(PGLOBAL g) = 0; + bool Initialize(PGLOBAL g); + bool InitCol(PGLOBAL g); + + // Members + PQRYRES Qrp; + int N; // Row number + bool Init; + }; // end of class TDBCAT + +/***********************************************************************/ +/* Class CATCOL: ODBC info column. */ +/***********************************************************************/ +class CATCOL : public COLBLK { + friend class TDBCAT; + public: + // Constructors + CATCOL(PCOLDEF cdp, PTDB tdbp, int n); + + // Implementation + virtual int GetAmType(void) {return TYPE_AM_ODBC;} + + // Methods + virtual void ReadColumn(PGLOBAL g); + + protected: + CATCOL(void) {} // Default constructor not to be used + + // Members + PTDBCAT Tdbp; // Points to ODBC table block + PCOLRES Crp; // The column data array + int Flag; + }; // end of class CATCOL + #endif // TABLE_DEFINED |