Commit f590296c authored by Olivier Bertrand's avatar Olivier Bertrand

-- Finalize work on MongoDB access

   Implement discovery for the MongoDB Java Driver
   Create classes to minimize code and avoid dupicates
   Rearrange and rename implied files
  modified:   storage/connect/CMakeLists.txt
  renamed:    storage/connect/mongofam.cpp -> storage/connect/cmgfam.cpp
  renamed:    storage/connect/mongofam.h -> storage/connect/cmgfam.h
  modified:   storage/connect/cmgoconn.h
  modified:   storage/connect/javaconn.h
  modified:   storage/connect/jdbconn.cpp
  modified:   storage/connect/jmgoconn.cpp
  modified:   storage/connect/jmgoconn.h
  modified:   storage/connect/mongo.cpp
  modified:   storage/connect/mongo.h
  renamed:    storage/connect/tabmgo.cpp -> storage/connect/tabcmg.cpp
  renamed:    storage/connect/tabmgo.h -> storage/connect/tabcmg.h
  modified:   storage/connect/tabjmg.cpp
  modified:   storage/connect/tabjmg.h
  modified:   storage/connect/tabjson.cpp
  modified:   storage/connect/tabjson.h

-- Trace Sarea allocation and freeing
  modified:   storage/connect/connect.cc
  modified:   storage/connect/plugutil.cpp
  modified:   storage/connect/user_connect.cc

-- Null Json values where not mark as null in JSNX::SetJsonValue
   This was added in TYPE_NULL (declared as TYPE_VOID)
  modified:   storage/connect/json.cpp
  modified:   storage/connect/json.h
  modified:   storage/connect/jsonudf.cpp

-- Null JValues are ignored in JSNX::CalculateArray
   Also done in tabjson.cpp for JSONCOL::CalculateArray
  modified:   storage/connect/json.h
  modified:   storage/connect/jsonudf.cpp
  modified:   storage/connect/tabjson.cpp

-- Null JSON values now represented by connect_json_null session variable
  modified:   storage/connect/json.cpp
  modified:   storage/connect/json.h
  modified:   storage/connect/jsonudf.cpp
  modified:   storage/connect/tabjson.cpp

-- JVALUE has size = 1
  modified:   storage/connect/json.h

-- Fix by vuvova because Debian compilation failure.
  modified:   storage/connect/value.cpp
