summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2019-08-17 16:58:58 +0200
committerOlivier Bertrand <bertrandop@gmail.com>2019-08-17 16:58:58 +0200
commit4d93c7f3b0bfc59da369702c2eca725f1e362305 (patch)
tree83ea1ff5f3e4d4b7df712679132fd42771fda76e /storage
parentd302cb3534f4b4e8a5ae6e293b6ef2c2c9180862 (diff)
downloadmariadb-git-4d93c7f3b0bfc59da369702c2eca725f1e362305.tar.gz
In CONNECT version 1.6.10 NOSQL facility is enhanced by a new way to retrieve NOSQL data.
In addition to files and Mongo collections, JSON as well as XML and CSV data can be retrieved from the net as answers from REST queries. Because it uses and external package (cpprestsdk) this is currently available only to MariaDB servers compiled from source. -- Add compile flags needed on Windows /MD or /MDd (debug) -- Also include some changes needed on Linux modified: storage/connect/CMakeLists.txt - Add the xtrc tracing function modified: storage/connect/global.h modified: storage/connect/plugutil.cpp - Modify tracing to use xtrc and some typo modified: storage/connect/array.cpp modified: storage/connect/block.h modified: storage/connect/restget.cpp - Fix compilation error when ZIP is not supported modified: storage/connect/ha_connect.cc modified: storage/connect/tabfmt.cpp - Add some tracing + typo modified: storage/connect/mycat.cc modified: storage/connect/tabjson.cpp - Add conditional code based on MARIADB This to be able to use the same code in CONNECT and EOM modules modified: storage/connect/osutil.h modified: storage/connect/tabrest.cpp - Replace PlugSetPath by some concat (crashed on Fedora) + typo modified: storage/connect/reldef.cpp - Try to fix test failures modified: zlib/CMakeLists.txt
Diffstat (limited to 'storage')
-rw-r--r--storage/connect/CMakeLists.txt17
-rw-r--r--storage/connect/array.cpp127
-rw-r--r--storage/connect/block.h4
-rw-r--r--storage/connect/global.h1
-rw-r--r--storage/connect/ha_connect.cc4
-rw-r--r--storage/connect/mini-global.h33
-rw-r--r--storage/connect/mycat.cc161
-rw-r--r--storage/connect/osutil.h4
-rw-r--r--storage/connect/plugutil.cpp36
-rw-r--r--storage/connect/reldef.cpp299
-rw-r--r--storage/connect/rest.def4
-rw-r--r--storage/connect/rest.h33
-rw-r--r--storage/connect/restget.cpp104
-rw-r--r--storage/connect/tabfmt.cpp2
-rw-r--r--storage/connect/tabjson.cpp1929
-rw-r--r--storage/connect/tabrest.cpp157
16 files changed, 1540 insertions, 1375 deletions
diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
index 8fc7cf695e7..6fd3b5e3018 100644
--- a/storage/connect/CMakeLists.txt
+++ b/storage/connect/CMakeLists.txt
@@ -68,6 +68,10 @@ 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
@@ -315,6 +319,12 @@ IF(CONNECT_WITH_REST)
FIND_PACKAGE(cpprestsdk)
IF (cpprestsdk_FOUND)
MESSAGE(STATUS "=====> cpprestsdk found")
+ IF(UNIX)
+# INCLUDE_DIRECTORIES(${CPPRESTSDK_INCLUDE_DIR})
+# Edit next line to set the path to libcpprest.so
+ SET(REST_LIBRARY -L/usr/lib64 -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)
@@ -341,7 +351,7 @@ 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()
@@ -349,8 +359,8 @@ ENDIF()
IF(WIN32)
IF (libmongoc-1.0_FOUND)
- SET_TARGET_PROPERTIES(connect PROPERTIES LINK_FLAGS
- "/DELAYLOAD:libbson-1.0.dll /DELAYLOAD:libmongoc-1.0.dll")
+ SET_TARGET_PROPERTIES(connect PROPERTIES LINK_FLAGS
+ "/DELAYLOAD:libbson-1.0.dll /DELAYLOAD:libmongoc-1.0.dll")
ENDIF(libmongoc-1.0_FOUND)
ENDIF(WIN32)
@@ -377,3 +387,4 @@ IF(CONNECT_WITH_JDBC AND JAVA_FOUND AND JNI_FOUND)
${CMAKE_CURRENT_BINARY_DIR}/JdbcInterface.jar
DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
ENDIF()
+
diff --git a/storage/connect/array.cpp b/storage/connect/array.cpp
index cd1785b48ac..3478342a788 100644
--- a/storage/connect/array.cpp
+++ b/storage/connect/array.cpp
@@ -1,7 +1,7 @@
/************* 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. */
@@ -127,13 +126,13 @@ PARRAY MakeValueArray(PGLOBAL g, PPARM pp)
// Integer stored inside pp->Value
par->AddValue(g, parmp->Intval);
break;
- } // endswitch valtyp
+ } // endswitch valtyp
/*********************************************************************/
/* 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);
+ } // endif Type
-//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);
+ } // endif Type
+ 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);
+ } // endif Type
-//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
+ } // 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);
+ } // endif Type
+ 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);
+{
+ if (Type != xp->GetResultType()) {
+ sprintf(g->Message, MSG(ADD_BAD_TYPE),
+ GetTypeName(xp->GetResultType()), GetTypeName(Type));
+ return true;
+ } // endif Type
-//AddValue(xp->GetValue());
- Vblp->SetValue(xp->GetValue(), Nval++);
- return false;
- } // end of AddValue
+ xtrc(1, " adding (%d) from xp=%p\n", Nval, xp);
+ Vblp->SetValue(xp->GetValue(), Nval++);
+ return false;
+} // 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);
+ } // endif Type
+ 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;
@@ -988,11 +969,9 @@ PSZ ARRAY::MakeArrayList(PGLOBAL g)
Value->SetValue_pvblk(Vblp, i);
Value->Prints(g, tp, z);
len += strlen(tp);
- } // enfor i
-
- if (trace(1))
- htrc("Arraylist: len=%d\n", len);
+ } // enfor i
+ xtrc(1, "Arraylist: len=%d\n", len);
p = (char *)PlugSubAlloc(g, NULL, len);
strcpy(p, "(");
@@ -1001,19 +980,17 @@ PSZ ARRAY::MakeArrayList(PGLOBAL g)
Value->Prints(g, tp, z);
strcat(p, tp);
strcat(p, (++i == Nval) ? ")" : ",");
- } // enfor i
-
- if (trace(1))
- htrc("Arraylist: newlen=%d\n", strlen(p));
+ } // enfor i
+ 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 ---------------------------- */
diff --git a/storage/connect/block.h b/storage/connect/block.h
index 737c74c1293..2ca9586ee3f 100644
--- a/storage/connect/block.h
+++ b/storage/connect/block.h
@@ -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
diff --git a/storage/connect/global.h b/storage/connect/global.h
index dc1e149745f..fd26c87b800 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -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)
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index e7d1b5f0e86..be7c6548181 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -241,7 +241,9 @@ int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v);
void PushWarning(PGLOBAL g, THD *thd, int level);
bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, PCSZ host, PCSZ db,
PCSZ tab, PCSZ src, int port);
+#if defined(ZIP_SUPPORT)
bool ZipLoadFile(PGLOBAL, PCSZ, PCSZ, PCSZ, bool, bool);
+#endif // ZIP_SUPPORT
bool ExactInfo(void);
#if defined(CMGO_SUPPORT)
//void mongo_init(bool);
@@ -6730,6 +6732,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
if (trace(1))
htrc("xchk=%p createas=%d\n", g->Xchk, g->Createas);
+#if defined(ZIP_SUPPORT)
if (options->zipped) {
// Check whether the zip entry must be made from a file
PCSZ fn= GetListOption(g, "Load", options->oplist, NULL);
@@ -6759,6 +6762,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} // endif fn
} // endif zipped
+#endif // ZIP_SUPPORT
// To check whether indexes have to be made or remade
if (!g->Xchk) {
diff --git a/storage/connect/mini-global.h b/storage/connect/mini-global.h
new file mode 100644
index 00000000000..f712795827c
--- /dev/null
+++ b/storage/connect/mini-global.h
@@ -0,0 +1,33 @@
+/***********************************************************************/
+/* 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
diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc
index 5c67b92ec36..b1d23b8c5e2 100644
--- a/storage/connect/mycat.cc
+++ b/storage/connect/mycat.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
/*************** Mycat CC Program Source Code File (.CC) ***************/
/* PROGRAM NAME: MYCAT */
@@ -95,7 +95,7 @@
#endif // ZIP_SUPPORT
#if defined(REST_SUPPORT)
#include "tabrest.h"
-#endif // REST_SUPPORT
+#endif // Rest_SUPPORT
#include "mycat.h"
/***********************************************************************/
@@ -104,11 +104,9 @@
#if defined(__WIN__)
extern "C" HINSTANCE s_hModule; // Saved module handle
#endif // !__WIN__
-
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
bool MongoEnabled(void);
#endif // JAVA_SUPPORT || CMGO_SUPPORT
-
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
/***********************************************************************/
@@ -124,11 +122,11 @@ char *GetPluginDir(void)
/***********************************************************************/
TABTYPE GetTypeID(const char *type)
{
- return (!type) ? TAB_UNDEF
+ return (!type) ? TAB_UNDEF
: (!stricmp(type, "DOS")) ? TAB_DOS
: (!stricmp(type, "FIX")) ? TAB_FIX
: (!stricmp(type, "BIN")) ? TAB_BIN
- : (!stricmp(type, "CSV")) ? TAB_CSV
+ : (!stricmp(type, "CSV")) ? TAB_CSV
: (!stricmp(type, "FMT")) ? TAB_FMT
: (!stricmp(type, "DBF")) ? TAB_DBF
#if defined(XML_SUPPORT)
@@ -140,30 +138,30 @@ TABTYPE GetTypeID(const char *type)
: (!stricmp(type, "ODBC")) ? TAB_ODBC
#endif
#if defined(JAVA_SUPPORT)
- : (!stricmp(type, "JDBC")) ? TAB_JDBC
+ : (!stricmp(type, "JDBC")) ? TAB_JDBC
#endif
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
- : (!stricmp(type, "MONGO") && MongoEnabled()) ? TAB_MONGO
+ : (!stricmp(type, "MONGO") && MongoEnabled()) ? TAB_MONGO
#endif
- : (!stricmp(type, "MYSQL")) ? TAB_MYSQL
+ : (!stricmp(type, "MYSQL")) ? TAB_MYSQL
: (!stricmp(type, "MYPRX")) ? TAB_MYSQL
: (!stricmp(type, "DIR")) ? TAB_DIR
#if defined(__WIN__)
- : (!stricmp(type, "MAC")) ? TAB_MAC
- : (!stricmp(type, "WMI")) ? TAB_WMI
+ : (!stricmp(type, "MAC")) ? TAB_MAC
+ : (!stricmp(type, "WMI")) ? TAB_WMI
#endif
- : (!stricmp(type, "TBL")) ? TAB_TBL
- : (!stricmp(type, "XCOL")) ? TAB_XCL
- : (!stricmp(type, "OCCUR")) ? TAB_OCCUR
+ : (!stricmp(type, "TBL")) ? TAB_TBL
+ : (!stricmp(type, "XCOL")) ? TAB_XCL
+ : (!stricmp(type, "OCCUR")) ? TAB_OCCUR
: (!stricmp(type, "CATLG")) ? TAB_PRX // Legacy
: (!stricmp(type, "PROXY")) ? TAB_PRX
: (!stricmp(type, "PIVOT")) ? TAB_PIVOT
: (!stricmp(type, "VIR")) ? TAB_VIR
: (!stricmp(type, "JSON")) ? TAB_JSON
#if defined(ZIP_SUPPORT)
- : (!stricmp(type, "ZIP")) ? TAB_ZIP
+ : (!stricmp(type, "ZIP")) ? TAB_ZIP
#endif
- : (!stricmp(type, "OEM")) ? TAB_OEM : TAB_NIY;
+ : (!stricmp(type, "OEM")) ? TAB_OEM : TAB_NIY;
} // end of GetTypeID
/***********************************************************************/
@@ -173,19 +171,19 @@ bool IsFileType(TABTYPE type)
{
bool isfile;
- switch (type) {
+ switch (type) {
case TAB_DOS:
case TAB_FIX:
case TAB_BIN:
- case TAB_CSV:
+ case TAB_CSV:
case TAB_FMT:
case TAB_DBF:
case TAB_XML:
case TAB_INI:
case TAB_VEC:
case TAB_JSON:
- case TAB_REST:
-// case TAB_ZIP:
+ case TAB_REST:
+ // case TAB_ZIP:
isfile= true;
break;
default:
@@ -203,7 +201,7 @@ bool IsExactType(TABTYPE type)
{
bool exact;
- switch (type) {
+ switch (type) {
case TAB_FIX:
case TAB_BIN:
case TAB_DBF:
@@ -228,7 +226,7 @@ bool IsTypeNullable(TABTYPE type)
{
bool nullable;
- switch (type) {
+ switch (type) {
case TAB_MAC:
case TAB_DIR:
nullable= false;
@@ -248,7 +246,7 @@ bool IsTypeFixed(TABTYPE type)
{
bool fix;
- switch (type) {
+ switch (type) {
case TAB_FIX:
case TAB_BIN:
case TAB_VEC:
@@ -270,7 +268,7 @@ bool IsTypeIndexable(TABTYPE type)
{
bool idx;
- switch (type) {
+ switch (type) {
case TAB_DOS:
case TAB_CSV:
case TAB_FMT:
@@ -296,7 +294,7 @@ int GetIndexType(TABTYPE type)
{
int xtyp;
- switch (type) {
+ switch (type) {
case TAB_DOS:
case TAB_CSV:
case TAB_FMT:
@@ -309,9 +307,9 @@ int GetIndexType(TABTYPE type)
break;
case TAB_MYSQL:
case TAB_ODBC:
- case TAB_JDBC:
- case TAB_MONGO:
- xtyp= 2;
+ case TAB_JDBC:
+ case TAB_MONGO:
+ xtyp= 2;
break;
case TAB_VIR:
xtyp= 3;
@@ -383,7 +381,7 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info)
return NULL;
} else
PlugSetPath(soname, module, GetPluginDir());
-
+
// The exported name is always in uppercase
for (int i = 0; ; i++) {
c = subtype[i];
@@ -460,7 +458,7 @@ CATALOG::CATALOG(void)
memset(&Ctb, 0, sizeof(CURTAB));
Cbuf= NULL;
Cblen= 0;
- DefHuge= false;
+ DefHuge= false;
} // end of CATALOG constructor
/* -------------------------- Class MYCAT ---------------------------- */
@@ -470,7 +468,7 @@ CATALOG::CATALOG(void)
/***********************************************************************/
MYCAT::MYCAT(PHC hc) : CATALOG()
{
- Hc= hc;
+ Hc= hc;
DefHuge= false;
} // end of MYCAT constructor
@@ -487,16 +485,23 @@ void MYCAT::Reset(void)
/***********************************************************************/
PRELDEF MYCAT::GetTableDesc(PGLOBAL g, PTABLE tablep,
LPCSTR type, PRELDEF *)
- {
- if (trace(1))
- printf("GetTableDesc: name=%s am=%s\n", tablep->GetName(), SVP(type));
+{
+ PRELDEF tdp= NULL;
- // If not specified get the type of this table
+ if (trace(1))
+ 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","*");
- 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. */
@@ -505,22 +510,22 @@ 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",
- name, SVP(schema), SVP(am));
+ if (trace(1))
+ 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);
+ if (!am) {
+ tc= Hc->GetRealType();
+ am= Hc->GetStringOption("Type","*");
+ } else
+ tc= GetTypeID(am);
switch (tc) {
case TAB_FIX:
@@ -535,49 +540,52 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
case TAB_XML: tdp= new(g) XMLDEF; break;
#endif // XML_SUPPORT
#if defined(VCT_SUPPORT)
- case TAB_VEC: tdp = new(g) VCTDEF; break;
+ case TAB_VEC: tdp = new(g) VCTDEF; break;
#endif // VCT_SUPPORT
#if defined(ODBC_SUPPORT)
case TAB_ODBC: tdp= new(g) ODBCDEF; break;
#endif // ODBC_SUPPORT
#if defined(JAVA_SUPPORT)
- case TAB_JDBC: tdp= new(g) JDBCDEF; break;
+ case TAB_JDBC: tdp= new(g) JDBCDEF; break;
#endif // JAVA_SUPPORT
#if defined(__WIN__)
case TAB_MAC: tdp= new(g) MACDEF; break;
case TAB_WMI: tdp= new(g) WMIDEF; break;
#endif // __WIN__
case TAB_OEM: tdp= new(g) OEMDEF; break;
- case TAB_TBL: tdp= new(g) TBLDEF; break;
- case TAB_XCL: tdp= new(g) XCLDEF; break;
- case TAB_PRX: tdp= new(g) PRXDEF; break;
- case TAB_OCCUR: tdp= new(g) OCCURDEF; break;
- case TAB_MYSQL: tdp= new(g) MYSQLDEF; break;
+ case TAB_TBL: tdp= new(g) TBLDEF; break;
+ case TAB_XCL: tdp= new(g) XCLDEF; break;
+ case TAB_PRX: tdp= new(g) PRXDEF; break;
+ case TAB_OCCUR: tdp= new(g) OCCURDEF; break;
+ case TAB_MYSQL: tdp= new(g) MYSQLDEF; break;
case TAB_PIVOT: tdp= new(g) PIVOTDEF; break;
case TAB_VIR: tdp= new(g) VIRDEF; break;
case TAB_JSON: tdp= new(g) JSONDEF; break;
#if defined(ZIP_SUPPORT)
- case TAB_ZIP: tdp= new(g) ZIPDEF; break;
+ case TAB_ZIP: tdp = new(g) ZIPDEF; break;
#endif // ZIP_SUPPORT
#if defined(REST_SUPPORT)
- case TAB_REST: tdp= new(g) RESTDEF; break;
+ case TAB_REST: tdp= new (g) RESTDEF; break;
#endif // REST_SUPPORT
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
- case TAB_MONGO:
- if (MongoEnabled()) {
- tdp = new(g) MGODEF;
- break;
- } // endif enabled
- // fall through
+ case TAB_MONGO:
+ if (MongoEnabled()) {
+ tdp = new(g) MGODEF;
+ break;
+ } // endif enabled
+ // fall through
#endif // JAVA_SUPPORT || CMGO_SUPPORT
- default:
- sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name);
+ default:
+ sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name);
} // endswitch
// Do make the table/view definition
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
@@ -590,26 +598,29 @@ PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode, LPCSTR type)
PTDB tdbp= NULL;
// LPCSTR name= tablep->GetName();
- if (trace(1))
- printf("GetTableDB: name=%s\n", tablep->GetName());
+ if (trace(1))
+ 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());
+ if (trace(1))
+ 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");
- if (tablep->GetSchema())
- tdp->Database = SetPath(g, tablep->GetSchema());
-
tdbp= tdp->GetTable(g, mode);
- } // endif tdp
+ } // endif tdp
if (tdbp) {
- if (trace(1))
- printf("tdbp=%p name=%s amtype=%d\n", tdbp, tdbp->GetName(),
- tdbp->GetAmType());
+ if (trace(1))
+ htrc("tdbp=%p name=%s amtype=%d\n", tdbp, tdbp->GetName(),
+ tdbp->GetAmType());
tablep->SetTo_Tdb(tdbp);
tdbp->SetTable(tablep);
tdbp->SetMode(mode);
diff --git a/storage/connect/osutil.h b/storage/connect/osutil.h
index 7e6b8823b9b..380e7bebb22 100644
--- a/storage/connect/osutil.h
+++ b/storage/connect/osutil.h
@@ -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"
diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp
index 6790e7eb45c..e74937b942a 100644
--- a/storage/connect/plugutil.cpp
+++ b/storage/connect/plugutil.cpp
@@ -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, ...)
- {
- va_list ap;
- va_start (ap, fmt);
+void xtrc(uint x, char const *fmt, ...)
+{
+ if (GetTraceValue() & x) {
+ va_list ap;
+ va_start(ap, fmt);
+
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ } // endif x
+} // end of xtrc
-//if (trace == 1)
-// vfprintf(debug, fmt, ap);
-//else
- vfprintf(stderr, fmt, ap);
+/**************************************************************************/
+/* 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. */
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp
index 30d8063d1a6..8ba8aac3621 100644
--- a/storage/connect/reldef.cpp
+++ b/storage/connect/reldef.cpp
@@ -81,51 +81,51 @@ RELDEF::RELDEF(void)
/* This function return a pointer to the Table Option Struct. */
/***********************************************************************/
PTOS RELDEF::GetTopt(void)
- {
- return Hc->GetTableOptionStruct();
- } // end of GetTopt
+ {
+ return Hc->GetTableOptionStruct();
+ } // end of GetTopt
/***********************************************************************/
/* This function sets an integer table information. */
/***********************************************************************/
bool RELDEF::SetIntCatInfo(PCSZ what, int n)
- {
- return Hc->SetIntegerOption(what, n);
- } // end of SetIntCatInfo
+ {
+ return Hc->SetIntegerOption(what, n);
+ } // end of SetIntCatInfo
/***********************************************************************/
/* This function returns integer table information. */
/***********************************************************************/
int RELDEF::GetIntCatInfo(PCSZ what, int idef)
- {
- int n= Hc->GetIntegerOption(what);
+ {
+ int n= Hc->GetIntegerOption(what);
- return (n == NO_IVAL) ? idef : n;
- } // end of GetIntCatInfo
+ return (n == NO_IVAL) ? idef : n;
+ } // end of GetIntCatInfo
/***********************************************************************/
/* This function returns Boolean table information. */
/***********************************************************************/
bool RELDEF::GetBoolCatInfo(PCSZ what, bool bdef)
- {
- bool b= Hc->GetBooleanOption(what, bdef);
+ {
+ bool b= Hc->GetBooleanOption(what, bdef);
- return b;
- } // end of GetBoolCatInfo
+ return b;
+ } // end of GetBoolCatInfo
/***********************************************************************/
/* This function returns size catalog information. */
/***********************************************************************/
int RELDEF::GetSizeCatInfo(PCSZ what, PCSZ sdef)
- {
- char c;
- PCSZ s;
+ {
+ char c;
+ PCSZ s;
int i, n= 0;
- if (!(s= Hc->GetStringOption(what)))
- s= sdef;
+ if (!(s= Hc->GetStringOption(what)))
+ s= sdef;
- if ((i= sscanf(s, " %d %c ", &n, &c)) == 2)
+ if ((i= sscanf(s, " %d %c ", &n, &c)) == 2)
switch (toupper(c)) {
case 'M':
n *= 1024;
@@ -141,41 +141,41 @@ int RELDEF::GetSizeCatInfo(PCSZ what, PCSZ sdef)
/* This function sets char table information in buf. */
/***********************************************************************/
int RELDEF::GetCharCatInfo(PCSZ what, PCSZ sdef, char *buf, int size)
- {
- PCSZ s= Hc->GetStringOption(what);
+ {
+ PCSZ s= Hc->GetStringOption(what);
- strncpy(buf, ((s) ? s : sdef), size);
- return size;
- } // end of GetCharCatInfo
+ strncpy(buf, ((s) ? s : sdef), size);
+ return size;
+ } // end of GetCharCatInfo
/***********************************************************************/
/* To be used by any TDB's. */
/***********************************************************************/
bool RELDEF::Partitioned(void)
- {
- return Hc->IsPartitioned();
- } // end of Partitioned
+ {
+ return Hc->IsPartitioned();
+ } // end of Partitioned
/***********************************************************************/
/* This function returns string table information. */
/* Default parameter is "*" to get the handler default. */
/***********************************************************************/
char *RELDEF::GetStringCatInfo(PGLOBAL g, PCSZ what, PCSZ sdef)
- {
- char *sval = NULL;
- PCSZ name, s= Hc->GetStringOption(what, sdef);
-
- if (s) {
+ {
+ char *sval = NULL;
+ PCSZ name, s= Hc->GetStringOption(what, sdef);
+
+ if (s) {
if (!Hc->IsPartitioned() ||
(stricmp(what, "filename") && stricmp(what, "tabname")
&& stricmp(what, "connect")))
- sval= PlugDup(g, s);
+ sval= PlugDup(g, s);
else
sval= (char*)s;
} else if (!stricmp(what, "filename")) {
// Return default file name
- PCSZ ftype= Hc->GetStringOption("Type", "*");
+ PCSZ ftype= Hc->GetStringOption("Type", "*");
int i, n;
if (IsFileType(GetTypeID(ftype))) {
@@ -183,7 +183,7 @@ char *RELDEF::GetStringCatInfo(PGLOBAL g, PCSZ what, PCSZ sdef)
sval= (char*)PlugSubAlloc(g, NULL, strlen(name) + 12);
strcat(strcpy(sval, name), ".");
n= strlen(sval);
-
+
// Fold ftype to lower case
for (i= 0; i < 12; i++)
if (!ftype[i]) {
@@ -196,8 +196,8 @@ char *RELDEF::GetStringCatInfo(PGLOBAL g, PCSZ what, PCSZ sdef)
} // endif s
- return sval;
- } // end of GetStringCatInfo
+ return sval;
+ } // end of GetStringCatInfo
/* --------------------------- Class TABDEF -------------------------- */
@@ -223,14 +223,14 @@ TABDEF::TABDEF(void)
/***********************************************************************/
/* Define: initialize the table definition block from XDB file. */
/***********************************************************************/
-bool TABDEF::Define(PGLOBAL g, PCATLG cat,
- LPCSTR name, LPCSTR schema, LPCSTR am)
+bool TABDEF::Define(PGLOBAL g, PCATLG cat,
+ LPCSTR name, LPCSTR schema, LPCSTR am)
{
int poff = 0;
- Hc = ((MYCAT*)cat)->GetHandler();
- Name = (PSZ)name;
- Schema = (PSZ)Hc->GetDBName(schema);
+ Hc = ((MYCAT*)cat)->GetHandler();
+ Name = (PSZ)name;
+ Schema = (PSZ)Hc->GetDBName(schema);
Cat = cat;
Catfunc = GetFuncID(GetStringCatInfo(g, "Catfunc", NULL));
Elemt = GetIntCatInfo("Elements", 0);
@@ -263,14 +263,14 @@ PCSZ TABDEF::GetPath(void)
/* This function returns column table information. */
/***********************************************************************/
int TABDEF::GetColCatInfo(PGLOBAL g)
- {
- char *type= GetStringCatInfo(g, "Type", "*");
+ {
+ char *type= GetStringCatInfo(g, "Type", "*");
char c, fty, eds;
- int i, n, loff, poff, nof, nlg;
- void *field= NULL;
+ int i, n, loff, poff, nof, nlg;
+ void *field= NULL;
TABTYPE tc;
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));
@@ -278,33 +278,33 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
tc= (Catfunc == FNC_NO) ? GetTypeID(type) : TAB_PRX;
// Take care of the column definitions
- i= poff= nof= nlg= 0;
+ i= poff= nof= nlg= 0;
#if defined(__WIN__)
- // Offsets of HTML and DIR tables start from 0, DBF at 1
- loff= (tc == TAB_DBF) ? 1 : (tc == TAB_XML || tc == TAB_DIR) ? -1 : 0;
+ // 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;
#else // !__WIN__
- // Offsets of HTML tables start from 0, DIR and DBF at 1
- loff = (tc == TAB_DBF || tc == TAB_DIR) ? 1 : (tc == TAB_XML) ? -1 : 0;
+ // 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;
#endif // !__WIN__
while (true) {
- // Default Offset depends on table type
- switch (tc) {
+ // Default Offset depends on table type
+ switch (tc) {
case TAB_DOS:
case TAB_FIX:
case TAB_BIN:
case TAB_VEC:
case TAB_DBF:
- poff= loff + nof; // Default next offset
- nlg= MY_MAX(nlg, poff); // Default lrecl
+ poff= loff + nof; // Default next offset
+ nlg= MY_MAX(nlg, poff); // Default lrecl
break;
case TAB_CSV:
case TAB_FMT:
- nlg+= nof;
+ nlg+= nof;
case TAB_DIR:
case TAB_XML:
- poff= loff + (pcf->Flags & U_VIRTUAL ? 0 : 1);
+ poff= loff + (pcf->Flags & U_VIRTUAL ? 0 : 1);
break;
case TAB_INI:
case TAB_MAC:
@@ -316,39 +316,39 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
poff = 0; // Offset represents an independant flag
break;
default: // VCT PLG ODBC JDBC MYSQL WMI...
- poff = 0; // NA
+ poff = 0; // NA
break;
- } // endswitch tc
+ } // endswitch tc
-// do {
- field= Hc->GetColumnOption(g, field, pcf);
+// do {
+ field= Hc->GetColumnOption(g, field, pcf);
// } while (field && (*pcf->Name =='*' /*|| pcf->Flags & U_VIRTUAL*/));
- if (tc == TAB_DBF && pcf->Type == TYPE_DATE && !pcf->Datefmt) {
- // DBF date format defaults to 'YYYMMDD'
- pcf->Datefmt= "YYYYMMDD";
- pcf->Length= 8;
- } // endif tc
+ if (tc == TAB_DBF && pcf->Type == TYPE_DATE && !pcf->Datefmt) {
+ // DBF date format defaults to 'YYYMMDD'
+ pcf->Datefmt= "YYYYMMDD";
+ pcf->Length= 8;
+ } // endif tc
- if (!field)
- break;
+ if (!field)
+ break;
// Allocate the column description block
cdp= new(g) COLDEF;
if ((nof= cdp->Define(g, NULL, pcf, poff)) < 0)
- return -1; // Error, probably unhandled type
- else
- loff= cdp->GetOffset();
-
- switch (tc) {
- case TAB_VEC:
- cdp->SetOffset(0); // Not to have shift
- case TAB_BIN:
- // BIN/VEC are packed by default
+ return -1; // Error, probably unhandled type
+ else
+ loff= cdp->GetOffset();
+
+ switch (tc) {
+ case TAB_VEC:
+ cdp->SetOffset(0); // Not to have shift
+ case TAB_BIN:
+ // BIN/VEC are packed by default
if (nof) {
- // Field width is the internal representation width
- // that can also depend on the column format
+ // Field width is the internal representation width
+ // that can also depend on the column format
fty = cdp->Decode ? 'C' : 'X';
eds = 0;
n = 0;
@@ -371,38 +371,38 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
if (n)
nof = n;
else switch (fty) {
- case 'X':
+ case 'X':
if (eds && IsTypeChar(cdp->Buf_Type))
nof = sizeof(longlong);
else
nof= cdp->Clen;
break;
- case 'C': break;
- case 'R':
- case 'F': nof = sizeof(float); break;
- case 'I': nof = sizeof(int); break;
- case 'D': nof = sizeof(double); break;
- case 'S': nof = sizeof(short); break;
- case 'T': nof = sizeof(char); break;
- case 'G': nof = sizeof(longlong); break;
- default: /* Wrong format */
+ case 'C': break;
+ case 'R':
+ case 'F': nof = sizeof(float); break;
+ case 'I': nof = sizeof(int); break;
+ case 'D': nof = sizeof(double); break;
+ case 'S': nof = sizeof(short); break;
+ case 'T': nof = sizeof(char); break;
+ case 'G': nof = sizeof(longlong); break;
+ default: /* Wrong format */
sprintf(g->Message, "Invalid format %c", fty);
return -1;
- } // endswitch fty
+ } // endswitch fty
} // endif nof
default:
- break;
- } // endswitch tc
+ break;
+ } // endswitch tc
- if (lcdp)
- lcdp->SetNext(cdp);
- else
- tocols= cdp;
+ if (lcdp)
+ lcdp->SetNext(cdp);
+ else
+ tocols= cdp;
- lcdp= cdp;
+ lcdp= cdp;
i++;
} // endwhile
@@ -410,31 +410,31 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
if (i != GetDegree())
SetDegree(i);
- if (GetDefType() == TYPE_AM_DOS) {
- int ending, recln= 0;
+ if (GetDefType() == TYPE_AM_DOS) {
+ int ending, recln= 0;
- // Was commented because sometimes ending is 0 even when
- // not specified (for instance if quoted is specified)
-// if ((ending= Hc->GetIntegerOption("Ending")) < 0) {
- if ((ending= Hc->GetIntegerOption("Ending")) <= 0) {
+ // Was commented because sometimes ending is 0 even when
+ // not specified (for instance if quoted is specified)
+// if ((ending= Hc->GetIntegerOption("Ending")) < 0) {
+ if ((ending= Hc->GetIntegerOption("Ending")) <= 0) {
ending= (tc == TAB_BIN || tc == TAB_VEC) ? 0 : CRLF;
- Hc->SetIntegerOption("Ending", ending);
- } // endif ending
+ Hc->SetIntegerOption("Ending", ending);
+ } // endif ending
- // Calculate the default record size
- switch (tc) {
+ // Calculate the default record size
+ switch (tc) {
case TAB_FIX:
case TAB_BIN:
recln= nlg + ending; // + length of line ending
break;
case TAB_VEC:
recln= nlg;
-
+
// if ((k= (pak < 0) ? 8 : pak) > 1)
// See above for detailed comment
// Round up lrecl to multiple of 8 or pak
// recln= ((recln + k - 1) / k) * k;
-
+
break;
case TAB_DOS:
case TAB_DBF:
@@ -443,26 +443,30 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
case TAB_CSV:
case TAB_FMT:
// The number of separators (assuming an extra one can exist)
-// recln= poff * ((qotd) ? 3 : 1); to be investigated
- recln= nlg + poff * 3; // To be safe
+// recln= poff * ((qotd) ? 3 : 1); to be investigated
+ recln= nlg + poff * 3; // To be safe
default:
break;
} // endswitch tc
- // lrecl must be at least recln to avoid buffer overflow
- if (trace(1))
- htrc("Lrecl: Calculated=%d defined=%d\n",
- recln, Hc->GetIntegerOption("Lrecl"));
+ // lrecl must be at least recln to avoid buffer overflow
+ if (trace(1))
+ htrc("Lrecl: Calculated=%d defined=%d\n",
+ recln, Hc->GetIntegerOption("Lrecl"));
- recln = MY_MAX(recln, Hc->GetIntegerOption("Lrecl"));
- Hc->SetIntegerOption("Lrecl", recln);
- ((PDOSDEF)this)->SetLrecl(recln);
- } // endif Lrecl
+ recln = MY_MAX(recln, Hc->GetIntegerOption("Lrecl"));
+ Hc->SetIntegerOption("Lrecl", recln);
+ ((PDOSDEF)this)->SetLrecl(recln);
- // Attach the column definition to the tabdef
- SetCols(tocols);
- return poff;
- } // end of GetColCatInfo
+ if (trace(1))
+ htrc("Lrecl set to %d\n", recln);
+
+ } // endif Lrecl
+
+ // Attach the column definition to the tabdef
+ SetCols(tocols);
+ return poff;
+ } // end of GetColCatInfo
/***********************************************************************/
/* SetIndexInfo: retrieve index description from the table structure. */
@@ -487,16 +491,17 @@ 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?
if (!Hdll && !(Hdll = GetModuleHandle(soname)))
@@ -522,31 +527,31 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
// Get the function returning an instance of the external DEF class
if (!(getdef = (XGETDEF)GetProcAddress((HINSTANCE)Hdll, getname))) {
- char buf[256];
- DWORD rc = GetLastError();
-
- sprintf(g->Message, MSG(PROCADD_ERROR), rc, getname);
- 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);
+ char buf[256];
+ DWORD rc = GetLastError();
+
+ sprintf(g->Message, MSG(PROCADD_ERROR), rc, getname);
+ 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 getdef
#else // !__WIN__
const char *error = NULL;
-
+
#if 0 // Don't know what all this stuff does
- Dl_info dl_info;
+ Dl_info dl_info;
- // The OEM lib must retrieve exported CONNECT variables
+ // The OEM lib must retrieve exported CONNECT variables
if (dladdr(&connect_hton, &dl_info)) {
if (dlopen(dl_info.dli_fname, RTLD_NOLOAD | RTLD_NOW | RTLD_GLOBAL) == 0) {
error = dlerror();
sprintf(g->Message, "dlopen failed: %s, OEM not supported", SVP(error));
return NULL;
} // endif dlopen
-
+
} else {
error = dlerror();
sprintf(g->Message, "dladdr failed: %s, OEM not supported", SVP(error));
@@ -626,7 +631,7 @@ bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int)
char *desc = (char*)PlugSubAlloc(g, NULL, strlen(Module)
+ strlen(Subtype) + 3);
sprintf(desc, "%s(%s)", Module, Subtype);
- Desc = desc;
+ Desc = desc;
return false;
} // end of DefineAM
@@ -701,17 +706,17 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
txfp = new(g) FIXFAM(defp);
} else if (rfm == RECFM_VCT) {
#if defined(VCT_SUPPORT)
- assert(Pxdef->GetDefType() == TYPE_AM_VCT);
+ assert(Pxdef->GetDefType() == TYPE_AM_VCT);
if (map)
txfp = new(g) VCMFAM((PVCTDEF)defp);
else
txfp = new(g) VCTFAM((PVCTDEF)defp);
#else // !VCT_SUPPORT
- strcpy(g->Message, "VCT no more supported");
- return NULL;
+ strcpy(g->Message, "VCT no more supported");
+ return NULL;
#endif // !VCT_SUPPORT
- } // endif's
+ } // endif's
((PTDBDOS)tdbp)->SetTxfp(txfp);
} // endif Txfp
diff --git a/storage/connect/rest.def b/storage/connect/rest.def
new file mode 100644
index 00000000000..71c76740af9
--- /dev/null
+++ b/storage/connect/rest.def
@@ -0,0 +1,4 @@
+LIBRARY REST2
+EXPORTS
+ GetREST @1
+ ColREST @2
diff --git a/storage/connect/rest.h b/storage/connect/rest.h
new file mode 100644
index 00000000000..f1d77e0a279
--- /dev/null
+++ b/storage/connect/rest.h
@@ -0,0 +1,33 @@
+/***********************************************************************/
+/* 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 \ No newline at end of file
diff --git a/storage/connect/restget.cpp b/storage/connect/restget.cpp
index 955e5f97fbc..d5ceb7b8a39 100644
--- a/storage/connect/restget.cpp
+++ b/storage/connect/restget.cpp
@@ -7,7 +7,8 @@
#if defined(MARIADB)
#include <my_global.h>
#else
-#include "mini_global.h"
+#include "mini-global.h"
+#define _OS_H_INCLUDED // Prevent os.h to be called
#endif
using namespace utility::conversions; // String conversions utilities
@@ -18,70 +19,71 @@ using namespace concurrency::streams; // Asynchronous streams
#include "global.h"
+static uint xt = 0; // Used by lamda expressions
/***********************************************************************/
/* Make a local copy of the requested file. */
/***********************************************************************/
int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn)
{
- int rc= 0;
- auto fileStream= std::make_shared<ostream>();
+ int rc = 0;
+ auto fileStream = std::make_shared<ostream>();
- if (!http || !fn) {
- strcpy(g->Message, "Missing http or filename");
- return 2;
- } // endif
+ if (!http || !fn) {
+ strcpy(g->Message, "Missing http or filename");
+ return 2;
+ } // endif
- //std::string sfn(fn);
- //auto wfn= to_string_t(sfn);
- //rc= 0;
+ xt = GetTraceValue();
+ xtrc(515, "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;
-
- // 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 defined(DEVELOPMENT)
- fprintf(stderr, "Received response status code:%u\n",
- response.status_code());
-#endif // DEVELOPMENT
-
- // Write response body into the file.
- return response.body().read_to_end(fileStream->streambuf());
- })
-
- // Close the file stream.
- .then([=](size_t) { return fileStream->close(); });
+ pplx::task<void> requestTask = fstream::open_ostream(to_string_t(fn))
+ .then([=](ostream outFile) {
+ *fileStream= outFile;
+
+ if (xt & 515)
+ 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 & 515)
+ 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 & 515)
+ htrc("Return size=%u\n", n);
+
+ return fileStream->close();
+ });
// Wait for all the outstanding I/O to complete and handle any exceptions
- try
- {
+ try {
requestTask.wait();
- }
- catch (const std::exception &e)
- {
-#if defined(DEVELOPMENT)
- fprintf(stderr, "Error exception: %s\n", e.what());
-#endif // DEVELOPMENT
- sprintf(g->Message, "Error exception: %s", e.what());
+ xtrc(515, "In Wait\n");
+ } catch (const std::exception &e) {
+ xtrc(515, "Error exception: %s\n", e.what());
+ sprintf(g->Message, "Error exception: %s", e.what());
rc= 1;
} // end try/catch
+ xtrc(515, "restget done: rc=%d\n", rc);
return rc;
-} // end of restGetFile \ No newline at end of file
+} // end of restGetFile
diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp
index 02720a3089a..746382178fb 100644
--- a/storage/connect/tabfmt.cpp
+++ b/storage/connect/tabfmt.cpp
@@ -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);
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index a8f76900cb4..0b282345c8a 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -71,15 +71,15 @@ char *GetJsonNull(void);
/***********************************************************************/
PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
{
- static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
+ static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING};
- static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
+ static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
FLD_LENGTH, FLD_SCALE, FLD_NULL, FLD_FORMAT};
static unsigned int length[] = {0, 6, 8, 10, 10, 6, 6, 0};
- int i, n = 0;
+ int i, n = 0;
int ncol = sizeof(buftyp) / sizeof(int);
- PJCL jcp;
- JSONDISC *pjdc = NULL;
+ PJCL jcp;
+ JSONDISC *pjdc = NULL;
PQRYRES qrp;
PCOLRES crp;
@@ -89,15 +89,15 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
goto skipit;
} // endif info
- if (GetIntegerTableOption(g, topt, "Multiple", 0)) {
- strcpy(g->Message, "Cannot find column definition for multiple table");
- return NULL;
- } // endif Multiple
+ if (GetIntegerTableOption(g, topt, "Multiple", 0)) {
+ strcpy(g->Message, "Cannot find column definition for multiple table");
+ return NULL;
+ } // endif Multiple
- pjdc = new(g) JSONDISC(g, length);
+ pjdc = new(g) JSONDISC(g, length);
- if (!(n = pjdc->GetColumns(g, db, dsn, topt)))
- return NULL;
+ if (!(n = pjdc->GetColumns(g, db, dsn, topt)))
+ return NULL;
skipit:
if (trace(1))
@@ -110,8 +110,8 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
buftyp, fldtyp, length, false, false);
crp = qrp->Colresp->Next->Next->Next->Next->Next->Next;
- crp->Name = PlugDup(g, "Nullable");
- crp->Next->Name = PlugDup(g, "Jpath");
+ crp->Name = PlugDup(g, "Nullable");
+ crp->Next->Name = PlugDup(g, "Jpath");
if (info || !qrp)
return qrp;
@@ -122,8 +122,8 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
/* Now get the results into blocks. */
/*********************************************************************/
for (i = 0, jcp = pjdc->fjcp; jcp; i++, jcp = jcp->Next) {
- if (jcp->Type == TYPE_UNKNOWN)
- jcp->Type = TYPE_STRING; // Void column
+ if (jcp->Type == TYPE_UNKNOWN)
+ jcp->Type = TYPE_STRING; // Void column
crp = qrp->Colresp; // Column Name
crp->Kdata->SetValue(jcp->Name, i);
@@ -159,380 +159,380 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
/***********************************************************************/
JSONDISC::JSONDISC(PGLOBAL g, uint *lg)
{
- length = lg;
- jcp = fjcp = pjcp = NULL;
- tjnp = NULL;
- jpp = NULL;
- tjsp = NULL;
- jsp = NULL;
- row = NULL;
- sep = NULL;
- i = n = bf = ncol = lvl = 0;
- all = false;
-} // end of JSONDISC constructor
+ length = lg;
+ jcp = fjcp = pjcp = NULL;
+ tjnp = NULL;
+ jpp = NULL;
+ tjsp = NULL;
+ jsp = NULL;
+ row = NULL;
+ sep = NULL;
+ i = n = bf = ncol = lvl = 0;
+ all = false;
+} // end of JSONDISC constructor
int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
{
- char filename[_MAX_PATH];
- bool mgo = (GetTypeID(topt->type) == TAB_MONGO);
- PCSZ level = GetStringTableOption(g, topt, "Level", NULL);
-
- if (level) {
- lvl = atoi(level);
- lvl = (lvl > 16) ? 16 : lvl;
- } else
- lvl = 0;
-
- sep = GetStringTableOption(g, topt, "Separator", ".");
-
- /*********************************************************************/
- /* Open the input file. */
- /*********************************************************************/
- tdp = new(g) JSONDEF;
+ char filename[_MAX_PATH];
+ bool mgo = (GetTypeID(topt->type) == TAB_MONGO);
+ PCSZ level = GetStringTableOption(g, topt, "Level", NULL);
+
+ if (level) {
+ lvl = atoi(level);
+ lvl = (lvl > 16) ? 16 : lvl;
+ } else
+ lvl = 0;
+
+ sep = GetStringTableOption(g, topt, "Separator", ".");
+
+ /*********************************************************************/
+ /* Open the input file. */
+ /*********************************************************************/
+ tdp = new(g) JSONDEF;
#if defined(ZIP_SUPPORT)
- tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL);
- tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false);
+ tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL);
+ tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false);
#endif // ZIP_SUPPORT
- tdp->Fn = GetStringTableOption(g, topt, "Filename", NULL);
-
- if (!(tdp->Database = SetPath(g, db)))
- return 0;
-
- tdp->Objname = GetStringTableOption(g, topt, "Object", NULL);
- tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0;
- tdp->Pretty = GetIntegerTableOption(g, topt, "Pretty", 2);
- tdp->Xcol = GetStringTableOption(g, topt, "Expand", NULL);
- tdp->Accept = GetBooleanTableOption(g, topt, "Accept", false);
- tdp->Uri = (dsn && *dsn ? dsn : NULL);
-
- if (!tdp->Fn && !tdp->Uri) {
- strcpy(g->Message, MSG(MISSING_FNAME));
- return 0;
- } // endif Fn
-
- if (tdp->Fn) {
- // We used the file name relative to recorded datapath
- PlugSetPath(filename, tdp->Fn, tdp->GetPath());
- tdp->Fn = PlugDup(g, filename);
- } // endif Fn
-
- if (trace(1))
- htrc("File %s objname=%s pretty=%d lvl=%d\n",
- tdp->Fn, tdp->Objname, tdp->Pretty, lvl);
-
- if (tdp->Uri) {
+ tdp->Fn = GetStringTableOption(g, topt, "Filename", NULL);
+
+ if (!(tdp->Database = SetPath(g, db)))
+ return 0;
+
+ tdp->Objname = GetStringTableOption(g, topt, "Object", NULL);
+ tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0;
+ tdp->Pretty = GetIntegerTableOption(g, topt, "Pretty", 2);
+ tdp->Xcol = GetStringTableOption(g, topt, "Expand", NULL);
+ tdp->Accept = GetBooleanTableOption(g, topt, "Accept", false);
+ tdp->Uri = (dsn && *dsn ? dsn : NULL);
+
+ if (!tdp->Fn && !tdp->Uri) {
+ strcpy(g->Message, MSG(MISSING_FNAME));
+ return 0;
+ } // endif Fn
+
+ if (tdp->Fn) {
+ // We used the file name relative to recorded datapath
+ PlugSetPath(filename, tdp->Fn, tdp->GetPath());
+ tdp->Fn = PlugDup(g, filename);
+ } // endif Fn
+
+ if (trace(1))
+ htrc("File %s objname=%s pretty=%d lvl=%d\n",
+ tdp->Fn, tdp->Objname, tdp->Pretty, lvl);
+
+ if (tdp->Uri) {
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
- tdp->Collname = GetStringTableOption(g, topt, "Name", NULL);
- tdp->Collname = GetStringTableOption(g, topt, "Tabname", tdp->Collname);
- tdp->Schema = GetStringTableOption(g, topt, "Dbname", "test");
- tdp->Options = (PSZ)GetStringTableOption(g, topt, "Colist", "all");
- tdp->Pipe = GetBooleanTableOption(g, topt, "Pipeline", false);
- tdp->Driver = (PSZ)GetStringTableOption(g, topt, "Driver", NULL);
- tdp->Version = GetIntegerTableOption(g, topt, "Version", 3);
- tdp->Wrapname = (PSZ)GetStringTableOption(g, topt, "Wrapper",
- (tdp->Version == 2) ? "Mongo2Interface" : "Mongo3Interface");
- tdp->Pretty = 0;
+ tdp->Collname = GetStringTableOption(g, topt, "Name", NULL);
+ tdp->Collname = GetStringTableOption(g, topt, "Tabname", tdp->Collname);
+ tdp->Schema = GetStringTableOption(g, topt, "Dbname", "test");
+ tdp->Options = (PSZ)GetStringTableOption(g, topt, "Colist", "all");
+ tdp->Pipe = GetBooleanTableOption(g, topt, "Pipeline", false);
+ tdp->Driver = (PSZ)GetStringTableOption(g, topt, "Driver", NULL);
+ tdp->Version = GetIntegerTableOption(g, topt, "Version", 3);
+ tdp->Wrapname = (PSZ)GetStringTableOption(g, topt, "Wrapper",
+ (tdp->Version == 2) ? "Mongo2Interface" : "Mongo3Interface");
+ tdp->Pretty = 0;
#else // !MONGO_SUPPORT
- sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO");
- return 0;
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO");
+ return 0;
#endif // !MONGO_SUPPORT
- } // endif Uri
+ } // endif Uri
- if (tdp->Pretty == 2) {
- if (tdp->Zipped) {
+ if (tdp->Pretty == 2) {
+ if (tdp->Zipped) {
#if defined(ZIP_SUPPORT)
- tjsp = new(g) TDBJSON(tdp, new(g) UNZFAM(tdp));
+ tjsp = new(g) TDBJSON(tdp, new(g) UNZFAM(tdp));
#else // !ZIP_SUPPORT
- sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
- return 0;
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
+ return 0;
#endif // !ZIP_SUPPORT
- } else
- tjsp = new(g) TDBJSON(tdp, new(g) MAPFAM(tdp));
+ } else
+ tjsp = new(g) TDBJSON(tdp, new(g) MAPFAM(tdp));
- if (tjsp->MakeDocument(g))
- return 0;
+ if (tjsp->MakeDocument(g))
+ return 0;
- jsp = (tjsp->GetDoc()) ? tjsp->GetDoc()->GetValue(0) : NULL;
- } else {
- if (!(tdp->Lrecl = GetIntegerTableOption(g, topt, "Lrecl", 0)))
- if (!mgo) {
- sprintf(g->Message, "LRECL must be specified for pretty=%d", tdp->Pretty);
- return 0;
- } else
- tdp->Lrecl = 8192; // Should be enough
+ jsp = (tjsp->GetDoc()) ? tjsp->GetDoc()->GetValue(0) : NULL;
+ } else {
+ if (!(tdp->Lrecl = GetIntegerTableOption(g, topt, "Lrecl", 0)))
+ if (!mgo) {
+ sprintf(g->Message, "LRECL must be specified for pretty=%d", tdp->Pretty);
+ return 0;
+ } else
+ tdp->Lrecl = 8192; // Should be enough
- tdp->Ending = GetIntegerTableOption(g, topt, "Ending", CRLF);
+ tdp->Ending = GetIntegerTableOption(g, topt, "Ending", CRLF);
- if (tdp->Zipped) {
+ if (tdp->Zipped) {
#if defined(ZIP_SUPPORT)
- tjnp = new(g)TDBJSN(tdp, new(g) UNZFAM(tdp));
+ tjnp = new(g)TDBJSN(tdp, new(g) UNZFAM(tdp));
#else // !ZIP_SUPPORT
- sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
- return NULL;
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
+ return NULL;
#endif // !ZIP_SUPPORT
- } else if (tdp->Uri) {
- if (tdp->Driver && toupper(*tdp->Driver) == 'C') {
+ } else if (tdp->Uri) {
+ if (tdp->Driver && toupper(*tdp->Driver) == 'C') {
#if defined(CMGO_SUPPORT)
- tjnp = new(g) TDBJSN(tdp, new(g) CMGFAM(tdp));
+ tjnp = new(g) TDBJSN(tdp, new(g) CMGFAM(tdp));
#else
- sprintf(g->Message, "Mongo %s Driver not available", "C");
- return 0;
+ sprintf(g->Message, "Mongo %s Driver not available", "C");
+ return 0;
#endif
- } else if (tdp->Driver && toupper(*tdp->Driver) == 'J') {
+ } else if (tdp->Driver && toupper(*tdp->Driver) == 'J') {
#if defined(JAVA_SUPPORT)
- tjnp = new(g) TDBJSN(tdp, new(g) JMGFAM(tdp));
+ tjnp = new(g) TDBJSN(tdp, new(g) JMGFAM(tdp));
#else
- sprintf(g->Message, "Mongo %s Driver not available", "Java");
- return 0;
+ sprintf(g->Message, "Mongo %s Driver not available", "Java");
+ return 0;
#endif
- } else { // Driver not specified
+ } else { // Driver not specified
#if defined(CMGO_SUPPORT)
- tjnp = new(g) TDBJSN(tdp, new(g) CMGFAM(tdp));
+ tjnp = new(g) TDBJSN(tdp, new(g) CMGFAM(tdp));
#elif defined(JAVA_SUPPORT)
- tjnp = new(g) TDBJSN(tdp, new(g) JMGFAM(tdp));
+ tjnp = new(g) TDBJSN(tdp, new(g) JMGFAM(tdp));
#else
- sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO");
- return 0;
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO");
+ return 0;
#endif
- } // endif Driver
-
- } else
- tjnp = new(g) TDBJSN(tdp, new(g) DOSFAM(tdp));
-
- tjnp->SetMode(MODE_READ);
-
- // Allocate the parse work memory
- PGLOBAL G = (PGLOBAL)PlugSubAlloc(g, NULL, sizeof(GLOBAL));
- memset(G, 0, sizeof(GLOBAL));
- G->Sarea_Size = tdp->Lrecl * 10;
- G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size);
- PlugSubSet(G->Sarea, G->Sarea_Size);
- G->jump_level = 0;
- tjnp->SetG(G);
-
- if (tjnp->OpenDB(g))
- return 0;
-
- switch (tjnp->ReadDB(g)) {
- case RC_EF:
- strcpy(g->Message, "Void json table");
- case RC_FX:
- goto err;
- default:
- jsp = tjnp->GetRow();
- } // endswitch ReadDB
-
- } // endif pretty
-
- if (!(row = (jsp) ? jsp->GetObject() : NULL)) {
- strcpy(g->Message, "Can only retrieve columns from object rows");
- goto err;
- } // endif row
-
- all = GetBooleanTableOption(g, topt, "Fullarray", false);
- jcol.Name = jcol.Fmt = NULL;
- jcol.Next = NULL;
- jcol.Found = true;
- colname[0] = 0;
-
- if (!tdp->Uri) {
- fmt[0] = '$';
- fmt[1] = '.';
- bf = 2;
- } // endif Uri
-
- /*********************************************************************/
- /* Analyse the JSON tree and define columns. */
- /*********************************************************************/
- for (i = 1; ; i++) {
- for (jpp = row->GetFirst(); jpp; jpp = jpp->GetNext()) {
- strncpy(colname, jpp->GetKey(), 64);
- fmt[bf] = 0;
-
- if (Find(g, jpp->GetVal(), colname, MY_MIN(lvl, 0)))
- goto err;
-
- } // endfor jpp
-
- // Missing column can be null
- for (jcp = fjcp; jcp; jcp = jcp->Next) {
- jcp->Cbn |= !jcp->Found;
- jcp->Found = false;
- } // endfor jcp
-
- if (tdp->Pretty != 2) {
- // Read next record
- switch (tjnp->ReadDB(g)) {
- case RC_EF:
- jsp = NULL;
- break;
- case RC_FX:
- goto err;
- default:
- jsp = tjnp->GetRow();
- } // endswitch ReadDB
-
- } else
- jsp = tjsp->GetDoc()->GetValue(i);
-
- if (!(row = (jsp) ? jsp->GetObject() : NULL))
- break;
-
- } // endfor i
-
- if (tdp->Pretty != 2)
- tjnp->CloseDB(g);
-
- return n;
+ } // endif Driver
+
+ } else
+ tjnp = new(g) TDBJSN(tdp, new(g) DOSFAM(tdp));
+
+ tjnp->SetMode(MODE_READ);
+
+ // Allocate the parse work memory
+ PGLOBAL G = (PGLOBAL)PlugSubAlloc(g, NULL, sizeof(GLOBAL));
+ memset(G, 0, sizeof(GLOBAL));
+ G->Sarea_Size = tdp->Lrecl * 10;
+ G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size);
+ PlugSubSet(G->Sarea, G->Sarea_Size);
+ G->jump_level = 0;
+ tjnp->SetG(G);
+
+ if (tjnp->OpenDB(g))
+ return 0;
+
+ switch (tjnp->ReadDB(g)) {
+ case RC_EF:
+ strcpy(g->Message, "Void json table");
+ case RC_FX:
+ goto err;
+ default:
+ jsp = tjnp->GetRow();
+ } // endswitch ReadDB
+
+ } // endif pretty
+
+ if (!(row = (jsp) ? jsp->GetObject() : NULL)) {
+ strcpy(g->Message, "Can only retrieve columns from object rows");
+ goto err;
+ } // endif row
+
+ all = GetBooleanTableOption(g, topt, "Fullarray", false);
+ jcol.Name = jcol.Fmt = NULL;
+ jcol.Next = NULL;
+ jcol.Found = true;
+ colname[0] = 0;
+
+ if (!tdp->Uri) {
+ fmt[0] = '$';
+ fmt[1] = '.';
+ bf = 2;
+ } // endif Uri
+
+ /*********************************************************************/
+ /* Analyse the JSON tree and define columns. */
+ /*********************************************************************/
+ for (i = 1; ; i++) {
+ for (jpp = row->GetFirst(); jpp; jpp = jpp->GetNext()) {
+ strncpy(colname, jpp->GetKey(), 64);
+ fmt[bf] = 0;
+
+ if (Find(g, jpp->GetVal(), colname, MY_MIN(lvl, 0)))
+ goto err;
+
+ } // endfor jpp
+
+ // Missing column can be null
+ for (jcp = fjcp; jcp; jcp = jcp->Next) {
+ jcp->Cbn |= !jcp->Found;
+ jcp->Found = false;
+ } // endfor jcp
+
+ if (tdp->Pretty != 2) {
+ // Read next record
+ switch (tjnp->ReadDB(g)) {
+ case RC_EF:
+ jsp = NULL;
+ break;
+ case RC_FX:
+ goto err;
+ default:
+ jsp = tjnp->GetRow();
+ } // endswitch ReadDB
+
+ } else
+ jsp = tjsp->GetDoc()->GetValue(i);
+
+ if (!(row = (jsp) ? jsp->GetObject() : NULL))
+ break;
+
+ } // endfor i
+
+ if (tdp->Pretty != 2)
+ tjnp->CloseDB(g);
+
+ return n;
err:
- if (tdp->Pretty != 2)
- tjnp->CloseDB(g);
+ if (tdp->Pretty != 2)
+ tjnp->CloseDB(g);
- return 0;
-} // end of GetColumns
+ return 0;
+} // end of GetColumns
bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j)
{
- char *p, *pc = colname + strlen(colname);
- int ars;
- PJOB job;
- PJAR jar;
-
- if ((valp = jvp ? jvp->GetValue() : NULL)) {
- jcol.Type = valp->GetType();
- jcol.Len = valp->GetValLen();
- jcol.Scale = valp->GetValPrec();
- jcol.Cbn = valp->IsNull();
- } else if (!jvp || jvp->IsNull()) {
- jcol.Type = TYPE_UNKNOWN;
- jcol.Len = jcol.Scale = 0;
- jcol.Cbn = true;
- } else if (j < lvl) {
- if (!fmt[bf])
- strcat(fmt, colname);
-
- p = fmt + strlen(fmt);
- jsp = jvp->GetJson();
-
- switch (jsp->GetType()) {
- case TYPE_JOB:
- job = (PJOB)jsp;
-
- for (PJPR jrp = job->GetFirst(); jrp; jrp = jrp->GetNext()) {
- PCSZ k = jrp->GetKey();
-
- if (*k != '$') {
- strncat(strncat(fmt, sep, 128), k, 128);
- strncat(strncat(colname, "_", 64), k, 64);
- } // endif Key
-
- if (Find(g, jrp->GetVal(), k, j + 1))
- return true;
-
- *p = *pc = 0;
- } // endfor jrp
-
- return false;
- case TYPE_JAR:
- jar = (PJAR)jsp;
-
- if (all || (tdp->Xcol && !stricmp(tdp->Xcol, key)))
- ars = jar->GetSize(false);
- else
- ars = MY_MIN(jar->GetSize(false), 1);
-
- for (int k = 0; k < ars; k++) {
- if (!tdp->Xcol || stricmp(tdp->Xcol, key)) {
- sprintf(buf, "%d", k);
-
- if (tdp->Uri)
- strncat(strncat(fmt, sep, 128), buf, 128);
- else
- strncat(strncat(strncat(fmt, "[", 128), buf, 128), "]", 128);
-
- if (all)
- strncat(strncat(colname, "_", 64), buf, 64);
-
- } else
- strncat(fmt, (tdp->Uri ? sep : "[*]"), 128);
-
- if (Find(g, jar->GetValue(k), "", j))
- return true;
-
- *p = *pc = 0;
- } // endfor k
-
- return false;
- default:
- sprintf(g->Message, "Logical error after %s", fmt);
- return true;
- } // endswitch Type
-
- } else if (lvl >= 0) {
- jcol.Type = TYPE_STRING;
- jcol.Len = 256;
- jcol.Scale = 0;
- jcol.Cbn = true;
- } else
- return false;
-
- AddColumn(g);
- return false;
-} // end of Find
+ char *p, *pc = colname + strlen(colname);
+ int ars;
+ PJOB job;
+ PJAR jar;
+
+ if ((valp = jvp ? jvp->GetValue() : NULL)) {
+ jcol.Type = valp->GetType();
+ jcol.Len = valp->GetValLen();
+ jcol.Scale = valp->GetValPrec();
+ jcol.Cbn = valp->IsNull();
+ } else if (!jvp || jvp->IsNull()) {
+ jcol.Type = TYPE_UNKNOWN;
+ jcol.Len = jcol.Scale = 0;
+ jcol.Cbn = true;
+ } else if (j < lvl) {
+ if (!fmt[bf])
+ strcat(fmt, colname);
+
+ p = fmt + strlen(fmt);
+ jsp = jvp->GetJson();
+
+ switch (jsp->GetType()) {
+ case TYPE_JOB:
+ job = (PJOB)jsp;
+
+ for (PJPR jrp = job->GetFirst(); jrp; jrp = jrp->GetNext()) {
+ PCSZ k = jrp->GetKey();
+
+ if (*k != '$') {
+ strncat(strncat(fmt, sep, 128), k, 128);
+ strncat(strncat(colname, "_", 64), k, 64);
+ } // endif Key
+
+ if (Find(g, jrp->GetVal(), k, j + 1))
+ return true;
+
+ *p = *pc = 0;
+ } // endfor jrp
+
+ return false;
+ case TYPE_JAR:
+ jar = (PJAR)jsp;
+
+ if (all || (tdp->Xcol && !stricmp(tdp->Xcol, key)))
+ ars = jar->GetSize(false);
+ else
+ ars = MY_MIN(jar->GetSize(false), 1);
+
+ for (int k = 0; k < ars; k++) {
+ if (!tdp->Xcol || stricmp(tdp->Xcol, key)) {
+ sprintf(buf, "%d", k);
+
+ if (tdp->Uri)
+ strncat(strncat(fmt, sep, 128), buf, 128);
+ else
+ strncat(strncat(strncat(fmt, "[", 128), buf, 128), "]", 128);
+
+ if (all)
+ strncat(strncat(colname, "_", 64), buf, 64);
+
+ } else
+ strncat(fmt, (tdp->Uri ? sep : "[*]"), 128);
+
+ if (Find(g, jar->GetValue(k), "", j))
+ return true;
+
+ *p = *pc = 0;
+ } // endfor k
+
+ return false;
+ default:
+ sprintf(g->Message, "Logical error after %s", fmt);
+ return true;
+ } // endswitch Type
+
+ } else if (lvl >= 0) {
+ jcol.Type = TYPE_STRING;
+ jcol.Len = 256;
+ jcol.Scale = 0;
+ jcol.Cbn = true;
+ } else
+ return false;
+
+ AddColumn(g);
+ return false;
+} // end of Find
void JSONDISC::AddColumn(PGLOBAL g)
{
- bool b = fmt[bf] != 0; // True if formatted
-
- // Check whether this column was already found
- for (jcp = fjcp; jcp; jcp = jcp->Next)
- if (!strcmp(colname, jcp->Name))
- break;
-
- if (jcp) {
- if (jcp->Type != jcol.Type) {
- if (jcp->Type == TYPE_UNKNOWN)
- jcp->Type = jcol.Type;
- else if (jcol.Type != TYPE_UNKNOWN)
- jcp->Type = TYPE_STRING;
-
- } // endif Type
-
- if (b && (!jcp->Fmt || strlen(jcp->Fmt) < strlen(fmt))) {
- jcp->Fmt = PlugDup(g, fmt);
- length[7] = MY_MAX(length[7], strlen(fmt));
- } // endif fmt
-
- jcp->Len = MY_MAX(jcp->Len, jcol.Len);
- jcp->Scale = MY_MAX(jcp->Scale, jcol.Scale);
- jcp->Cbn |= jcol.Cbn;
- jcp->Found = true;
- } else if (jcol.Type != TYPE_UNKNOWN || tdp->Accept) {
- // New column
- jcp = (PJCL)PlugSubAlloc(g, NULL, sizeof(JCOL));
- *jcp = jcol;
- jcp->Cbn |= (i > 1);
- jcp->Name = PlugDup(g, colname);
- length[0] = MY_MAX(length[0], strlen(colname));
-
- if (b) {
- jcp->Fmt = PlugDup(g, fmt);
- length[7] = MY_MAX(length[7], strlen(fmt));
- } else
- jcp->Fmt = NULL;
-
- if (pjcp) {
- jcp->Next = pjcp->Next;
- pjcp->Next = jcp;
- } else
- fjcp = jcp;
-
- n++;
- } // endif jcp
-
- if (jcp)
- pjcp = jcp;
+ bool b = fmt[bf] != 0; // True if formatted
+
+ // Check whether this column was already found
+ for (jcp = fjcp; jcp; jcp = jcp->Next)
+ if (!strcmp(colname, jcp->Name))
+ break;
+
+ if (jcp) {
+ if (jcp->Type != jcol.Type) {
+ if (jcp->Type == TYPE_UNKNOWN)
+ jcp->Type = jcol.Type;
+ else if (jcol.Type != TYPE_UNKNOWN)
+ jcp->Type = TYPE_STRING;
+
+ } // endif Type
+
+ if (b && (!jcp->Fmt || strlen(jcp->Fmt) < strlen(fmt))) {
+ jcp->Fmt = PlugDup(g, fmt);
+ length[7] = MY_MAX(length[7], strlen(fmt));
+ } // endif fmt
+
+ jcp->Len = MY_MAX(jcp->Len, jcol.Len);
+ jcp->Scale = MY_MAX(jcp->Scale, jcol.Scale);
+ jcp->Cbn |= jcol.Cbn;
+ jcp->Found = true;
+ } else if (jcol.Type != TYPE_UNKNOWN || tdp->Accept) {
+ // New column
+ jcp = (PJCL)PlugSubAlloc(g, NULL, sizeof(JCOL));
+ *jcp = jcol;
+ jcp->Cbn |= (i > 1);
+ jcp->Name = PlugDup(g, colname);
+ length[0] = MY_MAX(length[0], strlen(colname));
+
+ if (b) {
+ jcp->Fmt = PlugDup(g, fmt);
+ length[7] = MY_MAX(length[7], strlen(fmt));
+ } else
+ jcp->Fmt = NULL;
+
+ if (pjcp) {
+ jcp->Next = pjcp->Next;
+ pjcp->Next = jcp;
+ } else
+ fjcp = jcp;
+
+ n++;
+ } // endif jcp
+
+ if (jcp)
+ pjcp = jcp;
} // end of AddColumn
@@ -548,13 +548,13 @@ JSONDEF::JSONDEF(void)
Limit = 1;
Base = 0;
Strict = false;
- Sep = '.';
- Uri = NULL;
- Collname = Options = Filter = NULL;
- Pipe = false;
- Driver = NULL;
- Version = 0;
- Wrapname = NULL;
+ Sep = '.';
+ Uri = NULL;
+ Collname = Options = Filter = NULL;
+ Pipe = false;
+ Driver = NULL;
+ Version = 0;
+ Wrapname = NULL;
} // end of JSONDEF constructor
/***********************************************************************/
@@ -562,41 +562,41 @@ JSONDEF::JSONDEF(void)
/***********************************************************************/
bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
- Schema = GetStringCatInfo(g, "DBname", Schema);
- Jmode = (JMODE)GetIntCatInfo("Jmode", MODE_OBJECT);
+ Schema = GetStringCatInfo(g, "DBname", Schema);
+ Jmode = (JMODE)GetIntCatInfo("Jmode", MODE_OBJECT);
Objname = GetStringCatInfo(g, "Object", NULL);
Xcol = GetStringCatInfo(g, "Expand", NULL);
Pretty = GetIntCatInfo("Pretty", 2);
Limit = GetIntCatInfo("Limit", 10);
Base = GetIntCatInfo("Base", 0) ? 1 : 0;
- Sep = *GetStringCatInfo(g, "Separator", ".");
- Accept = GetBoolCatInfo("Accept", false);
+ Sep = *GetStringCatInfo(g, "Separator", ".");
+ Accept = GetBoolCatInfo("Accept", false);
- // Don't use url as MONGO uri when called from REST
- if (stricmp(am, "REST") && (Uri = GetStringCatInfo(g, "Connect", NULL))) {
+ // 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",
- (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
- Collname = GetStringCatInfo(g, "Tabname", Collname);
- Options = GetStringCatInfo(g, "Colist", NULL);
- Filter = GetStringCatInfo(g, "Filter", NULL);
- Pipe = GetBoolCatInfo("Pipeline", false);
- Driver = GetStringCatInfo(g, "Driver", NULL);
- Version = GetIntCatInfo("Version", 3);
- Pretty = 0;
+ Collname = GetStringCatInfo(g, "Name",
+ (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
+ Collname = GetStringCatInfo(g, "Tabname", Collname);
+ Options = GetStringCatInfo(g, "Colist", NULL);
+ Filter = GetStringCatInfo(g, "Filter", NULL);
+ Pipe = GetBoolCatInfo("Pipeline", false);
+ Driver = GetStringCatInfo(g, "Driver", NULL);
+ Version = GetIntCatInfo("Version", 3);
+ Pretty = 0;
#if defined(JAVA_SUPPORT)
- if (Version == 2)
- Wrapname = GetStringCatInfo(g, "Wrapper", "Mongo2Interface");
- else
- Wrapname = GetStringCatInfo(g, "Wrapper", "Mongo3Interface");
+ if (Version == 2)
+ Wrapname = GetStringCatInfo(g, "Wrapper", "Mongo2Interface");
+ else
+ Wrapname = GetStringCatInfo(g, "Wrapper", "Mongo3Interface");
#endif // JAVA_SUPPORT
#else // !MONGO_SUPPORT
- sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO");
- return true;
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO");
+ return true;
#endif // !MONGO_SUPPORT
- } // endif Uri
+ } // endif Uri
- return DOSDEF::DefineAM(g, (Uri ? "XMGO" : "DOS"), poff);
+ return DOSDEF::DefineAM(g, (Uri ? "XMGO" : "DOS"), poff);
} // end of DefineAM
/***********************************************************************/
@@ -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);
@@ -618,47 +621,47 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
!(tmp == TMP_FORCE &&
(m == MODE_UPDATE || m == MODE_DELETE));
- if (Uri) {
- if (Driver && toupper(*Driver) == 'C') {
+ if (Uri) {
+ if (Driver && toupper(*Driver) == 'C') {
#if defined(CMGO_SUPPORT)
- txfp = new(g) CMGFAM(this);
+ txfp = new(g) CMGFAM(this);
#else
- sprintf(g->Message, "Mongo %s Driver not available", "C");
- return NULL;
+ sprintf(g->Message, "Mongo %s Driver not available", "C");
+ return NULL;
#endif
- } else if (Driver && toupper(*Driver) == 'J') {
+ } else if (Driver && toupper(*Driver) == 'J') {
#if defined(JAVA_SUPPORT)
- txfp = new(g) JMGFAM(this);
+ txfp = new(g) JMGFAM(this);
#else
- sprintf(g->Message, "Mongo %s Driver not available", "Java");
- return NULL;
+ sprintf(g->Message, "Mongo %s Driver not available", "Java");
+ return NULL;
#endif
- } else { // Driver not specified
+ } else { // Driver not specified
#if defined(CMGO_SUPPORT)
- txfp = new(g) CMGFAM(this);
+ txfp = new(g) CMGFAM(this);
#elif defined(JAVA_SUPPORT)
- txfp = new(g) JMGFAM(this);
-#else // !MONGO_SUPPORT
- sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO");
- return NULL;
+ txfp = new(g) JMGFAM(this);
+#else // !MONGO_SUPPORT
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO");
+ return NULL;
#endif // !MONGO_SUPPORT
- } // endif Driver
+ } // endif Driver
- } else if (Zipped) {
+ } else if (Zipped) {
#if defined(ZIP_SUPPORT)
- if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) {
- txfp = new(g) UNZFAM(this);
- } else if (m == MODE_INSERT) {
- txfp = new(g) ZIPFAM(this);
- } else {
- strcpy(g->Message, "UPDATE/DELETE not supported for ZIP");
- return NULL;
- } // endif's m
+ if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) {
+ txfp = new(g) UNZFAM(this);
+ } else if (m == MODE_INSERT) {
+ txfp = new(g) ZIPFAM(this);
+ } else {
+ strcpy(g->Message, "UPDATE/DELETE not supported for ZIP");
+ return NULL;
+ } // endif's m
#else // !ZIP_SUPPORT
- sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
- return NULL;
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
+ return NULL;
#endif // !ZIP_SUPPORT
- } else if (Compressed) {
+ } else if (Compressed) {
#if defined(GZ_SUPPORT)
if (Compressed == 1)
txfp = new(g) GZFAM(this);
@@ -668,7 +671,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "GZ");
return NULL;
#endif // !GZ_SUPPORT
- } else if (map)
+ } else if (map)
txfp = new(g) MAPFAM(this);
else
txfp = new(g) DOSFAM(this);
@@ -676,41 +679,41 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
// Txfp must be set for TDBDOS
tdbp = new(g) TDBJSN(this, txfp);
- if (Lrecl) {
- // Allocate the parse work memory
- PGLOBAL G = (PGLOBAL)PlugSubAlloc(g, NULL, sizeof(GLOBAL));
- memset(G, 0, sizeof(GLOBAL));
- G->Sarea_Size = Lrecl * 10;
- G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size);
- PlugSubSet(G->Sarea, G->Sarea_Size);
- G->jump_level = 0;
- ((TDBJSN*)tdbp)->G = G;
- } else {
- strcpy(g->Message, "LRECL is not defined");
- return NULL;
- } // endif Lrecl
-
- } else {
- if (Zipped) {
+ if (Lrecl) {
+ // Allocate the parse work memory
+ PGLOBAL G = (PGLOBAL)PlugSubAlloc(g, NULL, sizeof(GLOBAL));
+ memset(G, 0, sizeof(GLOBAL));
+ G->Sarea_Size = Lrecl * 10;
+ G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size);
+ PlugSubSet(G->Sarea, G->Sarea_Size);
+ G->jump_level = 0;
+ ((TDBJSN*)tdbp)->G = G;
+ } else {
+ strcpy(g->Message, "LRECL is not defined");
+ return NULL;
+ } // endif Lrecl
+
+ } else {
+ if (Zipped) {
#if defined(ZIP_SUPPORT)
- if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) {
- txfp = new(g) UNZFAM(this);
- } else if (m == MODE_INSERT) {
- strcpy(g->Message, "INSERT supported only for zipped JSON when pretty=0");
- return NULL;
- } else {
- strcpy(g->Message, "UPDATE/DELETE not supported for ZIP");
- return NULL;
- } // endif's m
+ if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) {
+ txfp = new(g) UNZFAM(this);
+ } else if (m == MODE_INSERT) {
+ strcpy(g->Message, "INSERT supported only for zipped JSON when pretty=0");
+ return NULL;
+ } else {
+ strcpy(g->Message, "UPDATE/DELETE not supported for ZIP");
+ return NULL;
+ } // endif's m
#else // !ZIP_SUPPORT
- sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
- return NULL;
+ sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
+ return NULL;
#endif // !ZIP_SUPPORT
- } else
- txfp = new(g) MAPFAM(this);
+ } else
+ txfp = new(g) MAPFAM(this);
tdbp = new(g) TDBJSON(this, txfp);
- ((TDBJSON*)tdbp)->G = g;
+ ((TDBJSON*)tdbp)->G = g;
} // endif Pretty
if (Multiple)
@@ -738,16 +741,16 @@ TDBJSN::TDBJSN(PJDEF tdp, PTXF txfp) : TDBDOS(tdp, txfp)
Limit = tdp->Limit;
Pretty = tdp->Pretty;
B = tdp->Base ? 1 : 0;
- Sep = tdp->Sep;
+ Sep = tdp->Sep;
Strict = tdp->Strict;
} else {
Jmode = MODE_OBJECT;
Objname = NULL;
- Xcol = NULL;
+ Xcol = NULL;
Limit = 1;
Pretty = 0;
B = 0;
- Sep = '.';
+ Sep = '.';
Strict = false;
} // endif tdp
@@ -761,7 +764,7 @@ TDBJSN::TDBJSN(PJDEF tdp, PTXF txfp) : TDBDOS(tdp, txfp)
TDBJSN::TDBJSN(TDBJSN *tdbp) : TDBDOS(NULL, tdbp)
{
- G = NULL;
+ G = NULL;
Top = tdbp->Top;
Row = tdbp->Row;
Val = tdbp->Val;
@@ -777,7 +780,7 @@ TDBJSN::TDBJSN(TDBJSN *tdbp) : TDBDOS(NULL, tdbp)
SameRow = tdbp->SameRow;
Xval = tdbp->Xval;
B = tdbp->B;
- Sep = tdbp->Sep;
+ Sep = tdbp->Sep;
Pretty = tdbp->Pretty;
Strict = tdbp->Strict;
Comma = tdbp->Comma;
@@ -786,7 +789,7 @@ TDBJSN::TDBJSN(TDBJSN *tdbp) : TDBDOS(NULL, tdbp)
// Used for update
PTDB TDBJSN::Clone(PTABS t)
{
- G = NULL;
+ G = NULL;
PTDB tp;
PJCOL cp1, cp2;
PGLOBAL g = t->G;
@@ -860,33 +863,33 @@ PJSON TDBJSN::FindRow(PGLOBAL g)
PJSON jsp = Row;
PJVAL val = NULL;
- for (objpath = PlugDup(g, Objname); jsp && objpath; objpath = p) {
- if ((p = strchr(objpath, Sep)))
- *p++ = 0;
+ for (objpath = PlugDup(g, Objname); jsp && objpath; objpath = p) {
+ if ((p = strchr(objpath, Sep)))
+ *p++ = 0;
- if (*objpath != '[' && !IsNum(objpath)) { // objpass is a key
- val = (jsp->GetType() == TYPE_JOB) ?
- jsp->GetObject()->GetValue(objpath) : NULL;
- } else {
- if (*objpath == '[') {
- if (objpath[strlen(objpath) - 1] == ']')
- objpath++;
- else
- return NULL;
- } // endif [
+ if (*objpath != '[' && !IsNum(objpath)) { // objpass is a key
+ val = (jsp->GetType() == TYPE_JOB) ?
+ jsp->GetObject()->GetValue(objpath) : NULL;
+ } else {
+ if (*objpath == '[') {
+ if (objpath[strlen(objpath) - 1] == ']')
+ objpath++;
+ else
+ return NULL;
+ } // endif [
- val = (jsp->GetType() == TYPE_JAR) ?
- jsp->GetArray()->GetValue(atoi(objpath) - B) : NULL;
- } // endif objpath
+ val = (jsp->GetType() == TYPE_JAR) ?
+ jsp->GetArray()->GetValue(atoi(objpath) - B) : NULL;
+ } // endif objpath
- jsp = (val) ? val->GetJson() : NULL;
- } // endfor objpath
+ jsp = (val) ? val->GetJson() : NULL;
+ } // endfor objpath
return jsp;
} // end of FindRow
/***********************************************************************/
-/* OpenDB: Data Base open routine for JSN access method. */
+/* OpenDB: Data Base open routine for JSN access method. */
/***********************************************************************/
bool TDBJSN::OpenDB(PGLOBAL g)
{
@@ -911,15 +914,15 @@ bool TDBJSN::OpenDB(PGLOBAL g)
return true;
} // endswitch Jmode
- } // endif Use
+ } // endif Use
- if (TDBDOS::OpenDB(g))
- return true;
+ if (TDBDOS::OpenDB(g))
+ return true;
- if (Xcol)
- To_Filter = NULL; // Imcompatible
+ if (Xcol)
+ To_Filter = NULL; // Imcompatible
- return false;
+ return false;
} // end of OpenDB
/***********************************************************************/
@@ -969,27 +972,27 @@ int TDBJSN::ReadDB(PGLOBAL g)
NextSame = 0;
M++;
return RC_OK;
- } else if ((rc = TDBDOS::ReadDB(g)) == RC_OK) {
- if (!IsRead() && ((rc = ReadBuffer(g)) != RC_OK))
- // Deferred reading failed
- return rc;
-
- // Recover the memory used for parsing
- PlugSubSet(G->Sarea, G->Sarea_Size);
-
- if ((Row = ParseJson(G, To_Line, strlen(To_Line), &Pretty, &Comma))) {
- Row = FindRow(g);
- SameRow = 0;
- Fpos++;
- M = 1;
- rc = RC_OK;
- } else if (Pretty != 1 || strcmp(To_Line, "]")) {
- strcpy(g->Message, G->Message);
- rc = RC_FX;
- } else
- rc = RC_EF;
-
- } // endif ReadDB
+ } else if ((rc = TDBDOS::ReadDB(g)) == RC_OK) {
+ if (!IsRead() && ((rc = ReadBuffer(g)) != RC_OK))
+ // Deferred reading failed
+ return rc;
+
+ // Recover the memory used for parsing
+ PlugSubSet(G->Sarea, G->Sarea_Size);
+
+ if ((Row = ParseJson(G, To_Line, strlen(To_Line), &Pretty, &Comma))) {
+ Row = FindRow(g);
+ SameRow = 0;
+ Fpos++;
+ M = 1;
+ rc = RC_OK;
+ } else if (Pretty != 1 || strcmp(To_Line, "]")) {
+ strcpy(g->Message, G->Message);
+ rc = RC_FX;
+ } else
+ rc = RC_EF;
+
+ } // endif ReadDB
return rc;
} // end of ReadDB
@@ -999,68 +1002,68 @@ int TDBJSN::ReadDB(PGLOBAL g)
/***********************************************************************/
int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp)
{
- if (Objname) {
- if (!Val) {
- // Parse and allocate Objname item(s)
- char *p;
- char *objpath = PlugDup(g, Objname);
- int i;
- PJOB objp;
- PJAR arp;
- PJVAL val = NULL;
+ if (Objname) {
+ if (!Val) {
+ // Parse and allocate Objname item(s)
+ char *p;
+ char *objpath = PlugDup(g, Objname);
+ int i;
+ PJOB objp;
+ PJAR arp;
+ PJVAL val = NULL;
- Top = NULL;
+ Top = NULL;
- for (; objpath; objpath = p) {
- if ((p = strchr(objpath, Sep)))
- *p++ = 0;
+ for (; objpath; objpath = p) {
+ if ((p = strchr(objpath, Sep)))
+ *p++ = 0;
- if (*objpath != '[' && !IsNum(objpath)) {
- objp = new(g) JOBJECT;
+ if (*objpath != '[' && !IsNum(objpath)) {
+ objp = new(g) JOBJECT;
- if (!Top)
- Top = objp;
+ if (!Top)
+ Top = objp;
- if (val)
- val->SetValue(objp);
+ if (val)
+ val->SetValue(objp);
- val = new(g) JVALUE;
- objp->SetValue(g, val, objpath);
- } else {
- if (*objpath == '[') {
- // Old style
- if (objpath[strlen(objpath) - 1] != ']') {
- sprintf(g->Message, "Invalid Table path %s", Objname);
- return RC_FX;
- } else
- objpath++;
+ val = new(g) JVALUE;
+ objp->SetValue(g, val, objpath);
+ } else {
+ if (*objpath == '[') {
+ // Old style
+ if (objpath[strlen(objpath) - 1] != ']') {
+ sprintf(g->Message, "Invalid Table path %s", Objname);
+ return RC_FX;
+ } else
+ objpath++;
- } // endif objpath
+ } // endif objpath
- arp = new(g) JARRAY;
+ arp = new(g) JARRAY;
- if (!Top)
- Top = arp;
+ if (!Top)
+ Top = arp;
- if (val)
- val->SetValue(arp);
+ if (val)
+ val->SetValue(arp);
- val = new(g) JVALUE;
- i = atoi(objpath) - B;
- arp->SetValue(g, val, i);
- arp->InitArray(g);
- } // endif objpath
+ val = new(g) JVALUE;
+ i = atoi(objpath) - B;
+ arp->SetValue(g, val, i);
+ arp->InitArray(g);
+ } // endif objpath
- } // endfor p
+ } // endfor p
- Val = val;
- } // endif Val
+ Val = val;
+ } // endif Val
- Val->SetValue(jsp);
- } else
- Top = jsp;
+ Val->SetValue(jsp);
+ } else
+ Top = jsp;
- return RC_OK;
+ return RC_OK;
} // end of MakeTopTree
/***********************************************************************/
@@ -1095,11 +1098,11 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp)
/***********************************************************************/
int TDBJSN::WriteDB(PGLOBAL g)
{
- int rc = TDBDOS::WriteDB(g);
+ int rc = TDBDOS::WriteDB(g);
- PlugSubSet(G->Sarea, G->Sarea_Size);
- Row->Clear();
- return rc;
+ PlugSubSet(G->Sarea, G->Sarea_Size);
+ Row->Clear();
+ return rc;
} // end of WriteDB
/* ---------------------------- JSONCOL ------------------------------ */
@@ -1111,12 +1114,12 @@ JSONCOL::JSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
: DOSCOL(g, cdp, tdbp, cprec, i, "DOS")
{
Tjp = (TDBJSN *)(tdbp->GetOrig() ? tdbp->GetOrig() : tdbp);
- G = Tjp->G;
+ G = Tjp->G;
Jpath = cdp->GetFmt();
MulVal = NULL;
Nodes = NULL;
Nod = 0;
- Sep = Tjp->Sep;
+ Sep = Tjp->Sep;
Xnod = -1;
Xpd = false;
Parsed = false;
@@ -1128,14 +1131,14 @@ JSONCOL::JSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
/***********************************************************************/
JSONCOL::JSONCOL(JSONCOL *col1, PTDB tdbp) : DOSCOL(col1, tdbp)
{
- G = col1->G;
+ G = col1->G;
Tjp = col1->Tjp;
Jpath = col1->Jpath;
MulVal = col1->MulVal;
Nodes = col1->Nodes;
Nod = col1->Nod;
- Sep = col1->Sep;
- Xnod = col1->Xnod;
+ Sep = col1->Sep;
+ Xnod = col1->Xnod;
Xpd = col1->Xpd;
Parsed = col1->Parsed;
} // end of JSONCOL copy constructor
@@ -1153,7 +1156,7 @@ bool JSONCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
return true;
Tjp = (TDBJSN*)To_Tdb;
- G = Tjp->G;
+ G = Tjp->G;
return false;
} // end of SetBuffer
@@ -1179,130 +1182,130 @@ bool JSONCOL::CheckExpand(PGLOBAL g, int i, PSZ nm, bool b)
/***********************************************************************/
bool JSONCOL::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
{
- int n;
- bool dg = true, b = false;
- PJNODE jnp = &Nodes[i];
-
- //if (*p == '[') p++; // Old syntax .[ or :[
- n = (int)strlen(p);
-
- if (*p) {
- if (p[n - 1] == ']') {
- p[--n] = 0;
- } else if (!IsNum(p)) {
- // Wrong array specification
- sprintf(g->Message, "Invalid array specification %s for %s", p, Name);
- return true;
- } // endif p
-
- } else
- b = true;
-
- // To check whether a numeric Rank was specified
- dg = IsNum(p);
-
- if (!n) {
- // Default specifications
- if (CheckExpand(g, i, nm, false))
- return true;
- else if (jnp->Op != OP_EXP) {
- if (b) {
- // Return 1st value (B is the index base)
- jnp->Rank = Tjp->B;
- jnp->Op = OP_EQ;
- } else if (!Value->IsTypeNum()) {
- jnp->CncVal = AllocateValue(g, (void*)", ", TYPE_STRING);
- jnp->Op = OP_CNC;
- } else
- jnp->Op = OP_ADD;
-
- } // endif OP
-
- } else if (dg) {
- // Return nth value
- jnp->Rank = atoi(p) - Tjp->B;
- jnp->Op = OP_EQ;
- } else if (n == 1) {
- // Set the Op value;
- if (Sep == ':')
- switch (*p) {
- case '*': *p = 'x'; break;
- case 'x':
- case 'X': *p = '*'; break; // Expand this array
- default: break;
- } // endswitch p
-
- switch (*p) {
- case '+': jnp->Op = OP_ADD; break;
- case 'x': jnp->Op = OP_MULT; break;
- case '>': jnp->Op = OP_MAX; break;
- case '<': jnp->Op = OP_MIN; break;
- case '!': jnp->Op = OP_SEP; break; // Average
- case '#': jnp->Op = OP_NUM; break;
- case '*': // Expand this array
- if (!Tjp->Xcol && nm) {
- Xpd = true;
- jnp->Op = OP_EXP;
- Tjp->Xval = i;
- Tjp->Xcol = nm;
- } else if (CheckExpand(g, i, nm, true))
- return true;
-
- break;
- default:
- sprintf(g->Message,
- "Invalid function specification %c for %s", *p, Name);
- return true;
- } // endswitch *p
-
- } else if (*p == '"' && p[n - 1] == '"') {
- // This is a concat specification
- jnp->Op = OP_CNC;
-
- if (n > 2) {
- // Set concat intermediate string
- p[n - 1] = 0;
- jnp->CncVal = AllocateValue(g, p + 1, TYPE_STRING);
- } // endif n
-
- } else {
- sprintf(g->Message, "Wrong array specification for %s", Name);
- return true;
- } // endif's
-
- // For calculated arrays, a local Value must be used
- switch (jnp->Op) {
- case OP_NUM:
- jnp->Valp = AllocateValue(g, TYPE_INT);
- break;
- case OP_ADD:
- case OP_MULT:
- case OP_SEP:
- if (!IsTypeChar(Buf_Type))
- jnp->Valp = AllocateValue(g, Buf_Type, 0, GetPrecision());
- else
- jnp->Valp = AllocateValue(g, TYPE_DOUBLE, 0, 2);
-
- break;
- case OP_MIN:
- case OP_MAX:
- jnp->Valp = AllocateValue(g, Buf_Type, Long, GetPrecision());
- break;
- case OP_CNC:
- if (IsTypeChar(Buf_Type))
- jnp->Valp = AllocateValue(g, TYPE_STRING, Long, GetPrecision());
- else
- jnp->Valp = AllocateValue(g, TYPE_STRING, 512);
-
- break;
- default:
- break;
- } // endswitch Op
-
- if (jnp->Valp)
- MulVal = AllocateValue(g, jnp->Valp);
-
- return false;
+ int n;
+ bool dg = true, b = false;
+ PJNODE jnp = &Nodes[i];
+
+ //if (*p == '[') p++; // Old syntax .[ or :[
+ n = (int)strlen(p);
+
+ if (*p) {
+ if (p[n - 1] == ']') {
+ p[--n] = 0;
+ } else if (!IsNum(p)) {
+ // Wrong array specification
+ sprintf(g->Message, "Invalid array specification %s for %s", p, Name);
+ return true;
+ } // endif p
+
+ } else
+ b = true;
+
+ // To check whether a numeric Rank was specified
+ dg = IsNum(p);
+
+ if (!n) {
+ // Default specifications
+ if (CheckExpand(g, i, nm, false))
+ return true;
+ else if (jnp->Op != OP_EXP) {
+ if (b) {
+ // Return 1st value (B is the index base)
+ jnp->Rank = Tjp->B;
+ jnp->Op = OP_EQ;
+ } else if (!Value->IsTypeNum()) {
+ jnp->CncVal = AllocateValue(g, (void*)", ", TYPE_STRING);
+ jnp->Op = OP_CNC;
+ } else
+ jnp->Op = OP_ADD;
+
+ } // endif OP
+
+ } else if (dg) {
+ // Return nth value
+ jnp->Rank = atoi(p) - Tjp->B;
+ jnp->Op = OP_EQ;
+ } else if (n == 1) {
+ // Set the Op value;
+ if (Sep == ':')
+ switch (*p) {
+ case '*': *p = 'x'; break;
+ case 'x':
+ case 'X': *p = '*'; break; // Expand this array
+ default: break;
+ } // endswitch p
+
+ switch (*p) {
+ case '+': jnp->Op = OP_ADD; break;
+ case 'x': jnp->Op = OP_MULT; break;
+ case '>': jnp->Op = OP_MAX; break;
+ case '<': jnp->Op = OP_MIN; break;
+ case '!': jnp->Op = OP_SEP; break; // Average
+ case '#': jnp->Op = OP_NUM; break;
+ case '*': // Expand this array
+ if (!Tjp->Xcol && nm) {
+ Xpd = true;
+ jnp->Op = OP_EXP;
+ Tjp->Xval = i;
+ Tjp->Xcol = nm;
+ } else if (CheckExpand(g, i, nm, true))
+ return true;
+
+ break;
+ default:
+ sprintf(g->Message,
+ "Invalid function specification %c for %s", *p, Name);
+ return true;
+ } // endswitch *p
+
+ } else if (*p == '"' && p[n - 1] == '"') {
+ // This is a concat specification
+ jnp->Op = OP_CNC;
+
+ if (n > 2) {
+ // Set concat intermediate string
+ p[n - 1] = 0;
+ jnp->CncVal = AllocateValue(g, p + 1, TYPE_STRING);
+ } // endif n
+
+ } else {
+ sprintf(g->Message, "Wrong array specification for %s", Name);
+ return true;
+ } // endif's
+
+ // For calculated arrays, a local Value must be used
+ switch (jnp->Op) {
+ case OP_NUM:
+ jnp->Valp = AllocateValue(g, TYPE_INT);
+ break;
+ case OP_ADD:
+ case OP_MULT:
+ case OP_SEP:
+ if (!IsTypeChar(Buf_Type))
+ jnp->Valp = AllocateValue(g, Buf_Type, 0, GetPrecision());
+ else
+ jnp->Valp = AllocateValue(g, TYPE_DOUBLE, 0, 2);
+
+ break;
+ case OP_MIN:
+ case OP_MAX:
+ jnp->Valp = AllocateValue(g, Buf_Type, Long, GetPrecision());
+ break;
+ case OP_CNC:
+ if (IsTypeChar(Buf_Type))
+ jnp->Valp = AllocateValue(g, TYPE_STRING, Long, GetPrecision());
+ else
+ jnp->Valp = AllocateValue(g, TYPE_STRING, 512);
+
+ break;
+ default:
+ break;
+ } // endswitch Op
+
+ if (jnp->Valp)
+ MulVal = AllocateValue(g, jnp->Valp);
+
+ return false;
} // end of SetArrayOptions
/***********************************************************************/
@@ -1313,87 +1316,87 @@ bool JSONCOL::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
/***********************************************************************/
bool JSONCOL::ParseJpath(PGLOBAL g)
{
- char *p, *p1 = NULL, *p2 = NULL, *pbuf = NULL;
- int i;
- bool a, mul = false;
-
- if (Parsed)
- return false; // Already done
- else if (InitValue(g))
- return true;
- else if (!Jpath)
- Jpath = Name;
-
- if (To_Tdb->GetOrig()) {
- // This is an updated column, get nodes from origin
- for (PJCOL colp = (PJCOL)Tjp->GetColumns(); colp;
- colp = (PJCOL)colp->GetNext())
- if (!stricmp(Name, colp->GetName())) {
- Nod = colp->Nod;
- Nodes = colp->Nodes;
- Xpd = colp->Xpd;
- goto fin;
- } // endif Name
-
- sprintf(g->Message, "Cannot parse updated column %s", Name);
- return true;
- } // endif To_Orig
-
- pbuf = PlugDup(g, Jpath);
- if (*pbuf == '$') pbuf++;
- if (*pbuf == Sep) pbuf++;
- if (*pbuf == '[') p1 = pbuf++;
-
- // Estimate the required number of nodes
- for (i = 0, p = pbuf; (p = NextChr(p, Sep)); i++, p++)
- Nod++; // One path node found
-
- Nodes = (PJNODE)PlugSubAlloc(g, NULL, (++Nod) * sizeof(JNODE));
- memset(Nodes, 0, (Nod) * sizeof(JNODE));
-
- // Analyze the Jpath for this column
- for (i = 0, p = pbuf; p && i < Nod; i++, p = (p2 ? p2 : NULL)) {
- a = (p1 != NULL);
- p1 = strchr(p, '[');
- p2 = strchr(p, Sep);
-
- if (!p2)
- p2 = p1;
- else if (p1) {
- if (p1 < p2)
- p2 = p1;
- else if (p1 == p2 + 1)
- *p2++ = 0; // Old syntax .[ or :[
- else
- p1 = NULL;
-
- } // endif p1
-
- if (p2)
- *p2++ = 0;
-
- // Jpath must be explicit
- if (a || *p == 0 || *p == '[' || IsNum(p)) {
- // Analyse intermediate array processing
- if (SetArrayOptions(g, p, i, Nodes[i - 1].Key))
- return true;
-
- } else if (*p == '*') {
- // Return JSON
- Nodes[i].Op = OP_XX;
- } else {
- Nodes[i].Key = p;
- Nodes[i].Op = OP_EXIST;
- } // endif's
-
- } // endfor i, p
-
- Nod = i;
+ char *p, *p1 = NULL, *p2 = NULL, *pbuf = NULL;
+ int i;
+ bool a, mul = false;
+
+ if (Parsed)
+ return false; // Already done
+ else if (InitValue(g))
+ return true;
+ else if (!Jpath)
+ Jpath = Name;
+
+ if (To_Tdb->GetOrig()) {
+ // This is an updated column, get nodes from origin
+ for (PJCOL colp = (PJCOL)Tjp->GetColumns(); colp;
+ colp = (PJCOL)colp->GetNext())
+ if (!stricmp(Name, colp->GetName())) {
+ Nod = colp->Nod;
+ Nodes = colp->Nodes;
+ Xpd = colp->Xpd;
+ goto fin;
+ } // endif Name
+
+ sprintf(g->Message, "Cannot parse updated column %s", Name);
+ return true;
+ } // endif To_Orig
+
+ pbuf = PlugDup(g, Jpath);
+ if (*pbuf == '$') pbuf++;
+ if (*pbuf == Sep) pbuf++;
+ if (*pbuf == '[') p1 = pbuf++;
+
+ // Estimate the required number of nodes
+ for (i = 0, p = pbuf; (p = NextChr(p, Sep)); i++, p++)
+ Nod++; // One path node found
+
+ Nodes = (PJNODE)PlugSubAlloc(g, NULL, (++Nod) * sizeof(JNODE));
+ memset(Nodes, 0, (Nod) * sizeof(JNODE));
+
+ // Analyze the Jpath for this column
+ for (i = 0, p = pbuf; p && i < Nod; i++, p = (p2 ? p2 : NULL)) {
+ a = (p1 != NULL);
+ p1 = strchr(p, '[');
+ p2 = strchr(p, Sep);
+
+ if (!p2)
+ p2 = p1;
+ else if (p1) {
+ if (p1 < p2)
+ p2 = p1;
+ else if (p1 == p2 + 1)
+ *p2++ = 0; // Old syntax .[ or :[
+ else
+ p1 = NULL;
+
+ } // endif p1
+
+ if (p2)
+ *p2++ = 0;
+
+ // Jpath must be explicit
+ if (a || *p == 0 || *p == '[' || IsNum(p)) {
+ // Analyse intermediate array processing
+ if (SetArrayOptions(g, p, i, Nodes[i - 1].Key))
+ return true;
+
+ } else if (*p == '*') {
+ // Return JSON
+ Nodes[i].Op = OP_XX;
+ } else {
+ Nodes[i].Key = p;
+ Nodes[i].Op = OP_EXIST;
+ } // endif's
+
+ } // endfor i, p
+
+ Nod = i;
fin:
- MulVal = AllocateValue(g, Value);
- Parsed = true;
- return false;
+ MulVal = AllocateValue(g, Value);
+ Parsed = true;
+ return false;
} // end of ParseJpath
/***********************************************************************/
@@ -1401,66 +1404,66 @@ fin:
/***********************************************************************/
PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj)
{
- if (Jpath) {
- char *p1, *p2, *mgopath;
- int i = 0;
-
- if (strcmp(Jpath, "*")) {
- p1 = Jpath;
- if (*p1 == '$') p1++;
- if (*p1 == '.') p1++;
- mgopath = PlugDup(g, p1);
- } else
- return NULL;
-
- for (p1 = p2 = mgopath; *p1; p1++)
- if (i) { // Inside []
- if (isdigit(*p1)) {
- if (!proj)
- *p2++ = *p1;
-
- } else if (*p1 == ']' && i == 1) {
- if (proj && p1[1] == '.')
- p1++;
-
- i = 0;
- } else if (*p1 == '.' && i == 2) {
- if (!proj)
- *p2++ = '.';
-
- i = 0;
- } else if (!proj)
- return NULL;
-
- } else switch (*p1) {
- case ':':
- case '.':
- if (isdigit(p1[1]))
- i = 2;
-
- *p2++ = '.';
- break;
- case '[':
- if (*(p2 - 1) != '.')
- *p2++ = '.';
-
- i = 1;
- break;
- case '*':
- if (*(p2 - 1) == '.' && !*(p1 + 1)) {
- p2--; // Suppress last :*
- break;
- } // endif p2
-
- default:
- *p2++ = *p1;
- break;
- } // endswitch p1;
-
- *p2 = 0;
- return mgopath;
- } else
- return NULL;
+ if (Jpath) {
+ char *p1, *p2, *mgopath;
+ int i = 0;
+
+ if (strcmp(Jpath, "*")) {
+ p1 = Jpath;
+ if (*p1 == '$') p1++;
+ if (*p1 == '.') p1++;
+ mgopath = PlugDup(g, p1);
+ } else
+ return NULL;
+
+ for (p1 = p2 = mgopath; *p1; p1++)
+ if (i) { // Inside []
+ if (isdigit(*p1)) {
+ if (!proj)
+ *p2++ = *p1;
+
+ } else if (*p1 == ']' && i == 1) {
+ if (proj && p1[1] == '.')
+ p1++;
+
+ i = 0;
+ } else if (*p1 == '.' && i == 2) {
+ if (!proj)
+ *p2++ = '.';
+
+ i = 0;
+ } else if (!proj)
+ return NULL;
+
+ } else switch (*p1) {
+ case ':':
+ case '.':
+ if (isdigit(p1[1]))
+ i = 2;
+
+ *p2++ = '.';
+ break;
+ case '[':
+ if (*(p2 - 1) != '.')
+ *p2++ = '.';
+
+ i = 1;
+ break;
+ case '*':
+ if (*(p2 - 1) == '.' && !*(p1 + 1)) {
+ p2--; // Suppress last :*
+ break;
+ } // endif p2
+
+ default:
+ *p2++ = *p1;
+ break;
+ } // endswitch p1;
+
+ *p2 = 0;
+ return mgopath;
+ } else
+ return NULL;
} // end of GetJpath
@@ -1469,7 +1472,7 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj)
/***********************************************************************/
PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp)
{
- if (Value->IsTypeNum()) {
+ if (Value->IsTypeNum()) {
strcpy(g->Message, "Cannot make Json for a numeric column");
Value->Reset();
} else
@@ -1484,22 +1487,22 @@ PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp)
void JSONCOL::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n)
{
if (val) {
- vp->SetNull(false);
+ vp->SetNull(false);
switch (val->GetValType()) {
case TYPE_STRG:
case TYPE_INTG:
- case TYPE_BINT:
- case TYPE_DBL:
- case TYPE_DTM:
- vp->SetValue_pval(val->GetValue());
+ case TYPE_BINT:
+ case TYPE_DBL:
+ case TYPE_DTM:
+ vp->SetValue_pval(val->GetValue());
break;
case TYPE_BOOL:
if (vp->IsTypeNum())
vp->SetValue(val->GetInteger() ? 1 : 0);
else
vp->SetValue_psz((PSZ)(val->GetInteger() ? "true" : "false"));
-
+
break;
case TYPE_JAR:
SetJsonValue(g, vp, val->GetArray()->GetValue(0), n);
@@ -1509,16 +1512,16 @@ void JSONCOL::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n)
vp->SetValue_psz(val->GetObject()->GetText(g, NULL));
break;
// } // endif Type
-
+
default:
- vp->Reset();
- vp->SetNull(true);
- } // endswitch Type
+ vp->Reset();
+ vp->SetNull(true);
+ } // endswitch Type
- } else {
- vp->Reset();
- vp->SetNull(true);
- } // endif val
+ } else {
+ vp->Reset();
+ vp->SetNull(true);
+ } // endif val
} // end of SetJsonValue
@@ -1530,8 +1533,8 @@ void JSONCOL::ReadColumn(PGLOBAL g)
if (!Tjp->SameRow || Xnod >= Tjp->SameRow)
Value->SetValue_pval(GetColumnValue(g, Tjp->Row, 0));
- if (Xpd && Value->IsNull() && !((PJDEF)Tjp->To_Def)->Accept)
- throw("Null expandable JSON value");
+ if (Xpd && Value->IsNull() && !((PJDEF)Tjp->To_Def)->Accept)
+ throw("Null expandable JSON value");
// Set null when applicable
if (!Nullable)
@@ -1579,11 +1582,11 @@ PVAL JSONCOL::GetColumnValue(PGLOBAL g, PJSON row, int i)
else
return CalculateArray(g, arp, i);
- } else {
- // Unexpected array, unwrap it as [0]
- val = arp->GetValue(0);
- i--;
- } // endif's
+ } else {
+ // Unexpected array, unwrap it as [0]
+ val = arp->GetValue(0);
+ i--;
+ } // endif's
break;
case TYPE_JVAL:
@@ -1612,17 +1615,17 @@ PVAL JSONCOL::ExpandArray(PGLOBAL g, PJAR arp, int n)
PJVAL jvp;
JVALUE jval;
- if (!ars) {
- Value->Reset();
- Value->SetNull(true);
- Tjp->NextSame = 0;
- return Value;
- } // endif ars
+ if (!ars) {
+ Value->Reset();
+ Value->SetNull(true);
+ Tjp->NextSame = 0;
+ return Value;
+ } // endif ars
if (!(jvp = arp->GetValue((Nodes[n].Rx = Nodes[n].Nx)))) {
strcpy(g->Message, "Logical error expanding array");
- throw 666;
- } // endif jvp
+ throw 666;
+ } // endif jvp
if (n < Nod - 1 && jvp->GetJson()) {
jval.SetValue(GetColumnValue(g, jvp->GetJson(), n + 1));
@@ -1637,7 +1640,7 @@ PVAL JSONCOL::ExpandArray(PGLOBAL g, PJAR arp, int n)
Xnod = n;
Tjp->NextSame = Xnod;
- } // endif NextSame
+ } // endif NextSame
SetJsonValue(g, Value, jvp, n);
return Value;
@@ -1648,58 +1651,58 @@ PVAL JSONCOL::ExpandArray(PGLOBAL g, PJAR arp, int n)
/***********************************************************************/
PVAL JSONCOL::CalculateArray(PGLOBAL g, PJAR arp, int n)
{
- int i, ars, nv = 0, nextsame = Tjp->NextSame;
- bool err;
+ int i, ars, nv = 0, nextsame = Tjp->NextSame;
+ bool err;
OPVAL op = Nodes[n].Op;
PVAL val[2], vp = Nodes[n].Valp;
PJVAL jvrp, jvp;
JVALUE jval;
vp->Reset();
- ars = MY_MIN(Tjp->Limit, arp->size());
+ ars = MY_MIN(Tjp->Limit, arp->size());
- if (trace(1))
- htrc("CalculateArray: size=%d op=%d nextsame=%d\n",
- ars, op, nextsame);
+ if (trace(1))
+ htrc("CalculateArray: size=%d op=%d nextsame=%d\n",
+ ars, op, nextsame);
- for (i = 0; i < ars; i++) {
- jvrp = arp->GetValue(i);
+ for (i = 0; i < ars; i++) {
+ jvrp = arp->GetValue(i);
- if (trace(1))
- htrc("i=%d nv=%d\n", i, nv);
+ if (trace(1))
+ htrc("i=%d nv=%d\n", i, nv);
- if (!jvrp->IsNull() || (op == OP_CNC && GetJsonNull())) do {
- if (jvrp->IsNull()) {
- jvrp->Value = AllocateValue(g, GetJsonNull(), TYPE_STRING);
- jvp = jvrp;
- } else if (n < Nod - 1 && jvrp->GetJson()) {
+ if (!jvrp->IsNull() || (op == OP_CNC && GetJsonNull())) do {
+ if (jvrp->IsNull()) {
+ jvrp->Value = AllocateValue(g, GetJsonNull(), TYPE_STRING);
+ jvp = jvrp;
+ } else if (n < Nod - 1 && jvrp->GetJson()) {
Tjp->NextSame = nextsame;
jval.SetValue(GetColumnValue(g, jvrp->GetJson(), n + 1));
jvp = &jval;
} else
jvp = jvrp;
-
- if (trace(1))
- htrc("jvp=%s null=%d\n",
- jvp->GetString(g), jvp->IsNull() ? 1 : 0);
- if (!nv++) {
+ if (trace(1))
+ htrc("jvp=%s null=%d\n",
+ jvp->GetString(g), jvp->IsNull() ? 1 : 0);
+
+ if (!nv++) {
SetJsonValue(g, vp, jvp, n);
continue;
} else
SetJsonValue(g, MulVal, jvp, n);
- if (!MulVal->IsNull()) {
- switch (op) {
+ if (!MulVal->IsNull()) {
+ switch (op) {
case OP_CNC:
if (Nodes[n].CncVal) {
val[0] = Nodes[n].CncVal;
err = vp->Compute(g, val, 1, op);
} // endif CncVal
-
+
val[0] = MulVal;
err = vp->Compute(g, val, 1, op);
- break;
+ break;
// case OP_NUM:
case OP_SEP:
val[0] = Nodes[n].Valp;
@@ -1714,16 +1717,16 @@ PVAL JSONCOL::CalculateArray(PGLOBAL g, PJAR arp, int n)
if (err)
vp->Reset();
-
- if (trace(1)) {
- char buf(32);
- htrc("vp='%s' err=%d\n",
- vp->GetCharString(&buf), err ? 1 : 0);
+ if (trace(1)) {
+ char buf(32);
- } // endif trace
+ htrc("vp='%s' err=%d\n",
+ vp->GetCharString(&buf), err ? 1 : 0);
- } // endif Null
+ } // endif trace
+
+ } // endif Null
} while (Tjp->NextSame > nextsame);
@@ -1753,8 +1756,8 @@ PJSON JSONCOL::GetRow(PGLOBAL g)
PJAR arp;
PJSON nwr, row = Tjp->Row;
- for (int i = 0; i < Nod && row; i++) {
- if (Nodes[i+1].Op == OP_XX)
+ for (int i = 0; i < Nod && row; i++) {
+ if (Nodes[i+1].Op == OP_XX)
break;
else switch (row->GetType()) {
case TYPE_JOB:
@@ -1765,19 +1768,19 @@ PJSON JSONCOL::GetRow(PGLOBAL g)
val = ((PJOB)row)->GetValue(Nodes[i].Key);
break;
case TYPE_JAR:
- arp = (PJAR)row;
+ arp = (PJAR)row;
- if (!Nodes[i].Key) {
+ if (!Nodes[i].Key) {
if (Nodes[i].Op == OP_EQ)
val = arp->GetValue(Nodes[i].Rank);
else
val = arp->GetValue(Nodes[i].Rx);
} else {
- // Unexpected array, unwrap it as [0]
- val = arp->GetValue(0);
- i--;
- } // endif Nodes
+ // Unexpected array, unwrap it as [0]
+ val = arp->GetValue(0);
+ i--;
+ } // endif Nodes
break;
case TYPE_JVAL:
@@ -1827,10 +1830,10 @@ PJSON JSONCOL::GetRow(PGLOBAL g)
/***********************************************************************/
void JSONCOL::WriteColumn(PGLOBAL g)
{
- if (Xpd && Tjp->Pretty < 2) {
- strcpy(g->Message, "Cannot write expanded column when Pretty is not 2");
- throw 666;
- } // endif Xpd
+ if (Xpd && Tjp->Pretty < 2) {
+ strcpy(g->Message, "Cannot write expanded column when Pretty is not 2");
+ throw 666;
+ } // endif Xpd
/*********************************************************************/
/* Check whether this node must be written. */
@@ -1864,8 +1867,8 @@ void JSONCOL::WriteColumn(PGLOBAL g)
if (!(jsp = ParseJson(G, s, (int)strlen(s)))) {
strcpy(g->Message, s);
- throw 666;
- } // endif jsp
+ throw 666;
+ } // endif jsp
if (arp) {
if (Nod > 1 && Nodes[Nod-2].Op == OP_EQ)
@@ -1887,10 +1890,10 @@ void JSONCOL::WriteColumn(PGLOBAL g)
// fall through
case TYPE_DATE:
case TYPE_INT:
- case TYPE_TINY:
- case TYPE_SHORT:
- case TYPE_BIGINT:
- case TYPE_DOUBLE:
+ case TYPE_TINY:
+ case TYPE_SHORT:
+ case TYPE_BIGINT:
+ case TYPE_DOUBLE:
if (arp) {
if (Nodes[Nod-1].Op == OP_EQ)
arp->SetValue(G, new(G) JVALUE(G, Value), Nodes[Nod-1].Rank);
@@ -1981,7 +1984,7 @@ int TDBJSON::MakeDocument(PGLOBAL g)
return RC_OK;
/*********************************************************************/
- /* Create the mapping file object in mode read. */
+ /* Create the mapping file object in mode read. */
/*********************************************************************/
Mode = MODE_READ;
@@ -2010,70 +2013,70 @@ int TDBJSON::MakeDocument(PGLOBAL g)
if (!jsp && g->Message[0])
return RC_FX;
- if ((objpath = PlugDup(g, Objname))) {
- if (*objpath == '$') objpath++;
- if (*objpath == '.') objpath++;
-
- /*********************************************************************/
- /* Find the table in the tree structure. */
- /*********************************************************************/
- for (; jsp && objpath; objpath = p) {
- if ((p = strchr(objpath, Sep)))
- *p++ = 0;
-
- if (*objpath != '[' && !IsNum(objpath)) {
- // objpass is a key
- if (jsp->GetType() != TYPE_JOB) {
- strcpy(g->Message, "Table path does not match the json file");
- return RC_FX;
- } // endif Type
-
- key = objpath;
- objp = jsp->GetObject();
- arp = NULL;
- val = objp->GetValue(key);
-
- if (!val || !(jsp = val->GetJson())) {
- sprintf(g->Message, "Cannot find object key %s", key);
- return RC_FX;
- } // endif val
-
- } else {
- if (*objpath == '[') {
- // Old style
- if (objpath[strlen(objpath) - 1] != ']') {
- sprintf(g->Message, "Invalid Table path %s", Objname);
- return RC_FX;
- } else
- objpath++;
-
- } // endif objpath
-
- if (jsp->GetType() != TYPE_JAR) {
- strcpy(g->Message, "Table path does not match the json file");
- return RC_FX;
- } // endif Type
-
- arp = jsp->GetArray();
- objp = NULL;
- i = atoi(objpath) - B;
- val = arp->GetValue(i);
-
- if (!val) {
- sprintf(g->Message, "Cannot find array value %d", i);
- return RC_FX;
- } // endif val
-
- } // endif
-
- jsp = val->GetJson();
- } // endfor objpath
-
- } // endif objpath
+ if ((objpath = PlugDup(g, Objname))) {
+ if (*objpath == '$') objpath++;
+ if (*objpath == '.') objpath++;
+
+ /*********************************************************************/
+ /* Find the table in the tree structure. */
+ /*********************************************************************/
+ for (; jsp && objpath; objpath = p) {
+ if ((p = strchr(objpath, Sep)))
+ *p++ = 0;
+
+ if (*objpath != '[' && !IsNum(objpath)) {
+ // objpass is a key
+ if (jsp->GetType() != TYPE_JOB) {
+ strcpy(g->Message, "Table path does not match the json file");
+ return RC_FX;
+ } // endif Type
+
+ key = objpath;
+ objp = jsp->GetObject();
+ arp = NULL;
+ val = objp->GetValue(key);
+
+ if (!val || !(jsp = val->GetJson())) {
+ sprintf(g->Message, "Cannot find object key %s", key);
+ return RC_FX;
+ } // endif val
+
+ } else {
+ if (*objpath == '[') {
+ // Old style
+ if (objpath[strlen(objpath) - 1] != ']') {
+ sprintf(g->Message, "Invalid Table path %s", Objname);
+ return RC_FX;
+ } else
+ objpath++;
+
+ } // endif objpath
+
+ if (jsp->GetType() != TYPE_JAR) {
+ strcpy(g->Message, "Table path does not match the json file");
+ return RC_FX;
+ } // endif Type
+
+ arp = jsp->GetArray();
+ objp = NULL;
+ i = atoi(objpath) - B;
+ val = arp->GetValue(i);
+
+ if (!val) {
+ sprintf(g->Message, "Cannot find array value %d", i);
+ return RC_FX;
+ } // endif val
+
+ } // endif
+
+ jsp = val->GetJson();
+ } // endfor objpath
+
+ } // endif objpath
if (jsp && jsp->GetType() == TYPE_JAR)
Doc = jsp->GetArray();
- else {
+ else {
// The table is void or is just one object or one value
Doc = new(g) JARRAY;
@@ -2149,7 +2152,7 @@ int TDBJSON::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool)
} else
return RC_OK;
- } // end of MakeIndex
+ } // end of MakeIndex
/***********************************************************************/
/* Return the position in the table. */
@@ -2227,11 +2230,11 @@ bool TDBJSON::OpenDB(PGLOBAL g)
return true;
} // endswitch Jmode
- if (Xcol)
- To_Filter = NULL; // Imcompatible
+ if (Xcol)
+ To_Filter = NULL; // Imcompatible
- Use = USE_OPEN;
- return false;
+ Use = USE_OPEN;
+ return false;
} // end of OpenDB
/***********************************************************************/
@@ -2241,7 +2244,7 @@ int TDBJSON::ReadDB(PGLOBAL)
{
int rc;
- N++;
+ N++;
if (NextSame) {
SameRow = NextSame;
@@ -2352,8 +2355,8 @@ void TDBJSON::CloseDB(PGLOBAL g)
TDBJCL::TDBJCL(PJDEF tdp) : TDBCAT(tdp)
{
Topt = tdp->GetTopt();
- Db = tdp->Schema;
- Dsn = tdp->Uri;
+ Db = tdp->Schema;
+ Dsn = tdp->Uri;
} // end of TDBJCL constructor
/***********************************************************************/
diff --git a/storage/connect/tabrest.cpp b/storage/connect/tabrest.cpp
index e800411a36d..eef90f0dc1d 100644
--- a/storage/connect/tabrest.cpp
+++ b/storage/connect/tabrest.cpp
@@ -1,13 +1,23 @@
/*************** Rest C++ Program Source Code File (.CPP) **************/
-/* PROGRAM NAME: Rest Version 1.3 */
+/* PROGRAM NAME: Rest Version 1.5 */
/* (C) Copyright to the author Olivier BERTRAND 2018 - 2019 */
-/* This program is the REST OEM (Web API support) module definition. */
+/* 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: */
@@ -19,12 +29,12 @@
#include "plgdbsem.h"
#include "xtable.h"
#include "filamtxt.h"
-#include "plgxml.h"
#include "tabdos.h"
-#include "tabfmt.h"
+#include "plgxml.h"
+#include "tabxml.h"
#include "tabjson.h"
+#include "tabfmt.h"
#include "tabrest.h"
-#include "tabxml.h"
/***********************************************************************/
/* Get the file from the Web. */
@@ -32,25 +42,61 @@
int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn);
#if defined(__WIN__)
-static PCSZ slash= "\\";
+static PCSZ slash = "\\";
#else // !__WIN__
-static PCSZ slash= "/";
+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];
+ 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");
+ 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);
@@ -60,11 +106,11 @@ PQRYRES RESTColumns(PGLOBAL g, PTOS tp, char *tab, char *db, bool info)
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);
+ qrp = XMLColumns(g, db, tab, tp, info);
else if (!stricmp(ftype, "JSON"))
- qrp= JSONColumns(g, db, NULL, tp, info);
+ qrp = JSONColumns(g, db, NULL, tp, info);
else if (!stricmp(ftype, "CSV"))
- qrp= CSVColumns(g, NULL, tp, info);
+ qrp = CSVColumns(g, NULL, tp, info);
else
sprintf(g->Message, "Usupported file type %s", ftype);
@@ -78,40 +124,59 @@ PQRYRES RESTColumns(PGLOBAL g, PTOS tp, char *tab, char *db, bool info)
/***********************************************************************/
bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
- char filename[_MAX_PATH];
- TABTYPE type= GetTypeID(am);
-
- switch (type) {
- case TAB_JSON:
- case TAB_XML:
- case TAB_CSV:
- break;
- default:
- sprintf(g->Message, "Unsupported REST table type %s", am);
- return true;
- } // endswitch type
-
- Http= GetStringCatInfo(g, "Http", NULL);
- Uri= GetStringCatInfo(g, "Uri", NULL);
- Fn= GetStringCatInfo(g, "Filename", "rest.json");
+ 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(1))
+ 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());
+ //PlugSetPath(filename, Fn, GetPath());
+ strncat(strcpy(filename, GetPath()), Fn, _MAX_PATH);
// Retrieve the file from the web and copy it locally
- if (Http && restGetFile(g, Http, Uri, filename)) {}
- else if (type == TAB_JSON)
- Tdp= new (g) JSONDEF;
- else if (type == TAB_XML)
- Tdp= new (g) XMLDEF;
- else if (type == TAB_CSV)
- Tdp= new (g) CSVDEF;
- else
- sprintf(g->Message, "Unsupported REST table type %s", am);
+ rc = restGetFile(g, Http, Uri, filename);
+
+ if (trace(1))
+ 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
+ Tdp = NULL; // Error occured
+
+ if (trace(1))
+ htrc("Tdp defined\n", rc);
// Return true in case of error
return (Tdp == NULL);
@@ -122,10 +187,12 @@ bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
/***********************************************************************/
PTDB RESTDEF::GetTable(PGLOBAL g, MODE m)
{
- if (m != MODE_READ && m != MODE_READX) {
- strcpy(g->Message, "REST tables are currently read only");
- return NULL;
- } // endif m
+ xtrc(515, "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