Commit 2cb4b152 authored by Olivier Bertrand's avatar Olivier Bertrand

=====================================================================

This new CONNECT version 1.07 fully implements NOSQL support.
It allows working on JSON or XML data retrieved as REST query results
from all binary distributions of MariaDB when cpprestsdk is installed
and the GetRest library is available.
=====================================================================
- Make Rest available for MariaDB binary distributed versions.
  Change RestGet function so it can be called from a library.
  modified:   storage/connect/CMakeLists.txt
  modified:   storage/connect/restget.cpp
  modified:   storage/connect/tabrest.cpp

- Make column FLAG option available to discovery functions.
  modified:   storage/connect/ha_connect.cc
  modified:   storage/connect/plgdbsem.h

- Update CONNECT version number and date.
  modified:   storage/connect/ha_connect.cc

- Move OEMColumns function from mycat.cc to reldef.cpp.
  modified:   storage/connect/mycat.cc
  modified:   storage/connect/reldef.cpp

- Allocate tables as TABREF (was RELDEF)
  modified:   storage/connect/mycat.cc
  modified:   storage/connect/mycat.h

- Fix MDEV-20845 by commenting out TIMEOUT setting.
  modified:   storage/connect/myconn.cpp

- Call DefineAM before calling GetColCatInfo. Column offset
  is now based on record format instead of table type.
  The RECFM_VCT format was added.
  This enables tables to specify the record format and is
  useful in particular for OEM tables.
  modified:   storage/connect/plgdbsem.h
  modified:   storage/connect/reldef.cpp
  modified:   storage/connect/reldef.h
  modified:   storage/connect/tabdos.cpp
  modified:   storage/connect/tabdos.h
  modified:   storage/connect/tabfix.cpp
  modified:   storage/connect/tabfmt.cpp
  modified:   storage/connect/tabmysql.cpp
  modified:   storage/connect/tabutil.cpp
  modified:   storage/connect/tabutil.h
  modified:   storage/connect/tabvct.cpp
  modified:   storage/connect/xindex.cpp
parent a00b7131
...@@ -312,6 +312,8 @@ OPTION(CONNECT_WITH_REST "Compile CONNECT storage engine with REST support" ON) ...@@ -312,6 +312,8 @@ OPTION(CONNECT_WITH_REST "Compile CONNECT storage engine with REST support" ON)
IF(CONNECT_WITH_REST) IF(CONNECT_WITH_REST)
MESSAGE(STATUS "=====> REST support is ON") MESSAGE(STATUS "=====> REST support is ON")
SET(CONNECT_SOURCES ${CONNECT_SOURCES} tabrest.cpp tabrest.h)
add_definitions(-DREST_SUPPORT)
FIND_PACKAGE(cpprestsdk) FIND_PACKAGE(cpprestsdk)
IF (cpprestsdk_FOUND) IF (cpprestsdk_FOUND)
MESSAGE(STATUS "=====> cpprestsdk found") MESSAGE(STATUS "=====> cpprestsdk found")
...@@ -326,8 +328,8 @@ IF(CONNECT_WITH_REST) ...@@ -326,8 +328,8 @@ IF(CONNECT_WITH_REST)
# Comment it out if not needed depending on your cpprestsdk installation. # Comment it out if not needed depending on your cpprestsdk installation.
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd") SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
ENDIF(UNIX) ENDIF(UNIX)
SET(CONNECT_SOURCES ${CONNECT_SOURCES} tabrest.cpp restget.cpp tabrest.h) SET(CONNECT_SOURCES ${CONNECT_SOURCES} restget.cpp)
add_definitions(-DREST_SUPPORT) add_definitions(-DREST_SOURCE)
ELSE(NOT cpprestsdk_FOUND) ELSE(NOT cpprestsdk_FOUND)
MESSAGE(STATUS "=====> cpprestsdk package not found") MESSAGE(STATUS "=====> cpprestsdk package not found")
ENDIF (cpprestsdk_FOUND) ENDIF (cpprestsdk_FOUND)
......
...@@ -170,9 +170,9 @@ ...@@ -170,9 +170,9 @@
#define JSONMAX 10 // JSON Default max grp size #define JSONMAX 10 // JSON Default max grp size
extern "C" { extern "C" {
char version[]= "Version 1.06.0010 June 01, 2019"; char version[]= "Version 1.07.0001 November 12, 2019";
#if defined(__WIN__) #if defined(__WIN__)
char compver[]= "Version 1.06.0010 " __DATE__ " " __TIME__; char compver[]= "Version 1.07.0001 " __DATE__ " " __TIME__;
char slash= '\\'; char slash= '\\';
#else // !__WIN__ #else // !__WIN__
char slash= '/'; char slash= '/';
...@@ -6062,7 +6062,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -6062,7 +6062,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
} // endif !nblin } // endif !nblin
for (i= 0; !rc && i < qrp->Nblin; i++) { for (i= 0; !rc && i < qrp->Nblin; i++) {
typ= len= prec= dec= 0; typ= len= prec= dec= flg= 0;
tm= NOT_NULL_FLAG; tm= NOT_NULL_FLAG;
cnm= (char*)"noname"; cnm= (char*)"noname";
dft= xtra= key= fmt= tn= NULL; dft= xtra= key= fmt= tn= NULL;
...@@ -6102,6 +6102,9 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -6102,6 +6102,9 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
if (crp->Kdata->GetIntValue(i)) if (crp->Kdata->GetIntValue(i))
tm= 0; // Nullable tm= 0; // Nullable
break;
case FLD_FLAG:
flg = crp->Kdata->GetIntValue(i);
break; break;
case FLD_FORMAT: case FLD_FORMAT:
fmt= (crp->Kdata) ? crp->Kdata->GetCharValue(i) : NULL; fmt= (crp->Kdata) ? crp->Kdata->GetCharValue(i) : NULL;
...@@ -6233,7 +6236,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -6233,7 +6236,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
// Now add the field // Now add the field
if (add_field(&sql, cnm, typ, prec, dec, key, tm, rem, dft, xtra, if (add_field(&sql, cnm, typ, prec, dec, key, tm, rem, dft, xtra,
fmt, 0, dbf, v)) fmt, flg, dbf, v))
rc= HA_ERR_OUT_OF_MEM; rc= HA_ERR_OUT_OF_MEM;
} // endfor i } // endfor i
...@@ -7379,14 +7382,14 @@ maria_declare_plugin(connect) ...@@ -7379,14 +7382,14 @@ maria_declare_plugin(connect)
&connect_storage_engine, &connect_storage_engine,
"CONNECT", "CONNECT",
"Olivier Bertrand", "Olivier Bertrand",
"Management of External Data (SQL/NOSQL/MED), including many file formats", "Management of External Data (SQL/NOSQL/MED), including Rest query results",
PLUGIN_LICENSE_GPL, PLUGIN_LICENSE_GPL,
connect_init_func, /* Plugin Init */ connect_init_func, /* Plugin Init */
connect_done_func, /* Plugin Deinit */ connect_done_func, /* Plugin Deinit */
0x0106, /* version number (1.06) */ 0x0107, /* version number (1.07) */
NULL, /* status variables */ NULL, /* status variables */
connect_system_variables, /* system variables */ connect_system_variables, /* system variables */
"1.06.0010", /* string version */ "1.07.0001", /* string version */
MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
} }
maria_declare_plugin_end; maria_declare_plugin_end;
...@@ -95,7 +95,7 @@ ...@@ -95,7 +95,7 @@
#endif // ZIP_SUPPORT #endif // ZIP_SUPPORT
#if defined(REST_SUPPORT) #if defined(REST_SUPPORT)
#include "tabrest.h" #include "tabrest.h"
#endif // Rest_SUPPORT #endif // REST_SUPPORT
#include "mycat.h" #include "mycat.h"
/***********************************************************************/ /***********************************************************************/
...@@ -107,7 +107,6 @@ extern "C" HINSTANCE s_hModule; // Saved module handle ...@@ -107,7 +107,6 @@ extern "C" HINSTANCE s_hModule; // Saved module handle
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT) #if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
bool MongoEnabled(void); bool MongoEnabled(void);
#endif // JAVA_SUPPORT || CMGO_SUPPORT #endif // JAVA_SUPPORT || CMGO_SUPPORT
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
/***********************************************************************/ /***********************************************************************/
/* Get the plugin directory. */ /* Get the plugin directory. */
...@@ -349,100 +348,6 @@ uint GetFuncID(const char *func) ...@@ -349,100 +348,6 @@ uint GetFuncID(const char *func)
return fnc; return fnc;
} // end of GetFuncID } // end of GetFuncID
/***********************************************************************/
/* OEMColumn: Get table column info for an OEM table. */
/***********************************************************************/
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info)
{
typedef PQRYRES (__stdcall *XCOLDEF) (PGLOBAL, void*, char*, char*, bool);
const char *module, *subtype;
char c, soname[_MAX_PATH], getname[40] = "Col";
#if defined(__WIN__)
HANDLE hdll; /* Handle to the external DLL */
#else // !__WIN__
void *hdll; /* Handle for the loaded shared library */
#endif // !__WIN__
XCOLDEF coldef = NULL;
PQRYRES qrp = NULL;
module = topt->module;
subtype = topt->subtype;
if (!module || !subtype)
return NULL;
/*********************************************************************/
/* Ensure that the .dll doesn't have a path. */
/* This is done to ensure that only approved dll from the system */
/* directories are used (to make this even remotely secure). */
/*********************************************************************/
if (check_valid_path(module, strlen(module))) {
strcpy(g->Message, "Module cannot contain a path");
return NULL;
} else
PlugSetPath(soname, module, GetPluginDir());
// The exported name is always in uppercase
for (int i = 0; ; i++) {
c = subtype[i];
getname[i + 3] = toupper(c);
if (!c) break;
} // endfor i
#if defined(__WIN__)
// Load the Dll implementing the table
if (!(hdll = LoadLibrary(soname))) {
char buf[256];
DWORD rc = GetLastError();
sprintf(g->Message, MSG(DLL_LOAD_ERROR), rc, soname);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)buf, sizeof(buf), NULL);
strcat(strcat(g->Message, ": "), buf);
return NULL;
} // endif hDll
// Get the function returning an instance of the external DEF class
if (!(coldef = (XCOLDEF)GetProcAddress((HINSTANCE)hdll, getname))) {
sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), getname);
FreeLibrary((HMODULE)hdll);
return NULL;
} // endif coldef
#else // !__WIN__
const char *error = NULL;
// Load the desired shared library
if (!(hdll = dlopen(soname, RTLD_LAZY))) {
error = dlerror();
sprintf(g->Message, MSG(SHARED_LIB_ERR), soname, SVP(error));
return NULL;
} // endif Hdll
// Get the function returning an instance of the external DEF class
if (!(coldef = (XCOLDEF)dlsym(hdll, getname))) {
error = dlerror();
sprintf(g->Message, MSG(GET_FUNC_ERR), getname, SVP(error));
dlclose(hdll);
return NULL;
} // endif coldef
#endif // !__WIN__
// Just in case the external Get function does not set error messages
sprintf(g->Message, "Error getting column info from %s", subtype);
// Get the table column definition
qrp = coldef(g, topt, tab, db, info);
#if defined(__WIN__)
FreeLibrary((HMODULE)hdll);
#else // !__WIN__
dlclose(hdll);
#endif // !__WIN__
return qrp;
} // end of OEMColumns
/* ------------------------- Class CATALOG --------------------------- */ /* ------------------------- Class CATALOG --------------------------- */
/***********************************************************************/ /***********************************************************************/
...@@ -483,10 +388,10 @@ void MYCAT::Reset(void) ...@@ -483,10 +388,10 @@ void MYCAT::Reset(void)
/* GetTableDesc: retrieve a table descriptor. */ /* GetTableDesc: retrieve a table descriptor. */
/* Look for a table descriptor matching the name and type. */ /* Look for a table descriptor matching the name and type. */
/***********************************************************************/ /***********************************************************************/
PRELDEF MYCAT::GetTableDesc(PGLOBAL g, PTABLE tablep, PTABDEF MYCAT::GetTableDesc(PGLOBAL g, PTABLE tablep,
LPCSTR type, PRELDEF *) LPCSTR type, PRELDEF *)
{ {
PRELDEF tdp= NULL; PTABDEF tdp= NULL;
if (trace(1)) if (trace(1))
htrc("GetTableDesc: name=%s am=%s\n", tablep->GetName(), SVP(type)); htrc("GetTableDesc: name=%s am=%s\n", tablep->GetName(), SVP(type));
...@@ -507,12 +412,12 @@ PRELDEF MYCAT::GetTableDesc(PGLOBAL g, PTABLE tablep, ...@@ -507,12 +412,12 @@ PRELDEF MYCAT::GetTableDesc(PGLOBAL g, PTABLE tablep,
/* MakeTableDesc: make a table/view description. */ /* MakeTableDesc: make a table/view description. */
/* Note: caller must check if name already exists before calling it. */ /* Note: caller must check if name already exists before calling it. */
/***********************************************************************/ /***********************************************************************/
PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am) PTABDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
{ {
TABTYPE tc; TABTYPE tc;
LPCSTR name= (PSZ)PlugDup(g, tablep->GetName()); LPCSTR name= (PSZ)PlugDup(g, tablep->GetName());
LPCSTR schema= (PSZ)PlugDup(g, tablep->GetSchema()); LPCSTR schema= (PSZ)PlugDup(g, tablep->GetSchema());
PRELDEF tdp= NULL; PTABDEF tdp= NULL;
if (trace(1)) if (trace(1))
htrc("MakeTableDesc: name=%s schema=%s am=%s\n", htrc("MakeTableDesc: name=%s schema=%s am=%s\n",
...@@ -580,8 +485,8 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am) ...@@ -580,8 +485,8 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
} // endswitch } // endswitch
// Do make the table/view definition // Do make the table/view definition
if (tdp && tdp->Define(g, this, name, schema, am)) if (tdp && tdp->Define(g, this, name, schema, am))
tdp= NULL; tdp = NULL;
if (trace(1)) if (trace(1))
htrc("Table %s made\n", am); htrc("Table %s made\n", am);
...@@ -594,7 +499,7 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am) ...@@ -594,7 +499,7 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
/***********************************************************************/ /***********************************************************************/
PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode, LPCSTR type) PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode, LPCSTR type)
{ {
PRELDEF tdp; PTABDEF tdp;
PTDB tdbp= NULL; PTDB tdbp= NULL;
// LPCSTR name= tablep->GetName(); // LPCSTR name= tablep->GetName();
......
...@@ -102,14 +102,14 @@ class MYCAT : public CATALOG { ...@@ -102,14 +102,14 @@ class MYCAT : public CATALOG {
// Methods // Methods
void Reset(void); void Reset(void);
bool StoreIndex(PGLOBAL, PTABDEF) {return false;} // Temporary bool StoreIndex(PGLOBAL, PTABDEF) {return false;} // Temporary
PRELDEF GetTableDesc(PGLOBAL g, PTABLE tablep, PTABDEF GetTableDesc(PGLOBAL g, PTABLE tablep,
LPCSTR type, PRELDEF *prp = NULL); LPCSTR type, PRELDEF *prp = NULL);
PTDB GetTable(PGLOBAL g, PTABLE tablep, PTDB GetTable(PGLOBAL g, PTABLE tablep,
MODE mode = MODE_READ, LPCSTR type = NULL); MODE mode = MODE_READ, LPCSTR type = NULL);
void ClearDB(PGLOBAL g); void ClearDB(PGLOBAL g);
protected: protected:
PRELDEF MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am); PTABDEF MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am);
// Members // Members
ha_connect *Hc; // The Connect handler ha_connect *Hc; // The Connect handler
......
...@@ -472,7 +472,7 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db, ...@@ -472,7 +472,7 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
int pt, const char *csname) int pt, const char *csname)
{ {
const char *pipe = NULL; const char *pipe = NULL;
uint cto = 10, nrt = 20; //uint cto = 10, nrt = 20;
my_bool my_true= 1; my_bool my_true= 1;
m_DB = mysql_init(NULL); m_DB = mysql_init(NULL);
...@@ -485,11 +485,11 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db, ...@@ -485,11 +485,11 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
if (trace(1)) if (trace(1))
htrc("MYSQLC Open: m_DB=%.4X size=%d\n", m_DB, (int)sizeof(*m_DB)); htrc("MYSQLC Open: m_DB=%.4X size=%d\n", m_DB, (int)sizeof(*m_DB));
// Removed to do like FEDERATED do // Removed to do like FEDERATED does
//mysql_options(m_DB, MYSQL_READ_DEFAULT_GROUP, "client-mariadb"); //mysql_options(m_DB, MYSQL_READ_DEFAULT_GROUP, "client-mariadb");
mysql_options(m_DB, MYSQL_OPT_USE_REMOTE_CONNECTION, NULL); //mysql_options(m_DB, MYSQL_OPT_USE_REMOTE_CONNECTION, NULL);
mysql_options(m_DB, MYSQL_OPT_CONNECT_TIMEOUT, &cto); //mysql_options(m_DB, MYSQL_OPT_CONNECT_TIMEOUT, &cto);
mysql_options(m_DB, MYSQL_OPT_READ_TIMEOUT, &nrt); //mysql_options(m_DB, MYSQL_OPT_READ_TIMEOUT, &nrt);
//mysql_options(m_DB, MYSQL_OPT_WRITE_TIMEOUT, ...); //mysql_options(m_DB, MYSQL_OPT_WRITE_TIMEOUT, ...);
#if defined(__WIN__) #if defined(__WIN__)
......
...@@ -149,16 +149,22 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */ ...@@ -149,16 +149,22 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_MGO = 194, /* MGO access method type no */ TYPE_AM_MGO = 194, /* MGO access method type no */
TYPE_AM_OUT = 200}; /* Output relations (storage) */ TYPE_AM_OUT = 200}; /* Output relations (storage) */
enum RECFM {RECFM_NAF = -2, /* Not a file */ enum RECFM {RECFM_DFLT = 0, /* Default table type */
RECFM_OEM = -1, /* OEM file access method */ RECFM_NAF = 1, /* Not a file table */
RECFM_VAR = 0, /* Varying length DOS files */ RECFM_OEM = 2, /* OEM table */
RECFM_FIX = 1, /* Fixed length DOS files */ RECFM_VAR = 3, /* Varying length DOS files */
RECFM_BIN = 2, /* Binary DOS files (also fixed) */ RECFM_FIX = 4, /* Fixed length DOS files */
RECFM_VCT = 3, /* VCT formatted files */ RECFM_BIN = 5, /* Binary DOS files (also fixed) */
RECFM_ODBC = 4, /* Table accessed via ODBC */ RECFM_DBF = 6, /* DBase formatted file */
RECFM_JDBC = 5, /* Table accessed via JDBC */ RECFM_CSV = 7, /* CSV file */
RECFM_PLG = 6, /* Table accessed via PLGconn */ RECFM_FMT = 8, /* FMT formatted file */
RECFM_DBF = 7}; /* DBase formatted file */ RECFM_VCT = 9, /* VCT formatted files */
RECFM_XML = 10, /* XML formatted files */
RECFM_JASON = 11, /* JASON formatted files */
RECFM_DIR = 12, /* DIR table */
RECFM_ODBC = 13, /* Table accessed via ODBC */
RECFM_JDBC = 14, /* Table accessed via JDBC */
RECFM_PLG = 15}; /* Table accessed via PLGconn */
enum MISC {DB_TABNO = 1, /* DB routines in Utility Table */ enum MISC {DB_TABNO = 1, /* DB routines in Utility Table */
MAX_MULT_KEY = 10, /* Max multiple key number */ MAX_MULT_KEY = 10, /* Max multiple key number */
...@@ -537,7 +543,8 @@ enum XFLD {FLD_NO = 0, /* Not a field definition item */ ...@@ -537,7 +543,8 @@ enum XFLD {FLD_NO = 0, /* Not a field definition item */
FLD_FORMAT = 16, /* Field format */ FLD_FORMAT = 16, /* Field format */
FLD_CAT = 17, /* Table catalog */ FLD_CAT = 17, /* Table catalog */
FLD_SCHEM = 18, /* Table schema */ FLD_SCHEM = 18, /* Table schema */
FLD_TABNAME = 19}; /* Column Table name */ FLD_TABNAME = 19, /* Column Table name */
FLD_FLAG = 20}; /* Field flag (CONNECT specific) */
/***********************************************************************/ /***********************************************************************/
/* Result of last SQL noconv query. */ /* Result of last SQL noconv query. */
......
/************* RelDef CPP Program Source Code File (.CPP) **************/ /************* RelDef CPP Program Source Code File (.CPP) **************/
/* PROGRAM NAME: RELDEF */ /* PROGRAM NAME: RELDEF */
/* ------------- */ /* ------------- */
/* Version 1.6 */ /* Version 1.7 */
/* */ /* */
/* COPYRIGHT: */ /* COPYRIGHT: */
/* ---------- */ /* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 2004-2016 */ /* (C) Copyright to the author Olivier BERTRAND 2004-2019 */
/* */ /* */
/* WHAT THIS PROGRAM DOES: */ /* WHAT THIS PROGRAM DOES: */
/* ----------------------- */ /* ----------------------- */
...@@ -61,6 +61,102 @@ extern handlerton *connect_hton; ...@@ -61,6 +61,102 @@ extern handlerton *connect_hton;
/***********************************************************************/ /***********************************************************************/
USETEMP UseTemp(void); USETEMP UseTemp(void);
char *GetPluginDir(void); char *GetPluginDir(void);
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info);
/***********************************************************************/
/* OEMColumns: Get table column info for an OEM table. */
/***********************************************************************/
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info)
{
typedef PQRYRES(__stdcall* XCOLDEF) (PGLOBAL, void*, char*, char*, bool);
const char* module, * subtype;
char c, soname[_MAX_PATH], getname[40] = "Col";
#if defined(__WIN__)
HANDLE hdll; /* Handle to the external DLL */
#else // !__WIN__
void* hdll; /* Handle for the loaded shared library */
#endif // !__WIN__
XCOLDEF coldef = NULL;
PQRYRES qrp = NULL;
module = topt->module;
subtype = topt->subtype;
if (!module || !subtype)
return NULL;
/*********************************************************************/
/* Ensure that the .dll doesn't have a path. */
/* This is done to ensure that only approved dll from the system */
/* directories are used (to make this even remotely secure). */
/*********************************************************************/
if (check_valid_path(module, strlen(module))) {
strcpy(g->Message, "Module cannot contain a path");
return NULL;
}
else
PlugSetPath(soname, module, GetPluginDir());
// The exported name is always in uppercase
for (int i = 0; ; i++) {
c = subtype[i];
getname[i + 3] = toupper(c);
if (!c) break;
} // endfor i
#if defined(__WIN__)
// Load the Dll implementing the table
if (!(hdll = LoadLibrary(soname))) {
char buf[256];
DWORD rc = GetLastError();
sprintf(g->Message, MSG(DLL_LOAD_ERROR), rc, soname);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)buf, sizeof(buf), NULL);
strcat(strcat(g->Message, ": "), buf);
return NULL;
} // endif hDll
// Get the function returning an instance of the external DEF class
if (!(coldef = (XCOLDEF)GetProcAddress((HINSTANCE)hdll, getname))) {
sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), getname);
FreeLibrary((HMODULE)hdll);
return NULL;
} // endif coldef
#else // !__WIN__
const char* error = NULL;
// Load the desired shared library
if (!(hdll = dlopen(soname, RTLD_LAZY))) {
error = dlerror();
sprintf(g->Message, MSG(SHARED_LIB_ERR), soname, SVP(error));
return NULL;
} // endif Hdll
// Get the function returning an instance of the external DEF class
if (!(coldef = (XCOLDEF)dlsym(hdll, getname))) {
error = dlerror();
sprintf(g->Message, MSG(GET_FUNC_ERR), getname, SVP(error));
dlclose(hdll);
return NULL;
} // endif coldef
#endif // !__WIN__
// Just in case the external Get function does not set error messages
sprintf(g->Message, "Error getting column info from %s", subtype);
// Get the table column definition
qrp = coldef(g, topt, tab, db, info);
#if defined(__WIN__)
FreeLibrary((HMODULE)hdll);
#else // !__WIN__
dlclose(hdll);
#endif // !__WIN__
return qrp;
} // end of OEMColumns
/* --------------------------- Class RELDEF -------------------------- */ /* --------------------------- Class RELDEF -------------------------- */
...@@ -208,6 +304,7 @@ TABDEF::TABDEF(void) ...@@ -208,6 +304,7 @@ TABDEF::TABDEF(void)
{ {
Schema = NULL; Schema = NULL;
Desc = NULL; Desc = NULL;
Recfm = RECFM_DFLT;
Catfunc = FNC_NO; Catfunc = FNC_NO;
Card = 0; Card = 0;
Elemt = 0; Elemt = 0;
...@@ -220,12 +317,41 @@ TABDEF::TABDEF(void) ...@@ -220,12 +317,41 @@ TABDEF::TABDEF(void)
csname = NULL; csname = NULL;
} // end of TABDEF constructor } // end of TABDEF constructor
/***********************************************************************/
/* Return the table format. */
/***********************************************************************/
RECFM TABDEF::GetTableFormat(const char* type)
{
RECFM recfm = Recfm;
if (recfm == RECFM_DFLT) {
// Default format depends on the table type
TABTYPE tc = (Catfunc == FNC_NO) ? GetTypeID(type) : TAB_PRX;
switch (tc) {
case TAB_DOS: recfm = RECFM_VAR; break;
case TAB_CSV: recfm = RECFM_CSV; break;
case TAB_FMT: recfm = RECFM_FMT; break;
case TAB_FIX: recfm = RECFM_FIX; break;
case TAB_BIN: recfm = RECFM_BIN; break;
case TAB_VEC: recfm = RECFM_VCT; break;
case TAB_DBF: recfm = RECFM_DBF; break;
case TAB_XML: recfm = RECFM_XML; break;
case TAB_DIR: recfm = RECFM_DIR; break;
default: recfm = RECFM_NAF; break;
} // endswitch type
} // endif recfm
return recfm;
} // end of GetTableFormat
/***********************************************************************/ /***********************************************************************/
/* Define: initialize the table definition block from XDB file. */ /* Define: initialize the table definition block from XDB file. */
/***********************************************************************/ /***********************************************************************/
bool TABDEF::Define(PGLOBAL g, PCATLG cat, bool TABDEF::Define(PGLOBAL g, PCATLG cat,
LPCSTR name, LPCSTR schema, LPCSTR am) LPCSTR name, LPCSTR schema, LPCSTR am)
{ {
int poff = 0; int poff = 0;
Hc = ((MYCAT*)cat)->GetHandler(); Hc = ((MYCAT*)cat)->GetHandler();
...@@ -243,13 +369,17 @@ bool TABDEF::Define(PGLOBAL g, PCATLG cat, ...@@ -243,13 +369,17 @@ bool TABDEF::Define(PGLOBAL g, PCATLG cat,
NULL; NULL;
csname = GetStringCatInfo(g, "Table_charset", NULL); csname = GetStringCatInfo(g, "Table_charset", NULL);
// Get The column definitions // Do the definition of AM specific fields
if ((poff = GetColCatInfo(g)) < 0) if (DefineAM(g, am, 0))
return true; return true;
// Do the definition of AM specific fields // Get The column definitions
return DefineAM(g, am, poff); if (stricmp(am, "OEM") && GetColCatInfo(g) < 0)
} // end of Define return true;
Hc->tshp = NULL; // TO BE CHECKED
return false;
} // end of Define
/***********************************************************************/ /***********************************************************************/
/* This function returns the database data path. */ /* This function returns the database data path. */
...@@ -264,71 +394,71 @@ PCSZ TABDEF::GetPath(void) ...@@ -264,71 +394,71 @@ PCSZ TABDEF::GetPath(void)
/***********************************************************************/ /***********************************************************************/
int TABDEF::GetColCatInfo(PGLOBAL g) int TABDEF::GetColCatInfo(PGLOBAL g)
{ {
char *type= GetStringCatInfo(g, "Type", "*"); char *type = GetStringCatInfo(g, "Type", "*");
char c, fty, eds; char c, fty, eds;
int i, n, loff, poff, nof, nlg; int i, n, loff, poff, nof, nlg;
void *field= NULL; void *field = NULL;
TABTYPE tc; RECFM trf;
PCOLDEF cdp, lcdp= NULL, tocols= NULL; PCOLDEF cdp, lcdp = NULL, tocols= NULL;
PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO)); PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO));
memset(pcf, 0, sizeof(COLINFO)); memset(pcf, 0, sizeof(COLINFO));
// Get a unique char identifier for type // Get the table format
tc= (Catfunc == FNC_NO) ? GetTypeID(type) : TAB_PRX; trf = GetTableFormat(type);
// Take care of the column definitions // Take care of the column definitions
i= poff= nof= nlg= 0; i= poff= nof= nlg= 0;
#if defined(__WIN__) #if defined(__WIN__)
// Offsets of HTML and DIR tables start from 0, DBF at 1 // Offsets of HTML and DIR tables start from 0, DBF at 1
loff= (tc == TAB_DBF) ? 1 : (tc == TAB_XML || tc == TAB_DIR) ? -1 : 0; loff= (trf == RECFM_DBF) ? 1 : (trf == RECFM_XML || trf == RECFM_DIR) ? -1 : 0;
#else // !__WIN__ #else // !__WIN__
// Offsets of HTML tables start from 0, DIR and DBF at 1 // Offsets of HTML tables start from 0, DIR and DBF at 1
loff = (tc == TAB_DBF || tc == TAB_DIR) ? 1 : (tc == TAB_XML) ? -1 : 0; loff = (trf == RECFM_DBF || trf == RECFM_DIR) ? 1 : (trf == RECFM_XML) ? -1 : 0;
#endif // !__WIN__ #endif // !__WIN__
while (true) { while (true) {
// Default Offset depends on table type // Default Offset depends on table format
switch (tc) { switch (trf ) {
case TAB_DOS: case RECFM_VAR:
case TAB_FIX: case RECFM_FIX:
case TAB_BIN: case RECFM_BIN:
case TAB_VEC: case RECFM_VCT:
case TAB_DBF: case RECFM_DBF:
poff= loff + nof; // Default next offset poff= loff + nof; // Default next offset
nlg= MY_MAX(nlg, poff); // Default lrecl nlg= MY_MAX(nlg, poff); // Default lrecl
break; break;
case TAB_CSV: case RECFM_CSV:
case TAB_FMT: case RECFM_FMT:
nlg+= nof; nlg+= nof;
case TAB_DIR: case RECFM_DIR:
case TAB_XML: case RECFM_XML:
poff= loff + (pcf->Flags & U_VIRTUAL ? 0 : 1); poff= loff + (pcf->Flags & U_VIRTUAL ? 0 : 1);
break; break;
case TAB_INI: //case RECFM_INI:
case TAB_MAC: //case RECFM_MAC:
case TAB_TBL: //case RECFM_TBL:
case TAB_XCL: //case RECFM_XCL:
case TAB_OCCUR: //case RECFM_OCCUR:
case TAB_PRX: //case RECFM_PRX:
case TAB_OEM: case RECFM_OEM:
poff = 0; // Offset represents an independant flag poff = 0; // Offset represents an independant flag
break; break;
default: // VCT PLG ODBC JDBC MYSQL WMI... default: // PLG ODBC JDBC MYSQL WMI...
poff = 0; // NA poff = 0; // NA
break; break;
} // endswitch tc } // endswitch trf
// do { // do {
field= Hc->GetColumnOption(g, field, pcf); field= Hc->GetColumnOption(g, field, pcf);
// } while (field && (*pcf->Name =='*' /*|| pcf->Flags & U_VIRTUAL*/)); // } while (field && (*pcf->Name =='*' /*|| pcf->Flags & U_VIRTUAL*/));
if (tc == TAB_DBF && pcf->Type == TYPE_DATE && !pcf->Datefmt) { if (trf == RECFM_DBF && pcf->Type == TYPE_DATE && !pcf->Datefmt) {
// DBF date format defaults to 'YYYMMDD' // DBF date format defaults to 'YYYMMDD'
pcf->Datefmt= "YYYYMMDD"; pcf->Datefmt= "YYYYMMDD";
pcf->Length= 8; pcf->Length= 8;
} // endif tc } // endif trf
if (!field) if (!field)
break; break;
...@@ -341,10 +471,10 @@ int TABDEF::GetColCatInfo(PGLOBAL g) ...@@ -341,10 +471,10 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
else else
loff= cdp->GetOffset(); loff= cdp->GetOffset();
switch (tc) { switch (trf ) {
case TAB_VEC: case RECFM_VCT:
cdp->SetOffset(0); // Not to have shift cdp->SetOffset(0); // Not to have shift
case TAB_BIN: case RECFM_BIN:
// BIN/VEC are packed by default // BIN/VEC are packed by default
if (nof) { if (nof) {
// Field width is the internal representation width // Field width is the internal representation width
...@@ -395,7 +525,7 @@ int TABDEF::GetColCatInfo(PGLOBAL g) ...@@ -395,7 +525,7 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
default: default:
break; break;
} // endswitch tc } // endswitch trf
if (lcdp) if (lcdp)
lcdp->SetNext(cdp); lcdp->SetNext(cdp);
...@@ -413,21 +543,15 @@ int TABDEF::GetColCatInfo(PGLOBAL g) ...@@ -413,21 +543,15 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
if (GetDefType() == TYPE_AM_DOS) { if (GetDefType() == TYPE_AM_DOS) {
int ending, recln= 0; int ending, recln= 0;
// Was commented because sometimes ending is 0 even when ending = Hc->GetIntegerOption("Ending");
// not specified (for instance if quoted is specified)
// if ((ending= Hc->GetIntegerOption("Ending")) < 0) {
if ((ending= Hc->GetIntegerOption("Ending")) <= 0) {
ending= (tc == TAB_BIN || tc == TAB_VEC) ? 0 : CRLF;
Hc->SetIntegerOption("Ending", ending);
} // endif ending
// Calculate the default record size // Calculate the default record size
switch (tc) { switch (trf ) {
case TAB_FIX: case RECFM_FIX:
case TAB_BIN: case RECFM_BIN:
recln= nlg + ending; // + length of line ending recln= nlg + ending; // + length of line ending
break; break;
case TAB_VEC: case RECFM_VCT:
recln= nlg; recln= nlg;
// if ((k= (pak < 0) ? 8 : pak) > 1) // if ((k= (pak < 0) ? 8 : pak) > 1)
...@@ -436,18 +560,18 @@ int TABDEF::GetColCatInfo(PGLOBAL g) ...@@ -436,18 +560,18 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
// recln= ((recln + k - 1) / k) * k; // recln= ((recln + k - 1) / k) * k;
break; break;
case TAB_DOS: case RECFM_VAR:
case TAB_DBF: case RECFM_DBF:
recln= nlg; recln= nlg;
break; break;
case TAB_CSV: case RECFM_CSV:
case TAB_FMT: case RECFM_FMT:
// The number of separators (assuming an extra one can exist) // The number of separators (assuming an extra one can exist)
// recln= poff * ((qotd) ? 3 : 1); to be investigated // recln= poff * ((qotd) ? 3 : 1); to be investigated
recln= nlg + poff * 3; // To be safe recln= nlg + poff * 3; // To be safe
default: default:
break; break;
} // endswitch tc } // endswitch trf
// lrecl must be at least recln to avoid buffer overflow // lrecl must be at least recln to avoid buffer overflow
if (trace(1)) if (trace(1))
...@@ -461,7 +585,7 @@ int TABDEF::GetColCatInfo(PGLOBAL g) ...@@ -461,7 +585,7 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
if (trace(1)) if (trace(1))
htrc("Lrecl set to %d\n", recln); htrc("Lrecl set to %d\n", recln);
} // endif Lrecl } // endif TYPE
// Attach the column definition to the tabdef // Attach the column definition to the tabdef
SetCols(tocols); SetCols(tocols);
...@@ -596,10 +720,6 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g) ...@@ -596,10 +720,6 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
cat->Cbuf = (char*)PlugSubAlloc(g, NULL, cat->Cblen); cat->Cbuf = (char*)PlugSubAlloc(g, NULL, cat->Cblen);
} // endif Cbuf } // endif Cbuf
// Here "OEM" should be replace by a more useful value
if (xdefp->Define(g, cat, Name, Schema, "OEM"))
return NULL;
// Ok, return external block // Ok, return external block
return xdefp; return xdefp;
} // end of GetXdef } // end of GetXdef
...@@ -622,7 +742,7 @@ bool OEMDEF::DeleteTableFile(PGLOBAL g) ...@@ -622,7 +742,7 @@ bool OEMDEF::DeleteTableFile(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int) bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int)
{ {
Module = GetStringCatInfo(g, "Module", ""); Module = GetStringCatInfo(g, "Module", "");
Subtype = GetStringCatInfo(g, "Subtype", Module); Subtype = GetStringCatInfo(g, "Subtype", Module);
if (!*Module) if (!*Module)
...@@ -632,7 +752,13 @@ bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int) ...@@ -632,7 +752,13 @@ bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int)
+ strlen(Subtype) + 3); + strlen(Subtype) + 3);
sprintf(desc, "%s(%s)", Module, Subtype); sprintf(desc, "%s(%s)", Module, Subtype);
Desc = desc; Desc = desc;
return false;
// If define block not here yet, get it now
if (!Pxdef && !(Pxdef = GetXdef(g)))
return true; // Error
// Here "OEM" should be replace by a more useful value
return Pxdef->Define(g, Cat, Name, Schema, Subtype);
} // end of DefineAM } // end of DefineAM
/***********************************************************************/ /***********************************************************************/
...@@ -640,7 +766,6 @@ bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int) ...@@ -640,7 +766,6 @@ bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int)
/***********************************************************************/ /***********************************************************************/
PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode) PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
{ {
RECFM rfm;
PTDB tdbp = NULL; PTDB tdbp = NULL;
// If define block not here yet, get it now // If define block not here yet, get it now
...@@ -653,18 +778,10 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode) ...@@ -653,18 +778,10 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
/*********************************************************************/ /*********************************************************************/
if (!(tdbp = Pxdef->GetTable(g, mode))) if (!(tdbp = Pxdef->GetTable(g, mode)))
return NULL; return NULL;
else else if (Multiple && tdbp->GetFtype() == RECFM_OEM)
rfm = tdbp->GetFtype(); tdbp = new(g) TDBMUL(tdbp); // No block optimization yet
if (rfm == RECFM_NAF)
return tdbp;
else if (rfm == RECFM_OEM) {
if (Multiple)
tdbp = new(g) TDBMUL(tdbp); // No block optimization yet
return tdbp;
} // endif OEM
#if 0
/*********************************************************************/ /*********************************************************************/
/* The OEM table is based on a file type (currently DOS+ only) */ /* The OEM table is based on a file type (currently DOS+ only) */
/*********************************************************************/ /*********************************************************************/
...@@ -723,7 +840,7 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode) ...@@ -723,7 +840,7 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
if (Multiple) if (Multiple)
tdbp = new(g) TDBMUL(tdbp); tdbp = new(g) TDBMUL(tdbp);
#endif // 0
return tdbp; return tdbp;
} // end of GetTable } // end of GetTable
......
...@@ -84,10 +84,12 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */ ...@@ -84,10 +84,12 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */
void SetNext(PTABDEF tdfp) {Next = tdfp;} void SetNext(PTABDEF tdfp) {Next = tdfp;}
int GetMultiple(void) {return Multiple;} int GetMultiple(void) {return Multiple;}
int GetPseudo(void) {return Pseudo;} int GetPseudo(void) {return Pseudo;}
PCSZ GetPath(void); RECFM GetRecfm(void) {return Recfm;}
PCSZ GetPath(void);
//PSZ GetPath(void) //PSZ GetPath(void)
// {return (Database) ? (PSZ)Database : Cat->GetDataPath();} // {return (Database) ? (PSZ)Database : Cat->GetDataPath();}
bool SepIndex(void) {return GetBoolCatInfo("SepIndex", false);} RECFM GetTableFormat(const char* type);
bool SepIndex(void) {return GetBoolCatInfo("SepIndex", false);}
bool IsReadOnly(void) {return Read_Only;} bool IsReadOnly(void) {return Read_Only;}
virtual AMT GetDefType(void) {return TYPE_AM_TAB;} virtual AMT GetDefType(void) {return TYPE_AM_TAB;}
virtual PIXDEF GetIndx(void) {return NULL;} virtual PIXDEF GetIndx(void) {return NULL;}
...@@ -108,7 +110,8 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */ ...@@ -108,7 +110,8 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */
// Members // Members
PCSZ Schema; /* Table schema (for ODBC) */ PCSZ Schema; /* Table schema (for ODBC) */
PCSZ Desc; /* Table description */ PCSZ Desc; /* Table description */
uint Catfunc; /* Catalog function ID */ RECFM Recfm; /* File or table format */
uint Catfunc; /* Catalog function ID */
int Card; /* (max) number of rows in table */ int Card; /* (max) number of rows in table */
int Elemt; /* Number of rows in blocks or rowset */ int Elemt; /* Number of rows in blocks or rowset */
int Sort; /* Table already sorted ??? */ int Sort; /* Table already sorted ??? */
......
...@@ -4,12 +4,6 @@ ...@@ -4,12 +4,6 @@
/***********************************************************************/ /***********************************************************************/
#include <cpprest/filestream.h> #include <cpprest/filestream.h>
#include <cpprest/http_client.h> #include <cpprest/http_client.h>
#if defined(MARIADB)
#include <my_global.h>
#else
#include "mini-global.h"
#define _OS_H_INCLUDED // Prevent os.h to be called
#endif
using namespace utility::conversions; // String conversions utilities using namespace utility::conversions; // String conversions utilities
using namespace web; // Common features like URIs. using namespace web; // Common features like URIs.
...@@ -17,24 +11,24 @@ using namespace web::http; // Common HTTP functionality ...@@ -17,24 +11,24 @@ using namespace web::http; // Common HTTP functionality
using namespace web::http::client; // HTTP client features using namespace web::http::client; // HTTP client features
using namespace concurrency::streams; // Asynchronous streams using namespace concurrency::streams; // Asynchronous streams
#include "global.h" typedef const char* PCSZ;
/***********************************************************************/ /***********************************************************************/
/* Make a local copy of the requested file. */ /* Make a local copy of the requested file. */
/***********************************************************************/ /***********************************************************************/
int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn) int restGetFile(char *m, bool xt, PCSZ http, PCSZ uri, PCSZ fn)
{ {
int rc = 0; int rc = 0;
bool xt = trace(515);
auto fileStream = std::make_shared<ostream>(); auto fileStream = std::make_shared<ostream>();
if (!http || !fn) { if (!http || !fn) {
strcpy(g->Message, "Missing http or filename"); //strcpy(g->Message, "Missing http or filename");
return 2; strcpy(m, "Missing http or filename");
return 2;
} // endif } // endif
if (xt) if (xt)
htrc("restGetFile: fn=%s\n", fn); fprintf(stderr, "restGetFile: fn=%s\n", fn);
// Open stream to output file. // Open stream to output file.
pplx::task<void> requestTask = fstream::open_ostream(to_string_t(fn)) pplx::task<void> requestTask = fstream::open_ostream(to_string_t(fn))
...@@ -42,7 +36,7 @@ int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn) ...@@ -42,7 +36,7 @@ int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn)
*fileStream= outFile; *fileStream= outFile;
if (xt) if (xt)
htrc("Outfile isopen=%d\n", outFile.is_open()); fprintf(stderr, "Outfile isopen=%d\n", outFile.is_open());
// Create http_client to send the request. // Create http_client to send the request.
http_client client(to_string_t(http)); http_client client(to_string_t(http));
...@@ -58,8 +52,8 @@ int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn) ...@@ -58,8 +52,8 @@ int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn)
// Handle response headers arriving. // Handle response headers arriving.
.then([=](http_response response) { .then([=](http_response response) {
if (xt) if (xt)
htrc("Received response status code:%u\n", fprintf(stderr, "Received response status code:%u\n",
response.status_code()); response.status_code());
// Write response body into the file. // Write response body into the file.
return response.body().read_to_end(fileStream->streambuf()); return response.body().read_to_end(fileStream->streambuf());
...@@ -68,27 +62,27 @@ int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn) ...@@ -68,27 +62,27 @@ int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn)
// Close the file stream. // Close the file stream.
.then([=](size_t n) { .then([=](size_t n) {
if (xt) if (xt)
htrc("Return size=%u\n", n); fprintf(stderr, "Return size=%zu\n", n);
return fileStream->close(); return fileStream->close();
}); });
// Wait for all the outstanding I/O to complete and handle any exceptions // Wait for all the outstanding I/O to complete and handle any exceptions
try { try {
requestTask.wait();
if (xt) if (xt)
htrc("In Wait\n"); fprintf(stderr, "Waiting\n");
requestTask.wait();
} catch (const std::exception &e) { } catch (const std::exception &e) {
if (xt) if (xt)
htrc("Error exception: %s\n", e.what()); fprintf(stderr, "Error exception: %s\n", e.what());
sprintf(g->Message, "Error exception: %s", e.what());
rc= 1; sprintf(m, "Error exception: %s", e.what());
rc= 1;
} // end try/catch } // end try/catch
if (xt) if (xt)
htrc("restget done: rc=%d\n", rc); fprintf(stderr, "restget done: rc=%d\n", rc);
return rc; return rc;
} // end of restGetFile } // end of restGetFile
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
#include "global.h" #include "global.h"
#include "osutil.h" #include "osutil.h"
#include "plgdbsem.h" #include "plgdbsem.h"
#include "catalog.h" //#include "catalog.h"
#include "mycat.h" #include "mycat.h"
#include "xindex.h" #include "xindex.h"
#include "filamap.h" #include "filamap.h"
...@@ -161,7 +161,12 @@ bool DOSDEF::DefineAM(PGLOBAL g, LPCSTR am, int) ...@@ -161,7 +161,12 @@ bool DOSDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
//Last = GetIntCatInfo("Last", 0); //Last = GetIntCatInfo("Last", 0);
Ending = GetIntCatInfo("Ending", CRLF); Ending = GetIntCatInfo("Ending", CRLF);
if (Recfm == RECFM_FIX || Recfm == RECFM_BIN) { if (Ending <= 0) {
Ending = (Recfm == RECFM_BIN || Recfm == RECFM_VCT) ? 0 : CRLF;
SetIntCatInfo("Ending", Ending);
} // endif ending
if (Recfm == RECFM_FIX || Recfm == RECFM_BIN) {
Huge = GetBoolCatInfo("Huge", Cat->GetDefHuge()); Huge = GetBoolCatInfo("Huge", Cat->GetDefHuge());
Padded = GetBoolCatInfo("Padded", false); Padded = GetBoolCatInfo("Padded", false);
Blksize = GetIntCatInfo("Blksize", 0); Blksize = GetIntCatInfo("Blksize", 0);
...@@ -191,7 +196,8 @@ bool DOSDEF::GetOptFileName(PGLOBAL g, char *filename) ...@@ -191,7 +196,8 @@ bool DOSDEF::GetOptFileName(PGLOBAL g, char *filename)
case RECFM_FIX: ftype = ".fop"; break; case RECFM_FIX: ftype = ".fop"; break;
case RECFM_BIN: ftype = ".bop"; break; case RECFM_BIN: ftype = ".bop"; break;
case RECFM_VCT: ftype = ".vop"; break; case RECFM_VCT: ftype = ".vop"; break;
case RECFM_DBF: ftype = ".dbp"; break; case RECFM_CSV: ftype = ".cop"; break;
case RECFM_DBF: ftype = ".dbp"; break;
default: default:
sprintf(g->Message, MSG(INVALID_FTYPE), Recfm); sprintf(g->Message, MSG(INVALID_FTYPE), Recfm);
return true; return true;
...@@ -261,7 +267,8 @@ bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf) ...@@ -261,7 +267,8 @@ bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf)
case RECFM_FIX: ftype = ".fnx"; break; case RECFM_FIX: ftype = ".fnx"; break;
case RECFM_BIN: ftype = ".bnx"; break; case RECFM_BIN: ftype = ".bnx"; break;
case RECFM_VCT: ftype = ".vnx"; break; case RECFM_VCT: ftype = ".vnx"; break;
case RECFM_DBF: ftype = ".dbx"; break; case RECFM_CSV: ftype = ".cnx"; break;
case RECFM_DBF: ftype = ".dbx"; break;
default: default:
sprintf(g->Message, MSG(BAD_RECFM_VAL), Recfm); sprintf(g->Message, MSG(BAD_RECFM_VAL), Recfm);
return true; return true;
...@@ -2257,7 +2264,7 @@ int TDBDOS::ReadDB(PGLOBAL g) ...@@ -2257,7 +2264,7 @@ int TDBDOS::ReadDB(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
bool TDBDOS::PrepareWriting(PGLOBAL) bool TDBDOS::PrepareWriting(PGLOBAL)
{ {
if (!Ftype && (Mode == MODE_INSERT || Txfp->GetUseTemp())) { if (Ftype == RECFM_VAR && (Mode == MODE_INSERT || Txfp->GetUseTemp())) {
char *p; char *p;
/*******************************************************************/ /*******************************************************************/
...@@ -2542,7 +2549,8 @@ void DOSCOL::ReadColumn(PGLOBAL g) ...@@ -2542,7 +2549,8 @@ void DOSCOL::ReadColumn(PGLOBAL g)
/*********************************************************************/ /*********************************************************************/
/* For a variable length file, check if the field exists. */ /* For a variable length file, check if the field exists. */
/*********************************************************************/ /*********************************************************************/
if (tdbp->Ftype == RECFM_VAR && strlen(tdbp->To_Line) < (unsigned)Deplac) if ((tdbp->Ftype == RECFM_VAR || tdbp->Ftype == RECFM_CSV)
&& strlen(tdbp->To_Line) < (unsigned)Deplac)
field = 0; field = 0;
else if (Dsp) else if (Dsp)
for(i = 0; i < field; i++) for(i = 0; i < field; i++)
...@@ -2552,7 +2560,8 @@ void DOSCOL::ReadColumn(PGLOBAL g) ...@@ -2552,7 +2560,8 @@ void DOSCOL::ReadColumn(PGLOBAL g)
switch (tdbp->Ftype) { switch (tdbp->Ftype) {
case RECFM_VAR: case RECFM_VAR:
case RECFM_FIX: // Fixed length text file case RECFM_FIX: // Fixed length text file
case RECFM_DBF: // Fixed length DBase file case RECFM_CSV: // Variable length CSV or FMT file
case RECFM_DBF: // Fixed length DBase file
if (Nod) switch (Buf_Type) { if (Nod) switch (Buf_Type) {
case TYPE_INT: case TYPE_INT:
case TYPE_SHORT: case TYPE_SHORT:
......
...@@ -80,7 +80,6 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */ ...@@ -80,7 +80,6 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
PCSZ Entry; /* Zip entry name or pattern */ PCSZ Entry; /* Zip entry name or pattern */
PCSZ Pwd; /* Zip password */ PCSZ Pwd; /* Zip password */
PIXDEF To_Indx; /* To index definitions blocks */ PIXDEF To_Indx; /* To index definitions blocks */
RECFM Recfm; /* 0:VAR, 1:FIX, 2:BIN, 3:VCT, 6:DBF */
bool Mapped; /* 0: disk file, 1: memory mapped file */ bool Mapped; /* 0: disk file, 1: memory mapped file */
bool Zipped; /* true for zipped table file */ bool Zipped; /* true for zipped table file */
bool Mulentries; /* true for multiple entries */ bool Mulentries; /* true for multiple entries */
......
...@@ -84,7 +84,7 @@ PTDB TDBFIX::Clone(PTABS t) ...@@ -84,7 +84,7 @@ PTDB TDBFIX::Clone(PTABS t)
tp = new(g) TDBFIX(g, this); tp = new(g) TDBFIX(g, this);
if (Ftype < 2) { if (Ftype == RECFM_VAR || Ftype == RECFM_FIX) {
// File is text // File is text
PDOSCOL cp1, cp2; PDOSCOL cp1, cp2;
......
/************* TabFmt C++ Program Source Code File (.CPP) **************/ /************* TabFmt C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABFMT */ /* PROGRAM NAME: TABFMT */
/* ------------- */ /* ------------- */
/* Version 3.9.2 */ /* Version 3.9.3 */
/* */ /* */
/* COPYRIGHT: */ /* COPYRIGHT: */
/* ---------- */ /* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 2001 - 2017 */ /* (C) Copyright to the author Olivier BERTRAND 2001 - 2019 */
/* */ /* */
/* WHAT THIS PROGRAM DOES: */ /* WHAT THIS PROGRAM DOES: */
/* ----------------------- */ /* ----------------------- */
...@@ -477,6 +477,7 @@ bool CSVDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -477,6 +477,7 @@ bool CSVDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
if (DOSDEF::DefineAM(g, "CSV", poff)) if (DOSDEF::DefineAM(g, "CSV", poff))
return true; return true;
Recfm = RECFM_CSV;
GetCharCatInfo("Separator", ",", buf, sizeof(buf)); GetCharCatInfo("Separator", ",", buf, sizeof(buf));
Sep = (strlen(buf) == 2 && buf[0] == '\\' && buf[1] == 't') ? '\t' : *buf; Sep = (strlen(buf) == 2 && buf[0] == '\\' && buf[1] == 't') ? '\t' : *buf;
Quoted = GetIntCatInfo("Quoted", -1); Quoted = GetIntCatInfo("Quoted", -1);
......
...@@ -342,11 +342,13 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int) ...@@ -342,11 +342,13 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
Delayed = !!GetIntCatInfo("Delayed", 0); Delayed = !!GetIntCatInfo("Delayed", 0);
} else { } else {
// MYSQL access from a PROXY table // MYSQL access from a PROXY table
Tabschema = GetStringCatInfo(g, "Database", Tabschema ? Tabschema : PlugDup(g, "*")); TABLE_SHARE* s;
Tabschema = GetStringCatInfo(g, "Database", Tabschema ? Tabschema : PlugDup(g, "*"));
Isview = GetBoolCatInfo("View", false); Isview = GetBoolCatInfo("View", false);
// We must get other connection parms from the calling table // We must get other connection parms from the calling table
Remove_tshp(Cat); s = Remove_tshp(Cat);
url = GetStringCatInfo(g, "Connect", NULL); url = GetStringCatInfo(g, "Connect", NULL);
if (!url || !*url) { if (!url || !*url) {
...@@ -365,6 +367,9 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int) ...@@ -365,6 +367,9 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
} // endif url } // endif url
Tabname = Name; Tabname = Name;
// Needed for column description
Restore_tshp(Cat, s);
} // endif am } // endif am
if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) { if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) {
......
/*************** Rest C++ Program Source Code File (.CPP) **************/ /*************** Rest C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: Rest Version 1.5 */ /* PROGRAM NAME: Rest Version 1.6 */
/* (C) Copyright to the author Olivier BERTRAND 2018 - 2019 */ /* (C) Copyright to the author Olivier BERTRAND 2018 - 2019 */
/* This program is the REST Web API support for MariaDB. */ /* This program is the REST Web API support for MariaDB. */
/* When compiled without MARIADB defined, it is the EOM module code. */ /* When compiled without MARIADB defined, it is the EOM module code. */
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
/***********************************************************************/ /***********************************************************************/
/* Get the file from the Web. */ /* Get the file from the Web. */
/***********************************************************************/ /***********************************************************************/
int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn); int restGetFile(char *m, bool x, PCSZ http, PCSZ uri, PCSZ fn);
#if defined(__WIN__) #if defined(__WIN__)
static PCSZ slash = "\\"; static PCSZ slash = "\\";
...@@ -48,6 +48,10 @@ static PCSZ slash = "/"; ...@@ -48,6 +48,10 @@ static PCSZ slash = "/";
#define stricmp strcasecmp #define stricmp strcasecmp
#endif // !__WIN__ #endif // !__WIN__
typedef int(__stdcall* XGETREST) (char*, bool, PCSZ, PCSZ, PCSZ);
static XGETREST getRestFnc = NULL;
#if !defined(MARIADB) #if !defined(MARIADB)
/***********************************************************************/ /***********************************************************************/
/* DB static variables. */ /* DB static variables. */
...@@ -75,6 +79,74 @@ PTABDEF __stdcall GetREST(PGLOBAL g, void *memp) ...@@ -75,6 +79,74 @@ PTABDEF __stdcall GetREST(PGLOBAL g, void *memp)
} // end of GetREST } // end of GetREST
#endif // !MARIADB #endif // !MARIADB
/***********************************************************************/
/* GetREST: get the external TABDEF from OEM module. */
/***********************************************************************/
XGETREST GetRestFunction(PGLOBAL g)
{
if (getRestFnc)
return getRestFnc;
#if !defined(REST_SOURCE)
if (trace(515))
htrc("Looking for GetRest library\n");
#if defined(__WIN__)
HANDLE Hdll;
const char* soname = "GetRest.dll"; // Module name
if (!(Hdll = LoadLibrary(soname))) {
char buf[256];
DWORD rc = GetLastError();
sprintf(g->Message, MSG(DLL_LOAD_ERROR), rc, soname);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)buf, sizeof(buf), NULL);
strcat(strcat(g->Message, ": "), buf);
return NULL;
} // endif Hdll
// Get the function returning an instance of the external DEF class
if (!(getRestFnc = (XGETREST)GetProcAddress((HINSTANCE)Hdll, "restGetFile"))) {
char buf[256];
DWORD rc = GetLastError();
sprintf(g->Message, MSG(PROCADD_ERROR), rc, "restGetFile");
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)buf, sizeof(buf), NULL);
strcat(strcat(g->Message, ": "), buf);
FreeLibrary((HMODULE)Hdll);
return NULL;
} // endif getRestFnc
#else // !__WIN__
void* Hso;
const char* error = NULL;
const char* soname = "GetRest.so"; // Module name
// Load the desired shared library
if (!(Hso = dlopen(soname, RTLD_LAZY))) {
error = dlerror();
sprintf(g->Message, MSG(SHARED_LIB_ERR), soname, SVP(error));
return NULL;
} // endif Hdll
// Get the function returning an instance of the external DEF class
if (!(getRestFnc = (XGETREST)dlsym(Hdll, "restGetFile"))) {
error = dlerror();
sprintf(g->Message, MSG(GET_FUNC_ERR), "restGetFile", SVP(error));
dlclose(Hso);
return NULL;
} // endif getdef
#endif // !__WIN__
#else
getRestFnc = restGetFile;
#endif
return getRestFnc;
} // end of GetRestFunction
/***********************************************************************/ /***********************************************************************/
/* Return the columns definition to MariaDB. */ /* Return the columns definition to MariaDB. */
/***********************************************************************/ /***********************************************************************/
...@@ -87,6 +159,10 @@ PQRYRES __stdcall ColREST(PGLOBAL g, PTOS tp, char *tab, char *db, bool info) ...@@ -87,6 +159,10 @@ PQRYRES __stdcall ColREST(PGLOBAL g, PTOS tp, char *tab, char *db, bool info)
PQRYRES qrp= NULL; PQRYRES qrp= NULL;
char filename[_MAX_PATH + 1]; // MAX PATH ??? char filename[_MAX_PATH + 1]; // MAX PATH ???
PCSZ http, uri, fn, ftype; PCSZ http, uri, fn, ftype;
XGETREST grf = GetRestFunction(g);
if (!grf)
return NULL;
http = GetStringTableOption(g, tp, "Http", NULL); http = GetStringTableOption(g, tp, "Http", NULL);
uri = GetStringTableOption(g, tp, "Uri", NULL); uri = GetStringTableOption(g, tp, "Uri", NULL);
...@@ -103,8 +179,8 @@ PQRYRES __stdcall ColREST(PGLOBAL g, PTOS tp, char *tab, char *db, bool info) ...@@ -103,8 +179,8 @@ PQRYRES __stdcall ColREST(PGLOBAL g, PTOS tp, char *tab, char *db, bool info)
strncat(filename, fn, _MAX_PATH); strncat(filename, fn, _MAX_PATH);
// Retrieve the file from the web and copy it locally // Retrieve the file from the web and copy it locally
if (http && restGetFile(g, http, uri, filename)) { if (http && grf(g->Message, trace(515), http, uri, filename)) {
// sprintf(g->Message, "Failed to get file at %s", http); // sprintf(g->Message, "Failed to get file at %s", http);
} else if (!stricmp(ftype, "XML")) } else if (!stricmp(ftype, "XML"))
qrp = XMLColumns(g, db, tab, tp, info); qrp = XMLColumns(g, db, tab, tp, info);
else if (!stricmp(ftype, "JSON")) else if (!stricmp(ftype, "JSON"))
...@@ -124,9 +200,14 @@ PQRYRES __stdcall ColREST(PGLOBAL g, PTOS tp, char *tab, char *db, bool info) ...@@ -124,9 +200,14 @@ PQRYRES __stdcall ColREST(PGLOBAL g, PTOS tp, char *tab, char *db, bool info)
/***********************************************************************/ /***********************************************************************/
bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{ {
char filename[_MAX_PATH + 1]; char filename[_MAX_PATH + 1];
int rc = 0, n; int rc = 0, n;
LPCSTR ftype; bool xt = trace(515);
LPCSTR ftype;
XGETREST grf = GetRestFunction(g);
if (!grf)
return true;
#if defined(MARIADB) #if defined(MARIADB)
ftype = GetStringCatInfo(g, "Type", "JSON"); ftype = GetStringCatInfo(g, "Type", "JSON");
...@@ -135,7 +216,7 @@ bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -135,7 +216,7 @@ bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
ftype = GetStringCatInfo(g, "Ftype", "JSON"); ftype = GetStringCatInfo(g, "Ftype", "JSON");
#endif // !MARIADB #endif // !MARIADB
if (trace(515)) if (xt)
htrc("ftype = %s am = %s\n", ftype, SVP(am)); htrc("ftype = %s am = %s\n", ftype, SVP(am));
n = (!stricmp(ftype, "JSON")) ? 1 n = (!stricmp(ftype, "JSON")) ? 1
...@@ -157,9 +238,9 @@ bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -157,9 +238,9 @@ bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
strncat(strcpy(filename, GetPath()), Fn, _MAX_PATH); strncat(strcpy(filename, GetPath()), Fn, _MAX_PATH);
// Retrieve the file from the web and copy it locally // Retrieve the file from the web and copy it locally
rc = restGetFile(g, Http, Uri, filename); rc = grf(g->Message, xt, Http, Uri, filename);
if (trace(515)) if (xt)
htrc("Return from restGetFile: rc=%d\n", rc); htrc("Return from restGetFile: rc=%d\n", rc);
if (rc) if (rc)
...@@ -175,7 +256,7 @@ bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -175,7 +256,7 @@ bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
if (Tdp && Tdp->Define(g, Cat, Name, Schema, "REST")) if (Tdp && Tdp->Define(g, Cat, Name, Schema, "REST"))
Tdp = NULL; // Error occured Tdp = NULL; // Error occured
if (trace(515)) if (xt)
htrc("Tdp defined\n", rc); htrc("Tdp defined\n", rc);
// Return true in case of error // Return true in case of error
......
...@@ -59,11 +59,23 @@ int GetConvSize(void); ...@@ -59,11 +59,23 @@ int GetConvSize(void);
/* Used by MYSQL tables to get MySQL parameters from the calling proxy */ /* Used by MYSQL tables to get MySQL parameters from the calling proxy */
/* table (PROXY, TBL, XCL, or OCCUR) when used by one of these. */ /* table (PROXY, TBL, XCL, or OCCUR) when used by one of these. */
/************************************************************************/ /************************************************************************/
void Remove_tshp(PCATLG cat) TABLE_SHARE *Remove_tshp(PCATLG cat)
{ {
((MYCAT*)cat)->GetHandler()->tshp = NULL; TABLE_SHARE *s = ((MYCAT*)cat)->GetHandler()->tshp;
((MYCAT*)cat)->GetHandler()->tshp = NULL;
return s;
} // end of Remove_thsp } // end of Remove_thsp
/************************************************************************/
/* Used by MYSQL tables to get MySQL parameters from the calling proxy */
/* table (PROXY, TBL, XCL, or OCCUR) when used by one of these. */
/************************************************************************/
void Restore_tshp(PCATLG cat, TABLE_SHARE *s)
{
((MYCAT*)cat)->GetHandler()->tshp = s;
} // end of Restore_thsp
/************************************************************************/ /************************************************************************/
/* GetTableShare: allocates and open a table share. */ /* GetTableShare: allocates and open a table share. */
/************************************************************************/ /************************************************************************/
......
...@@ -18,7 +18,8 @@ TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db, ...@@ -18,7 +18,8 @@ TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db,
PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
const char *name, bool& info); const char *name, bool& info);
void Remove_tshp(PCATLG cat); TABLE_SHARE *Remove_tshp(PCATLG cat);
void Restore_tshp(PCATLG cat, TABLE_SHARE *s);
/* -------------------------- PROXY classes -------------------------- */ /* -------------------------- PROXY classes -------------------------- */
......
...@@ -115,11 +115,14 @@ bool VCTDEF::DefineAM(PGLOBAL g, LPCSTR, int poff) ...@@ -115,11 +115,14 @@ bool VCTDEF::DefineAM(PGLOBAL g, LPCSTR, int poff)
Recfm = RECFM_VCT; Recfm = RECFM_VCT;
// poff is no more in use; This will have to be revisited
#if 0
// For packed files the logical record length is calculated in poff // For packed files the logical record length is calculated in poff
if (poff != Lrecl) { if (poff != Lrecl) {
Lrecl = poff; Lrecl = poff;
SetIntCatInfo("Lrecl", poff); SetIntCatInfo("Lrecl", poff);
} // endif poff } // endif poff
#endif // 0
Padded = false; Padded = false;
Blksize = 0; Blksize = 0;
......
...@@ -659,7 +659,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -659,7 +659,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
/* Not true for DBF tables because of eventual soft deleted lines. */ /* Not true for DBF tables because of eventual soft deleted lines. */
/* Note: for Num_K = 1 any non null value is Ok. */ /* Note: for Num_K = 1 any non null value is Ok. */
/*********************************************************************/ /*********************************************************************/
if (Srtd && !filp && Tdbp->Ftype != RECFM_VAR if (Srtd && !filp && Tdbp->Ftype != RECFM_VAR && Tdbp->Ftype != RECFM_CSV
&& Tdbp->Txfp->GetAmType() != TYPE_AM_DBF) { && Tdbp->Txfp->GetAmType() != TYPE_AM_DBF) {
Incr = (Num_K > 1) ? To_Rec[1] : Num_K; Incr = (Num_K > 1) ? To_Rec[1] : Num_K;
PlgDBfree(Record); PlgDBfree(Record);
...@@ -837,7 +837,8 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp) ...@@ -837,7 +837,8 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp)
case RECFM_FIX: ftype = ".fnx"; break; case RECFM_FIX: ftype = ".fnx"; break;
case RECFM_BIN: ftype = ".bnx"; break; case RECFM_BIN: ftype = ".bnx"; break;
case RECFM_VCT: ftype = ".vnx"; break; case RECFM_VCT: ftype = ".vnx"; break;
case RECFM_DBF: ftype = ".dbx"; break; case RECFM_CSV: ftype = ".cnx"; break;
case RECFM_DBF: ftype = ".dbx"; break;
default: default:
sprintf(g->Message, MSG(INVALID_FTYPE), Tdbp->Ftype); sprintf(g->Message, MSG(INVALID_FTYPE), Tdbp->Ftype);
return true; return true;
...@@ -990,7 +991,8 @@ bool XINDEX::Init(PGLOBAL g) ...@@ -990,7 +991,8 @@ bool XINDEX::Init(PGLOBAL g)
case RECFM_FIX: ftype = ".fnx"; break; case RECFM_FIX: ftype = ".fnx"; break;
case RECFM_BIN: ftype = ".bnx"; break; case RECFM_BIN: ftype = ".bnx"; break;
case RECFM_VCT: ftype = ".vnx"; break; case RECFM_VCT: ftype = ".vnx"; break;
case RECFM_DBF: ftype = ".dbx"; break; case RECFM_CSV: ftype = ".cnx"; break;
case RECFM_DBF: ftype = ".dbx"; break;
default: default:
sprintf(g->Message, MSG(INVALID_FTYPE), Tdbp->Ftype); sprintf(g->Message, MSG(INVALID_FTYPE), Tdbp->Ftype);
return true; return true;
...@@ -1243,7 +1245,8 @@ bool XINDEX::MapInit(PGLOBAL g) ...@@ -1243,7 +1245,8 @@ bool XINDEX::MapInit(PGLOBAL g)
case RECFM_FIX: ftype = ".fnx"; break; case RECFM_FIX: ftype = ".fnx"; break;
case RECFM_BIN: ftype = ".bnx"; break; case RECFM_BIN: ftype = ".bnx"; break;
case RECFM_VCT: ftype = ".vnx"; break; case RECFM_VCT: ftype = ".vnx"; break;
case RECFM_DBF: ftype = ".dbx"; break; case RECFM_CSV: ftype = ".cnx"; break;
case RECFM_DBF: ftype = ".dbx"; break;
default: default:
sprintf(g->Message, MSG(INVALID_FTYPE), Tdbp->Ftype); sprintf(g->Message, MSG(INVALID_FTYPE), Tdbp->Ftype);
return true; return true;
...@@ -1457,7 +1460,8 @@ bool XINDEX::GetAllSizes(PGLOBAL g,/* int &ndif,*/ int &numk) ...@@ -1457,7 +1460,8 @@ bool XINDEX::GetAllSizes(PGLOBAL g,/* int &ndif,*/ int &numk)
case RECFM_FIX: ftype = ".fnx"; break; case RECFM_FIX: ftype = ".fnx"; break;
case RECFM_BIN: ftype = ".bnx"; break; case RECFM_BIN: ftype = ".bnx"; break;
case RECFM_VCT: ftype = ".vnx"; break; case RECFM_VCT: ftype = ".vnx"; break;
case RECFM_DBF: ftype = ".dbx"; break; case RECFM_CSV: ftype = ".cnx"; break;
case RECFM_DBF: ftype = ".dbx"; break;
default: default:
sprintf(g->Message, MSG(INVALID_FTYPE), Tdbp->Ftype); sprintf(g->Message, MSG(INVALID_FTYPE), Tdbp->Ftype);
return true; return true;
......
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