Commit 5bc538dd authored by Olivier Bertrand's avatar Olivier Bertrand

Commit the 2 last commits merged from 10.1

parent 92d283c0
......@@ -172,7 +172,7 @@
#define JSONMAX 10 // JSON Default max grp size
extern "C" {
char version[]= "Version 1.05.0003 February 27, 2017";
char version[]= "Version 1.05.0003 March 7, 2017";
#if defined(__WIN__)
char compver[]= "Version 1.05.0003 " __DATE__ " " __TIME__;
char slash= '\\';
......@@ -509,7 +509,7 @@ ha_create_table_option connect_table_option_list[]=
HA_TOPTION_NUMBER("LRECL", lrecl, 0, 0, INT_MAX32, 1),
HA_TOPTION_NUMBER("BLOCK_SIZE", elements, 0, 0, INT_MAX32, 1),
//HA_TOPTION_NUMBER("ESTIMATE", estimate, 0, 0, INT_MAX32, 1),
HA_TOPTION_NUMBER("MULTIPLE", multiple, 0, 0, 2, 1),
HA_TOPTION_NUMBER("MULTIPLE", multiple, 0, 0, 3, 1),
HA_TOPTION_NUMBER("HEADER", header, 0, 0, 3, 1),
HA_TOPTION_NUMBER("QUOTED", quoted, (ulonglong) -1, 0, 3, 1),
HA_TOPTION_NUMBER("ENDING", ending, (ulonglong) -1, 0, INT_MAX32, 1),
......
......@@ -135,10 +135,12 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
FLD_KEY, FLD_SCALE, FLD_RADIX, FLD_NULL,
FLD_REM, FLD_NO, FLD_DEFAULT, FLD_EXTRA,
FLD_CHARSET};
unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0};
char *fld, *colname, *chset, *fmt, v, buf[128], uns[16], zero[16];
//unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0};
unsigned int length[] = {0, 4, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0};
char *fld, *colname, *chset, *fmt, v, buf[128], uns[16], zero[16];
int i, n, nf, ncol = sizeof(buftyp) / sizeof(int);
int len, type, prec, rc, k = 0;
bool b;
PQRYRES qrp;
PCOLRES crp;
MYSQLC myc;
......@@ -157,7 +159,7 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
/* Do an evaluation of the result size. */
/********************************************************************/
STRING cmd(g, 64, "SHOW FULL COLUMNS FROM ");
bool b = cmd.Append((PSZ)table);
b = cmd.Append((PSZ)table);
b |= cmd.Append(" FROM ");
b |= cmd.Append((PSZ)(db ? db : PlgGetUser(g)->DBName));
......@@ -232,11 +234,31 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
fld = myc.GetCharField(1);
prec = 0;
len = 0;
v = (chset && !strcmp(chset, "binary")) ? 'B' : 0;
// v = (chset && !strcmp(chset, "binary")) ? 'B' : 0;
v = 0;
*uns = 0;
*zero = 0;
switch ((nf = sscanf(fld, "%[^(](%d,%d", buf, &len, &prec))) {
b = false;
if (!strnicmp(fld, "enum", 4)) {
char *p2, *p1 = fld + 6; // to skip enum('
while (true) {
p2 = strchr(p1, '\'');
len = MY_MAX(len, p2 - p1);
if (*++p2 != ',') break;
p1 = p2 + 2;
} // endwhile
v = (len > 255) ? 'V' : 0;
strcpy(buf, "enum");
b = true;
} else if (!strnicmp(fld, "set", 3)) {
len = (int)strlen(fld) - 2;
v = 'V';
strcpy(buf, "set");
b = true;
} else switch ((nf = sscanf(fld, "%[^(](%d,%d", buf, &len, &prec))) {
case 3:
nf = sscanf(fld, "%[^(](%d,%d) %s %s", buf, &len, &prec, uns, zero);
break;
......@@ -271,7 +293,7 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
colname, len);
PushWarning(g, thd);
v = 'V';
} else
} else
len = MY_MIN(len, 4096);
} // endif type
......@@ -286,6 +308,9 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
default: crp->Nulls[i] = v; break;
} // endswitch nf
if (b) // enum or set
nf = sscanf(fld, "%s ", buf); // get values
crp = crp->Next; // Type_Name
crp->Kdata->SetValue(buf, i);
......
......@@ -42,7 +42,8 @@ int MYSQLtoPLG(char *typname, char *var)
type = TYPE_INT;
else if (!stricmp(typname, "smallint"))
type = TYPE_SHORT;
else if (!stricmp(typname, "char") || !stricmp(typname, "varchar"))
else if (!stricmp(typname, "char") || !stricmp(typname, "varchar") ||
!stricmp(typname, "enum") || !stricmp(typname, "set"))
type = TYPE_STRING;
else if (!stricmp(typname, "double") || !stricmp(typname, "float") ||
!stricmp(typname, "real"))
......@@ -87,10 +88,12 @@ int MYSQLtoPLG(char *typname, char *var)
else if (!stricmp(typname, "year"))
*var = 'Y';
} else if (type == TYPE_STRING && !stricmp(typname, "varchar"))
// This is to make the difference between CHAR and VARCHAR
*var = 'V';
else if (type == TYPE_ERROR && xconv == TPC_SKIP)
} else if (type == TYPE_STRING) {
if (!stricmp(typname, "varchar"))
// This is to make the difference between CHAR and VARCHAR
*var = 'V';
} else if (type == TYPE_ERROR && xconv == TPC_SKIP)
*var = 'K';
else
*var = 0;
......
/************* TabMul C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABMUL */
/* ------------- */
/* Version 1.8 */
/* Version 1.9 */
/* */
/* COPYRIGHT: */
/* ---------- */
......@@ -44,6 +44,11 @@
#define __MFC_COMPAT__ // To define min/max as macro
#endif
//#include <windows.h>
#if defined(PATHMATCHSPEC)
#include "Shlwapi.h"
//using namespace std;
#pragma comment(lib,"shlwapi.lib")
#endif // PATHMATCHSPEC
#else
#if defined(UNIX)
#include <fnmatch.h>
......@@ -124,9 +129,10 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
{
#define PFNZ 4096
#define FNSZ (_MAX_DRIVE+_MAX_DIR+_MAX_FNAME+_MAX_EXT)
char *pfn[PFNZ];
char *filename;
int rc, n = 0;
PTDBDIR dirp;
PSZ pfn[PFNZ];
PSZ filename;
int rc, n = 0;
if (trace)
htrc("in InitFileName: fn[]=%d\n", FNSZ);
......@@ -141,115 +147,39 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
if (trace)
htrc("InitFileName: fn='%s'\n", filename);
if (Mul == 1) {
if (Mul != 2) {
/*******************************************************************/
/* To_File is a multiple name with special characters */
/*******************************************************************/
#if defined(__WIN__)
char drive[_MAX_DRIVE], direc[_MAX_DIR];
WIN32_FIND_DATA FileData;
HANDLE hSearch;
_splitpath(filename, drive, direc, NULL, NULL);
// Start searching files in the target directory.
hSearch = FindFirstFile(filename, &FileData);
if (hSearch == INVALID_HANDLE_VALUE) {
rc = GetLastError();
if (rc != ERROR_FILE_NOT_FOUND) {
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), 0,
(LPTSTR)&filename, sizeof(filename), NULL);
sprintf(g->Message, MSG(BAD_FILE_HANDLE), filename);
return true;
} // endif rc
if (Mul == 1)
dirp = new(g) TDBDIR(PlugDup(g, filename));
else // Mul == 3 (Subdir)
dirp = new(g) TDBSDR(PlugDup(g, filename));
goto suite;
} // endif hSearch
if (dirp->OpenDB(g))
return true;
while (n < PFNZ) {
if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
strcat(strcat(strcpy(filename, drive), direc), FileData.cFileName);
pfn[n++] = PlugDup(g, filename);
} // endif dwFileAttributes
if (!FindNextFile(hSearch, &FileData)) {
rc = GetLastError();
if (rc != ERROR_NO_MORE_FILES) {
sprintf(g->Message, MSG(NEXT_FILE_ERROR), rc);
FindClose(hSearch);
return true;
} // endif rc
break;
} // endif FindNextFile
} // endwhile n
// Close the search handle.
if (!FindClose(hSearch)) {
strcpy(g->Message, MSG(SRCH_CLOSE_ERR));
return true;
} // endif FindClose
if (trace && Mul == 3) {
int nf = ((PTDBSDR)dirp)->FindInDir(g);
htrc("Number of files = %d\n", nf);
} // endif trace
while (true)
if ((rc = dirp->ReadDB(g)) == RC_OK) {
#if defined(__WIN__)
strcat(strcpy(filename, dirp->Drive), dirp->Direc);
#else // !__WIN__
struct stat fileinfo;
char fn[FN_REFLEN], direc[FN_REFLEN], pattern[FN_HEADLEN], ftype[FN_EXTLEN];
DIR *dir;
struct dirent *entry;
_splitpath(filename, NULL, direc, pattern, ftype);
strcat(pattern, ftype);
if (trace)
htrc("direc=%s pattern=%s ftype=%s\n", direc, pattern, ftype);
// Start searching files in the target directory.
if (!(dir = opendir(direc))) {
sprintf(g->Message, MSG(BAD_DIRECTORY), direc, strerror(errno));
if (trace)
htrc("%s\n", g->Message);
return true;
} // endif dir
if (trace)
htrc("dir opened: reading files\n");
while ((entry = readdir(dir)) && n < PFNZ) {
strcat(strcpy(fn, direc), entry->d_name);
if (trace)
htrc("%s read\n", fn);
if (lstat(fn, &fileinfo) < 0) {
sprintf(g->Message, "%s: %s", fn, strerror(errno));
return true;
} else if (!S_ISREG(fileinfo.st_mode))
continue; // Not a regular file (should test for links)
/*******************************************************************/
/* Test whether the file name matches the table name filter. */
/*******************************************************************/
if (fnmatch(pattern, entry->d_name, 0))
continue; // Not a match
strcat(strcpy(filename, direc), entry->d_name);
pfn[n++] = PlugDup(g, filename);
if (trace)
htrc("Adding pfn[%d] %s\n", n, filename);
strcpy(filename, dirp->Direc);
#endif // !__WIN__
strcat(strcat(filename, dirp->Fname), dirp->Ftype);
pfn[n++] = PlugDup(g, filename);
} else
break;
} // endwhile readdir
dirp->CloseDB(g);
// Close the dir handle.
closedir(dir);
#endif // !__WIN__
if (rc == RC_FX)
return true;
} else {
/*******************************************************************/
......@@ -297,10 +227,6 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
} // endif Mul
#if defined(__WIN__)
suite:
#endif
if (n) {
Filenames = (char**)PlugSubAlloc(g, NULL, n * sizeof(char*));
......@@ -581,7 +507,95 @@ void TDBMUL::CloseDB(PGLOBAL g)
} // end of CloseDB
/* --------------------------- Class DIRDEF -------------------------- */
#if 0
/* ------------------------- Class TDBMSD ---------------------------- */
// Method
PTDB TDBMSD::Clone(PTABS t)
{
PTDBMSD tp;
PGLOBAL g = t->G; // Is this really useful ???
tp = new(g) TDBMSD(this);
tp->Tdbp = Tdbp->Clone(t);
tp->Columns = tp->Tdbp->GetColumns();
return tp;
} // end of Clone
PTDB TDBMSD::Duplicate(PGLOBAL g)
{
PTDBMSD tmup = new(g) TDBMSD(this);
tmup->Tdbp = Tdbp->Duplicate(g);
return tmup;
} // end of Duplicate
/***********************************************************************/
/* Initializes the table filename list. */
/* Note: tables created by concatenating the file components without */
/* specifying the LRECL value (that should be restricted to _MAX_PATH)*/
/* have a LRECL that is the sum of the lengths of all components. */
/* This is why we use a big filename array to take care of that. */
/***********************************************************************/
bool TDBMSD::InitFileNames(PGLOBAL g)
{
#define PFNZ 4096
#define FNSZ (_MAX_DRIVE+_MAX_DIR+_MAX_FNAME+_MAX_EXT)
PTDBSDR dirp;
PSZ pfn[PFNZ];
PSZ filename;
int rc, n = 0;
if (trace)
htrc("in InitFileName: fn[]=%d\n", FNSZ);
filename = (char*)PlugSubAlloc(g, NULL, FNSZ);
// The sub table may need to refer to the Table original block
Tdbp->SetTable(To_Table); // Was not set at construction
PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath());
if (trace)
htrc("InitFileName: fn='%s'\n", filename);
dirp = new(g) TDBSDR(filename);
if (dirp->OpenDB(g))
return true;
while (true)
if ((rc = dirp->ReadDB(g)) == RC_OK) {
#if defined(__WIN__)
strcat(strcpy(filename, dirp->Drive), dirp->Direc);
#else // !__WIN__
strcpy(filename, dirp->Direc);
#endif // !__WIN__
strcat(strcat(filename, dirp->Fname), dirp->Ftype);
pfn[n++] = PlugDup(g, filename);
} else
break;
if (rc == RC_FX)
return true;
if (n) {
Filenames = (char**)PlugSubAlloc(g, NULL, n * sizeof(char*));
for (int i = 0; i < n; i++)
Filenames[i] = pfn[i];
} else {
Filenames = (char**)PlugSubAlloc(g, NULL, sizeof(char*));
Filenames[0] = NULL;
} // endif n
NumFiles = n;
return false;
} // end of InitFileNames
#endif // 0
/* --------------------------- Class DIRDEF -------------------------- */
/***********************************************************************/
/* DefineAM: define specific AM block values from XDB file. */
......@@ -616,57 +630,38 @@ PTDB DIRDEF::GetTable(PGLOBAL g, MODE)
/***********************************************************************/
/* TABDIR constructors. */
/***********************************************************************/
TDBDIR::TDBDIR(PDIRDEF tdp) : TDBASE(tdp)
{
To_File = tdp->Fn;
iFile = 0;
#if defined(__WIN__)
memset(&FileData, 0, sizeof(_finddata_t));
Hsearch = -1;
*Drive = '\0';
#else // !__WIN__
memset(&Fileinfo, 0, sizeof(struct stat));
Entry = NULL;
Dir = NULL;
Done = false;
*Pattern = '\0';
#endif // !__WIN__
*Fpath = '\0';
*Direc = '\0';
*Fname = '\0';
*Ftype = '\0';
} // end of TDBDIR standard constructor
TDBDIR::TDBDIR(PTDBDIR tdbp) : TDBASE(tdbp)
{
To_File = tdbp->To_File;
iFile = tdbp->iFile;
void TDBDIR::Init(void)
{
iFile = 0;
#if defined(__WIN__)
FileData = tdbp->FileData;
Hsearch = tdbp->Hsearch;
strcpy(Drive, tdbp->Drive);
Dvalp = NULL;
memset(&FileData, 0, sizeof(_finddata_t));
hSearch = INVALID_HANDLE_VALUE;
*Drive = '\0';
#else // !__WIN__
Fileinfo = tdbp->Fileinfo;
Entry = tdbp->Entry;
Dir = tdbp->Dir;
Done = tdbp->Done;
strcpy(Pattern, tdbp->Pattern);
memset(&Fileinfo, 0, sizeof(struct stat));
Entry = NULL;
Dir = NULL;
Done = false;
*Pattern = '\0';
#endif // !__WIN__
strcpy(Direc, tdbp->Direc);
strcpy(Fname, tdbp->Fname);
strcpy(Ftype, tdbp->Ftype);
} // end of TDBDIR copy constructor
*Fpath = '\0';
*Direc = '\0';
*Fname = '\0';
*Ftype = '\0';
} // end of Init
// Method
PTDB TDBDIR::Clone(PTABS t)
{
PTDB tp;
PGLOBAL g = t->G; // Is this really useful ???
TDBDIR::TDBDIR(PDIRDEF tdp) : TDBASE(tdp)
{
To_File = tdp->Fn;
Init();
} // end of TDBDIR standard constructor
tp = new(g) TDBDIR(this);
tp->SetColumns(Columns);
return tp;
} // end of Clone
TDBDIR::TDBDIR(PSZ fpat) : TDBASE((PTABDEF)NULL)
{
To_File = fpat;
Init();
} // end of TDBDIR constructor
/***********************************************************************/
/* Initialize/get the components of the search file pattern. */
......@@ -674,18 +669,19 @@ PTDB TDBDIR::Clone(PTABS t)
char* TDBDIR::Path(PGLOBAL g)
{
PCATLG cat = PlgGetCatalog(g);
PTABDEF defp = (PTABDEF)To_Def;
#if defined(__WIN__)
if (!*Drive) {
PlugSetPath(Fpath, To_File, ((PTABDEF)To_Def)->GetPath());
PlugSetPath(Fpath, To_File, defp ? defp->GetPath() : NULL);
_splitpath(Fpath, Drive, Direc, Fname, Ftype);
} else
_makepath(Fpath, Drive, Direc, Fname, Ftype); // Usefull ???
_makepath(Fpath, Drive, Direc, Fname, Ftype); // Usefull for TDBSDR
return Fpath;
#else // !__WIN__
if (!Done) {
PlugSetPath(Fpath, To_File, ((PTABDEF)To_Def)->GetPath());
PlugSetPath(Fpath, To_File, defp ? defp->GetPath() : NULL);
_splitpath(Fpath, NULL, Direc, Fname, Ftype);
strcat(strcpy(Pattern, Fname), Ftype);
Done = true;
......@@ -709,23 +705,48 @@ PCOL TDBDIR::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
int TDBDIR::GetMaxSize(PGLOBAL g)
{
if (MaxSize < 0) {
int n = -1;
int rc, n = -1;
#if defined(__WIN__)
int h;
// Start searching files in the target directory.
h = _findfirst(Path(g), &FileData);
hSearch = FindFirstFile(Path(g), &FileData);
if (h != -1) {
for (n = 1;; n++)
if (_findnext(h, &FileData))
break;
if (hSearch == INVALID_HANDLE_VALUE) {
rc = GetLastError();
// Close the search handle.
_findclose(h);
} else
n = 0;
if (rc != ERROR_FILE_NOT_FOUND) {
char buf[512];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), 0, (LPTSTR)&buf, sizeof(buf), NULL);
sprintf(g->Message, MSG(BAD_FILE_HANDLE), buf);
return -1;
} // endif rc
return 0;
} // endif hSearch
while (true) {
if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
n++;
if (!FindNextFile(hSearch, &FileData)) {
rc = GetLastError();
if (rc != ERROR_NO_MORE_FILES) {
sprintf(g->Message, MSG(NEXT_FILE_ERROR), rc);
FindClose(hSearch);
return -1;
} // endif rc
break;
} // endif Next
} // endwhile
// Close the search handle.
FindClose(hSearch);
#else // !__WIN__
Path(g);
......@@ -791,30 +812,30 @@ int TDBDIR::ReadDB(PGLOBAL g)
int rc = RC_OK;
#if defined(__WIN__)
if (Hsearch == -1) {
if (hSearch == INVALID_HANDLE_VALUE) {
/*******************************************************************/
/* Start searching files in the target directory. The use of the */
/* Path function is required when called from TDBSDR. */
/*******************************************************************/
Hsearch = _findfirst(Path(g), &FileData);
hSearch = FindFirstFile(Path(g), &FileData);
if (Hsearch == -1)
if (hSearch == INVALID_HANDLE_VALUE)
rc = RC_EF;
else
iFile++;
} else {
if (_findnext(Hsearch, &FileData)) {
if (!FindNextFile(hSearch, &FileData)) {
// Restore file name and type pattern
_splitpath(To_File, NULL, NULL, Fname, Ftype);
rc = RC_EF;
} else
iFile++;
} // endif Hsearch
} // endif hSearch
if (rc == RC_OK)
_splitpath(FileData.name, NULL, NULL, Fname, Ftype);
_splitpath(FileData.cFileName, NULL, NULL, Fname, Ftype);
#else // !Win32
rc = RC_NF;
......@@ -878,8 +899,8 @@ void TDBDIR::CloseDB(PGLOBAL)
{
#if defined(__WIN__)
// Close the search handle.
_findclose(Hsearch);
Hsearch = -1;
FindClose(hSearch);
hSearch = INVALID_HANDLE_VALUE;
#else // !__WIN__
// Close the DIR handle
if (Dir) {
......@@ -907,6 +928,7 @@ DIRCOL::DIRCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ)
} // endif cprec
// Set additional DIR access method information for column.
Tdbp = (PTDBDIR)tdbp;
N = cdp->GetOffset();
} // end of DIRCOL constructor
......@@ -916,45 +938,73 @@ DIRCOL::DIRCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ)
/***********************************************************************/
DIRCOL::DIRCOL(DIRCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
{
N = col1->N;
Tdbp = (PTDBDIR)tdbp;
N = col1->N;
} // end of DIRCOL copy constructor
#if defined(__WIN__)
/***********************************************************************/
/* Retrieve time information from FileData. */
/***********************************************************************/
void DIRCOL::SetTimeValue(PGLOBAL g, FILETIME& ftime)
{
char tsp[24];
SYSTEMTIME stp;
if (FileTimeToSystemTime(&ftime, &stp)) {
sprintf(tsp, "%04d-%02d-%02d %02d:%02d:%02d",
stp.wYear, stp.wMonth, stp.wDay, stp.wHour, stp.wMinute, stp.wSecond);
if (Value->GetType() != TYPE_STRING) {
if (!Tdbp->Dvalp)
Tdbp->Dvalp = AllocateValue(g, TYPE_DATE, 20, 0, false,
"YYYY-MM-DD hh:mm:ss");
Tdbp->Dvalp->SetValue_psz(tsp);
Value->SetValue_pval(Tdbp->Dvalp);
} else
Value->SetValue_psz(tsp);
} else
Value->Reset();
} // end of SetTimeValue
#endif // __WIN__
/***********************************************************************/
/* ReadColumn: what this routine does is to access the information */
/* corresponding to this column and convert it to buffer type. */
/***********************************************************************/
void DIRCOL::ReadColumn(PGLOBAL g)
{
PTDBDIR tdbp = (PTDBDIR)To_Tdb;
{
if (trace)
htrc("DIR ReadColumn: col %s R%d use=%.4X status=%.4X type=%d N=%d\n",
Name, tdbp->GetTdb_No(), ColUse, Status, Buf_Type, N);
Name, Tdbp->GetTdb_No(), ColUse, Status, Buf_Type, N);
/*********************************************************************/
/* Retrieve the information corresponding to the column number. */
/*********************************************************************/
switch (N) {
#if defined(__WIN__)
case 0: Value->SetValue_psz(tdbp->Drive); break;
case 0: Value->SetValue_psz(Tdbp->Drive); break;
#endif // __WIN__
case 1: Value->SetValue_psz(tdbp->Direc); break;
case 2: Value->SetValue_psz(tdbp->Fname); break;
case 3: Value->SetValue_psz(tdbp->Ftype); break;
case 1: Value->SetValue_psz(Tdbp->Direc); break;
case 2: Value->SetValue_psz(Tdbp->Fname); break;
case 3: Value->SetValue_psz(Tdbp->Ftype); break;
#if defined(__WIN__)
case 4: Value->SetValue((int)tdbp->FileData.attrib); break;
case 5: Value->SetValue((int)tdbp->FileData.size); break;
case 6: Value->SetValue((int)tdbp->FileData.time_write); break;
case 7: Value->SetValue((int)tdbp->FileData.time_create); break;
case 8: Value->SetValue((int)tdbp->FileData.time_access); break;
case 4: Value->SetValue((int)Tdbp->FileData.dwFileAttributes); break;
case 5: Value->SetValue((int)Tdbp->FileData.nFileSizeLow); break;
case 6: SetTimeValue(g, Tdbp->FileData.ftLastWriteTime); break;
case 7: SetTimeValue(g, Tdbp->FileData.ftCreationTime); break;
case 8: SetTimeValue(g, Tdbp->FileData.ftLastAccessTime); break;
#else // !__WIN__
case 4: Value->SetValue((int)tdbp->Fileinfo.st_mode); break;
case 5: Value->SetValue((int)tdbp->Fileinfo.st_size); break;
case 6: Value->SetValue((int)tdbp->Fileinfo.st_mtime); break;
case 7: Value->SetValue((int)tdbp->Fileinfo.st_ctime); break;
case 8: Value->SetValue((int)tdbp->Fileinfo.st_atime); break;
case 9: Value->SetValue((int)tdbp->Fileinfo.st_uid); break;
case 10: Value->SetValue((int)tdbp->Fileinfo.st_gid); break;
case 4: Value->SetValue((int)Tdbp->Fileinfo.st_mode); break;
case 5: Value->SetValue((int)Tdbp->Fileinfo.st_size); break;
case 6: Value->SetValue((int)Tdbp->Fileinfo.st_mtime); break;
case 7: Value->SetValue((int)Tdbp->Fileinfo.st_ctime); break;
case 8: Value->SetValue((int)Tdbp->Fileinfo.st_atime); break;
case 9: Value->SetValue((int)Tdbp->Fileinfo.st_uid); break;
case 10: Value->SetValue((int)Tdbp->Fileinfo.st_gid); break;
#endif // !__WIN__
default:
sprintf(g->Message, MSG(INV_DIRCOL_OFST), N);
......@@ -969,25 +1019,6 @@ void DIRCOL::ReadColumn(PGLOBAL g)
/* ------------------------- Class TDBSDR ---------------------------- */
/***********************************************************************/
/* TABSDR copy constructors. */
/***********************************************************************/
TDBSDR::TDBSDR(PTDBSDR tdbp) : TDBDIR(tdbp)
{
Sub = tdbp->Sub;
} // end of TDBSDR copy constructor
// Method
PTDB TDBSDR::Clone(PTABS t)
{
PTDB tp;
PGLOBAL g = t->G; // Is this really useful ???
tp = new(g) TDBSDR(this);
tp->SetColumns(Columns);
return tp;
} // end of Clone
/***********************************************************************/
/* SDR GetMaxSize: returns the number of retrieved files. */
/***********************************************************************/
......@@ -1002,47 +1033,124 @@ int TDBSDR::GetMaxSize(PGLOBAL g)
} // end of GetMaxSize
/***********************************************************************/
/* SDR GetMaxSize: returns the number of retrieved files. */
/* SDR FindInDir: returns the number of retrieved files. */
/***********************************************************************/
int TDBSDR::FindInDir(PGLOBAL g)
{
int n = 0;
int rc, n = 0;
size_t m = strlen(Direc);
// Start searching files in the target directory.
#if defined(__WIN__)
int h = _findfirst(Path(g), &FileData);
HANDLE h;
if (h != -1) {
for (n = 1;; n++)
if (_findnext(h, &FileData))
break;
#if defined(PATHMATCHSPEC)
if (!*Drive)
Path(g);
// Close the search handle.
_findclose(h);
} // endif h
_makepath(Fpath, Drive, Direc, "*", "*");
// Now search files in sub-directories.
_makepath(Fpath, Drive, Direc, "*", "");
h = _findfirst(Fpath, &FileData);
h = FindFirstFile(Fpath, &FileData);
if (h != -1) {
while (true) {
if (FileData.attrib & _A_SUBDIR && *FileData.name != '.') {
// Look in the name sub-directory
strcat(strcat(Direc, FileData.name), "\\");
n += FindInDir(g);
Direc[m] = '\0'; // Restore path
} // endif SUBDIR
if (h == INVALID_HANDLE_VALUE) {
rc = GetLastError();
if (_findnext(h, &FileData))
break;
if (rc != ERROR_FILE_NOT_FOUND) {
char buf[512];
} // endwhile
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), 0, (LPTSTR)&buf, sizeof(buf), NULL);
sprintf(g->Message, MSG(BAD_FILE_HANDLE), buf);
return -1;
} // endif rc
// Close the search handle.
_findclose(h);
} // endif h
return 0;
} // endif h
while (true) {
if ((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
*FileData.cFileName != '.') {
// Look in the name sub-directory
strcat(strcat(Direc, FileData.cFileName), "/");
n += FindInDir(g);
Direc[m] = '\0'; // Restore path
} else if (PathMatchSpec(FileData.cFileName, Fpath))
n++;
if (!FindNextFile(h, &FileData)) {
rc = GetLastError();
if (rc != ERROR_NO_MORE_FILES) {
sprintf(g->Message, MSG(NEXT_FILE_ERROR), rc);
FindClose(h);
return -1;
} // endif rc
break;
} // endif Next
} // endwhile
#else // !PATHMATCHSPEC
h = FindFirstFile(Path(g), &FileData);
if (h == INVALID_HANDLE_VALUE) {
rc = GetLastError();
if (rc != ERROR_FILE_NOT_FOUND) {
char buf[512];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), 0, (LPTSTR)&buf, sizeof(buf), NULL);
sprintf(g->Message, MSG(BAD_FILE_HANDLE), buf);
return -1;
} // endif rc
return 0;
} // endif hSearch
while (true) {
n++;
if (!FindNextFile(h, &FileData)) {
rc = GetLastError();
if (rc != ERROR_NO_MORE_FILES) {
sprintf(g->Message, MSG(NEXT_FILE_ERROR), rc);
FindClose(h);
return -1;
} // endif rc
break;
} // endif Next
} // endwhile
// Now search files in sub-directories.
_makepath(Fpath, Drive, Direc, "*", ".");
h = FindFirstFile(Fpath, &FileData);
if (h != INVALID_HANDLE_VALUE) {
while (true) {
if ((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
*FileData.cFileName != '.') {
// Look in the name sub-directory
strcat(strcat(Direc, FileData.cFileName), "/");
n += FindInDir(g);
Direc[m] = '\0'; // Restore path
} // endif SUBDIR
if (!FindNextFile(h, &FileData))
break;
} // endwhile
} // endif h
#endif // !PATHMATCHSPEC
// Close the search handle.
FindClose(h);
#else // !__WIN__
int k;
DIR *dir = opendir(Direc);
......@@ -1094,7 +1202,7 @@ bool TDBSDR::OpenDB(PGLOBAL g)
Sub->Next = NULL;
Sub->Prev = NULL;
#if defined(__WIN__)
Sub->H = -1;
Sub->H = INVALID_HANDLE_VALUE;
Sub->Len = strlen(Direc);
#else // !__WIN__
Sub->D = NULL;
......@@ -1120,18 +1228,20 @@ int TDBSDR::ReadDB(PGLOBAL g)
// Are there more files in sub-directories
retry:
do {
if (Sub->H == -1) {
_makepath(Fpath, Drive, Direc, "*", "");
Sub->H = _findfirst(Fpath, &FileData);
} else if (_findnext(Sub->H, &FileData)) {
_findclose(Sub->H);
Sub->H = -1;
*FileData.name = '\0';
} // endif findnext
} while(*FileData.name == '.');
if (Sub->H == -1) {
if (Sub->H == INVALID_HANDLE_VALUE) {
_makepath(Fpath, Drive, Direc, "*", ".");
Sub->H = FindFirstFile(Fpath, &FileData);
} else if (!FindNextFile(Sub->H, &FileData)) {
FindClose(Sub->H);
Sub->H = INVALID_HANDLE_VALUE;
*FileData.cFileName= '\0';
break;
} // endif findnext
} while(!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|| *FileData.cFileName== '.');
if (Sub->H == INVALID_HANDLE_VALUE) {
// No more sub-directories. Are we in a sub-directory?
if (!Sub->Prev)
return rc; // No, all is finished
......@@ -1149,17 +1259,17 @@ int TDBSDR::ReadDB(PGLOBAL g)
sup = (PSUBDIR)PlugSubAlloc(g, NULL, sizeof(SUBDIR));
sup->Next = NULL;
sup->Prev = Sub;
sup->H = -1;
sup->H = INVALID_HANDLE_VALUE;
Sub->Next = sup;
} // endif Next
Sub = Sub->Next;
strcat(strcat(Direc, FileData.name), "\\");
strcat(strcat(Direc, FileData.cFileName), "/");
Sub->Len = strlen(Direc);
// Reset Hsearch used by TDBDIR::ReadDB
_findclose(Hsearch);
Hsearch = -1;
FindClose(hSearch);
hSearch = INVALID_HANDLE_VALUE;
goto again;
} // endif H
......
......@@ -69,6 +69,34 @@ class DllExport TDBMUL : public TDBASE {
int iFile; // Index of currently processed file
}; // end of class TDBMUL
#if 0
/***********************************************************************/
/* This is the MSD Access Method class declaration for files that are */
/* physically split in multiple files having the same format. */
/* This sub-class also include files of the sub-directories. */
/***********************************************************************/
class DllExport TDBMSD : public TDBMUL {
//friend class MULCOL;
public:
// Constructor
TDBMSD(PTDB tdbp) : TDBMUL(tdbp) {}
TDBMSD(PTDBMSD tdbp) : TDBMUL(tdbp) {}
// Implementation
virtual PTDB Duplicate(PGLOBAL g);
// Methods
virtual PTDB Clone(PTABS t);
bool InitFileNames(PGLOBAL g);
// Database routines
protected:
// Members
}; // end of class TDBMSD
#endif
/***********************************************************************/
/* Directory listing table. */
/***********************************************************************/
......@@ -101,18 +129,16 @@ class DllExport DIRDEF : public TABDEF { /* Directory listing table */
/***********************************************************************/
class TDBDIR : public TDBASE {
friend class DIRCOL;
public:
friend class TDBMUL;
public:
// Constructor
TDBDIR(PDIRDEF tdp);
TDBDIR(PTDBDIR tdbp);
TDBDIR(PSZ fpat);
// Implementation
virtual AMT GetAmType(void) {return TYPE_AM_DIR;}
virtual PTDB Duplicate(PGLOBAL g)
{return (PTDB)new(g) TDBDIR(this);}
// Methods
virtual PTDB Clone(PTABS t);
virtual int GetRecpos(void) {return iFile;}
// Database routines
......@@ -127,14 +153,16 @@ class TDBDIR : public TDBASE {
virtual void CloseDB(PGLOBAL g);
protected:
void Init(void);
char *Path(PGLOBAL g);
// Members
PSZ To_File; // Points to file search pathname
int iFile; // Index of currently retrieved file
#if defined(__WIN__)
_finddata_t FileData; // Find data structure
intptr_t Hsearch; // Search handle
PVAL Dvalp; // Used to retrieve file date values
WIN32_FIND_DATA FileData; // Find data structure
HANDLE hSearch; // Search handle
char Drive[_MAX_DRIVE]; // Drive name
#else // !__WIN__
struct stat Fileinfo; // File info structure
......@@ -158,17 +186,11 @@ class TDBDIR : public TDBASE {
/***********************************************************************/
class TDBSDR : public TDBDIR {
friend class DIRCOL;
friend class TDBMUL;
public:
// Constructors
TDBSDR(PDIRDEF tdp) : TDBDIR(tdp) {Sub = NULL;}
TDBSDR(PTDBSDR tdbp);
// Implementation
virtual PTDB Duplicate(PGLOBAL g)
{return (PTDB)new(g) TDBSDR(this);}
// Methods
virtual PTDB Clone(PTABS t);
TDBSDR(PSZ fpat) : TDBDIR(fpat) {Sub = NULL;}
// Database routines
virtual int GetMaxSize(PGLOBAL g);
......@@ -184,7 +206,7 @@ class TDBSDR : public TDBDIR {
struct _Sub_Dir *Next;
struct _Sub_Dir *Prev;
#if defined(__WIN__)
intptr_t H; // Search handle
HANDLE H; // Search handle
#else // !__WIN__
DIR *D;
#endif // !__WIN__
......@@ -214,7 +236,11 @@ class DIRCOL : public COLBLK {
protected:
// Default constructor not to be used
DIRCOL(void) {}
#if defined(__WIN__)
void SetTimeValue(PGLOBAL g, FILETIME& ftime);
#endif // __WIN__
// Members
PTDBDIR Tdbp; // To DIR table
int N; // Column number
}; // end of class DIRCOL
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment