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)
|
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)
|
|||||||
# 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 @@
|
|||||||
#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,
|
|||||||
} // 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,
|
|||||||
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,
|
|||||||
|
|
||||||
// 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)
|
|||||||
&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 @@
|
|||||||
#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
|
|||||||
#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)
|
|||||||
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)
|
|||||||
/* 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,
|
|||||||
/* 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)
|
|||||||
} // 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)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
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 {
|
|||||||
// 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,
|
|||||||
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,
|
|||||||
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 */
|
|||||||
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 */
|
|||||||
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. */
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
/************* 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;
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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,
|
|||||||
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)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
// 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
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)
|
|||||||
+ 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)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
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)
|
|||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
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)
|
|||||||
|
|
||||||
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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
// 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 @@
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
#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
|
|||||||
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)
|
|||||||
*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)
|
|||||||
// 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)
|
|||||||
// 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 @@
|
|||||||
#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)
|
|||||||
//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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
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)
|
|||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* 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)
|
|||||||
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 */
|
|||||||
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)
|
|||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
/************* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
} // 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))) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*************** 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 @@
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* 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 = "/";
|
|||||||
#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)
|
|||||||
} // 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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);
|
|||||||
/* 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,
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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;
|
||||||
|
Reference in New Issue
Block a user