parent a9d32010
......@@ -316,8 +316,8 @@ ENDIF(CONNECT_WITH_ZIP)
# INCLUDE_DIRECTORIES(${MONGO_INCLUDE_DIR})
# SET(MONGO_LIBRARY ${MONGO_LIBRARIES})
# SET(CONNECT_SOURCES ${CONNECT_SOURCES}
# cmgoconn.cpp mongofam.cpp tabmgo.cpp
# cmgoconn.h mongofam.h tabmgo.h)
# cmgoconn.cpp cmgfam.cpp tabcmg.cpp
# cmgoconn.h cmgfam.h tabcmg.h)
# IF (NOT JAVA_FOUND AND JNI_FOUND)
# SET(CONNECT_SOURCES ${CONNECT_SOURCES} mongo.cpp mongo.h)
# ENDIF (NOT JAVA_FOUND AND JNI_FOUND)
......
/************ MONGO FAM C++ Program Source Code File (.CPP) ************/
/* PROGRAM NAME: mongofam.cpp */
/************** CMGFAM C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: cmgfam.cpp */
/* ------------- */
/* Version 1.3 */
/* Version 1.4 */
/* */
/* COPYRIGHT: */
/* ---------- */
......@@ -30,18 +30,18 @@
#include "filamtxt.h"
#include "tabdos.h"
#include "tabjson.h"
#include "mongofam.h"
#include "cmgfam.h"
#if defined(UNIX) || defined(UNIV_LINUX)
#include "osutil.h"
#endif
/* --------------------------- Class MGOFAM -------------------------- */
/* --------------------------- Class CMGFAM -------------------------- */
/***********************************************************************/
/* Constructors. */
/***********************************************************************/
MGOFAM::MGOFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
CMGFAM::CMGFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
{
Cmgp = NULL;
Pcg.Tdbp = NULL;
......@@ -66,20 +66,20 @@ MGOFAM::MGOFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
Mode = MODE_ANY;
Done = false;
Lrecl = tdp->Lrecl + tdp->Ending;
} // end of MGOFAM standard constructor
} // end of CMGFAM standard constructor
MGOFAM::MGOFAM(PMGOFAM tdfp) : DOSFAM(tdfp)
CMGFAM::CMGFAM(PCMGFAM tdfp) : DOSFAM(tdfp)
{
Pcg = tdfp->Pcg;
To_Fbt = tdfp->To_Fbt;
Mode = tdfp->Mode;
Done = tdfp->Done;
} // end of MGOFAM copy constructor
} // end of CMGFAM copy constructor
/***********************************************************************/
/* Reset: reset position values at the beginning of file. */
/***********************************************************************/
void MGOFAM::Reset(void)
void CMGFAM::Reset(void)
{
TXTFAM::Reset();
Fpos = Tpos = Spos = 0;
......@@ -88,7 +88,7 @@ void MGOFAM::Reset(void)
/***********************************************************************/
/* MGO GetFileLength: returns file size in number of bytes. */
/***********************************************************************/
int MGOFAM::GetFileLength(PGLOBAL g)
int CMGFAM::GetFileLength(PGLOBAL g)
{
return 0;
} // end of GetFileLength
......@@ -98,7 +98,7 @@ int MGOFAM::GetFileLength(PGLOBAL g)
/* This function can be called with a null argument to test the */
/* availability of Cardinality implementation (1 yes, 0 no). */
/***********************************************************************/
int MGOFAM::Cardinality(PGLOBAL g)
int CMGFAM::Cardinality(PGLOBAL g)
{
if (!g)
return 1;
......@@ -109,7 +109,7 @@ int MGOFAM::Cardinality(PGLOBAL g)
/***********************************************************************/
/* Note: This function is not really implemented yet. */
/***********************************************************************/
int MGOFAM::MaxBlkSize(PGLOBAL, int s)
int CMGFAM::MaxBlkSize(PGLOBAL, int s)
{
return s;
} // end of MaxBlkSize
......@@ -117,7 +117,7 @@ int MGOFAM::MaxBlkSize(PGLOBAL, int s)
/***********************************************************************/
/* Init: initialize MongoDB processing. */
/***********************************************************************/
bool MGOFAM::Init(PGLOBAL g)
bool CMGFAM::Init(PGLOBAL g)
{
if (Done)
return false;
......@@ -141,7 +141,7 @@ bool MGOFAM::Init(PGLOBAL g)
/***********************************************************************/
/* OpenTableFile: Open a MongoDB table. */
/***********************************************************************/
bool MGOFAM::OpenTableFile(PGLOBAL g)
bool CMGFAM::OpenTableFile(PGLOBAL g)
{
Mode = Tdbp->GetMode();
......@@ -165,7 +165,7 @@ bool MGOFAM::OpenTableFile(PGLOBAL g)
/***********************************************************************/
/* GetRowID: return the RowID of last read record. */
/***********************************************************************/
int MGOFAM::GetRowID(void)
int CMGFAM::GetRowID(void)
{
return Rows;
} // end of GetRowID
......@@ -173,7 +173,7 @@ int MGOFAM::GetRowID(void)
/***********************************************************************/
/* GetPos: return the position of last read record. */
/***********************************************************************/
int MGOFAM::GetPos(void)
int CMGFAM::GetPos(void)
{
return Fpos;
} // end of GetPos
......@@ -181,7 +181,7 @@ int MGOFAM::GetPos(void)
/***********************************************************************/
/* GetNextPos: return the position of next record. */
/***********************************************************************/
int MGOFAM::GetNextPos(void)
int CMGFAM::GetNextPos(void)
{
return Fpos; // TODO
} // end of GetNextPos
......@@ -189,7 +189,7 @@ int MGOFAM::GetNextPos(void)
/***********************************************************************/
/* SetPos: Replace the table at the specified position. */
/***********************************************************************/
bool MGOFAM::SetPos(PGLOBAL g, int pos)
bool CMGFAM::SetPos(PGLOBAL g, int pos)
{
Fpos = pos;
Placed = true;
......@@ -199,25 +199,25 @@ bool MGOFAM::SetPos(PGLOBAL g, int pos)
/***********************************************************************/
/* Record file position in case of UPDATE or DELETE. */
/***********************************************************************/
bool MGOFAM::RecordPos(PGLOBAL g)
bool CMGFAM::RecordPos(PGLOBAL g)
{
strcpy(g->Message, "MGOFAM::RecordPos NIY");
strcpy(g->Message, "CMGFAM::RecordPos NIY");
return true;
} // end of RecordPos
/***********************************************************************/
/* Initialize Fpos and the current position for indexed DELETE. */
/***********************************************************************/
int MGOFAM::InitDelete(PGLOBAL g, int fpos, int spos)
int CMGFAM::InitDelete(PGLOBAL g, int fpos, int spos)
{
strcpy(g->Message, "MGOFAM::InitDelete NIY");
strcpy(g->Message, "CMGFAM::InitDelete NIY");
return RC_FX;
} // end of InitDelete
/***********************************************************************/
/* Skip one record in file. */
/***********************************************************************/
int MGOFAM::SkipRecord(PGLOBAL g, bool header)
int CMGFAM::SkipRecord(PGLOBAL g, bool header)
{
return RC_OK; // Dummy
} // end of SkipRecord
......@@ -225,7 +225,7 @@ int MGOFAM::SkipRecord(PGLOBAL g, bool header)
/***********************************************************************/
/* ReadBuffer: Get next document from a collection. */
/***********************************************************************/
int MGOFAM::ReadBuffer(PGLOBAL g)
int CMGFAM::ReadBuffer(PGLOBAL g)
{
int rc = Cmgp->ReadNext(g);
......@@ -239,7 +239,7 @@ int MGOFAM::ReadBuffer(PGLOBAL g)
/***********************************************************************/
/* WriteBuffer: File write routine for MGO access method. */
/***********************************************************************/
int MGOFAM::WriteBuffer(PGLOBAL g)
int CMGFAM::WriteBuffer(PGLOBAL g)
{
return Cmgp->Write(g);
} // end of WriteBuffer
......@@ -247,7 +247,7 @@ int MGOFAM::WriteBuffer(PGLOBAL g)
/***********************************************************************/
/* Data Base delete line routine for MGO and BLK access methods. */
/***********************************************************************/
int MGOFAM::DeleteRecords(PGLOBAL g, int irc)
int CMGFAM::DeleteRecords(PGLOBAL g, int irc)
{
return (irc == RC_OK) ? WriteBuffer(g) : RC_OK;
} // end of DeleteRecords
......@@ -255,7 +255,7 @@ int MGOFAM::DeleteRecords(PGLOBAL g, int irc)
/***********************************************************************/
/* Table file close routine for MGO access method. */
/***********************************************************************/
void MGOFAM::CloseTableFile(PGLOBAL g, bool)
void CMGFAM::CloseTableFile(PGLOBAL g, bool)
{
Cmgp->Close();
Done = false;
......@@ -264,7 +264,7 @@ void MGOFAM::CloseTableFile(PGLOBAL g, bool)
/***********************************************************************/
/* Rewind routine for MGO access method. */
/***********************************************************************/
void MGOFAM::Rewind(void)
void CMGFAM::Rewind(void)
{
Cmgp->Rewind();
} // end of Rewind
......
/************** MongoFam H Declares Source Code File (.H) **************/
/* Name: mongofam.h Version 1.4 */
/*************** CMGFam H Declares Source Code File (.H) ***************/
/* Name: cmgfam.h Version 1.5 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* */
......@@ -8,19 +8,19 @@
#include "cmgoconn.h"
typedef class TXTFAM *PTXF;
typedef class MGOFAM *PMGOFAM;
typedef class CMGFAM *PCMGFAM;
typedef class MGODEF *PMGODEF;
typedef class TDBMGO *PTDBMGO;
typedef class TDBCMG *PTDBCMG;
/***********************************************************************/
/* This is the MongoDB Access Method class declaration. */
/***********************************************************************/
class DllExport MGOFAM : public DOSFAM {
class DllExport CMGFAM : public DOSFAM {
friend void mongo_init(bool);
public:
// Constructor
MGOFAM(PJDEF tdp);
MGOFAM(PMGOFAM txfp);
CMGFAM(PJDEF tdp);
CMGFAM(PCMGFAM txfp);
// Implementation
virtual AMT GetAmType(void) { return TYPE_AM_MGO; }
......@@ -28,7 +28,7 @@ class DllExport MGOFAM : public DOSFAM {
virtual int GetPos(void);
virtual int GetNextPos(void);
void SetTdbp(PTDBDOS tdbp) { Tdbp = tdbp; }
virtual PTXF Duplicate(PGLOBAL g) { return (PTXF)new(g) MGOFAM(this); }
virtual PTXF Duplicate(PGLOBAL g) { return (PTXF)new(g) CMGFAM(this); }
void SetLrecl(int lrecl) { Lrecl = lrecl; }
// Methods
......@@ -61,5 +61,5 @@ class DllExport MGOFAM : public DOSFAM {
PFBLOCK To_Fbt; // Pointer to temp file block
MODE Mode;
bool Done; // Init done
}; // end of class MGOFAM
}; // end of class CMGFAM
......@@ -10,7 +10,7 @@
#include <mongoc.h>
// C connection to a MongoDB data source
class TDBMGO;
class TDBCMG;
class MGOCOL;
/***********************************************************************/
......@@ -18,7 +18,7 @@ class MGOCOL;
/***********************************************************************/
typedef class INCOL *PINCOL;
typedef class MGODEF *PMGODEF;
typedef class TDBMGO *PTDBMGO;
typedef class TDBCMG *PTDBCMG;
typedef class MGOCOL *PMGOCOL;
typedef struct mongo_parms {
......@@ -63,8 +63,8 @@ class INCOL : public BLOCK {
/* CMgoConn class. */
/***********************************************************************/
class CMgoConn : public BLOCK {
friend class TDBMGO;
friend class MGODISC;
friend class TDBCMG;
friend class CMGDISC;
public:
// Constructor
CMgoConn(PGLOBAL g, PCPARM pcg);
......
......@@ -80,7 +80,7 @@ PGLOBAL CntExit(PGLOBAL g)
/* CntEndDB: DB termination semantic routine. */
/***********************************************************************/
void CntEndDB(PGLOBAL g)
{
{
PDBUSER dbuserp= PlgGetUser(g);
if (dbuserp) {
......@@ -88,9 +88,14 @@ void CntEndDB(PGLOBAL g)
delete dbuserp->Catalog;
free(dbuserp);
if (trace)
htrc("CntEndDB: Freeing Dup\n");
g->Activityp->Aptr = NULL;
} // endif dbuserp
} // end of CntEndDB
} // end of CntEndDB
/***********************************************************************/
/* CntCheckDB: Initialize a DB application session. */
......
......@@ -58,31 +58,10 @@
/* Miscellaneous Constants */
/***********************************************************************/
#define NO_IVAL -95684275 /* Used by GetIntegerOption */
#define VMLANG 370 /* Size of olf VM lang blocks */
#define MAX_JUMP 24 /* Maximum jump level number */
#define MAX_STR 4160 /* Maximum message length */
#define STR_SIZE 501 /* Length of char strings. */
#define STD_INPUT 0 /* Standard language input */
#define STD_OUTPUT 1 /* Standard language output */
#define ERROR_OUTPUT 2 /* Error message output */
#define DEBUG_OUTPUT 3 /* Debug info output */
#define PROMPT_OUTPUT 4 /* Prompt message output */
#define COPY_OUTPUT 5 /* Copy of language input */
#define STD_MSG 6 /* System message file */
#define DEBUG_MSG 7 /* Debug message file */
#define DUMMY 0 /* Dummy file index in Ldm block */
#define STDIN 1 /* stdin file index in Ldm block */
#define STDOUT 2 /* stdout file index in Ldm block */
#define STDERR 3 /* stderr file index in Ldm block */
#define STDEBUG 4 /* debug file index in Ldm block */
#define STDPRN 5 /* stdprn file index in Ldm block */
#define STDFREE 6 /* Free file index in Ldm block */
#define TYPE_SEM -2 /* Returned semantic function */
#define TYPE_DFONC -2 /* Indirect sem ref in FPARM */
#define TYPE_VOID -1
#define TYPE_SBPAR -1 /* Phrase reference in FPARM */
#define TYPE_SEMX 0 /* Initial semantic function type? */
#define TYPE_ERROR 0
#define TYPE_STRING 1
#define TYPE_DOUBLE 2
......@@ -96,22 +75,6 @@
#define TYPE_BIN 10
#define TYPE_PCHAR 11
#if defined(OS32)
#define SYS_STAMP "OS32"
#elif defined(UNIX) || defined(LINUX) || defined(UNIV_LINUX)
#define SYS_STAMP "UNIX"
#elif defined(OS16)
#define SYS_STAMP "OS16"
#elif defined(DOSR)
#define SYS_STAMP "DOSR"
#elif defined(WIN)
#define SYS_STAMP "WIN1"
#elif defined(__WIN__)
#define SYS_STAMP "WIN2"
#else
#define SYS_STAMP "XXXX"
#endif
#if defined(__cplusplus)
extern "C" {
#endif
......@@ -119,11 +82,6 @@ extern "C" {
/***********************************************************************/
/* Static variables */
/***********************************************************************/
#if defined(STORAGE)
char sys_stamp[5] = SYS_STAMP;
#else
extern char sys_stamp[];
#endif
/***********************************************************************/
/* File-Selection Indicators */
......
......@@ -210,9 +210,9 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
PQRYRES VirColumns(PGLOBAL g, bool info);
PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info);
PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info);
#if defined(MONGO_SUPPORT)
#if defined(JDBC_SUPPORT) || defined(MONGO_SUPPORT)
PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ url, PTOS topt, bool info);
#endif // MONGO_SUPPORT
#endif // JDBC_SUPPORT || MONGO_SUPPORT
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,
......@@ -223,6 +223,7 @@ void mongo_init(bool);
USETEMP UseTemp(void);
int GetConvSize(void);
TYPCONV GetTypeConv(void);
char *GetJsonNull(void);
uint GetJsonGrpSize(void);
char *GetJavaWrapper(void);
uint GetWorkSize(void);
......@@ -332,6 +333,13 @@ static MYSQL_THDVAR_ENUM(
0, // def (no)
&xconv_typelib); // typelib
// Null representation for JSON values
static MYSQL_THDVAR_STR(json_null,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
"Representation of Json null values",
// check_json_null, update_json_null,
NULL, NULL, "<null>");
// Estimate max number of rows for JSON aggregate functions
static MYSQL_THDVAR_UINT(json_grp_size,
PLUGIN_VAR_RQCMDARG, // opt
......@@ -343,7 +351,7 @@ static MYSQL_THDVAR_UINT(json_grp_size,
static MYSQL_THDVAR_STR(java_wrapper,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
"Java wrapper class name",
// check_class_path, update_class_path,
// check_java_wrapper, update_java_wrapper,
NULL, NULL, "wrappers/JdbcInterface");
#endif // JDBC_SUPPORT
......@@ -383,6 +391,8 @@ bool ExactInfo(void) {return THDVAR(current_thd, exact_info);}
USETEMP UseTemp(void) {return (USETEMP)THDVAR(current_thd, use_tempfile);}
int GetConvSize(void) {return THDVAR(current_thd, conv_size);}
TYPCONV GetTypeConv(void) {return (TYPCONV)THDVAR(current_thd, type_conv);}
char *GetJsonNull(void)
{return connect_hton ? THDVAR(current_thd, json_null) : NULL;}
uint GetJsonGrpSize(void)
{return connect_hton ? THDVAR(current_thd, json_grp_size) : 10;}
uint GetWorkSize(void) {return THDVAR(current_thd, work_size);}
......@@ -5761,25 +5771,13 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#if !defined(MONGO_SUPPORT)
driver = "JAVA";
// strcpy(g->Message, "No column discovery for Java MONGO tables yet");
// Temporarily use the JSONColumns function
qrp = JSONColumns(g, db, url, topt, fnc == FNC_COL);
#elif !defined(JDBC_SUPPORT)
driver = "C";
qrp = MGOColumns(g, db, url, topt, fnc == FNC_COL);
#else // MONGO_SUPPORT && JDBC_SUPPORT
if (!driver)
driver = "C";
if (toupper(*driver) == 'C') {
qrp = MGOColumns(g, db, url, topt, fnc == FNC_COL);
} else {
// strcpy(g->Message, "No column discovery for Java MONGO tables yet");
// Temporarily use the JSONColumns function
qrp = JSONColumns(g, db, url, topt, fnc == FNC_COL);
} // endif driver
#endif // MONGO_SUPPORT && JDBC_SUPPORT
qrp = MGOColumns(g, db, url, topt, fnc == FNC_COL);
break;
#endif // MONGO_SUPPORT || JDBC_SUPPORT
#if defined(LIBXML2_SUPPORT) || defined(DOMDOC_SUPPORT)
......@@ -7137,6 +7135,7 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
#if defined(XMSG)
MYSQL_SYSVAR(errmsg_dir_path),
#endif // XMSG
MYSQL_SYSVAR(json_null),
MYSQL_SYSVAR(json_grp_size),
#if defined(JDBC_SUPPORT)
MYSQL_SYSVAR(jvm_path),
......
......@@ -63,6 +63,7 @@ class JAVAConn;
/***********************************************************************/
class JAVAConn : public BLOCK {
friend class TDBJMG;
friend class JMGDISC;
private:
JAVAConn(); // Standard (unused) constructor
......
......@@ -1226,7 +1226,7 @@ bool JDBConn::SetParam(JDBCCOL *colp)
case 5: crp->Name = "Nullable"; break;
} // endswitch i
// Build the java string array
// Build the java int array
jintArray val = env->NewIntArray(4);
if (val == nullptr) {
......
......@@ -110,8 +110,8 @@ JMgoConn::JMgoConn(PGLOBAL g, PCSZ collname, PCSZ wrapper)
deleteid = gcollid = countid = rewindid = nullptr;
DiscFunc = "MongoDisconnect";
Fpc = NULL;
m_Version = 0;
m_Fetch = 0;
m_Ncol = 0;
m_Version = 0;
} // end of JMgoConn
......@@ -122,13 +122,13 @@ void JMgoConn::AddJars(PSTRG jpop, char sep)
{
#if defined(DEVELOPMENT)
if (m_Version == 2) {
//jpop->Append(sep);
//jpop->Append("C:/Eclipse/workspace/MongoWrap2/bin");
jpop->Append(sep);
jpop->Append("C:/Eclipse/workspace/MongoWrap2/bin");
jpop->Append(sep);
jpop->Append("C:/mongo-java-driver/mongo-java-driver-2.13.3.jar");
} else {
//jpop->Append(sep);
//jpop->Append("C:/Eclipse/workspace/MongoWrap3/bin");
jpop->Append(sep);
jpop->Append("C:/Eclipse/workspace/MongoWrap3/bin");
jpop->Append(sep);
jpop->Append("C:/mongo-java-driver/mongo-java-driver-3.4.2.jar");
} // endif m_Version
......@@ -495,13 +495,15 @@ int JMgoConn::Fetch(int pos)
//else
// m_Fetch++;
m_Rows += (int)rc;
m_Ncol = (int)rc;
rc = MY_MIN(rc, 1);
m_Rows += rc;
} else
sprintf(g->Message, "Fetch: %s", Msg);
//} // endif pos
return (int)rc;
return rc;
} // end of Fetch
/***********************************************************************/
......
......@@ -19,31 +19,6 @@ typedef class MGODEF *PMGODEF;
typedef class TDBJMG *PTDBJMG;
typedef class JMGCOL *PJMGCOL;
#if 0
/***********************************************************************/
/* Class used to get the columns of a mongo collection. */
/***********************************************************************/
class MGODISC : public BLOCK {
public:
// Constructor
MGODISC(PGLOBAL g, int *lg);
// Functions
int GetColumns(PGLOBAL g, char *db, PTOS topt);
bool FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
char *pcn, char *pfmt, int i, int k, bool b);
// Members
BCOL bcol;
PBCOL bcp, fbcp, pbcp;
PMGODEF tdp;
TDBJMG *tmgp;
int *length;
int n, k, lvl;
bool all;
}; // end of MGODISC
#endif // 0
typedef struct JKCOL {
JKCOL *Next;
PJNCOL Jncolp;
......@@ -73,6 +48,7 @@ class JNCOL : public BLOCK {
/***********************************************************************/
class JMgoConn : public JAVAConn {
friend class TDBJMG;
friend class JMGDISC;
//friend class TDBXJDC;
//friend PQRYRES GetColumnInfo(PGLOBAL, char*&, char *, int, PVBLK&);
private:
......@@ -132,5 +108,6 @@ class JMgoConn : public JAVAConn {
jmethodID deleteid; // The CollDelete method ID
PJNCOL Fpc; // To JNCOL classes
int m_Fetch;
int m_Ncol;
int m_Version; // Java driver version (2 or 3)
}; // end of JMgoConn class definition
/*************** json CPP Declares Source Code File (.H) ***************/
/* Name: json.cpp Version 1.3 */
/* Name: json.cpp Version 1.4 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */
/* */
......@@ -53,6 +53,8 @@ void trans_func(unsigned int u, _EXCEPTION_POINTERS* pExp)
char *GetExceptionDesc(PGLOBAL g, unsigned int e);
#endif // SE_CATCH
char *GetJsonNull(void);
/***********************************************************************/
/* IsNum: check whether this string is all digits. */
/***********************************************************************/
......@@ -537,7 +539,7 @@ PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src)
if (!has_e)
goto err;
// passthru
// fall through
case '-':
if (found_digit)
goto err;
......@@ -827,7 +829,7 @@ bool JOUTSTR::Escape(const char *s)
case '\r':
case '\b':
case '\f': WriteChr('\\');
// passthru
// fall through
default:
WriteChr(s[i]);
break;
......@@ -963,6 +965,25 @@ return false;
/* -------------------------- Class JOBJECT -------------------------- */
/***********************************************************************/
/* Return the number of pairs in this object. */
/***********************************************************************/
int JOBJECT::GetSize(bool b)
{
if (b) {
// Return only non null pairs
int n = 0;
for (PJPR jpp = First; jpp; jpp = jpp->Next)
if (jpp->Val && !jpp->Val->IsNull())
n++;
return n;
} else
return Size;
} // end of GetSize
/***********************************************************************/
/* Add a new pair to an Object. */
/***********************************************************************/
......@@ -1046,7 +1067,7 @@ PSZ JOBJECT::GetText(PGLOBAL g, PSZ text)
PlugSubAlloc(g, NULL, strlen(text) + 1);
return text + n;
} // end of GetValue;
} // end of GetText;
/***********************************************************************/
/* Merge two objects. */
......@@ -1117,6 +1138,25 @@ bool JOBJECT::IsNull(void)
/* -------------------------- Class JARRAY --------------------------- */
/***********************************************************************/
/* Return the number of values in this object. */
/***********************************************************************/
int JARRAY::GetSize(bool b)
{
if (b) {
// Return only non null values
int n = 0;
for (PJVAL jvp = First; jvp; jvp = jvp->Next)
if (!jvp->IsNull())
n++;
return n;
} else
return Size;
} // end of GetSize
/***********************************************************************/
/* Make the array of values from the values list. */
/***********************************************************************/
......@@ -1225,6 +1265,30 @@ bool JARRAY::SetValue(PGLOBAL g, PJVAL jvp, int n)
return false;
} // end of SetValue
/***********************************************************************/
/* Return the text corresponding to all values. */
/***********************************************************************/
PSZ JARRAY::GetText(PGLOBAL g, PSZ text)
{
int n;
PJVAL jp;
if (!text) {
text = (char*)PlugSubAlloc(g, NULL, 0);
text[0] = 0;
n = 1;
} else
n = 0;
for (jp = First; jp; jp = jp->Next)
jp->GetText(g, text);
if (n)
PlugSubAlloc(g, NULL, strlen(text) + 1);
return text + n;
} // end of GetText;
/***********************************************************************/
/* Delete a Value from the Arrays Value list. */
/***********************************************************************/
......@@ -1286,7 +1350,7 @@ JTYP JVALUE::GetValType(void)
else if (Value)
return (JTYP)Value->GetType();
else
return (JTYP)TYPE_VOID;
return TYPE_NULL;
} // end of GetValType
......@@ -1350,7 +1414,7 @@ PSZ JVALUE::GetString(void)
/***********************************************************************/
PSZ JVALUE::GetText(PGLOBAL g, PSZ text)
{
if (Jsp && Jsp->GetType() == TYPE_JOB)
if (Jsp)
return Jsp->GetText(g, text);
char buf[32];
......@@ -1358,8 +1422,8 @@ PSZ JVALUE::GetText(PGLOBAL g, PSZ text)
if (s)
strcat(strcat(text, " "), s);
else
strcat(text, " <null>");
else if (GetJsonNull())
strcat(strcat(text, " "), GetJsonNull());
return text;
} // end of GetText
......
......@@ -13,7 +13,8 @@
#define X
#endif
enum JTYP {TYPE_STRG = TYPE_STRING,
enum JTYP {TYPE_NULL = TYPE_VOID,
TYPE_STRG = TYPE_STRING,
TYPE_DBL = TYPE_DOUBLE,
TYPE_BOOL = TYPE_TINY,
TYPE_BINT = TYPE_BIGINT,
......@@ -146,6 +147,7 @@ class JSON : public BLOCK {
JSON(void) {Size = 0;}
int size(void) {return Size;}
virtual int GetSize(bool b) {return Size;}
virtual void Clear(void) {Size = 0;}
virtual JTYP GetType(void) {return TYPE_JSON;}
virtual JTYP GetValType(void) {X return TYPE_JSON;}
......@@ -196,6 +198,7 @@ class JOBJECT : public JSON {
virtual void Clear(void) {First = Last = NULL; Size = 0;}
virtual JTYP GetType(void) {return TYPE_JOB;}
virtual PJPR GetFirst(void) {return First;}
virtual int GetSize(bool b);
virtual PJPR AddPair(PGLOBAL g, PCSZ key);
virtual PJOB GetObject(void) {return this;}
virtual PJVAL GetValue(const char* key);
......@@ -224,9 +227,11 @@ class JARRAY : public JSON {
virtual void Clear(void) {First = Last = NULL; Size = 0;}
virtual JTYP GetType(void) {return TYPE_JAR;}
virtual PJAR GetArray(void) {return this;}
virtual int GetSize(bool b);
PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL, int *x = NULL);
virtual void InitArray(PGLOBAL g);
virtual PJVAL GetValue(int i);
virtual PSZ GetText(PGLOBAL g, PSZ text);
virtual bool Merge(PGLOBAL g, PJSON jsp);
virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i);
virtual bool DeleteValue(int n);
......@@ -246,20 +251,20 @@ class JARRAY : public JSON {
class JVALUE : public JSON {
friend class JARRAY;
friend class JSNX;
friend class JSONCOL;
friend PJVAL ParseValue(PGLOBAL, int&, STRG&, bool*);
friend bool SerializeValue(JOUT *, PJVAL);
public:
JVALUE(void) : JSON()
{Jsp = NULL; Value = NULL; Next = NULL; Del = false;}
JVALUE(void) : JSON() {Clear();}
JVALUE(PJSON jsp) : JSON()
{Jsp = jsp; Value = NULL; Next = NULL; Del = false;}
{Jsp = jsp; Value = NULL; Next = NULL; Del = false; Size = 1;}
JVALUE(PGLOBAL g, PVAL valp);
JVALUE(PGLOBAL g, PCSZ strp);
using JSON::GetValue;
using JSON::SetValue;
virtual void Clear(void)
{Jsp = NULL; Value = NULL; Next = NULL; Del = false; Size = 0;}
{Jsp = NULL; Value = NULL; Next = NULL; Del = false; Size = 1;}
virtual JTYP GetType(void) {return TYPE_JVAL;}
virtual JTYP GetValType(void);
virtual PJOB GetObject(void);
......
/****************** jsonudf C++ Program Source Code File (.CPP) ******************/
/* PROGRAM NAME: jsonudf Version 1.5 */
/* PROGRAM NAME: jsonudf Version 1.6 */
/* (C) Copyright to the author Olivier BERTRAND 2015-2017 */
/* This program are the JSON User Defined Functions . */
/*********************************************************************************/
......@@ -29,6 +29,7 @@
bool IsNum(PSZ s);
char *NextChr(PSZ s, char sep);
char *GetJsonNull(void);
uint GetJsonGrpSize(void);
static int IsJson(UDF_ARGS *args, uint i);
static PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i);
......@@ -347,11 +348,13 @@ void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n)
SetJsonValue(g, vp, val->GetArray()->GetValue(0), n);
break;
case TYPE_JOB:
// if (!vp->IsTypeNum() || !Strict) {
// if (!vp->IsTypeNum() || !Strict) {
vp->SetValue_psz(val->GetObject()->GetText(g, NULL));
break;
// } // endif Type
// } // endif Type
case TYPE_NULL:
vp->SetNull(true);
default:
vp->Reset();
} // endswitch Type
......@@ -488,15 +491,16 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
JVALUE jval;
vp->Reset();
//ars = MY_MIN(Tjp->Limit, arp->size());
ars = arp->size();
for (i = 0; i < ars; i++) {
jvrp = arp->GetValue(i);
// do {
if (n < Nod - 1 && jvrp->GetJson()) {
// Tjp->NextSame = nextsame;
if (!jvrp->IsNull() || (op == OP_CNC && GetJsonNull())) {
if (jvrp->IsNull()) {
jvrp->Value = AllocateValue(g, GetJsonNull(), TYPE_STRING);
jvp = jvrp;
} else if (n < Nod - 1 && jvrp->GetJson()) {
jval.SetValue(GetColumnValue(g, jvrp->GetJson(), n + 1));
jvp = &jval;
} else
......@@ -519,7 +523,7 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
val[0] = MulVal;
err = vp->Compute(g, val, 1, op);
break;
// case OP_NUM:
// case OP_NUM:
case OP_SEP:
val[0] = Nodes[n].Valp;
val[1] = MulVal;
......@@ -536,7 +540,7 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
} // endif Zero
// } while (Tjp->NextSame > nextsame);
} // endif jvrp
} // endfor i
......@@ -1100,6 +1104,7 @@ inline void JsonMemSave(PGLOBAL g)
/*********************************************************************************/
inline void JsonFreeMem(PGLOBAL g)
{
g->Activityp = NULL;
PlugExit(g);
} /* end of JsonFreeMem */
......@@ -1111,7 +1116,7 @@ static my_bool JsonInit(UDF_INIT *initid, UDF_ARGS *args,
unsigned long reslen, unsigned long memlen,
unsigned long more = 0)
{
PGLOBAL g = PlugInit(NULL, memlen + more);
PGLOBAL g = PlugInit(NULL, memlen + more + 500); // +500 to avoid CheckMem
if (!g) {
strcpy(message, "Allocation error");
......@@ -1471,6 +1476,9 @@ static my_bool CheckMemory(PGLOBAL g, UDF_INIT *initid, UDF_ARGS *args, uint n,
ml += g->More;
if (ml > g->Sarea_Size) {
if (trace)
htrc("Freeing Sarea size=%d\n", g->Sarea_Size);
free(g->Sarea);
if (!(g->Sarea = PlugAllocMem(g, ml))) {
......@@ -1814,7 +1822,7 @@ char *json_make_array(UDF_INIT *initid, UDF_ARGS *args, char *result,
return str;
} // end of json_make_array
void json_array_deinit(UDF_INIT* initid)
void json_make_array_deinit(UDF_INIT* initid)
{
JsonFreeMem((PGLOBAL)initid->ptr);
} // end of json_make_array_deinit
......@@ -2097,6 +2105,206 @@ void json_array_delete_deinit(UDF_INIT* initid)
JsonFreeMem((PGLOBAL)initid->ptr);
} // end of json_array_delete_deinit
/*********************************************************************************/
/* Sum big integer values from a Json array. */
/*********************************************************************************/
my_bool jsonsum_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen, more;
if (args->arg_count != 1) {
strcpy(message, "This function must have 1 argument");
return true;
} else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
strcpy(message, "First argument must be a json item");
return true;
} else
CalcLen(args, false, reslen, memlen);
// TODO: calculate this
more = (IsJson(args, 0) != 3) ? 1000 : 0;
return JsonInit(initid, args, message, true, reslen, memlen, more);
} // end of jsonsum_int_init
long long jsonsum_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
long long n = 0LL;
PGLOBAL g = (PGLOBAL)initid->ptr;
if (g->N) {
if (!g->Activityp) {
*is_null = 1;
return 0LL;
} else
return *(long long*)g->Activityp;
} else if (initid->const_item)
g->N = 1;
if (!CheckMemory(g, initid, args, 1, false, false, true)) {
PJVAL jvp = MakeValue(g, args, 0);
if (jvp && jvp->GetValType() == TYPE_JAR) {
PJAR arp = jvp->GetArray();
for (int i = 0; i < arp->size(); i++)
n += arp->GetValue(i)->GetBigint();
} else {
PUSH_WARNING("First argument target is not an array");
} // endif jvp
} else {
*error = 1;
n = -1LL;
} // end of CheckMemory
if (g->N) {
// Keep result of constant function
long long *np = (long long*)PlugSubAlloc(g, NULL, sizeof(long long));
*np = n;
g->Activityp = (PACTIVITY)np;
} // endif const_item
return n;
} // end of jsonsum_int
void jsonsum_int_deinit(UDF_INIT* initid)
{
JsonFreeMem((PGLOBAL)initid->ptr);
} // end of jsonsum_int_deinit
/*********************************************************************************/
/* Sum big integer values from a Json array. */
/*********************************************************************************/
my_bool jsonsum_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen, more;
if (args->arg_count != 1) {
strcpy(message, "This function must have 1 argument");
return true;
} else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
strcpy(message, "First argument must be a json item");
return true;
} else
CalcLen(args, false, reslen, memlen);
// TODO: calculate this
more = (IsJson(args, 0) != 3) ? 1000 : 0;
return JsonInit(initid, args, message, true, reslen, memlen, more);
} // end of jsonsum_real_init
double jsonsum_real(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
double n = 0.0;
PGLOBAL g = (PGLOBAL)initid->ptr;
if (g->N) {
if (!g->Activityp) {
*is_null = 1;
return 0.0;
} else
return *(double*)g->Activityp;
} else if (initid->const_item)
g->N = 1;
if (!CheckMemory(g, initid, args, 1, false, false, true)) {
PJVAL jvp = MakeValue(g, args, 0);
if (jvp && jvp->GetValType() == TYPE_JAR) {
PJAR arp = jvp->GetArray();
for (int i = 0; i < arp->size(); i++)
n += arp->GetValue(i)->GetFloat();
} else {
PUSH_WARNING("First argument target is not an array");
} // endif jvp
} else {
*error = 1;
n = -1.0;
} // end of CheckMemory
if (g->N) {
// Keep result of constant function
double *np = (double*)PlugSubAlloc(g, NULL, sizeof(double));
*np = n;
g->Activityp = (PACTIVITY)np;
} // endif const_item
return n;
} // end of jsonsum_real
void jsonsum_real_deinit(UDF_INIT* initid)
{
JsonFreeMem((PGLOBAL)initid->ptr);
} // end of jsonsum_real_deinit
/*********************************************************************************/
/* Returns the average of big integer values from a Json array. */
/*********************************************************************************/
my_bool jsonavg_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
return jsonsum_real_init(initid, args, message);
} // end of jsonavg_real_init
double jsonavg_real(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
double n = 0.0;
PGLOBAL g = (PGLOBAL)initid->ptr;
if (g->N) {
if (!g->Activityp) {
*is_null = 1;
return 0.0;
} else
return *(double*)g->Activityp;
} else if (initid->const_item)
g->N = 1;
if (!CheckMemory(g, initid, args, 1, false, false, true)) {
PJVAL jvp = MakeValue(g, args, 0);
if (jvp && jvp->GetValType() == TYPE_JAR) {
PJAR arp = jvp->GetArray();
if (arp->size()) {
for (int i = 0; i < arp->size(); i++)
n += arp->GetValue(i)->GetFloat();
n /= arp->size();
} // endif size
} else {
PUSH_WARNING("First argument target is not an array");
} // endif jvp
} else {
*error = 1;
n = -1.0;
} // end of CheckMemory
if (g->N) {
// Keep result of constant function
double *np = (double*)PlugSubAlloc(g, NULL, sizeof(double));
*np = n;
g->Activityp = (PACTIVITY)np;
} // endif const_item
return n;
} // end of jsonavg_real
void jsonavg_real_deinit(UDF_INIT* initid)
{
JsonFreeMem((PGLOBAL)initid->ptr);
} // end of jsonavg_real_deinit
/*********************************************************************************/
/* Make a Json Object containing all the parameters. */
/*********************************************************************************/
......@@ -2990,6 +3198,7 @@ char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result,
} catch (int n) {
if (trace)
htrc("Exception %d: %s\n", n, g->Message);
PUSH_WARNING(g->Message);
str = NULL;
} catch (const char *msg) {
......@@ -3330,6 +3539,7 @@ char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
} catch (int n) {
if (trace)
htrc("Exception %d: %s\n", n, g->Message);
PUSH_WARNING(g->Message);
*error = 1;
path = NULL;
......@@ -3454,6 +3664,7 @@ char *json_locate_all(UDF_INIT *initid, UDF_ARGS *args, char *result,
} catch (int n) {
if (trace)
htrc("Exception %d: %s\n", n, g->Message);
PUSH_WARNING(g->Message);
*error = 1;
path = NULL;
......@@ -3728,6 +3939,7 @@ char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
} catch (int n) {
if (trace)
htrc("Exception %d: %s\n", n, g->Message);
PUSH_WARNING(g->Message);
str = NULL;
} catch (const char *msg) {
......
......@@ -53,6 +53,18 @@ extern "C" {
DllExport char *json_array_delete(UDF_EXEC_ARGS);
DllExport void json_array_delete_deinit(UDF_INIT*);
DllExport my_bool jsonsum_int_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport long long jsonsum_int(UDF_INIT*, UDF_ARGS*, char*, char*);
DllExport void jsonsum_int_deinit(UDF_INIT*);
DllExport my_bool jsonsum_real_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport double jsonsum_real(UDF_INIT*, UDF_ARGS*, char*, char*);
DllExport void jsonsum_real_deinit(UDF_INIT*);
DllExport my_bool jsonavg_real_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport double jsonavg_real(UDF_INIT*, UDF_ARGS*, char*, char*);
DllExport void jsonavg_real_deinit(UDF_INIT*);
DllExport my_bool json_make_object_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_make_object(UDF_EXEC_ARGS);
DllExport void json_make_object_deinit(UDF_INIT*);
......
......@@ -19,11 +19,265 @@
#include "xtable.h"
#include "tabext.h"
#if defined(MONGO_SUPPORT)
#include "tabmgo.h"
#include "tabcmg.h"
#endif // MONGO_SUPPORT
#if defined(JDBC_SUPPORT)
#include "tabjmg.h"
#endif // JDBC_SUPPORT
#include "resource.h"
/***********************************************************************/
/* This should be an option. */
/***********************************************************************/
#define MAXCOL 200 /* Default max column nb in result */
#define TYPE_UNKNOWN 12 /* Must be greater than other types */
bool IsNum(PSZ s);
/***********************************************************************/
/* MGOColumns: construct the result blocks containing the description */
/* of all the columns of a document contained inside MongoDB. */
/***********************************************************************/
PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt, bool info)
{
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,
FLD_LENGTH, FLD_SCALE, FLD_NULL, FLD_FORMAT};
unsigned int length[] = {0, 6, 8, 10, 10, 6, 6, 0};
int ncol = sizeof(buftyp) / sizeof(int);
int i, n = 0;
//PCSZ drv;
PBCOL bcp;
MGODISC *cmgd;
PQRYRES qrp;
PCOLRES crp;
if (info) {
length[0] = 128;
length[7] = 256;
goto skipit;
} // endif info
/*********************************************************************/
/* Open MongoDB. */
/*********************************************************************/
# if !defined(JDBC_SUPPORT)
cmgd = new(g) CMGDISC(g, (int*)length);
#elif !defined(MONGO_SUPPORT)
cmgd = new(g) JMGDISC(g, (int*)length);
#else
drv = GetStringTableOption(g, topt, "Driver", "C");
if (toupper(*drv) == 'C')
cmgd = new(g) CMGDISC(g, (int*)length);
else
cmgd = new(g) JMGDISC(g, (int*)length);
#endif
if ((n = cmgd->GetColumns(g, db, uri, topt)) < 0)
goto err;
skipit:
if (trace)
htrc("MGOColumns: n=%d len=%d\n", n, length[0]);
/*********************************************************************/
/* Allocate the structures used to refer to the result set. */
/*********************************************************************/
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
buftyp, fldtyp, length, false, false);
crp = qrp->Colresp->Next->Next->Next->Next->Next->Next;
crp->Name = "Nullable";
crp->Next->Name = "Bpath";
if (info || !qrp)
return qrp;
qrp->Nblin = n;
/*********************************************************************/
/* Now get the results into blocks. */
/*********************************************************************/
for (i = 0, bcp = cmgd->fbcp; bcp; i++, bcp = bcp->Next) {
if (bcp->Type == TYPE_UNKNOWN) // Void column
bcp->Type = TYPE_STRING;
crp = qrp->Colresp; // Column Name
crp->Kdata->SetValue(bcp->Name, i);
crp = crp->Next; // Data Type
crp->Kdata->SetValue(bcp->Type, i);
crp = crp->Next; // Type Name
crp->Kdata->SetValue(GetTypeName(bcp->Type), i);
crp = crp->Next; // Precision
crp->Kdata->SetValue(bcp->Len, i);
crp = crp->Next; // Length
crp->Kdata->SetValue(bcp->Len, i);
crp = crp->Next; // Scale (precision)
crp->Kdata->SetValue(bcp->Scale, i);
crp = crp->Next; // Nullable
crp->Kdata->SetValue(bcp->Cbn ? 1 : 0, i);
crp = crp->Next; // Field format
if (crp->Kdata)
crp->Kdata->SetValue(bcp->Fmt, i);
} // endfor i
/*********************************************************************/
/* Return the result pointer. */
/*********************************************************************/
return qrp;
err:
if (cmgd->tmgp)
cmgd->tmgp->CloseDB(g);
return NULL;
} // end of MGOColumns
/***********************************************************************/
/* Class used to get the columns of a mongo collection. */
/***********************************************************************/
MGODISC::MGODISC(PGLOBAL g, int *lg) {
length = lg;
fbcp = NULL;
pbcp = NULL;
tmgp = NULL;
drv = NULL;
i = ncol = lvl = 0;
all = false;
} // end of MGODISC constructor
/***********************************************************************/
/* Class used to get the columns of a mongo collection. */
/***********************************************************************/
int MGODISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt)
{
PCSZ level = GetStringTableOption(g, topt, "Level", NULL);
PMGODEF tdp;
if (level) {
lvl = atoi(level);
lvl = (lvl > 16) ? 16 : lvl;
} else
lvl = 0;
all = GetBooleanTableOption(g, topt, "Fullarray", false);
/*********************************************************************/
/* Open the MongoDB collection. */
/*********************************************************************/
tdp = new(g) MGODEF;
tdp->Uri = uri;
tdp->Driver = drv;
tdp->Tabname = GetStringTableOption(g, topt, "Name", NULL);
tdp->Tabname = GetStringTableOption(g, topt, "Tabname", tdp->Tabname);
tdp->Tabschema = GetStringTableOption(g, topt, "Dbname", db);
tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0;
tdp->Colist = GetStringTableOption(g, topt, "Colist", "all");
tdp->Filter = GetStringTableOption(g, topt, "Filter", NULL);
tdp->Pipe = GetBooleanTableOption(g, topt, "Pipeline", false);
tdp->Version = GetIntegerTableOption(g, topt, "Version", 3);
tdp->Wrapname = (PSZ)GetStringTableOption(g, topt, "Wrapper",
(tdp->Version == 2) ? "Mongo2Interface" : "Mongo3Interface");
if (trace)
htrc("Uri %s coll=%s db=%s colist=%s filter=%s lvl=%d\n",
tdp->Uri, tdp->Tabname, tdp->Tabschema, tdp->Colist, tdp->Filter, lvl);
tmgp = tdp->GetTable(g, MODE_READ);
tmgp->SetMode(MODE_READ);
if (tmgp->OpenDB(g))
return -1;
bcol.Next = NULL;
bcol.Name = bcol.Fmt = NULL;
bcol.Type = TYPE_UNKNOWN;
bcol.Len = bcol.Scale = 0;
bcol.Found = true;
bcol.Cbn = false;
if (Init(g))
return -1;
/*********************************************************************/
/* Analyse the BSON tree and define columns. */
/*********************************************************************/
for (i = 1; ; i++) {
switch (tmgp->ReadDB(g)) {
case RC_EF:
return ncol;
case RC_FX:
return -1;
default:
GetDoc();
} // endswitch ReadDB
if (Find(g))
return -1;
// Missing columns can be null
for (bcp = fbcp; bcp; bcp = bcp->Next) {
bcp->Cbn |= !bcp->Found;
bcp->Found = false;
} // endfor bcp
} // endfor i
return ncol;
} // end of GetColumns
/***********************************************************************/
/* Add a new column in the column list. */
/***********************************************************************/
void MGODISC::AddColumn(PGLOBAL g, PCSZ colname, PCSZ fmt, int k)
{
// Check whether this column was already found
for (bcp = fbcp; bcp; bcp = bcp->Next)
if (!strcmp(colname, bcp->Name))
break;
if (bcp) {
if (bcp->Type != bcol.Type)
bcp->Type = TYPE_STRING;
if (k && *fmt && (!bcp->Fmt || strlen(bcp->Fmt) < strlen(fmt))) {
bcp->Fmt = PlugDup(g, fmt);
length[7] = MY_MAX(length[7], strlen(fmt));
} // endif *fmt
bcp->Len = MY_MAX(bcp->Len, bcol.Len);
bcp->Scale = MY_MAX(bcp->Scale, bcol.Scale);
bcp->Cbn |= bcol.Cbn;
bcp->Found = true;
} else {
// New column
bcp = (PBCOL)PlugSubAlloc(g, NULL, sizeof(BCOL));
*bcp = bcol;
bcp->Cbn |= (i > 1);
bcp->Name = PlugDup(g, colname);
length[0] = MY_MAX(length[0], strlen(colname));
if (k) {
bcp->Fmt = PlugDup(g, fmt);
length[7] = MY_MAX(length[7], strlen(fmt));
} else
bcp->Fmt = NULL;
if (pbcp) {
bcp->Next = pbcp->Next;
pbcp->Next = bcp;
} else
fbcp = bcp;
ncol++;
} // endif jcp
pbcp = bcp;
} // end of AddColumn
/* -------------------------- Class MGODEF --------------------------- */
......@@ -91,7 +345,7 @@ PTDB MGODEF::GetTable(PGLOBAL g, MODE m)
#if defined(MONGO_SUPPORT)
if (Driver && toupper(*Driver) == 'C')
return new(g) TDBMGO(this);
return new(g) TDBCMG(this);
#endif // MONGO_SUPPORT
#if defined(JDBC_SUPPORT)
return new(g) TDBJMG(this);
......@@ -100,4 +354,3 @@ PTDB MGODEF::GetTable(PGLOBAL g, MODE m)
return NULL;
#endif // !JDBC_SUPPORT
} // end of GetTable
......@@ -25,15 +25,43 @@ typedef struct _bncol {
bool Found;
} BCOL, *PBCOL;
/***********************************************************************/
/* Class used to get the columns of a mongo collection. */
/***********************************************************************/
class MGODISC : public BLOCK {
public:
// Constructor
MGODISC(PGLOBAL g, int *lg);
// Methods
virtual bool Init(PGLOBAL g) { return false; }
virtual void GetDoc(void) {}
virtual bool Find(PGLOBAL g) = 0;
// Functions
int GetColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt);
void AddColumn(PGLOBAL g, PCSZ colname, PCSZ fmt, int k);
// Members
BCOL bcol;
PBCOL bcp, fbcp, pbcp;
PMGODEF tdp;
PTDB tmgp;
PCSZ drv;
int *length;
int i, ncol, lvl;
bool all;
}; // end of MGODISC
/***********************************************************************/
/* MongoDB table. */
/***********************************************************************/
class DllExport MGODEF : public EXTDEF { /* Table description */
friend class TDBMGO;
friend class TDBCMG;
friend class TDBJMG;
friend class TDBGOL;
friend class TDBJGL;
friend class MGOFAM;
friend class CMGFAM;
friend class MGODISC;
friend PQRYRES MGOColumns(PGLOBAL, PCSZ, PCSZ, PTOS, bool);
public:
......
......@@ -2,11 +2,11 @@
/* */
/* PROGRAM NAME: PLUGUTIL */
/* ------------- */
/* Version 2.9 */
/* Version 3.0 */
/* */
/* COPYRIGHT: */
/* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 1993-2015 */
/* (C) Copyright to the author Olivier BERTRAND 1993-2017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
......@@ -76,6 +76,7 @@
#include "osutil.h"
#include "global.h"
#include "plgdbsem.h"
#if defined(NEWMSG)
#include "rcmsg.h"
#endif // NEWMSG
......@@ -132,7 +133,7 @@ void htrc(char const *fmt, ...)
/* Return value is the pointer to the Global structure. */
/***********************************************************************/
PGLOBAL PlugInit(LPCSTR Language, uint worksize)
{
{
PGLOBAL g;
if (trace > 1)
......@@ -146,10 +147,6 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
return NULL;
} // end try/catch
//if (!(g = (PGLOBAL)malloc(sizeof(GLOBAL)))) {
// fprintf(stderr, MSG(GLOBAL_ERROR), (int)sizeof(GLOBAL));
// return NULL;
// } else {
g->Sarea = NULL;
g->Createas = 0;
g->Alchecked = 0;
......@@ -171,28 +168,33 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
} else
g->Sarea_Size = worksize;
//} /* endif g */
g->jump_level = -1; /* New setting to allow recursive call of Plug */
return(g);
} /* end of PlugInit */
} /* end of PlugInit */
/***********************************************************************/
/* PlugExit: Terminate Plug operations. */
/***********************************************************************/
int PlugExit(PGLOBAL g)
{
int rc = 0;
{
if (g) {
PDBUSER dup = PlgGetUser(g);
if (!g)
return rc;
if (dup)
free(dup);
if (g->Sarea) {
if (trace)
htrc("Freeing Sarea size=%d\n", g->Sarea_Size);
if (g->Sarea)
free(g->Sarea);
} // endif Sarea
delete g;
return rc;
} /* end of PlugExit */
} // endif g
return 0;
} // end of PlugExit
/***********************************************************************/
/* Remove the file type from a file name. */
......@@ -456,7 +458,7 @@ short GetLineLength(PGLOBAL g)
/* Program for memory allocation of work and language areas. */
/***********************************************************************/
void *PlugAllocMem(PGLOBAL g, uint size)
{
{
void *areap; /* Pointer to allocated area */
/*********************************************************************/
......@@ -465,7 +467,7 @@ void *PlugAllocMem(PGLOBAL g, uint size)
if (!(areap = malloc(size)))
sprintf(g->Message, MSG(MALLOC_ERROR), "malloc");
if (trace > 1) {
if (trace) {
if (areap)
htrc("Memory of %u allocated at %p\n", size, areap);
else
......@@ -474,7 +476,7 @@ void *PlugAllocMem(PGLOBAL g, uint size)
} // endif trace
return (areap);
} /* end of PlugAllocMem */
} // end of PlugAllocMem
/***********************************************************************/
/* Program for SubSet initialization of memory pools. */
......
/************** tabmgo C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: tabmgo Version 1.0 */
/************** tabcmg C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: tabcmg Version 1.1 */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* This program are the MongoDB class DB execution routines. */
/* This program are the C MongoDB class DB execution routines. */
/***********************************************************************/
/***********************************************************************/
......@@ -22,208 +22,34 @@
#include "maputil.h"
#include "filamtxt.h"
#include "tabext.h"
#include "tabmgo.h"
#include "tabcmg.h"
#include "tabmul.h"
#include "checklvl.h"
#include "resource.h"
#include "mycat.h" // for FNC_COL
#include "filter.h"
/***********************************************************************/
/* This should be an option. */
/***********************************************************************/
#define MAXCOL 200 /* Default max column nb in result */
#define TYPE_UNKNOWN 12 /* Must be greater than other types */
bool IsNum(PSZ s);
/* -------------------------- Class CMGDISC -------------------------- */
/***********************************************************************/
/* MGOColumns: construct the result blocks containing the description */
/* of all the columns of a document contained inside MongoDB. */
/* Get document. */
/***********************************************************************/
PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt, bool info)
void CMGDISC::GetDoc(void)
{
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,
FLD_LENGTH, FLD_SCALE, FLD_NULL, FLD_FORMAT};
unsigned int length[] = {0, 6, 8, 10, 10, 6, 6, 0};
int ncol = sizeof(buftyp) / sizeof(int);
int i, n = 0;
PBCOL bcp;
MGODISC *mgd;
PQRYRES qrp;
PCOLRES crp;
if (info) {
length[0] = 128;
length[7] = 256;
goto skipit;
} // endif info
/*********************************************************************/
/* Open MongoDB. */
/*********************************************************************/
mgd = new(g) MGODISC(g, (int*)length);
if ((n = mgd->GetColumns(g, db, uri, topt)) < 0)
goto err;
skipit:
if (trace)
htrc("MGOColumns: n=%d len=%d\n", n, length[0]);
/*********************************************************************/
/* Allocate the structures used to refer to the result set. */
/*********************************************************************/
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
buftyp, fldtyp, length, false, false);
crp = qrp->Colresp->Next->Next->Next->Next->Next->Next;
crp->Name = "Nullable";
crp->Next->Name = "Bpath";
if (info || !qrp)
return qrp;
qrp->Nblin = n;
/*********************************************************************/
/* Now get the results into blocks. */
/*********************************************************************/
for (i = 0, bcp = mgd->fbcp; bcp; i++, bcp = bcp->Next) {
if (bcp->Type == TYPE_UNKNOWN) // Void column
bcp->Type = TYPE_STRING;
crp = qrp->Colresp; // Column Name
crp->Kdata->SetValue(bcp->Name, i);
crp = crp->Next; // Data Type
crp->Kdata->SetValue(bcp->Type, i);
crp = crp->Next; // Type Name
crp->Kdata->SetValue(GetTypeName(bcp->Type), i);
crp = crp->Next; // Precision
crp->Kdata->SetValue(bcp->Len, i);
crp = crp->Next; // Length
crp->Kdata->SetValue(bcp->Len, i);
crp = crp->Next; // Scale (precision)
crp->Kdata->SetValue(bcp->Scale, i);
crp = crp->Next; // Nullable
crp->Kdata->SetValue(bcp->Cbn ? 1 : 0, i);
crp = crp->Next; // Field format
if (crp->Kdata)
crp->Kdata->SetValue(bcp->Fmt, i);
} // endfor i
/*********************************************************************/
/* Return the result pointer. */
/*********************************************************************/
return qrp;
err:
if (mgd->tmgp)
mgd->tmgp->CloseDB(g);
return NULL;
} // end of MGOColumns
doc = ((TDBCMG*)tmgp)->Cmgp->Document;
} // end of GetDoc
/***********************************************************************/
/* Class used to get the columns of a mongo collection. */
/***********************************************************************/
// Constructor
MGODISC::MGODISC(PGLOBAL g, int *lg) {
length = lg;
fbcp = NULL;
pbcp = NULL;
tmgp = NULL;
n = k = lvl = 0;
all = false;
} // end of MGODISC constructor
/***********************************************************************/
/* Class used to get the columns of a mongo collection. */
/* Analyse passed document. */
/***********************************************************************/
int MGODISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt)
//bool CMGDISC::Find(PGLOBAL g, int i, int k, bool b)
bool CMGDISC::Find(PGLOBAL g)
{
PCSZ level;
bson_iter_t iter;
const bson_t *doc;
PMGODEF tdp;
TDBMGO *tmgp = NULL;
level = GetStringTableOption(g, topt, "Level", NULL);
if (level) {
lvl = atoi(level);
lvl = (lvl > 16) ? 16 : lvl;
} else
lvl = 0;
all = GetBooleanTableOption(g, topt, "Fullarray", false);
/*********************************************************************/
/* Open the MongoDB collection. */
/*********************************************************************/
tdp = new(g) MGODEF;
tdp->Uri = uri;
tdp->Tabname = GetStringTableOption(g, topt, "Name", NULL);
tdp->Tabname = GetStringTableOption(g, topt, "Tabname", tdp->Tabname);
tdp->Tabschema = GetStringTableOption(g, topt, "Dbname", db);
tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0;
tdp->Colist = GetStringTableOption(g, topt, "Colist", "all");
tdp->Filter = GetStringTableOption(g, topt, "Filter", NULL);
tdp->Pipe = GetBooleanTableOption(g, topt, "Pipeline", false);
if (trace)
htrc("Uri %s coll=%s db=%s colist=%s filter=%s lvl=%d\n",
tdp->Uri, tdp->Tabname, tdp->Tabschema, tdp->Colist, tdp->Filter, lvl);
tmgp = new(g) TDBMGO(tdp);
tmgp->SetMode(MODE_READ);
if (tmgp->OpenDB(g))
return -1;
bcol.Next = NULL;
bcol.Name = bcol.Fmt = NULL;
bcol.Type = TYPE_UNKNOWN;
bcol.Len = bcol.Scale = 0;
bcol.Found = true;
bcol.Cbn = false;
return FindInDoc(g, &iter, doc, NULL, NULL, 0, false);
} // end of Find
/*********************************************************************/
/* Analyse the BSON tree and define columns. */
/*********************************************************************/
for (int i = 1; ; i++) {
switch (tmgp->ReadDB(g)) {
case RC_EF:
return n;
case RC_FX:
return -1;
default:
doc = tmgp->Cmgp->Document;
} // endswitch ReadDB
if (FindInDoc(g, &iter, doc, NULL, NULL, i, k, false))
return -1;
// Missing columns can be null
for (bcp = fbcp; bcp; bcp = bcp->Next) {
bcp->Cbn |= !bcp->Found;
bcp->Found = false;
} // endfor bcp
} // endfor i
return n;
} // end of GetColumns
/*********************************************************************/
/***********************************************************************/
/* Analyse passed document. */
/*********************************************************************/
bool MGODISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
char *pcn, char *pfmt, int i, int k, bool b)
/***********************************************************************/
bool CMGDISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
char *pcn, char *pfmt, int k, bool b)
{
if (!doc || bson_iter_init(iter, doc)) {
const char *key;
......@@ -286,7 +112,7 @@ bool MGODISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
bson_iter_t child;
if (bson_iter_recurse(iter, &child))
if (FindInDoc(g, &child, NULL, colname, fmt, i, k + 1, false))
if (FindInDoc(g, &child, NULL, colname, fmt, k + 1, false))
return true;
newcol = false;
......@@ -307,7 +133,7 @@ bool MGODISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
bson_iter_array(iter, &len, &data);
arr = bson_new_from_data(data, len);
if (FindInDoc(g, &itar, arr, colname, fmt, i, k + 1, !all))
if (FindInDoc(g, &itar, arr, colname, fmt, k + 1, !all))
return true;
newcol = false;
......@@ -315,50 +141,8 @@ bool MGODISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
} // endif's
if (newcol) {
// Check whether this column was already found
for (bcp = fbcp; bcp; bcp = bcp->Next)
if (!strcmp(colname, bcp->Name))
break;
if (bcp) {
if (bcp->Type != bcol.Type)
bcp->Type = TYPE_STRING;
if (k && *fmt && (!bcp->Fmt || strlen(bcp->Fmt) < strlen(fmt))) {
bcp->Fmt = PlugDup(g, fmt);
length[7] = MY_MAX(length[7], strlen(fmt));
} // endif *fmt
bcp->Len = MY_MAX(bcp->Len, bcol.Len);
bcp->Scale = MY_MAX(bcp->Scale, bcol.Scale);
bcp->Cbn |= bcol.Cbn;
bcp->Found = true;
} else {
// New column
bcp = (PBCOL)PlugSubAlloc(g, NULL, sizeof(BCOL));
*bcp = bcol;
bcp->Cbn |= (i > 1);
bcp->Name = PlugDup(g, colname);
length[0] = MY_MAX(length[0], strlen(colname));
if (k) {
bcp->Fmt = PlugDup(g, fmt);
length[7] = MY_MAX(length[7], strlen(fmt));
} else
bcp->Fmt = NULL;
if (pbcp) {
bcp->Next = pbcp->Next;
pbcp->Next = bcp;
} else
fbcp = bcp;
n++;
} // endif jcp
pbcp = bcp;
} // endif newcol
if (newcol)
AddColumn(g, colname, fmt, k);
if (b)
break; // Test only first element of arrays
......@@ -370,12 +154,12 @@ bool MGODISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
return false;
} // end of FindInDoc
/* --------------------------- Class TDBMGO -------------------------- */
/* --------------------------- Class TDBCMG -------------------------- */
/***********************************************************************/
/* Implementation of the TDBMGO class. */
/* Implementation of the TDBCMG class. */
/***********************************************************************/
TDBMGO::TDBMGO(MGODEF *tdp) : TDBEXT(tdp)
TDBCMG::TDBCMG(MGODEF *tdp) : TDBEXT(tdp)
{
Cmgp = NULL;
Cnd = NULL;
......@@ -402,9 +186,9 @@ TDBMGO::TDBMGO(MGODEF *tdp) : TDBEXT(tdp)
Fpos = -1;
N = 0;
Done = false;
} // end of TDBMGO standard constructor
} // end of TDBCMG standard constructor
TDBMGO::TDBMGO(TDBMGO *tdbp) : TDBEXT(tdbp)
TDBCMG::TDBCMG(TDBCMG *tdbp) : TDBEXT(tdbp)
{
Cmgp = tdbp->Cmgp;
Cnd = tdbp->Cnd;
......@@ -413,16 +197,16 @@ TDBMGO::TDBMGO(TDBMGO *tdbp) : TDBEXT(tdbp)
Fpos = tdbp->Fpos;
N = tdbp->N;
Done = tdbp->Done;
} // end of TDBMGO copy constructor
} // end of TDBCMG copy constructor
// Used for update
PTDB TDBMGO::Clone(PTABS t)
PTDB TDBCMG::Clone(PTABS t)
{
PTDB tp;
PMGOCOL cp1, cp2;
PGLOBAL g = t->G;
tp = new(g) TDBMGO(this);
tp = new(g) TDBCMG(this);
for (cp1 = (PMGOCOL)Columns; cp1; cp1 = (PMGOCOL)cp1->GetNext())
if (!cp1->IsSpecial()) {
......@@ -436,7 +220,7 @@ PTDB TDBMGO::Clone(PTABS t)
/***********************************************************************/
/* Allocate JSN column description block. */
/***********************************************************************/
PCOL TDBMGO::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
PCOL TDBCMG::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
{
PMGOCOL colp = new(g) MGOCOL(g, cdp, this, cprec, n);
......@@ -446,7 +230,7 @@ PCOL TDBMGO::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
/***********************************************************************/
/* InsertSpecialColumn: Put a special column ahead of the column list.*/
/***********************************************************************/
PCOL TDBMGO::InsertSpecialColumn(PCOL colp)
PCOL TDBCMG::InsertSpecialColumn(PCOL colp)
{
if (!colp->IsSpecial())
return NULL;
......@@ -459,7 +243,7 @@ PCOL TDBMGO::InsertSpecialColumn(PCOL colp)
/***********************************************************************/
/* Init: initialize MongoDB processing. */
/***********************************************************************/
bool TDBMGO::Init(PGLOBAL g)
bool TDBCMG::Init(PGLOBAL g)
{
if (Done)
return false;
......@@ -482,7 +266,7 @@ bool TDBMGO::Init(PGLOBAL g)
/***********************************************************************/
/* MONGO Cardinality: returns table size in number of rows. */
/***********************************************************************/
int TDBMGO::Cardinality(PGLOBAL g)
int TDBCMG::Cardinality(PGLOBAL g)
{
if (!g)
return 1;
......@@ -495,7 +279,7 @@ int TDBMGO::Cardinality(PGLOBAL g)
/***********************************************************************/
/* MONGO GetMaxSize: returns collection size estimate. */
/***********************************************************************/
int TDBMGO::GetMaxSize(PGLOBAL g)
int TDBCMG::GetMaxSize(PGLOBAL g)
{
if (MaxSize < 0)
MaxSize = Cardinality(g);
......@@ -506,7 +290,7 @@ int TDBMGO::GetMaxSize(PGLOBAL g)
/***********************************************************************/
/* OpenDB: Data Base open routine for MONGO access method. */
/***********************************************************************/
bool TDBMGO::OpenDB(PGLOBAL g)
bool TDBCMG::OpenDB(PGLOBAL g)
{
if (Use == USE_OPEN) {
/*******************************************************************/
......@@ -540,7 +324,7 @@ bool TDBMGO::OpenDB(PGLOBAL g)
/***********************************************************************/
/* Data Base indexed read routine for ODBC access method. */
/***********************************************************************/
bool TDBMGO::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
bool TDBCMG::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
{
strcpy(g->Message, "MONGO tables are not indexable");
return true;
......@@ -549,7 +333,7 @@ bool TDBMGO::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
/***********************************************************************/
/* ReadDB: Get next document from a collection. */
/***********************************************************************/
int TDBMGO::ReadDB(PGLOBAL g)
int TDBCMG::ReadDB(PGLOBAL g)
{
return Cmgp->ReadNext(g);
} // end of ReadDB
......@@ -557,7 +341,7 @@ int TDBMGO::ReadDB(PGLOBAL g)
/***********************************************************************/
/* WriteDB: Data Base write routine for MGO access method. */
/***********************************************************************/
int TDBMGO::WriteDB(PGLOBAL g)
int TDBCMG::WriteDB(PGLOBAL g)
{
return Cmgp->Write(g);
} // end of WriteDB
......@@ -565,7 +349,7 @@ int TDBMGO::WriteDB(PGLOBAL g)
/***********************************************************************/
/* Data Base delete line routine for MGO access method. */
/***********************************************************************/
int TDBMGO::DeleteDB(PGLOBAL g, int irc)
int TDBCMG::DeleteDB(PGLOBAL g, int irc)
{
return (irc == RC_OK) ? WriteDB(g) : RC_OK;
} // end of DeleteDB
......@@ -573,7 +357,7 @@ int TDBMGO::DeleteDB(PGLOBAL g, int irc)
/***********************************************************************/
/* Table close routine for MONGO tables. */
/***********************************************************************/
void TDBMGO::CloseDB(PGLOBAL g)
void TDBCMG::CloseDB(PGLOBAL g)
{
Cmgp->Close();
Done = false;
......@@ -587,7 +371,7 @@ void TDBMGO::CloseDB(PGLOBAL g)
MGOCOL::MGOCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
: EXTCOL(cdp, tdbp, cprec, i, "MGO")
{
Tmgp = (PTDBMGO)(tdbp->GetOrig() ? tdbp->GetOrig() : tdbp);
Tmgp = (PTDBCMG)(tdbp->GetOrig() ? tdbp->GetOrig() : tdbp);
Jpath = cdp->GetFmt() ? cdp->GetFmt() : cdp->GetName();
} // end of MGOCOL constructor
......
/**************** tabmgo H Declares Source Code File (.H) **************/
/* Name: tabmgo.h Version 1.1 */
/**************** tabcmg H Declares Source Code File (.H) **************/
/* Name: tabcmg.h Version 1.2 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* */
......@@ -11,45 +11,46 @@
/***********************************************************************/
/* Class used to get the columns of a mongo collection. */
/***********************************************************************/
class MGODISC : public BLOCK {
class CMGDISC : public MGODISC {
public:
// Constructor
MGODISC(PGLOBAL g, int *lg);
CMGDISC(PGLOBAL g, int *lg) : MGODISC(g, lg) { drv = "C"; }
// Functions
int GetColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt);
// Methods
virtual void GetDoc(void);
//virtual bool Find(PGLOBAL g, int i, int k, bool b);
virtual bool Find(PGLOBAL g);
// BSON Function
//bool FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
// char *pcn, char *pfmt, int i, int k, bool b);
bool FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
char *pcn, char *pfmt, int i, int k, bool b);
char *pcn, char *pfmt, int k, bool b);
// Members
BCOL bcol;
PBCOL bcp, fbcp, pbcp;
PMGODEF tdp;
TDBMGO *tmgp;
int *length;
int n, k, lvl;
bool all;
}; // end of MGODISC
bson_iter_t iter;
const bson_t *doc;
}; // end of CMGDISC
/* -------------------------- TDBMGO class --------------------------- */
/* -------------------------- TDBCMG class --------------------------- */
/***********************************************************************/
/* This is the MongoDB Table Type class declaration. */
/* The table is a collection, each record being a document. */
/***********************************************************************/
class DllExport TDBMGO : public TDBEXT {
class DllExport TDBCMG : public TDBEXT {
friend class MGOCOL;
friend class MGODEF;
friend class MGODISC;
friend class CMGDISC;
friend PQRYRES MGOColumns(PGLOBAL, PCSZ, PCSZ, PTOS, bool);
public:
// Constructor
TDBMGO(MGODEF *tdp);
TDBMGO(TDBMGO *tdbp);
TDBCMG(MGODEF *tdp);
TDBCMG(TDBCMG *tdbp);
// Implementation
virtual AMT GetAmType(void) {return TYPE_AM_MGO;}
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMGO(this);}
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBCMG(this);}
// Methods
virtual PTDB Clone(PTABS t);
......@@ -78,7 +79,7 @@ class DllExport TDBMGO : public TDBEXT {
int N; // The current Rownum
int B; // Array index base
bool Done; // Init done
}; // end of class TDBMGO
}; // end of class TDBCMG
/* --------------------------- MGOCOL class -------------------------- */
......@@ -86,7 +87,7 @@ class DllExport TDBMGO : public TDBEXT {
/* Class MGOCOL: MongoDB access method column descriptor. */
/***********************************************************************/
class DllExport MGOCOL : public EXTCOL {
friend class TDBMGO;
friend class TDBCMG;
friend class FILTER;
public:
// Constructors
......@@ -106,7 +107,7 @@ class DllExport MGOCOL : public EXTCOL {
MGOCOL(void) {}
// Members
TDBMGO *Tmgp; // To the MGO table block
TDBCMG *Tmgp; // To the MGO table block
char *Jpath; // The json path
}; // end of class MGOCOL
......
......@@ -27,13 +27,108 @@
#include "mycat.h" // for FNC_COL
#include "filter.h"
PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt, bool info);
/* -------------------------- Class JMGDISC -------------------------- */
/***********************************************************************/
/* Initialyze. */
/***********************************************************************/
bool JMGDISC::Init(PGLOBAL g)
{
if (!(Jcp = ((TDBJMG*)tmgp)->Jcp)) {
strcpy(g->Message, "Init: Jcp is NULL");
return true;
} else if (Jcp->gmID(g, columnid, "ColumnDesc",
"(Ljava/lang/Object;I[II)Ljava/lang/Object;"))
return true;
else if (Jcp->gmID(g, bvnameid, "ColDescName", "()Ljava/lang/String;"))
return true;
return false;
} // end of Init
/***********************************************************************/
/* Analyse passed document. */
/***********************************************************************/
bool JMGDISC::Find(PGLOBAL g)
{
return ColDesc(g, nullptr, NULL, NULL, Jcp->m_Ncol, 0);
} // end of Find
/***********************************************************************/
/* This should be an option. */
/* Analyse passed document. */
/***********************************************************************/
#define MAXCOL 200 /* Default max column nb in result */
#define TYPE_UNKNOWN 12 /* Must be greater than other types */
bool JMGDISC::ColDesc(PGLOBAL g, jobject obj, char *pcn, char *pfmt,
int ncol, int k)
{
const char *key;
char colname[65];
char fmt[129];
bool rc = true;
jint *n = nullptr;
jstring jkey;
jobject jres;
// Build the java int array
jintArray val = Jcp->env->NewIntArray(5);
if (val == nullptr) {
strcpy(g->Message, "Cannot allocate jint array");
return true;
} else if (!ncol)
n = Jcp->env->GetIntArrayElements(val, 0);
for (int i = 0; i < ncol; i++) {
jres = Jcp->env->CallObjectMethod(Jcp->job, columnid, obj, i, val, lvl - k);
n = Jcp->env->GetIntArrayElements(val, 0);
if (Jcp->Check(n[0])) {
sprintf(g->Message, "ColDesc: %s", Jcp->Msg);
goto err;
} else if (!n[0])
continue;
jkey = (jstring)Jcp->env->CallObjectMethod(Jcp->job, bvnameid);
key = Jcp->env->GetStringUTFChars(jkey, (jboolean)false);
if (pcn) {
strncpy(colname, pcn, 64);
colname[64] = 0;
strncat(strncat(colname, "_", 65), key, 65);
} else
strcpy(colname, key);
if (pfmt) {
strncpy(fmt, pfmt, 128);
fmt[128] = 0;
strncat(strncat(fmt, ".", 129), key, 129);
} else
strcpy(fmt, key);
if (!jres) {
bcol.Type = n[0];
bcol.Len = n[1];
bcol.Scale = n[2];
bcol.Cbn = n[3];
AddColumn(g, colname, fmt, k);
} else {
if (n[0] == 2 && !all)
n[4] = MY_MIN(n[4], 1);
if (ColDesc(g, jres, colname, fmt, n[4], k + 1))
goto err;
} // endif jres
PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info);
} // endfor i
rc = false;
err:
Jcp->env->ReleaseIntArrayElements(val, n, 0);
return rc;
} // end of ColDesc
/* --------------------------- Class TDBJMG -------------------------- */
......@@ -82,16 +177,6 @@ TDBJMG::TDBJMG(PMGODEF tdp) : TDBEXT(tdp)
TDBJMG::TDBJMG(TDBJMG *tdbp) : TDBEXT(tdbp)
{
Uri = tdbp->Uri;
//Pool = tdbp->Pool;
//Client = tdbp->Client;
//Database = NULL;
//Collection = tdbp->Collection;
//Cursor = tdbp->Cursor;
//Query = tdbp->Query;
//Opts = tdbp->Opts;
//Fpc = tdbp->Fpc;
//Cnd = tdbp->Cnd;
//Uristr = tdbp->Uristr;
Db_name = tdbp->Db_name;;
Coll_name = tdbp->Coll_name;
Options = tdbp->Options;
......@@ -126,11 +211,7 @@ PTDB TDBJMG::Clone(PTABS t)
/***********************************************************************/
PCOL TDBJMG::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
{
PJMGCOL colp = new(g) JMGCOL(g, cdp, this, cprec, n);
//colp->Mbuf = (char*)PlugSubAlloc(g, NULL, colp->Long + 1);
return colp;
//return (colp->ParseJpath(g)) ? NULL : colp;
return new(g) JMGCOL(g, cdp, this, cprec, n);
} // end of MakeCol
/***********************************************************************/
......@@ -497,12 +578,12 @@ TDBJGL::TDBJGL(PMGODEF tdp) : TDBCAT(tdp)
Db = tdp->GetTabschema();
} // end of TDBJCL constructor
/***********************************************************************/
/* GetResult: Get the list the JSON file columns. */
/***********************************************************************/
/***********************************************************************/
/* GetResult: Get the list the MongoDB collection columns. */
/***********************************************************************/
PQRYRES TDBJGL::GetResult(PGLOBAL g)
{
return JSONColumns(g, Db, Uri, Topt, false);
return MGOColumns(g, Db, Uri, Topt, false);
} // end of GetResult
/* -------------------------- End of mongo --------------------------- */
/* -------------------------- End of mongo --------------------------- */
......@@ -9,6 +9,31 @@
#include "jmgoconn.h"
#include "jdbccat.h"
/***********************************************************************/
/* Class used to get the columns of a mongo collection. */
/***********************************************************************/
class JMGDISC : public MGODISC {
public:
// Constructor
JMGDISC(PGLOBAL g, int *lg) : MGODISC(g, lg)
{ drv = "Java"; Jcp = NULL; columnid = nullptr; }
// Methods
virtual bool Init(PGLOBAL g);
virtual void GetDoc(void) {}
virtual bool Find(PGLOBAL g);
protected:
// Function
bool ColDesc(PGLOBAL g, jobject obj, char *pcn, char *pfmt,
int ncol, int k);
// Members
JMgoConn *Jcp; // Points to a Mongo connection class
jmethodID columnid; // The ColumnDesc method ID
jmethodID bvnameid; // The ColDescName method ID
}; // end of JMGDISC
/* -------------------------- TDBJMG class --------------------------- */
/***********************************************************************/
......@@ -18,7 +43,7 @@
class DllExport TDBJMG : public TDBEXT {
friend class JMGCOL;
friend class MGODEF;
friend class MGODISC;
friend class JMGDISC;
friend class JAVAConn;
friend PQRYRES MGOColumns(PGLOBAL, PCSZ, PCSZ, PTOS, bool);
public:
......
/************* tabjson C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: tabjson Version 1.4 */
/* PROGRAM NAME: tabjson Version 1.5 */
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */
/* This program are the JSON class DB execution routines. */
/***********************************************************************/
......@@ -35,7 +35,7 @@
#include "jmgfam.h"
#endif // JDBC_SUPPORT
#if defined(MONGO_SUPPORT)
#include "mongofam.h"
#include "cmgfam.h"
#endif // MONGO_SUPPORT
#include "tabmul.h"
#include "checklvl.h"
......@@ -47,7 +47,6 @@
/***********************************************************************/
#define MAXCOL 200 /* Default max column nb in result */
#define TYPE_UNKNOWN 12 /* Must be greater than other types */
#define USE_G 1 /* Use recoverable memory if 1 */
/***********************************************************************/
/* External functions. */
......@@ -55,6 +54,7 @@
USETEMP UseTemp(void);
bool IsNum(PSZ s);
char *NextChr(PSZ s, char sep);
char *GetJsonNull(void);
typedef struct _jncol {
struct _jncol *Next;
......@@ -199,12 +199,12 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
} else if (tdp->Uri) {
#if defined(MONGO_SUPPORT) || defined(JDBC_SUPPORT)
#if !defined(JDBC_SUPPORT)
tjnp = new(g) TDBJSN(tdp, new(g) MGOFAM(tdp));
tjnp = new(g) TDBJSN(tdp, new(g) CMGFAM(tdp));
#elif !defined(MONGO_SUPPORT)
tjnp = new(g) TDBJSN(tdp, new(g) JMGFAM(tdp));
#else
if (tdp->Driver && toupper(*tdp->Driver) == 'C')
tjnp = new(g) TDBJSN(tdp, new(g) MGOFAM(tdp));
tjnp = new(g) TDBJSN(tdp, new(g) CMGFAM(tdp));
else
tjnp = new(g) TDBJSN(tdp, new(g) JMGFAM(tdp));
#endif
......@@ -217,7 +217,6 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
tjnp->SetMode(MODE_READ);
#if USE_G
// Allocate the parse work memory
PGLOBAL G = (PGLOBAL)PlugSubAlloc(g, NULL, sizeof(GLOBAL));
memset(G, 0, sizeof(GLOBAL));
......@@ -226,9 +225,6 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
PlugSubSet(G, G->Sarea, G->Sarea_Size);
G->jump_level = 0;
tjnp->SetG(G);
#else
tjnp->SetG(g);
#endif
if (tjnp->OpenDB(g))
return NULL;
......@@ -560,12 +556,12 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
if (Uri) {
#if defined(MONGO_SUPPORT) || defined(JDBC_SUPPORT)
#if !defined(JDBC_SUPPORT)
txfp = new(g) MGOFAM(this);
txfp = new(g) CMGFAM(this);
#elif !defined(MONGO_SUPPORT)
txfp = new(g) JMGFAM(this);
#else
if (Driver && toupper(*Driver) == 'C')
txfp = new(g) MGOFAM(this);
txfp = new(g) CMGFAM(this);
else
txfp = new(g) JMGFAM(this);
#endif
......@@ -602,7 +598,6 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
// Txfp must be set for TDBDOS
tdbp = new(g) TDBJSN(this, txfp);
#if USE_G
if (Lrecl) {
// Allocate the parse work memory
PGLOBAL G = (PGLOBAL)PlugSubAlloc(g, NULL, sizeof(GLOBAL));
......@@ -616,9 +611,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
strcpy(g->Message, "LRECL is not defined");
return NULL;
} // endif Lrecl
#else
((TDBJSN*)tdbp)->G = g;
#endif
} else {
if (Zipped) {
#if defined(ZIP_SUPPORT)
......@@ -903,10 +896,8 @@ int TDBJSN::ReadDB(PGLOBAL g)
// Deferred reading failed
return rc;
#if USE_G
// Recover the memory used for parsing
PlugSubSet(G, G->Sarea, G->Sarea_Size);
#endif
if ((Row = ParseJson(G, To_Line, strlen(To_Line), &Pretty, &Comma))) {
Row = FindRow(g);
......@@ -915,9 +906,7 @@ int TDBJSN::ReadDB(PGLOBAL g)
M = 1;
rc = RC_OK;
} else if (Pretty != 1 || strcmp(To_Line, "]")) {
#if USE_G
strcpy(g->Message, G->Message);
#endif
rc = RC_FX;
} else
rc = RC_EF;
......@@ -1030,9 +1019,7 @@ int TDBJSN::WriteDB(PGLOBAL g)
{
int rc = TDBDOS::WriteDB(g);
#if USE_G
PlugSubSet(G, G->Sarea, G->Sarea_Size);
#endif
Row->Clear();
return rc;
} // end of WriteDB
......@@ -1586,8 +1573,11 @@ PVAL JSONCOL::CalculateArray(PGLOBAL g, PJAR arp, int n)
for (i = 0; i < ars; i++) {
jvrp = arp->GetValue(i);
do {
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;
......
......@@ -40,7 +40,7 @@ class DllExport JSONDEF : public DOSDEF { /* Table description */
friend class JMGFAM;
#endif // JDBC_SUPPORT
#if defined(MONGO_SUPPORT)
friend class MGOFAM;
friend class CMGFAM;
#endif // MONGO_SUPPORT
friend PQRYRES JSONColumns(PGLOBAL, PCSZ, PCSZ, PTOS, bool);
public:
......@@ -93,7 +93,7 @@ class DllExport TDBJSN : public TDBDOS {
friend class JMGFAM;
#endif // JDBC_SUPPORT
#if defined(MONGO_SUPPORT)
friend class MGOFAM;
friend class CMGFAM;
#endif // MONGO_SUPPORT
public:
// Constructor
......@@ -163,7 +163,7 @@ class DllExport JSONCOL : public DOSCOL {
friend class JMGFAM;
#endif // JDBC_SUPPORT
#if defined(MONGO_SUPPORT)
friend class MGOFAM;
friend class CMGFAM;
#endif // MONGO_SUPPORT
public:
// Constructors
......
......@@ -111,7 +111,10 @@ bool user_connect::user_init()
int rc= PlugExit(g);
g= NULL;
if (dup)
free(dup);
return true;
} // endif g->
......@@ -152,10 +155,14 @@ bool user_connect::CheckCleanup(bool force)
PlugCleanup(g, true);
if (g->Sarea_Size != worksize) {
if (g->Sarea)
if (g->Sarea) {
if (trace)
htrc("CheckCleanup: Free Sarea %d\n", g->Sarea_Size);
free(g->Sarea);
} // endif Size
// Check whether the work area size was changed
// Check whether the work area could be allocated
if (!(g->Sarea = PlugAllocMem(g, worksize))) {
g->Sarea = PlugAllocMem(g, g->Sarea_Size);
SetWorkSize(g->Sarea_Size); // Was too big
......
......@@ -119,6 +119,7 @@ ulonglong CharToNumber(const char *p, int n, ulonglong maxval,
if (minus) *minus = true;
} // endif Unsigned
// Fall through
case '+':
p++;
break;
......@@ -571,7 +572,7 @@ void VALUE::Printf(PGLOBAL g, FILE *f, uint n)
if (Null)
fprintf(f, "%s<null>\n", m);
else
fprintf(f, strcat(strcat(GetCharString(buf), "\n"), m));
fprintf(f, "%s%s\n", m, GetCharString(buf));
} /* end of Printf */
......@@ -2566,7 +2567,7 @@ bool DTVAL::SetValue_pval(PVAL valp, bool chktype)
} else if (valp->GetType() == TYPE_BIGINT &&
!(valp->GetBigintValue() % 1000)) {
// Assuming that this timestamp is in milliseconds
Tval = valp->GetBigintValue() / 1000;
Tval = (int)(valp->GetBigintValue() / 1000);
} else
Tval = valp->GetIntValue();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment