mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
=====================================================================
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
This commit is contained in:
@@ -312,6 +312,8 @@ OPTION(CONNECT_WITH_REST "Compile CONNECT storage engine with REST support" ON)
|
||||
|
||||
IF(CONNECT_WITH_REST)
|
||||
MESSAGE(STATUS "=====> REST support is ON")
|
||||
SET(CONNECT_SOURCES ${CONNECT_SOURCES} tabrest.cpp tabrest.h)
|
||||
add_definitions(-DREST_SUPPORT)
|
||||
FIND_PACKAGE(cpprestsdk)
|
||||
IF (cpprestsdk_FOUND)
|
||||
MESSAGE(STATUS "=====> cpprestsdk found")
|
||||
@@ -326,8 +328,8 @@ IF(CONNECT_WITH_REST)
|
||||
# Comment it out if not needed depending on your cpprestsdk installation.
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
|
||||
ENDIF(UNIX)
|
||||
SET(CONNECT_SOURCES ${CONNECT_SOURCES} tabrest.cpp restget.cpp tabrest.h)
|
||||
add_definitions(-DREST_SUPPORT)
|
||||
SET(CONNECT_SOURCES ${CONNECT_SOURCES} restget.cpp)
|
||||
add_definitions(-DREST_SOURCE)
|
||||
ELSE(NOT cpprestsdk_FOUND)
|
||||
MESSAGE(STATUS "=====> cpprestsdk package not found")
|
||||
ENDIF (cpprestsdk_FOUND)
|
||||
|
@@ -170,9 +170,9 @@
|
||||
#define JSONMAX 10 // JSON Default max grp size
|
||||
|
||||
extern "C" {
|
||||
char version[]= "Version 1.06.0010 June 01, 2019";
|
||||
char version[]= "Version 1.07.0001 November 12, 2019";
|
||||
#if defined(__WIN__)
|
||||
char compver[]= "Version 1.06.0010 " __DATE__ " " __TIME__;
|
||||
char compver[]= "Version 1.07.0001 " __DATE__ " " __TIME__;
|
||||
char slash= '\\';
|
||||
#else // !__WIN__
|
||||
char slash= '/';
|
||||
@@ -6062,7 +6062,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
|
||||
} // endif !nblin
|
||||
|
||||
for (i= 0; !rc && i < qrp->Nblin; i++) {
|
||||
typ= len= prec= dec= 0;
|
||||
typ= len= prec= dec= flg= 0;
|
||||
tm= NOT_NULL_FLAG;
|
||||
cnm= (char*)"noname";
|
||||
dft= xtra= key= fmt= tn= NULL;
|
||||
@@ -6102,6 +6102,9 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
|
||||
if (crp->Kdata->GetIntValue(i))
|
||||
tm= 0; // Nullable
|
||||
|
||||
break;
|
||||
case FLD_FLAG:
|
||||
flg = crp->Kdata->GetIntValue(i);
|
||||
break;
|
||||
case FLD_FORMAT:
|
||||
fmt= (crp->Kdata) ? crp->Kdata->GetCharValue(i) : NULL;
|
||||
@@ -6233,7 +6236,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
|
||||
|
||||
// Now add the field
|
||||
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;
|
||||
} // endfor i
|
||||
|
||||
@@ -7379,14 +7382,14 @@ maria_declare_plugin(connect)
|
||||
&connect_storage_engine,
|
||||
"CONNECT",
|
||||
"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,
|
||||
connect_init_func, /* Plugin Init */
|
||||
connect_done_func, /* Plugin Deinit */
|
||||
0x0106, /* version number (1.06) */
|
||||
0x0107, /* version number (1.07) */
|
||||
NULL, /* status variables */
|
||||
connect_system_variables, /* system variables */
|
||||
"1.06.0010", /* string version */
|
||||
"1.07.0001", /* string version */
|
||||
MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
|
||||
}
|
||||
maria_declare_plugin_end;
|
||||
|
@@ -95,7 +95,7 @@
|
||||
#endif // ZIP_SUPPORT
|
||||
#if defined(REST_SUPPORT)
|
||||
#include "tabrest.h"
|
||||
#endif // Rest_SUPPORT
|
||||
#endif // REST_SUPPORT
|
||||
#include "mycat.h"
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -107,7 +107,6 @@ extern "C" HINSTANCE s_hModule; // Saved module handle
|
||||
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
|
||||
bool MongoEnabled(void);
|
||||
#endif // JAVA_SUPPORT || CMGO_SUPPORT
|
||||
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
|
||||
|
||||
/***********************************************************************/
|
||||
/* Get the plugin directory. */
|
||||
@@ -349,100 +348,6 @@ uint GetFuncID(const char *func)
|
||||
return fnc;
|
||||
} // 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 --------------------------- */
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -483,10 +388,10 @@ void MYCAT::Reset(void)
|
||||
/* GetTableDesc: retrieve a table descriptor. */
|
||||
/* 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 *)
|
||||
{
|
||||
PRELDEF tdp= NULL;
|
||||
PTABDEF tdp= NULL;
|
||||
|
||||
if (trace(1))
|
||||
htrc("GetTableDesc: name=%s am=%s\n", tablep->GetName(), SVP(type));
|
||||
@@ -507,12 +412,12 @@ PRELDEF MYCAT::GetTableDesc(PGLOBAL g, PTABLE tablep,
|
||||
/* MakeTableDesc: make a table/view description. */
|
||||
/* 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;
|
||||
LPCSTR name= (PSZ)PlugDup(g, tablep->GetName());
|
||||
LPCSTR schema= (PSZ)PlugDup(g, tablep->GetSchema());
|
||||
PRELDEF tdp= NULL;
|
||||
PTABDEF tdp= NULL;
|
||||
|
||||
if (trace(1))
|
||||
htrc("MakeTableDesc: name=%s schema=%s am=%s\n",
|
||||
@@ -581,7 +486,7 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
|
||||
|
||||
// Do make the table/view definition
|
||||
if (tdp && tdp->Define(g, this, name, schema, am))
|
||||
tdp= NULL;
|
||||
tdp = NULL;
|
||||
|
||||
if (trace(1))
|
||||
htrc("Table %s made\n", 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)
|
||||
{
|
||||
PRELDEF tdp;
|
||||
PTABDEF tdp;
|
||||
PTDB tdbp= NULL;
|
||||
// LPCSTR name= tablep->GetName();
|
||||
|
||||
|
@@ -102,14 +102,14 @@ class MYCAT : public CATALOG {
|
||||
// Methods
|
||||
void Reset(void);
|
||||
bool StoreIndex(PGLOBAL, PTABDEF) {return false;} // Temporary
|
||||
PRELDEF GetTableDesc(PGLOBAL g, PTABLE tablep,
|
||||
PTABDEF GetTableDesc(PGLOBAL g, PTABLE tablep,
|
||||
LPCSTR type, PRELDEF *prp = NULL);
|
||||
PTDB GetTable(PGLOBAL g, PTABLE tablep,
|
||||
MODE mode = MODE_READ, LPCSTR type = NULL);
|
||||
void ClearDB(PGLOBAL g);
|
||||
|
||||
protected:
|
||||
PRELDEF MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am);
|
||||
PTABDEF MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am);
|
||||
|
||||
// Members
|
||||
ha_connect *Hc; // The Connect handler
|
||||
|
@@ -472,7 +472,7 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
|
||||
int pt, const char *csname)
|
||||
{
|
||||
const char *pipe = NULL;
|
||||
uint cto = 10, nrt = 20;
|
||||
//uint cto = 10, nrt = 20;
|
||||
my_bool my_true= 1;
|
||||
|
||||
m_DB = mysql_init(NULL);
|
||||
@@ -485,11 +485,11 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
|
||||
if (trace(1))
|
||||
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_OPT_USE_REMOTE_CONNECTION, NULL);
|
||||
mysql_options(m_DB, MYSQL_OPT_CONNECT_TIMEOUT, &cto);
|
||||
mysql_options(m_DB, MYSQL_OPT_READ_TIMEOUT, &nrt);
|
||||
//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_READ_TIMEOUT, &nrt);
|
||||
//mysql_options(m_DB, MYSQL_OPT_WRITE_TIMEOUT, ...);
|
||||
|
||||
#if defined(__WIN__)
|
||||
|
@@ -149,16 +149,22 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
|
||||
TYPE_AM_MGO = 194, /* MGO access method type no */
|
||||
TYPE_AM_OUT = 200}; /* Output relations (storage) */
|
||||
|
||||
enum RECFM {RECFM_NAF = -2, /* Not a file */
|
||||
RECFM_OEM = -1, /* OEM file access method */
|
||||
RECFM_VAR = 0, /* Varying length DOS files */
|
||||
RECFM_FIX = 1, /* Fixed length DOS files */
|
||||
RECFM_BIN = 2, /* Binary DOS files (also fixed) */
|
||||
RECFM_VCT = 3, /* VCT formatted files */
|
||||
RECFM_ODBC = 4, /* Table accessed via ODBC */
|
||||
RECFM_JDBC = 5, /* Table accessed via JDBC */
|
||||
RECFM_PLG = 6, /* Table accessed via PLGconn */
|
||||
RECFM_DBF = 7}; /* DBase formatted file */
|
||||
enum RECFM {RECFM_DFLT = 0, /* Default table type */
|
||||
RECFM_NAF = 1, /* Not a file table */
|
||||
RECFM_OEM = 2, /* OEM table */
|
||||
RECFM_VAR = 3, /* Varying length DOS files */
|
||||
RECFM_FIX = 4, /* Fixed length DOS files */
|
||||
RECFM_BIN = 5, /* Binary DOS files (also fixed) */
|
||||
RECFM_DBF = 6, /* DBase formatted file */
|
||||
RECFM_CSV = 7, /* CSV file */
|
||||
RECFM_FMT = 8, /* FMT 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 */
|
||||
MAX_MULT_KEY = 10, /* Max multiple key number */
|
||||
@@ -537,7 +543,8 @@ enum XFLD {FLD_NO = 0, /* Not a field definition item */
|
||||
FLD_FORMAT = 16, /* Field format */
|
||||
FLD_CAT = 17, /* Table catalog */
|
||||
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. */
|
||||
|
@@ -1,11 +1,11 @@
|
||||
/************* RelDef CPP Program Source Code File (.CPP) **************/
|
||||
/* PROGRAM NAME: RELDEF */
|
||||
/* ------------- */
|
||||
/* Version 1.6 */
|
||||
/* Version 1.7 */
|
||||
/* */
|
||||
/* COPYRIGHT: */
|
||||
/* ---------- */
|
||||
/* (C) Copyright to the author Olivier BERTRAND 2004-2016 */
|
||||
/* (C) Copyright to the author Olivier BERTRAND 2004-2019 */
|
||||
/* */
|
||||
/* WHAT THIS PROGRAM DOES: */
|
||||
/* ----------------------- */
|
||||
@@ -61,6 +61,102 @@ extern handlerton *connect_hton;
|
||||
/***********************************************************************/
|
||||
USETEMP UseTemp(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 -------------------------- */
|
||||
|
||||
@@ -208,6 +304,7 @@ TABDEF::TABDEF(void)
|
||||
{
|
||||
Schema = NULL;
|
||||
Desc = NULL;
|
||||
Recfm = RECFM_DFLT;
|
||||
Catfunc = FNC_NO;
|
||||
Card = 0;
|
||||
Elemt = 0;
|
||||
@@ -220,12 +317,41 @@ TABDEF::TABDEF(void)
|
||||
csname = NULL;
|
||||
} // 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. */
|
||||
/***********************************************************************/
|
||||
bool TABDEF::Define(PGLOBAL g, PCATLG cat,
|
||||
LPCSTR name, LPCSTR schema, LPCSTR am)
|
||||
{
|
||||
{
|
||||
int poff = 0;
|
||||
|
||||
Hc = ((MYCAT*)cat)->GetHandler();
|
||||
@@ -243,13 +369,17 @@ bool TABDEF::Define(PGLOBAL g, PCATLG cat,
|
||||
NULL;
|
||||
csname = GetStringCatInfo(g, "Table_charset", NULL);
|
||||
|
||||
// Get The column definitions
|
||||
if ((poff = GetColCatInfo(g)) < 0)
|
||||
// Do the definition of AM specific fields
|
||||
if (DefineAM(g, am, 0))
|
||||
return true;
|
||||
|
||||
// Do the definition of AM specific fields
|
||||
return DefineAM(g, am, poff);
|
||||
} // end of Define
|
||||
// Get The column definitions
|
||||
if (stricmp(am, "OEM") && GetColCatInfo(g) < 0)
|
||||
return true;
|
||||
|
||||
Hc->tshp = NULL; // TO BE CHECKED
|
||||
return false;
|
||||
} // end of Define
|
||||
|
||||
/***********************************************************************/
|
||||
/* This function returns the database data path. */
|
||||
@@ -264,71 +394,71 @@ PCSZ TABDEF::GetPath(void)
|
||||
/***********************************************************************/
|
||||
int TABDEF::GetColCatInfo(PGLOBAL g)
|
||||
{
|
||||
char *type= GetStringCatInfo(g, "Type", "*");
|
||||
char *type = GetStringCatInfo(g, "Type", "*");
|
||||
char c, fty, eds;
|
||||
int i, n, loff, poff, nof, nlg;
|
||||
void *field= NULL;
|
||||
TABTYPE tc;
|
||||
PCOLDEF cdp, lcdp= NULL, tocols= NULL;
|
||||
void *field = NULL;
|
||||
RECFM trf;
|
||||
PCOLDEF cdp, lcdp = NULL, tocols= NULL;
|
||||
PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO));
|
||||
|
||||
memset(pcf, 0, sizeof(COLINFO));
|
||||
|
||||
// Get a unique char identifier for type
|
||||
tc= (Catfunc == FNC_NO) ? GetTypeID(type) : TAB_PRX;
|
||||
// Get the table format
|
||||
trf = GetTableFormat(type);
|
||||
|
||||
// Take care of the column definitions
|
||||
i= poff= nof= nlg= 0;
|
||||
|
||||
#if defined(__WIN__)
|
||||
// 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__
|
||||
// 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__
|
||||
|
||||
while (true) {
|
||||
// Default Offset depends on table type
|
||||
switch (tc) {
|
||||
case TAB_DOS:
|
||||
case TAB_FIX:
|
||||
case TAB_BIN:
|
||||
case TAB_VEC:
|
||||
case TAB_DBF:
|
||||
// Default Offset depends on table format
|
||||
switch (trf ) {
|
||||
case RECFM_VAR:
|
||||
case RECFM_FIX:
|
||||
case RECFM_BIN:
|
||||
case RECFM_VCT:
|
||||
case RECFM_DBF:
|
||||
poff= loff + nof; // Default next offset
|
||||
nlg= MY_MAX(nlg, poff); // Default lrecl
|
||||
break;
|
||||
case TAB_CSV:
|
||||
case TAB_FMT:
|
||||
case RECFM_CSV:
|
||||
case RECFM_FMT:
|
||||
nlg+= nof;
|
||||
case TAB_DIR:
|
||||
case TAB_XML:
|
||||
case RECFM_DIR:
|
||||
case RECFM_XML:
|
||||
poff= loff + (pcf->Flags & U_VIRTUAL ? 0 : 1);
|
||||
break;
|
||||
case TAB_INI:
|
||||
case TAB_MAC:
|
||||
case TAB_TBL:
|
||||
case TAB_XCL:
|
||||
case TAB_OCCUR:
|
||||
case TAB_PRX:
|
||||
case TAB_OEM:
|
||||
//case RECFM_INI:
|
||||
//case RECFM_MAC:
|
||||
//case RECFM_TBL:
|
||||
//case RECFM_XCL:
|
||||
//case RECFM_OCCUR:
|
||||
//case RECFM_PRX:
|
||||
case RECFM_OEM:
|
||||
poff = 0; // Offset represents an independant flag
|
||||
break;
|
||||
default: // VCT PLG ODBC JDBC MYSQL WMI...
|
||||
default: // PLG ODBC JDBC MYSQL WMI...
|
||||
poff = 0; // NA
|
||||
break;
|
||||
} // endswitch tc
|
||||
} // endswitch trf
|
||||
|
||||
// do {
|
||||
field= Hc->GetColumnOption(g, field, pcf);
|
||||
// } 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'
|
||||
pcf->Datefmt= "YYYYMMDD";
|
||||
pcf->Length= 8;
|
||||
} // endif tc
|
||||
} // endif trf
|
||||
|
||||
if (!field)
|
||||
break;
|
||||
@@ -341,10 +471,10 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
|
||||
else
|
||||
loff= cdp->GetOffset();
|
||||
|
||||
switch (tc) {
|
||||
case TAB_VEC:
|
||||
switch (trf ) {
|
||||
case RECFM_VCT:
|
||||
cdp->SetOffset(0); // Not to have shift
|
||||
case TAB_BIN:
|
||||
case RECFM_BIN:
|
||||
// BIN/VEC are packed by default
|
||||
if (nof) {
|
||||
// Field width is the internal representation width
|
||||
@@ -395,7 +525,7 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
|
||||
|
||||
default:
|
||||
break;
|
||||
} // endswitch tc
|
||||
} // endswitch trf
|
||||
|
||||
if (lcdp)
|
||||
lcdp->SetNext(cdp);
|
||||
@@ -413,21 +543,15 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
|
||||
if (GetDefType() == TYPE_AM_DOS) {
|
||||
int ending, recln= 0;
|
||||
|
||||
// Was commented because sometimes ending is 0 even when
|
||||
// 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
|
||||
ending = Hc->GetIntegerOption("Ending");
|
||||
|
||||
// Calculate the default record size
|
||||
switch (tc) {
|
||||
case TAB_FIX:
|
||||
case TAB_BIN:
|
||||
switch (trf ) {
|
||||
case RECFM_FIX:
|
||||
case RECFM_BIN:
|
||||
recln= nlg + ending; // + length of line ending
|
||||
break;
|
||||
case TAB_VEC:
|
||||
case RECFM_VCT:
|
||||
recln= nlg;
|
||||
|
||||
// if ((k= (pak < 0) ? 8 : pak) > 1)
|
||||
@@ -436,18 +560,18 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
|
||||
// recln= ((recln + k - 1) / k) * k;
|
||||
|
||||
break;
|
||||
case TAB_DOS:
|
||||
case TAB_DBF:
|
||||
case RECFM_VAR:
|
||||
case RECFM_DBF:
|
||||
recln= nlg;
|
||||
break;
|
||||
case TAB_CSV:
|
||||
case TAB_FMT:
|
||||
case RECFM_CSV:
|
||||
case RECFM_FMT:
|
||||
// The number of separators (assuming an extra one can exist)
|
||||
// recln= poff * ((qotd) ? 3 : 1); to be investigated
|
||||
recln= nlg + poff * 3; // To be safe
|
||||
default:
|
||||
break;
|
||||
} // endswitch tc
|
||||
} // endswitch trf
|
||||
|
||||
// lrecl must be at least recln to avoid buffer overflow
|
||||
if (trace(1))
|
||||
@@ -461,7 +585,7 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
|
||||
if (trace(1))
|
||||
htrc("Lrecl set to %d\n", recln);
|
||||
|
||||
} // endif Lrecl
|
||||
} // endif TYPE
|
||||
|
||||
// Attach the column definition to the tabdef
|
||||
SetCols(tocols);
|
||||
@@ -596,10 +720,6 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
|
||||
cat->Cbuf = (char*)PlugSubAlloc(g, NULL, cat->Cblen);
|
||||
} // 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
|
||||
return xdefp;
|
||||
} // end of GetXdef
|
||||
@@ -632,7 +752,13 @@ bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int)
|
||||
+ strlen(Subtype) + 3);
|
||||
sprintf(desc, "%s(%s)", Module, Subtype);
|
||||
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
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -640,7 +766,6 @@ bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int)
|
||||
/***********************************************************************/
|
||||
PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
|
||||
{
|
||||
RECFM rfm;
|
||||
PTDB tdbp = NULL;
|
||||
|
||||
// If define block not here yet, get it now
|
||||
@@ -653,18 +778,10 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
|
||||
/*********************************************************************/
|
||||
if (!(tdbp = Pxdef->GetTable(g, mode)))
|
||||
return NULL;
|
||||
else
|
||||
rfm = tdbp->GetFtype();
|
||||
|
||||
if (rfm == RECFM_NAF)
|
||||
return tdbp;
|
||||
else if (rfm == RECFM_OEM) {
|
||||
if (Multiple)
|
||||
else if (Multiple && tdbp->GetFtype() == RECFM_OEM)
|
||||
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) */
|
||||
/*********************************************************************/
|
||||
@@ -723,7 +840,7 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
|
||||
|
||||
if (Multiple)
|
||||
tdbp = new(g) TDBMUL(tdbp);
|
||||
|
||||
#endif // 0
|
||||
return tdbp;
|
||||
} // end of GetTable
|
||||
|
||||
|
@@ -84,9 +84,11 @@ public:
|
||||
void SetNext(PTABDEF tdfp) {Next = tdfp;}
|
||||
int GetMultiple(void) {return Multiple;}
|
||||
int GetPseudo(void) {return Pseudo;}
|
||||
RECFM GetRecfm(void) {return Recfm;}
|
||||
PCSZ GetPath(void);
|
||||
//PSZ GetPath(void)
|
||||
// {return (Database) ? (PSZ)Database : Cat->GetDataPath();}
|
||||
RECFM GetTableFormat(const char* type);
|
||||
bool SepIndex(void) {return GetBoolCatInfo("SepIndex", false);}
|
||||
bool IsReadOnly(void) {return Read_Only;}
|
||||
virtual AMT GetDefType(void) {return TYPE_AM_TAB;}
|
||||
@@ -108,6 +110,7 @@ public:
|
||||
// Members
|
||||
PCSZ Schema; /* Table schema (for ODBC) */
|
||||
PCSZ Desc; /* Table description */
|
||||
RECFM Recfm; /* File or table format */
|
||||
uint Catfunc; /* Catalog function ID */
|
||||
int Card; /* (max) number of rows in table */
|
||||
int Elemt; /* Number of rows in blocks or rowset */
|
||||
|
@@ -4,12 +4,6 @@
|
||||
/***********************************************************************/
|
||||
#include <cpprest/filestream.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 web; // Common features like URIs.
|
||||
@@ -17,24 +11,24 @@ using namespace web::http; // Common HTTP functionality
|
||||
using namespace web::http::client; // HTTP client features
|
||||
using namespace concurrency::streams; // Asynchronous streams
|
||||
|
||||
#include "global.h"
|
||||
typedef const char* PCSZ;
|
||||
|
||||
/***********************************************************************/
|
||||
/* 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;
|
||||
bool xt = trace(515);
|
||||
auto fileStream = std::make_shared<ostream>();
|
||||
|
||||
if (!http || !fn) {
|
||||
strcpy(g->Message, "Missing http or filename");
|
||||
//strcpy(g->Message, "Missing http or filename");
|
||||
strcpy(m, "Missing http or filename");
|
||||
return 2;
|
||||
} // endif
|
||||
|
||||
if (xt)
|
||||
htrc("restGetFile: fn=%s\n", fn);
|
||||
fprintf(stderr, "restGetFile: fn=%s\n", fn);
|
||||
|
||||
// Open stream to output file.
|
||||
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)
|
||||
*fileStream= outFile;
|
||||
|
||||
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.
|
||||
http_client client(to_string_t(http));
|
||||
@@ -58,7 +52,7 @@ int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn)
|
||||
// Handle response headers arriving.
|
||||
.then([=](http_response response) {
|
||||
if (xt)
|
||||
htrc("Received response status code:%u\n",
|
||||
fprintf(stderr, "Received response status code:%u\n",
|
||||
response.status_code());
|
||||
|
||||
// Write response body into the file.
|
||||
@@ -68,27 +62,27 @@ int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn)
|
||||
// Close the file stream.
|
||||
.then([=](size_t n) {
|
||||
if (xt)
|
||||
htrc("Return size=%u\n", n);
|
||||
fprintf(stderr, "Return size=%zu\n", n);
|
||||
|
||||
return fileStream->close();
|
||||
});
|
||||
|
||||
// Wait for all the outstanding I/O to complete and handle any exceptions
|
||||
try {
|
||||
requestTask.wait();
|
||||
|
||||
if (xt)
|
||||
htrc("In Wait\n");
|
||||
fprintf(stderr, "Waiting\n");
|
||||
|
||||
requestTask.wait();
|
||||
} catch (const std::exception &e) {
|
||||
if (xt)
|
||||
htrc("Error exception: %s\n", e.what());
|
||||
sprintf(g->Message, "Error exception: %s", e.what());
|
||||
fprintf(stderr, "Error exception: %s\n", e.what());
|
||||
|
||||
sprintf(m, "Error exception: %s", e.what());
|
||||
rc= 1;
|
||||
} // end try/catch
|
||||
|
||||
if (xt)
|
||||
htrc("restget done: rc=%d\n", rc);
|
||||
fprintf(stderr, "restget done: rc=%d\n", rc);
|
||||
|
||||
return rc;
|
||||
} // end of restGetFile
|
||||
|
@@ -45,7 +45,7 @@
|
||||
#include "global.h"
|
||||
#include "osutil.h"
|
||||
#include "plgdbsem.h"
|
||||
#include "catalog.h"
|
||||
//#include "catalog.h"
|
||||
#include "mycat.h"
|
||||
#include "xindex.h"
|
||||
#include "filamap.h"
|
||||
@@ -161,6 +161,11 @@ bool DOSDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
|
||||
//Last = GetIntCatInfo("Last", 0);
|
||||
Ending = GetIntCatInfo("Ending", CRLF);
|
||||
|
||||
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());
|
||||
Padded = GetBoolCatInfo("Padded", false);
|
||||
@@ -191,6 +196,7 @@ bool DOSDEF::GetOptFileName(PGLOBAL g, char *filename)
|
||||
case RECFM_FIX: ftype = ".fop"; break;
|
||||
case RECFM_BIN: ftype = ".bop"; break;
|
||||
case RECFM_VCT: ftype = ".vop"; break;
|
||||
case RECFM_CSV: ftype = ".cop"; break;
|
||||
case RECFM_DBF: ftype = ".dbp"; break;
|
||||
default:
|
||||
sprintf(g->Message, MSG(INVALID_FTYPE), Recfm);
|
||||
@@ -261,6 +267,7 @@ bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf)
|
||||
case RECFM_FIX: ftype = ".fnx"; break;
|
||||
case RECFM_BIN: ftype = ".bnx"; break;
|
||||
case RECFM_VCT: ftype = ".vnx"; break;
|
||||
case RECFM_CSV: ftype = ".cnx"; break;
|
||||
case RECFM_DBF: ftype = ".dbx"; break;
|
||||
default:
|
||||
sprintf(g->Message, MSG(BAD_RECFM_VAL), Recfm);
|
||||
@@ -2257,7 +2264,7 @@ int TDBDOS::ReadDB(PGLOBAL g)
|
||||
/***********************************************************************/
|
||||
bool TDBDOS::PrepareWriting(PGLOBAL)
|
||||
{
|
||||
if (!Ftype && (Mode == MODE_INSERT || Txfp->GetUseTemp())) {
|
||||
if (Ftype == RECFM_VAR && (Mode == MODE_INSERT || Txfp->GetUseTemp())) {
|
||||
char *p;
|
||||
|
||||
/*******************************************************************/
|
||||
@@ -2542,7 +2549,8 @@ void DOSCOL::ReadColumn(PGLOBAL g)
|
||||
/*********************************************************************/
|
||||
/* 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;
|
||||
else if (Dsp)
|
||||
for(i = 0; i < field; i++)
|
||||
@@ -2552,6 +2560,7 @@ void DOSCOL::ReadColumn(PGLOBAL g)
|
||||
switch (tdbp->Ftype) {
|
||||
case RECFM_VAR:
|
||||
case RECFM_FIX: // Fixed length text file
|
||||
case RECFM_CSV: // Variable length CSV or FMT file
|
||||
case RECFM_DBF: // Fixed length DBase file
|
||||
if (Nod) switch (Buf_Type) {
|
||||
case TYPE_INT:
|
||||
|
@@ -80,7 +80,6 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
|
||||
PCSZ Entry; /* Zip entry name or pattern */
|
||||
PCSZ Pwd; /* Zip password */
|
||||
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 Zipped; /* true for zipped table file */
|
||||
bool Mulentries; /* true for multiple entries */
|
||||
|
@@ -84,7 +84,7 @@ PTDB TDBFIX::Clone(PTABS t)
|
||||
|
||||
tp = new(g) TDBFIX(g, this);
|
||||
|
||||
if (Ftype < 2) {
|
||||
if (Ftype == RECFM_VAR || Ftype == RECFM_FIX) {
|
||||
// File is text
|
||||
PDOSCOL cp1, cp2;
|
||||
|
||||
|
@@ -1,11 +1,11 @@
|
||||
/************* TabFmt C++ Program Source Code File (.CPP) **************/
|
||||
/* PROGRAM NAME: TABFMT */
|
||||
/* ------------- */
|
||||
/* Version 3.9.2 */
|
||||
/* Version 3.9.3 */
|
||||
/* */
|
||||
/* COPYRIGHT: */
|
||||
/* ---------- */
|
||||
/* (C) Copyright to the author Olivier BERTRAND 2001 - 2017 */
|
||||
/* (C) Copyright to the author Olivier BERTRAND 2001 - 2019 */
|
||||
/* */
|
||||
/* WHAT THIS PROGRAM DOES: */
|
||||
/* ----------------------- */
|
||||
@@ -477,6 +477,7 @@ bool CSVDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
||||
if (DOSDEF::DefineAM(g, "CSV", poff))
|
||||
return true;
|
||||
|
||||
Recfm = RECFM_CSV;
|
||||
GetCharCatInfo("Separator", ",", buf, sizeof(buf));
|
||||
Sep = (strlen(buf) == 2 && buf[0] == '\\' && buf[1] == 't') ? '\t' : *buf;
|
||||
Quoted = GetIntCatInfo("Quoted", -1);
|
||||
|
@@ -342,11 +342,13 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
|
||||
Delayed = !!GetIntCatInfo("Delayed", 0);
|
||||
} else {
|
||||
// MYSQL access from a PROXY table
|
||||
TABLE_SHARE* s;
|
||||
|
||||
Tabschema = GetStringCatInfo(g, "Database", Tabschema ? Tabschema : PlugDup(g, "*"));
|
||||
Isview = GetBoolCatInfo("View", false);
|
||||
|
||||
// We must get other connection parms from the calling table
|
||||
Remove_tshp(Cat);
|
||||
s = Remove_tshp(Cat);
|
||||
url = GetStringCatInfo(g, "Connect", NULL);
|
||||
|
||||
if (!url || !*url) {
|
||||
@@ -365,6 +367,9 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
|
||||
} // endif url
|
||||
|
||||
Tabname = Name;
|
||||
|
||||
// Needed for column description
|
||||
Restore_tshp(Cat, s);
|
||||
} // endif am
|
||||
|
||||
if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*************** 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 */
|
||||
/* This program is the REST Web API support for MariaDB. */
|
||||
/* When compiled without MARIADB defined, it is the EOM module code. */
|
||||
@@ -39,7 +39,7 @@
|
||||
/***********************************************************************/
|
||||
/* 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__)
|
||||
static PCSZ slash = "\\";
|
||||
@@ -48,6 +48,10 @@ static PCSZ slash = "/";
|
||||
#define stricmp strcasecmp
|
||||
#endif // !__WIN__
|
||||
|
||||
typedef int(__stdcall* XGETREST) (char*, bool, PCSZ, PCSZ, PCSZ);
|
||||
static XGETREST getRestFnc = NULL;
|
||||
|
||||
|
||||
#if !defined(MARIADB)
|
||||
/***********************************************************************/
|
||||
/* DB static variables. */
|
||||
@@ -75,6 +79,74 @@ PTABDEF __stdcall GetREST(PGLOBAL g, void *memp)
|
||||
} // end of GetREST
|
||||
#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. */
|
||||
/***********************************************************************/
|
||||
@@ -87,6 +159,10 @@ PQRYRES __stdcall ColREST(PGLOBAL g, PTOS tp, char *tab, char *db, bool info)
|
||||
PQRYRES qrp= NULL;
|
||||
char filename[_MAX_PATH + 1]; // MAX PATH ???
|
||||
PCSZ http, uri, fn, ftype;
|
||||
XGETREST grf = GetRestFunction(g);
|
||||
|
||||
if (!grf)
|
||||
return NULL;
|
||||
|
||||
http = GetStringTableOption(g, tp, "Http", NULL);
|
||||
uri = GetStringTableOption(g, tp, "Uri", NULL);
|
||||
@@ -103,7 +179,7 @@ PQRYRES __stdcall ColREST(PGLOBAL g, PTOS tp, char *tab, char *db, bool info)
|
||||
strncat(filename, fn, _MAX_PATH);
|
||||
|
||||
// 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);
|
||||
} else if (!stricmp(ftype, "XML"))
|
||||
qrp = XMLColumns(g, db, tab, tp, info);
|
||||
@@ -126,7 +202,12 @@ bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
||||
{
|
||||
char filename[_MAX_PATH + 1];
|
||||
int rc = 0, n;
|
||||
bool xt = trace(515);
|
||||
LPCSTR ftype;
|
||||
XGETREST grf = GetRestFunction(g);
|
||||
|
||||
if (!grf)
|
||||
return true;
|
||||
|
||||
#if defined(MARIADB)
|
||||
ftype = GetStringCatInfo(g, "Type", "JSON");
|
||||
@@ -135,7 +216,7 @@ bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
||||
ftype = GetStringCatInfo(g, "Ftype", "JSON");
|
||||
#endif // !MARIADB
|
||||
|
||||
if (trace(515))
|
||||
if (xt)
|
||||
htrc("ftype = %s am = %s\n", ftype, SVP(am));
|
||||
|
||||
n = (!stricmp(ftype, "JSON")) ? 1
|
||||
@@ -157,9 +238,9 @@ bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
||||
strncat(strcpy(filename, GetPath()), Fn, _MAX_PATH);
|
||||
|
||||
// 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);
|
||||
|
||||
if (rc)
|
||||
@@ -175,7 +256,7 @@ bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
||||
if (Tdp && Tdp->Define(g, Cat, Name, Schema, "REST"))
|
||||
Tdp = NULL; // Error occured
|
||||
|
||||
if (trace(515))
|
||||
if (xt)
|
||||
htrc("Tdp defined\n", rc);
|
||||
|
||||
// Return true in case of error
|
||||
|
@@ -59,11 +59,23 @@ int GetConvSize(void);
|
||||
/* 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 Remove_tshp(PCATLG cat)
|
||||
TABLE_SHARE *Remove_tshp(PCATLG cat)
|
||||
{
|
||||
TABLE_SHARE *s = ((MYCAT*)cat)->GetHandler()->tshp;
|
||||
|
||||
((MYCAT*)cat)->GetHandler()->tshp = NULL;
|
||||
return s;
|
||||
} // 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. */
|
||||
/************************************************************************/
|
||||
|
@@ -18,7 +18,8 @@ TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db,
|
||||
PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
|
||||
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 -------------------------- */
|
||||
|
||||
|
@@ -115,11 +115,14 @@ bool VCTDEF::DefineAM(PGLOBAL g, LPCSTR, int poff)
|
||||
|
||||
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
|
||||
if (poff != Lrecl) {
|
||||
Lrecl = poff;
|
||||
SetIntCatInfo("Lrecl", poff);
|
||||
} // endif poff
|
||||
#endif // 0
|
||||
|
||||
Padded = false;
|
||||
Blksize = 0;
|
||||
|
@@ -659,7 +659,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
|
||||
/* Not true for DBF tables because of eventual soft deleted lines. */
|
||||
/* 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) {
|
||||
Incr = (Num_K > 1) ? To_Rec[1] : Num_K;
|
||||
PlgDBfree(Record);
|
||||
@@ -837,6 +837,7 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp)
|
||||
case RECFM_FIX: ftype = ".fnx"; break;
|
||||
case RECFM_BIN: ftype = ".bnx"; break;
|
||||
case RECFM_VCT: ftype = ".vnx"; break;
|
||||
case RECFM_CSV: ftype = ".cnx"; break;
|
||||
case RECFM_DBF: ftype = ".dbx"; break;
|
||||
default:
|
||||
sprintf(g->Message, MSG(INVALID_FTYPE), Tdbp->Ftype);
|
||||
@@ -990,6 +991,7 @@ bool XINDEX::Init(PGLOBAL g)
|
||||
case RECFM_FIX: ftype = ".fnx"; break;
|
||||
case RECFM_BIN: ftype = ".bnx"; break;
|
||||
case RECFM_VCT: ftype = ".vnx"; break;
|
||||
case RECFM_CSV: ftype = ".cnx"; break;
|
||||
case RECFM_DBF: ftype = ".dbx"; break;
|
||||
default:
|
||||
sprintf(g->Message, MSG(INVALID_FTYPE), Tdbp->Ftype);
|
||||
@@ -1243,6 +1245,7 @@ bool XINDEX::MapInit(PGLOBAL g)
|
||||
case RECFM_FIX: ftype = ".fnx"; break;
|
||||
case RECFM_BIN: ftype = ".bnx"; break;
|
||||
case RECFM_VCT: ftype = ".vnx"; break;
|
||||
case RECFM_CSV: ftype = ".cnx"; break;
|
||||
case RECFM_DBF: ftype = ".dbx"; break;
|
||||
default:
|
||||
sprintf(g->Message, MSG(INVALID_FTYPE), Tdbp->Ftype);
|
||||
@@ -1457,6 +1460,7 @@ bool XINDEX::GetAllSizes(PGLOBAL g,/* int &ndif,*/ int &numk)
|
||||
case RECFM_FIX: ftype = ".fnx"; break;
|
||||
case RECFM_BIN: ftype = ".bnx"; break;
|
||||
case RECFM_VCT: ftype = ".vnx"; break;
|
||||
case RECFM_CSV: ftype = ".cnx"; break;
|
||||
case RECFM_DBF: ftype = ".dbx"; break;
|
||||
default:
|
||||
sprintf(g->Message, MSG(INVALID_FTYPE), Tdbp->Ftype);
|
||||
|
Reference in New Issue
Block a user