Commit 708d4615 authored by Oleksandr Byelkin's avatar Oleksandr Byelkin

Merge remote-tracking branch 'connect/10.1' into 10.1

parents b58c38a3 ea084a41
......@@ -73,7 +73,15 @@ ELSE(NOT UNIX)
tabwmi.cpp tabwmi.h tabmac.cpp tabmac.h macutil.cpp macutil.h)
# Add exception handling to the CONNECT project)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MD")
SET(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /MD")
SET(IPHLPAPI_LIBRARY iphlpapi.lib)
IF(MSVC AND (CMAKE_CXX_COMPILER_ID MATCHES Clang))
# Connect does not work with clang-cl
RETURN()
ENDIF()
ENDIF(UNIX)
......@@ -114,7 +122,6 @@ IF(CONNECT_WITH_LIBXML2)
FIND_PACKAGE(LibXml2)
IF (LIBXML2_FOUND)
INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR})
SET(ZLIB_LIBRARY "z") # see ZLIB_INCLUDE_DIR below
SET(XML_LIBRARY ${LIBXML2_LIBRARIES})
SET(CONNECT_SOURCES ${CONNECT_SOURCES} libdoc.cpp libdoc.h)
add_definitions(-DLIBXML2_SUPPORT)
......@@ -308,6 +315,30 @@ IF(CONNECT_WITH_MONGO)
ENDIF(CONNECT_WITH_MONGO)
#
# REST
#
OPTION(CONNECT_WITH_REST "Compile CONNECT storage engine with REST support" ON)
IF(CONNECT_WITH_REST)
MESSAGE(STATUS "=====> REST support is ON")
FIND_PACKAGE(cpprestsdk)
IF (cpprestsdk_FOUND)
MESSAGE(STATUS "=====> cpprestsdk found")
IF(UNIX)
# INCLUDE_DIRECTORIES(${CPPRESTSDK_INCLUDE_DIR})
# If needed edit next line to set the path to libcpprest.so
SET(REST_LIBRARY -lcpprest)
MESSAGE (STATUS ${REST_LIBRARY})
ENDIF(UNIX)
SET(CONNECT_SOURCES ${CONNECT_SOURCES} tabrest.cpp restget.cpp tabrest.h)
add_definitions(-DREST_SUPPORT)
ELSE(NOT cpprestsdk_FOUND)
MESSAGE(STATUS "=====> cpprestsdk package not found")
ENDIF (cpprestsdk_FOUND)
ENDIF(CONNECT_WITH_REST)
#
# XMAP
#
......@@ -327,20 +358,12 @@ MYSQL_ADD_PLUGIN(connect ${CONNECT_SOURCES}
COMPONENT connect-engine
RECOMPILE_FOR_EMBEDDED
LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY}
${ODBC_LIBRARY} ${JDBC_LIBRARY} ${MONGOC_LIBRARY} ${IPHLPAPI_LIBRARY})
${ODBC_LIBRARY} ${JDBC_LIBRARY} ${MONGOC_LIBRARY} ${IPHLPAPI_LIBRARY} ${REST_LIBRARY})
IF(NOT TARGET connect)
RETURN()
ENDIF()
# Don't link with bundled zlib and systel libxml2 at the same time.
# System libxml2 uses system zlib, might conflict with the bundled one.
IF (XML_LIBRARY AND BUILD_BUNDLED_ZLIB)
GET_PROPERTY(INCS TARGET connect PROPERTY INCLUDE_DIRECTORIES)
LIST(REMOVE_ITEM INCS ${ZLIB_INCLUDE_DIR})
SET_PROPERTY(TARGET connect PROPERTY INCLUDE_DIRECTORIES ${INCS})
ENDIF()
IF(WIN32)
IF (libmongoc-1.0_FOUND)
SET_TARGET_PROPERTIES(connect PROPERTIES LINK_FLAGS
......@@ -371,3 +394,4 @@ IF(CONNECT_WITH_JDBC AND JAVA_FOUND AND JNI_FOUND)
${CMAKE_CURRENT_BINARY_DIR}/JdbcInterface.jar
DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
ENDIF()
/************* Array C++ Functions Source Code File (.CPP) *************/
/* Name: ARRAY.CPP Version 2.3 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2005-2017 */
/* (C) Copyright to the author Olivier BERTRAND 2005-2019 */
/* */
/* This file contains the XOBJECT derived class ARRAY functions. */
/* ARRAY is used for elaborate type of processing, such as sorting */
......@@ -67,7 +67,7 @@ PARRAY MakeValueArray(PGLOBAL g, PPARM pp); // avoid gcc warning
/* MakeValueArray: Makes a value array from a value list. */
/***********************************************************************/
PARRAY MakeValueArray(PGLOBAL g, PPARM pp)
{
{
int n, valtyp = 0;
size_t len = 0;
PARRAY par;
......@@ -82,8 +82,7 @@ PARRAY MakeValueArray(PGLOBAL g, PPARM pp)
if ((valtyp = pp->Type) != TYPE_STRING)
len = 1;
if (trace(1))
htrc("valtyp=%d len=%d\n", valtyp, len);
xtrc(1, "valtyp=%d len=%d\n", valtyp, len);
/*********************************************************************/
/* Firstly check the list and count the number of values in it. */
......@@ -133,7 +132,7 @@ PARRAY MakeValueArray(PGLOBAL g, PPARM pp)
/* Send back resulting array. */
/*********************************************************************/
return par;
} // end of MakeValueArray
} // end of MakeValueArray
/* -------------------------- Class ARRAY ---------------------------- */
......@@ -151,6 +150,9 @@ ARRAY::ARRAY(PGLOBAL g, int type, int size, int length, int prec)
Type = type;
Xsize = -1;
Len = 1;
X = 0;
Inf = 0;
Sup = 0;
switch (type) {
case TYPE_STRING:
......@@ -281,130 +283,109 @@ void ARRAY::Empty(void)
/* Add a string element to an array. */
/***********************************************************************/
bool ARRAY::AddValue(PGLOBAL g, PSZ strp)
{
{
if (Type != TYPE_STRING) {
sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(Type), "CHAR");
return true;
} // endif Type
if (trace(1))
htrc(" adding string(%d): '%s'\n", Nval, strp);
//Value->SetValue_psz(strp);
//Vblp->SetValue(valp, Nval++);
xtrc(1, " adding string(%d): '%s'\n", Nval, strp);
Vblp->SetValue(strp, Nval++);
return false;
} // end of AddValue
} // end of AddValue
/***********************************************************************/
/* Add a char pointer element to an array. */
/***********************************************************************/
bool ARRAY::AddValue(PGLOBAL g, void *p)
{
{
if (Type != TYPE_PCHAR) {
sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(Type), "PCHAR");
return true;
} // endif Type
if (trace(1))
htrc(" adding pointer(%d): %p\n", Nval, p);
xtrc(1, " adding pointer(%d): %p\n", Nval, p);
Vblp->SetValue((PSZ)p, Nval++);
return false;
} // end of AddValue
} // end of AddValue
/***********************************************************************/
/* Add a short integer element to an array. */
/***********************************************************************/
bool ARRAY::AddValue(PGLOBAL g, short n)
{
{
if (Type != TYPE_SHORT) {
sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(Type), "SHORT");
return true;
} // endif Type
if (trace(1))
htrc(" adding SHORT(%d): %hd\n", Nval, n);
//Value->SetValue(n);
//Vblp->SetValue(valp, Nval++);
xtrc(1, " adding SHORT(%d): %hd\n", Nval, n);
Vblp->SetValue(n, Nval++);
return false;
} // end of AddValue
} // end of AddValue
/***********************************************************************/
/* Add an integer element to an array. */
/***********************************************************************/
bool ARRAY::AddValue(PGLOBAL g, int n)
{
{
if (Type != TYPE_INT) {
sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(Type), "INTEGER");
return true;
} // endif Type
if (trace(1))
htrc(" adding int(%d): %d\n", Nval, n);
//Value->SetValue(n);
//Vblp->SetValue(valp, Nval++);
xtrc(1, " adding int(%d): %d\n", Nval, n);
Vblp->SetValue(n, Nval++);
return false;
} // end of AddValue
} // end of AddValue
/***********************************************************************/
/* Add a double float element to an array. */
/***********************************************************************/
bool ARRAY::AddValue(PGLOBAL g, double d)
{
{
if (Type != TYPE_DOUBLE) {
sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(Type), "DOUBLE");
return true;
} // endif Type
if (trace(1))
htrc(" adding float(%d): %lf\n", Nval, d);
xtrc(1, " adding float(%d): %lf\n", Nval, d);
Value->SetValue(d);
Vblp->SetValue(Value, Nval++);
return false;
} // end of AddValue
} // end of AddValue
/***********************************************************************/
/* Add the value of a XOBJECT block to an array. */
/***********************************************************************/
bool ARRAY::AddValue(PGLOBAL g, PXOB xp)
{
{
if (Type != xp->GetResultType()) {
sprintf(g->Message, MSG(ADD_BAD_TYPE),
GetTypeName(xp->GetResultType()), GetTypeName(Type));
return true;
} // endif Type
if (trace(1))
htrc(" adding (%d) from xp=%p\n", Nval, xp);
//AddValue(xp->GetValue());
xtrc(1, " adding (%d) from xp=%p\n", Nval, xp);
Vblp->SetValue(xp->GetValue(), Nval++);
return false;
} // end of AddValue
} // end of AddValue
/***********************************************************************/
/* Add a value to an array. */
/***********************************************************************/
bool ARRAY::AddValue(PGLOBAL g, PVAL vp)
{
{
if (Type != vp->GetType()) {
sprintf(g->Message, MSG(ADD_BAD_TYPE),
GetTypeName(vp->GetType()), GetTypeName(Type));
return true;
} // endif Type
if (trace(1))
htrc(" adding (%d) from vp=%p\n", Nval, vp);
xtrc(1, " adding (%d) from vp=%p\n", Nval, vp);
Vblp->SetValue(vp, Nval++);
return false;
} // end of AddValue
} // end of AddValue
/***********************************************************************/
/* Retrieve the nth value of the array. */
......@@ -973,7 +954,7 @@ int ARRAY::BlockTest(PGLOBAL, int opc, int opm,
/* MakeArrayList: Makes a value list from an SQL IN array (in work). */
/***********************************************************************/
PSZ ARRAY::MakeArrayList(PGLOBAL g)
{
{
char *p, *tp;
int i;
size_t z, len = 2;
......@@ -990,9 +971,7 @@ PSZ ARRAY::MakeArrayList(PGLOBAL g)
len += strlen(tp);
} // enfor i
if (trace(1))
htrc("Arraylist: len=%d\n", len);
xtrc(1, "Arraylist: len=%d\n", len);
p = (char *)PlugSubAlloc(g, NULL, len);
strcpy(p, "(");
......@@ -1003,17 +982,15 @@ PSZ ARRAY::MakeArrayList(PGLOBAL g)
strcat(p, (++i == Nval) ? ")" : ",");
} // enfor i
if (trace(1))
htrc("Arraylist: newlen=%d\n", strlen(p));
xtrc(1, "Arraylist: newlen=%d\n", strlen(p));
return p;
} // end of MakeArrayList
} // end of MakeArrayList
/***********************************************************************/
/* Make file output of ARRAY contents. */
/***********************************************************************/
void ARRAY::Printf(PGLOBAL g, FILE *f, uint n)
{
{
char m[64];
int lim = MY_MIN(Nval,10);
......@@ -1035,19 +1012,19 @@ void ARRAY::Printf(PGLOBAL g, FILE *f, uint n)
} else
fprintf(f, "%sVALLST: numval=%d\n", m, Nval);
} // end of Printf
} // end of Printf
/***********************************************************************/
/* Make string output of ARRAY contents. */
/***********************************************************************/
void ARRAY::Prints(PGLOBAL, char *ps, uint z)
{
{
if (z < 16)
return;
sprintf(ps, "ARRAY: type=%d\n", Type);
// More to be implemented later
} // end of Prints
} // end of Prints
/* -------------------------- Class MULAR ---------------------------- */
......
......@@ -38,9 +38,7 @@ typedef class BLOCK *PBLOCK;
class DllExport BLOCK {
public:
void * operator new(size_t size, PGLOBAL g, void *p = NULL) {
if (trace(256))
htrc("New BLOCK: size=%d g=%p p=%p\n", size, g, p);
xtrc(256, "New BLOCK: size=%d g=%p p=%p\n", size, g, p);
return (PlugSubAlloc(g, p, size));
} // end of new
......
......@@ -33,6 +33,7 @@
/* plgdbsem.h is header containing the DB applic. declarations. */
/***********************************************************************/
#define DONT_DEFINE_VOID
#include <my_global.h>
#include "handler.h"
#undef OFFSET
......
......@@ -224,6 +224,7 @@ DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t);
DllExport char *PlugDup(PGLOBAL g, const char *str);
DllExport void *MakePtr(void *, OFFSET);
DllExport void htrc(char const *fmt, ...);
DllExport void xtrc(uint, char const* fmt, ...);
DllExport uint GetTraceValue(void);
#if defined(__cplusplus)
......
This diff is collapsed.
......@@ -194,7 +194,7 @@ static void PROFILE_Save( FILE *file, PROFILESECTION *section )
}
for (key = section->key; key; key = key->next)
if (key->name[0]) {
if (key->name && key->name[0]) {
fprintf(file, "%s", SVP(key->name));
if (key->value)
......
......@@ -813,4 +813,3 @@ PSZ JMgoConn::GetColumnValue(PSZ path)
return fld;
} // end of GetColumnValue
/****************** jsonudf C++ Program Source Code File (.CPP) ******************/
/* PROGRAM NAME: jsonudf Version 1.7 */
/* (C) Copyright to the author Olivier BERTRAND 2015-2018 */
/* PROGRAM NAME: jsonudf Version 1.8 */
/* (C) Copyright to the author Olivier BERTRAND 2015-2019 */
/* This program are the JSON User Defined Functions . */
/*********************************************************************************/
......@@ -1686,7 +1686,7 @@ static PCSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i)
} // endif *s
if (n < 1)
return "Key";
return (PCSZ) "Key";
if (!b) {
if ((p = (PSZ)PlgDBSubAlloc(g, NULL, n + 1))) {
......@@ -1703,7 +1703,7 @@ static PCSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i)
return s;
} // endif count
return "Key";
return (PCSZ) "Key";
} // end of MakeKey
/*********************************************************************************/
......
......@@ -1035,7 +1035,7 @@ PXNODE XML2NODE::AddChildNode(PGLOBAL g, PCSZ name, PXNODE np)
// If name has the format m[n] only m is taken as node name
if ((p = strchr(pn, '[')))
p = BufAlloc(g, pn, p - pn);
p = BufAlloc(g, pn, int(p - pn));
else
p = pn;
......
/***********************************************************************/
/* Definitions needed by the included files. */
/***********************************************************************/
#if !defined(MY_GLOBAL_H)
#define MY_GLOBAL_H
typedef unsigned int uint;
typedef unsigned int uint32;
typedef unsigned short ushort;
typedef unsigned long ulong;
typedef unsigned long DWORD;
typedef char *LPSTR;
typedef const char *LPCSTR;
typedef int BOOL;
#if defined(_WINDOWS)
typedef void *HANDLE;
#else
typedef int HANDLE;
#endif
typedef char *PSZ;
typedef const char *PCSZ;
typedef unsigned char BYTE;
typedef unsigned char uchar;
typedef long long longlong;
typedef unsigned long long ulonglong;
typedef char my_bool;
struct charset_info_st {};
typedef const charset_info_st CHARSET_INFO;
#define FALSE 0
#define TRUE 1
#define Item char
#define MY_MAX(a,b) ((a>b)?(a):(b))
#define MY_MIN(a,b) ((a<b)?(a):(b))
#endif // MY_GLOBAL_H
......@@ -16,9 +16,9 @@
/*************** Mycat CC Program Source Code File (.CC) ***************/
/* PROGRAM NAME: MYCAT */
/* ------------- */
/* Version 1.6 */
/* Version 1.7 */
/* */
/* Author: Olivier Bertrand 2012 - 2018 */
/* Author: Olivier Bertrand 2012 - 2019 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
......@@ -93,6 +93,9 @@
#if defined(ZIP_SUPPORT)
#include "tabzip.h"
#endif // ZIP_SUPPORT
#if defined(REST_SUPPORT)
#include "tabrest.h"
#endif // Rest_SUPPORT
#include "mycat.h"
/***********************************************************************/
......@@ -135,9 +138,6 @@ TABTYPE GetTypeID(const char *type)
#if defined(JAVA_SUPPORT)
: (!stricmp(type, "JDBC")) ? TAB_JDBC
#endif
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
: (!stricmp(type, "MONGO") && MongoEnabled()) ? TAB_MONGO
#endif
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
: (!stricmp(type, "MONGO") && MongoEnabled()) ? TAB_MONGO
#endif
......@@ -180,7 +180,8 @@ bool IsFileType(TABTYPE type)
case TAB_INI:
case TAB_VEC:
case TAB_JSON:
// case TAB_ZIP:
case TAB_REST:
// case TAB_ZIP:
isfile= true;
break;
default:
......@@ -482,16 +483,23 @@ void MYCAT::Reset(void)
/***********************************************************************/
PRELDEF MYCAT::GetTableDesc(PGLOBAL g, PTABLE tablep,
LPCSTR type, PRELDEF *)
{
{
PRELDEF tdp= NULL;
if (trace(1))
printf("GetTableDesc: name=%s am=%s\n", tablep->GetName(), SVP(type));
htrc("GetTableDesc: name=%s am=%s\n", tablep->GetName(), SVP(type));
// If not specified get the type of this table
if (!type)
type= Hc->GetStringOption("Type","*");
//if (!type)
// type= Hc->GetStringOption("Type","*");
return MakeTableDesc(g, tablep, type);
} // end of GetTableDesc
tdp= MakeTableDesc(g, tablep, type);
if (trace(1))
htrc("GetTableDesc: tdp=%p\n", tdp);
return tdp;
} // end of GetTableDesc
/***********************************************************************/
/* MakeTableDesc: make a table/view description. */
......@@ -500,17 +508,21 @@ PRELDEF MYCAT::GetTableDesc(PGLOBAL g, PTABLE tablep,
PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
{
TABTYPE tc;
LPCSTR name = (PSZ)PlugDup(g, tablep->GetName());
LPCSTR schema = (PSZ)PlugDup(g, tablep->GetSchema());
LPCSTR name= (PSZ)PlugDup(g, tablep->GetName());
LPCSTR schema= (PSZ)PlugDup(g, tablep->GetSchema());
PRELDEF tdp= NULL;
if (trace(1))
printf("MakeTableDesc: name=%s schema=%s am=%s\n",
htrc("MakeTableDesc: name=%s schema=%s am=%s\n",
name, SVP(schema), SVP(am));
/*********************************************************************/
/* Get a unique enum identifier for types. */
/*********************************************************************/
if (!am) {
tc= Hc->GetRealType();
am= Hc->GetStringOption("Type","*");
} else
tc= GetTypeID(am);
switch (tc) {
......@@ -550,6 +562,9 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
#if defined(ZIP_SUPPORT)
case TAB_ZIP: tdp = new(g) ZIPDEF; break;
#endif // ZIP_SUPPORT
#if defined(REST_SUPPORT)
case TAB_REST: tdp= new (g) RESTDEF; break;
#endif // REST_SUPPORT
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
case TAB_MONGO:
if (MongoEnabled()) {
......@@ -566,6 +581,9 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
if (tdp && tdp->Define(g, this, name, schema, am))
tdp= NULL;
if (trace(1))
htrc("Table %s made\n", am);
return tdp;
} // end of MakeTableDesc
......@@ -579,24 +597,27 @@ PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode, LPCSTR type)
// LPCSTR name= tablep->GetName();
if (trace(1))
printf("GetTableDB: name=%s\n", tablep->GetName());
htrc("GetTableDB: name=%s\n", tablep->GetName());
// Look for the description of the requested table
tdp= GetTableDesc(g, tablep, type);
if (tdp) {
if (trace(1))
printf("tdb=%p type=%s\n", tdp, tdp->GetType());
htrc("tdb=%p type=%s\n", tdp, tdp->GetType());
if (tablep->GetSchema())
tdp->Database = SetPath(g, tablep->GetSchema());
if (trace(2))
htrc("Going to get table...\n");
tdbp= tdp->GetTable(g, mode);
} // endif tdp
if (tdbp) {
if (trace(1))
printf("tdbp=%p name=%s amtype=%d\n", tdbp, tdbp->GetName(),
htrc("tdbp=%p name=%s amtype=%d\n", tdbp, tdbp->GetName(),
tdbp->GetAmType());
tablep->SetTo_Tdb(tdbp);
tdbp->SetTable(tablep);
......
......@@ -14,7 +14,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
/**************** MYCAT H Declares Source Code File (.H) ***************/
/* Name: MYCAT.H Version 2.3 */
/* Name: MYCAT.H Version 2.4 */
/* Author: Olivier Bertrand */
/* This file contains the CONNECT plugin MYCAT class definitions. */
/***********************************************************************/
......@@ -50,6 +50,8 @@ struct ha_table_option_struct {
const char *filter;
const char *oplist;
const char *data_charset;
const char *http;
const char *uri;
ulonglong lrecl;
ulonglong elements;
//ulonglong estimate;
......
......@@ -51,14 +51,14 @@ WEB XQuery Kick Start en Per Bothner 2003 49.99
WEB XQuery Kick Start en Kurt Cagle 2003 49.99
WEB Learning XML en Erik T. Ray 2003 39.95
Warnings:
Warning 1105 Mutiple values limited to 3
Warning 1105 Multiple values limited to 3
# One line lost because the where clause is applied only on the first 3 rows
SELECT category, title, author, price FROM bookstore WHERE author LIKE 'J%';
category title author price
CHILDREN Harry Potter J K. Rowling 29.99
WEB XQuery Kick Start James McGovern 49.99
Warnings:
Warning 1105 Mutiple values limited to 3
Warning 1105 Multiple values limited to 3
#
# Testing concatenated values
#
......@@ -91,12 +91,12 @@ CHILDREN Harry Potter en J K. Rowling 2005 29.99
WEB XQuery Kick Start en James McGovern, Per Bothner, Kurt Cagle, James Linn 2003 49.99
WEB Learning XML en Erik T. Ray 2003 39.95
Warnings:
Warning 1105 Mutiple values limited to 4
Warning 1105 Multiple values limited to 4
# The where clause is applied on the concatenated column result
SELECT category, title, author, price FROM bookstore WHERE author LIKE 'J%';
category title author price
CHILDREN Harry Potter J K. Rowling 29.99
WEB XQuery Kick Start James McGovern, Per Bothner, Kurt Cagle, James Linn 49.99
Warnings:
Warning 1105 Mutiple values limited to 4
Warning 1105 Multiple values limited to 4
DROP TABLE bookstore;
......@@ -49,14 +49,14 @@ WEB XQuery Kick Start en Per Bothner 2003 49.99
WEB XQuery Kick Start en Kurt Cagle 2003 49.99
WEB Learning XML en Erik T. Ray 2003 39.95
Warnings:
Warning 1105 Mutiple values limited to 3
Warning 1105 Multiple values limited to 3
# One line lost because the where clause is applied only on the first 3 rows
SELECT category, title, author, price FROM bookstore WHERE author LIKE 'J%';
category title author price
CHILDREN Harry Potter J K. Rowling 29.99
WEB XQuery Kick Start James McGovern 49.99
Warnings:
Warning 1105 Mutiple values limited to 3
Warning 1105 Multiple values limited to 3
#
# Testing concatenated values
#
......@@ -89,12 +89,12 @@ CHILDREN Harry Potter en J K. Rowling 2005 29.99
WEB XQuery Kick Start en James McGovern, Per Bothner, Kurt Cagle, James Linn 2003 49.99
WEB Learning XML en Erik T. Ray 2003 39.95
Warnings:
Warning 1105 Mutiple values limited to 4
Warning 1105 Multiple values limited to 4
# The where clause is applied on the concatenated column result
SELECT category, title, author, price FROM bookstore WHERE author LIKE 'J%';
category title author price
CHILDREN Harry Potter J K. Rowling 29.99
WEB XQuery Kick Start James McGovern, Per Bothner, Kurt Cagle, James Linn 49.99
Warnings:
Warning 1105 Mutiple values limited to 4
Warning 1105 Multiple values limited to 4
DROP TABLE bookstore;
......@@ -3,7 +3,11 @@
#define __OSUTIL_H__
#if defined(UNIX) || defined(UNIV_LINUX)
#if defined(MARIADB)
#include "my_global.h"
#else
#include "mini-global.h"
#endif
#include <errno.h>
#include <stddef.h>
#include "os.h"
......
/************** PlgDBSem H Declares Source Code File (.H) **************/
/* Name: PLGDBSEM.H Version 3.7 */
/* Name: PLGDBSEM.H Version 3.8 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 1998-2017 */
/* (C) Copyright to the author Olivier BERTRAND 1998-2019 */
/* */
/* This file contains the CONNECT storage engine definitions. */
/***********************************************************************/
......@@ -82,6 +82,7 @@ enum TABTYPE {TAB_UNDEF = 0, /* Table of undefined type */
TAB_JDBC = 26, /* Table accessed via JDBC */
TAB_ZIP = 27, /* ZIP file info table */
TAB_MONGO = 28, /* Table retrieved from MongoDB */
TAB_REST = 29, /* Table retrieved from Rest */
TAB_NIY = 30}; /* Table not implemented yet */
enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
......@@ -400,6 +401,7 @@ typedef class VCTDEF *PVCTDEF;
typedef class PIVOTDEF *PPIVOTDEF;
typedef class DOMDEF *PDOMDEF;
typedef class DIRDEF *PDIRDEF;
typedef class RESTDEF *PRESTDEF;
typedef class OEMDEF *POEMDEF;
typedef class COLCRT *PCOLCRT;
typedef class COLDEF *PCOLDEF;
......
......@@ -2,11 +2,11 @@
/* */
/* PROGRAM NAME: PLUGUTIL */
/* ------------- */
/* Version 3.0 */
/* Version 3.1 */
/* */
/* COPYRIGHT: */
/* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 1993-2017 */
/* (C) Copyright to the author Olivier BERTRAND 1993-2019 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
......@@ -111,21 +111,31 @@ ACTIVITY defActivity = { /* Describes activity and language */
#endif // UNIX
/**************************************************************************/
/* Tracing output function. */
/* Conditional tracing output function. */
/**************************************************************************/
void htrc(char const *fmt, ...)
{
void xtrc(uint x, char const *fmt, ...)
{
if (GetTraceValue() & x) {
va_list ap;
va_start (ap, fmt);
va_start(ap, fmt);
//if (trace == 1)
// vfprintf(debug, fmt, ap);
//else
vfprintf(stderr, fmt, ap);
va_end(ap);
} // endif x
} // end of xtrc
/**************************************************************************/
/* Tracing output function. */
/**************************************************************************/
void htrc(char const* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
va_end (ap);
} // end of htrc
vfprintf(stderr, fmt, ap);
va_end(ap);
} // end of htrc
/***********************************************************************/
/* Plug initialization routine. */
......
......@@ -457,6 +457,10 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
recln = MY_MAX(recln, Hc->GetIntegerOption("Lrecl"));
Hc->SetIntegerOption("Lrecl", recln);
((PDOSDEF)this)->SetLrecl(recln);
if (trace(1))
htrc("Lrecl set to %d\n", recln);
} // endif Lrecl
// Attach the column definition to the tabdef
......@@ -487,15 +491,16 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
PCATLG cat = Cat;
/*********************************************************************/
/* Ensure that the .dll doesn't have a path. */
/* This is done to ensure that only approved dll from the system */
/* Ensure that the module name doesn't have a path. */
/* This is done to ensure that only approved libs 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());
// PlugSetPath(soname, Module, GetPluginDir()); // Crashes on Fedora
strncat(strcpy(soname, GetPluginDir()), Module, _MAX_PATH);
#if defined(__WIN__)
// Is the DLL already loaded?
......
LIBRARY REST2
EXPORTS
GetREST @1
ColREST @2
/************* Restget C++ Program Source Code File (.CPP) *************/
/* Adapted from the sample program of the Casablanca tutorial. */
/* Copyright Olivier Bertrand 2019. */
/***********************************************************************/
#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.
using namespace web::http; // Common HTTP functionality
using namespace web::http::client; // HTTP client features
using namespace concurrency::streams; // Asynchronous streams
#include "global.h"
/***********************************************************************/
/* Make a local copy of the requested file. */
/***********************************************************************/
int restGetFile(PGLOBAL g, 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");
return 2;
} // endif
if (xt)
htrc("restGetFile: fn=%s\n", fn);
// Open stream to output file.
pplx::task<void> requestTask = fstream::open_ostream(to_string_t(fn))
.then([=](ostream outFile) {
*fileStream= outFile;
if (xt)
htrc("Outfile isopen=%d\n", outFile.is_open());
// Create http_client to send the request.
http_client client(to_string_t(http));
if (uri) {
// Build request URI and start the request.
uri_builder builder(to_string_t(uri));
return client.request(methods::GET, builder.to_string());
} else
return client.request(methods::GET);
})
// Handle response headers arriving.
.then([=](http_response response) {
if (xt)
htrc("Received response status code:%u\n",
response.status_code());
// Write response body into the file.
return response.body().read_to_end(fileStream->streambuf());
})
// Close the file stream.
.then([=](size_t n) {
if (xt)
htrc("Return size=%u\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");
} catch (const std::exception &e) {
if (xt)
htrc("Error exception: %s\n", e.what());
sprintf(g->Message, "Error exception: %s", e.what());
rc= 1;
} // end try/catch
if (xt)
htrc("restget done: rc=%d\n", rc);
return rc;
} // end of restGetFile
......@@ -189,9 +189,11 @@ PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info)
htrc("File %s Sep=%c Qot=%c Header=%d maxerr=%d\n",
SVP(tdp->Fn), tdp->Sep, tdp->Qot, tdp->Header, tdp->Maxerr);
#if defined(ZIP_SUPPORT)
if (tdp->Zipped)
tcvp = new(g)TDBCSV(tdp, new(g)UNZFAM(tdp));
else
#endif // ZIP_SUPPORT
tcvp = new(g) TDBCSV(tdp, new(g) DOSFAM(tdp));
tcvp->SetMode(MODE_READ);
......
......@@ -72,7 +72,6 @@
#include "tabext.h"
#include "tabjdbc.h"
#include "tabmul.h"
//#include "reldef.h"
#include "tabcol.h"
#include "valblk.h"
#include "ha_connect.h"
......@@ -89,6 +88,9 @@ extern int num_read, num_there, num_eq[2]; // Statistics
/* External function. */
/***********************************************************************/
bool ExactInfo(void);
#if defined(DEVELOPMENT)
extern char *GetUserVariable(PGLOBAL g, const uchar *varname);
#endif // DEVELOPMENT
/* -------------------------- Class JDBCDEF -------------------------- */
......@@ -147,10 +149,6 @@ int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b)
return RC_FX;
Tabname = p;
// } else if (b) {
// // Otherwise, straight server name,
// Tabname = GetStringCatInfo(g, "Name", NULL);
// Tabname = GetStringCatInfo(g, "Tabname", Tabname);
} // endif
if (trace(1))
......@@ -165,6 +163,11 @@ int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b)
return RC_FX;
} // endif server
#if defined(DEVELOPMENT)
if (*server->host == '@') {
Url = GetUserVariable(g, (const uchar*)&server->host[1]);
} else
#endif // 0
if (strncmp(server->host, "jdbc:", 5)) {
// Now make the required URL
Url = (PSZ)PlugSubAlloc(g, NULL, 0);
......@@ -191,6 +194,9 @@ int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b)
if (!Password && server->password)
Password = PlugDup(g, server->password);
Driver = PlugDup(g, GetListOption(g, "Driver", server->owner, NULL));
Wrapname = PlugDup(g, GetListOption(g, "Wrapper", server->owner, NULL));
Memory = atoi(GetListOption(g, "Memory", server->owner, "0"));
return RC_NF;
} // endif
......@@ -208,7 +214,6 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
if (EXTDEF::DefineAM(g, am, poff))
return true;
Driver = GetStringCatInfo(g, "Driver", NULL);
Desc = Url = GetStringCatInfo(g, "Connect", NULL);
if (!Url && !Catfunc) {
......@@ -228,7 +233,10 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
return true;
} // endif rc
Wrapname = GetStringCatInfo(g, "Wrapper", NULL);
// Default values may have been set in ParseURL
Memory = GetIntCatInfo("Memory", Memory);
Driver = GetStringCatInfo(g, "Driver", Driver);
Wrapname = GetStringCatInfo(g, "Wrapper", Wrapname);
return false;
} // end of DefineAM
......@@ -633,7 +641,9 @@ bool TDBJDBC::OpenDB(PGLOBAL g)
Cnp->InitValue(g);
if ((n = Jcp->GetResultSize(Query->GetStr(), Cnp)) < 0) {
sprintf(g->Message, "Cannot get result size rc=%d", n);
char* msg = PlugDup(g, g->Message);
sprintf(g->Message, "Get result size: %s (rc=%d)", msg, n);
return true;
} else if (n) {
Jcp->m_Rows = n;
......
......@@ -572,7 +572,7 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Sep = *GetStringCatInfo(g, "Separator", ".");
Accept = GetBoolCatInfo("Accept", false);
// Don't use url as uri when called from REST OEM module
// Don't use url as MONGO uri when called from REST
if (stricmp(am, "REST") && (Uri = GetStringCatInfo(g, "Connect", NULL))) {
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
Collname = GetStringCatInfo(g, "Name",
......@@ -604,6 +604,9 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
/***********************************************************************/
PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
{
if (trace(1))
htrc("JSON GetTable Pretty=%d Uri=%s\n", Pretty, SVP(Uri));
if (Catfunc == FNC_COL)
return new(g)TDBJCL(this);
......
/*************** Rest C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: Rest Version 1.5 */
/* (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. */
/***********************************************************************/
/***********************************************************************/
/* Definitions needed by the included files. */
/***********************************************************************/
#if defined(MARIADB)
#include <my_global.h> // All MariaDB stuff
#else // !MARIADB OEM module
#include "mini-global.h"
#define _MAX_PATH 260
#if !defined(__WIN__)
#define __stdcall
#endif // !__WIN__
#define _OS_H_INCLUDED // Prevent os.h to be called
#endif // !MARIADB
/***********************************************************************/
/* Include application header files: */
/* global.h is header containing all global declarations. */
/* plgdbsem.h is header containing the DB application declarations. */
/* (x)table.h is header containing the TDBASE declarations. */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "xtable.h"
#include "filamtxt.h"
#include "tabdos.h"
#include "plgxml.h"
#include "tabxml.h"
#include "tabjson.h"
#include "tabfmt.h"
#include "tabrest.h"
/***********************************************************************/
/* Get the file from the Web. */
/***********************************************************************/
int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn);
#if defined(__WIN__)
static PCSZ slash = "\\";
#else // !__WIN__
static PCSZ slash = "/";
#define stricmp strcasecmp
#endif // !__WIN__
#if !defined(MARIADB)
/***********************************************************************/
/* DB static variables. */
/***********************************************************************/
int TDB::Tnum;
int DTVAL::Shift;
int CSORT::Limit = 0;
double CSORT::Lg2 = log(2.0);
size_t CSORT::Cpn[1000] = { 0 };
/***********************************************************************/
/* These functions are exported from the REST library. */
/***********************************************************************/
extern "C" {
PTABDEF __stdcall GetREST(PGLOBAL, void*);
PQRYRES __stdcall ColREST(PGLOBAL, PTOS, char*, char*, bool);
} // extern "C"
/***********************************************************************/
/* This function returns a table definition class. */
/***********************************************************************/
PTABDEF __stdcall GetREST(PGLOBAL g, void *memp)
{
return new(g, memp) RESTDEF;
} // end of GetREST
#endif // !MARIADB
/***********************************************************************/
/* Return the columns definition to MariaDB. */
/***********************************************************************/
#if defined(MARIADB)
PQRYRES RESTColumns(PGLOBAL g, PTOS tp, char *tab, char *db, bool info)
#else // !MARIADB
PQRYRES __stdcall ColREST(PGLOBAL g, PTOS tp, char *tab, char *db, bool info)
#endif // !MARIADB
{
PQRYRES qrp= NULL;
char filename[_MAX_PATH + 1]; // MAX PATH ???
PCSZ http, uri, fn, ftype;
http = GetStringTableOption(g, tp, "Http", NULL);
uri = GetStringTableOption(g, tp, "Uri", NULL);
fn = GetStringTableOption(g, tp, "Filename", "rest.json");
#if defined(MARIADB)
ftype = GetStringTableOption(g, tp, "Type", "JSON");
#else // !MARIADB
// OEM tables must specify the file type
ftype = GetStringTableOption(g, tp, "Ftype", "JSON");
#endif // !MARIADB
// We used the file name relative to recorded datapath
strcat(strcat(strcat(strcpy(filename, "."), slash), db), slash);
strncat(filename, fn, _MAX_PATH);
// Retrieve the file from the web and copy it locally
if (http && restGetFile(g, 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);
else if (!stricmp(ftype, "JSON"))
qrp = JSONColumns(g, db, NULL, tp, info);
else if (!stricmp(ftype, "CSV"))
qrp = CSVColumns(g, NULL, tp, info);
else
sprintf(g->Message, "Usupported file type %s", ftype);
return qrp;
} // end of RESTColumns
/* -------------------------- Class RESTDEF -------------------------- */
/***********************************************************************/
/* DefineAM: define specific AM block values. */
/***********************************************************************/
bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
char filename[_MAX_PATH + 1];
int rc = 0, n;
LPCSTR ftype;
#if defined(MARIADB)
ftype = GetStringCatInfo(g, "Type", "JSON");
#else // !MARIADB
// OEM tables must specify the file type
ftype = GetStringCatInfo(g, "Ftype", "JSON");
#endif // !MARIADB
if (trace(515))
htrc("ftype = %s am = %s\n", ftype, SVP(am));
n = (!stricmp(ftype, "JSON")) ? 1
: (!stricmp(ftype, "XML")) ? 2
: (!stricmp(ftype, "CSV")) ? 3 : 0;
if (n == 0) {
htrc("DefineAM: Unsupported REST table type %s", am);
sprintf(g->Message, "Unsupported REST table type %s", am);
return true;
} // endif n
Http = GetStringCatInfo(g, "Http", NULL);
Uri = GetStringCatInfo(g, "Uri", NULL);
Fn = GetStringCatInfo(g, "Filename", "rest.json");
// We used the file name relative to recorded datapath
//PlugSetPath(filename, Fn, GetPath());
strncat(strcpy(filename, GetPath()), Fn, _MAX_PATH);
// Retrieve the file from the web and copy it locally
rc = restGetFile(g, Http, Uri, filename);
if (trace(515))
htrc("Return from restGetFile: rc=%d\n", rc);
if (rc)
return true;
else switch (n) {
case 1: Tdp = new (g) JSONDEF; break;
case 2: Tdp = new (g) XMLDEF; break;
case 3: Tdp = new (g) CSVDEF; break;
default: Tdp = NULL;
} // endswitch n
// Do make the table/view definition
if (Tdp && Tdp->Define(g, Cat, Name, Schema, "REST"))
Tdp = NULL; // Error occured
if (trace(515))
htrc("Tdp defined\n", rc);
// Return true in case of error
return (Tdp == NULL);
} // end of DefineAM
/***********************************************************************/
/* GetTable: makes a new Table Description Block. */
/***********************************************************************/
PTDB RESTDEF::GetTable(PGLOBAL g, MODE m)
{
if (trace(515))
htrc("REST GetTable mode=%d\n", m);
if (m != MODE_READ && m != MODE_READX) {
strcpy(g->Message, "REST tables are currently read only");
return NULL;
} // endif m
return Tdp->GetTable(g, m); // Leave file type do the job
} // end of GetTable
/* ---------------------- End of Class RESTDEF ----------------------- */
/*************** TabRest H Declares Source Code File (.H) **************/
/* Name: tabrest.h Version 1.0 */
/* (C) Copyright to the author Olivier BERTRAND 2019 */
/* This file contains the common tabrest classes declares. */
/***********************************************************************/
#pragma once
/***********************************************************************/
/* Restest table. */
/***********************************************************************/
class RESTDEF : public TABDEF { /* Table description */
public:
// Constructor
RESTDEF(void) { Tdp = NULL; Http = Uri = Fn = NULL; }
// Implementation
virtual const char *GetType(void) { return "REST"; }
// Methods
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m);
protected:
// Members
PRELDEF Tdp;
PCSZ Http; /* Web connection HTTP */
PCSZ Uri; /* Web connection URI */
PCSZ Fn; /* The intermediate file name */
}; // end of class RESTDEF
......@@ -232,7 +232,7 @@ bool TDBTBL::InitTableList(PGLOBAL g)
{
int n;
uint sln;
char *scs;
const char *scs;
PTABLE tp, tabp;
PCOL colp;
PTBLDEF tdp = (PTBLDEF)To_Def;
......@@ -281,7 +281,7 @@ bool TDBTBL::InitTableList(PGLOBAL g)
} // endfor tp
hc->get_table()->s->connect_string.str = scs;
hc->get_table()->s->connect_string.str = (char*)scs;
hc->get_table()->s->connect_string.length = sln;
//NumTables = n;
......
......@@ -1880,7 +1880,7 @@ void XMULCOL::ReadColumn(PGLOBAL g)
if (N > Tdbp->Limit) {
N = Tdbp->Limit;
sprintf(g->Message, "Mutiple values limited to %d", Tdbp->Limit);
sprintf(g->Message, "Multiple values limited to %d", Tdbp->Limit);
PushWarning(g, Tdbp);
} // endif N
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment