Commit 5c42d86a authored by Olivier Bertrand's avatar Olivier Bertrand

- New distribution enabling or disabling the MONGO table type

  modified:   storage/connect/CMakeLists.txt
  modified:   storage/connect/ha_connect.cc
  modified:   storage/connect/mycat.cc

- Extend SRCDEF parameter processing to MYSQL
  modified:   storage/connect/tabext.cpp
  modified:   storage/connect/tabext.h
  modified:   storage/connect/tabmysql.cpp

- Typo
  modified:   storage/connect/mysql-test/connect/std_data/Mongo2.jar
  modified:   storage/connect/mysql-test/connect/std_data/Mongo3.jar
parent 5b998bf9
...@@ -245,9 +245,9 @@ int main() { ...@@ -245,9 +245,9 @@ int main() {
ENDIF(CONNECT_WITH_ODBC) ENDIF(CONNECT_WITH_ODBC)
# #
# JDBC without MongoDB Java Driver # JDBC with MongoDB Java Driver included but disabled
# #
# OPTION(CONNECT_WITH_MONGO "Compile CONNECT storage engine with MONGO support" ON) OPTION(CONNECT_WITH_MONGO "Compile CONNECT storage engine with MONGO support" ON)
OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON) OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON)
IF(CONNECT_WITH_JDBC) IF(CONNECT_WITH_JDBC)
...@@ -264,13 +264,6 @@ IF(CONNECT_WITH_JDBC) ...@@ -264,13 +264,6 @@ IF(CONNECT_WITH_JDBC)
JdbcInterface.java ApacheInterface.java MariadbInterface.java JdbcInterface.java ApacheInterface.java MariadbInterface.java
MysqlInterface.java OracleInterface.java PostgresqlInterface.java MysqlInterface.java OracleInterface.java PostgresqlInterface.java
JavaWrappers.jar) JavaWrappers.jar)
# TODO: Find how to compile and install the java wrapper classes
# Find required libraries and include directories
SET (JAVA_SOURCES JdbcInterface.java)
add_jar(JdbcInterface ${JAVA_SOURCES})
install_jar(JdbcInterface DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/JavaWrappers.jar
DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
add_definitions(-DJDBC_SUPPORT) add_definitions(-DJDBC_SUPPORT)
IF(CONNECT_WITH_MONGO) IF(CONNECT_WITH_MONGO)
SET(CONNECT_SOURCES ${CONNECT_SOURCES} SET(CONNECT_SOURCES ${CONNECT_SOURCES}
...@@ -348,4 +341,33 @@ MYSQL_ADD_PLUGIN(connect ${CONNECT_SOURCES} ...@@ -348,4 +341,33 @@ MYSQL_ADD_PLUGIN(connect ${CONNECT_SOURCES}
LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY} LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY}
${ODBC_LIBRARY} ${JDBC_LIBRARY} ${IPHLPAPI_LIBRARY}) ${ODBC_LIBRARY} ${JDBC_LIBRARY} ${IPHLPAPI_LIBRARY})
IF(NOT TARGET connect)
RETURN()
ENDIF()
# Install some extra files that belong to connect engine
IF(WIN32)
# install ha_connect.lib
GET_TARGET_PROPERTY(CONNECT_LOCATION connect LOCATION)
STRING(REPLACE "dll" "lib" CONNECT_LIB ${CONNECT_LOCATION})
IF(CMAKE_CONFIGURATION_TYPES)
STRING(REPLACE "${CMAKE_CFG_INTDIR}" "\${CMAKE_INSTALL_CONFIG_NAME}"
CONNECT_LIB ${CONNECT_LIB})
ENDIF()
INSTALL(FILES ${CONNECT_LIB}
DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
ENDIF(WIN32)
IF(CONNECT_WITH_JDBC AND JAVA_FOUND AND JNI_FOUND)
# TODO: Find how to compile and install the java wrapper classes
# Find required libraries and include directories
SET (JAVA_SOURCES JdbcInterface.java)
add_jar(JdbcInterface ${JAVA_SOURCES})
INSTALL(FILES
${CMAKE_CURRENT_SOURCE_DIR}/JavaWrappers.jar
${CMAKE_CURRENT_BINARY_DIR}/JdbcInterface.jar
DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
ENDIF()
...@@ -171,9 +171,9 @@ ...@@ -171,9 +171,9 @@
#define JSONMAX 10 // JSON Default max grp size #define JSONMAX 10 // JSON Default max grp size
extern "C" { extern "C" {
char version[]= "Version 1.06.0001 April 17, 2017"; char version[]= "Version 1.06.0003 August 28, 2017";
#if defined(__WIN__) #if defined(__WIN__)
char compver[]= "Version 1.06.0001 " __DATE__ " " __TIME__; char compver[]= "Version 1.06.0003 " __DATE__ " " __TIME__;
char slash= '\\'; char slash= '\\';
#else // !__WIN__ #else // !__WIN__
char slash= '/'; char slash= '/';
...@@ -182,7 +182,10 @@ extern "C" { ...@@ -182,7 +182,10 @@ extern "C" {
#if defined(NEW_MAR) #if defined(NEW_MAR)
#define stored_in_db stored_in_db() #define stored_in_db stored_in_db()
#endif // NEW_MAR) #define MONGO_ENABLED 1
#else // !NEW_MAR
#define MONGO_ENABLED 0
#endif // !NEW_MAR)
#if defined(XMAP) #if defined(XMAP)
my_bool xmap= false; my_bool xmap= false;
...@@ -359,6 +362,13 @@ static MYSQL_THDVAR_STR(java_wrapper, ...@@ -359,6 +362,13 @@ static MYSQL_THDVAR_STR(java_wrapper,
NULL, NULL, "wrappers/JdbcInterface"); NULL, NULL, "wrappers/JdbcInterface");
#endif // JDBC_SUPPORT #endif // JDBC_SUPPORT
#if defined(MONGO_SUPPORT)
// Enabling MONGO table type
static MYSQL_THDVAR_BOOL(enable_mongo, PLUGIN_VAR_RQCMDARG,
"Enabling the MongoDB access",
NULL, NULL, MONGO_ENABLED);
#endif // MONGO_SUPPORT
#if defined(XMSG) || defined(NEWMSG) #if defined(XMSG) || defined(NEWMSG)
const char *language_names[]= const char *language_names[]=
{ {
...@@ -419,6 +429,10 @@ char *GetJavaWrapper(void) ...@@ -419,6 +429,10 @@ char *GetJavaWrapper(void)
{return connect_hton ? THDVAR(current_thd, java_wrapper) : (char*)"wrappers/JdbcInterface";} {return connect_hton ? THDVAR(current_thd, java_wrapper) : (char*)"wrappers/JdbcInterface";}
#endif // JDBC_SUPPORT #endif // JDBC_SUPPORT
#if defined(MONGO_SUPPORT)
bool MongoEnabled(void) { return THDVAR(current_thd, enable_mongo); }
#endif // MONGO_SUPPORT
extern "C" const char *msglang(void) extern "C" const char *msglang(void)
{ {
#if defined(FRENCH) #if defined(FRENCH)
...@@ -7176,7 +7190,10 @@ static struct st_mysql_sys_var* connect_system_variables[]= { ...@@ -7176,7 +7190,10 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
MYSQL_SYSVAR(class_path), MYSQL_SYSVAR(class_path),
MYSQL_SYSVAR(java_wrapper), MYSQL_SYSVAR(java_wrapper),
#endif // JDBC_SUPPORT #endif // JDBC_SUPPORT
NULL #if defined(MONGO_SUPPORT)
MYSQL_SYSVAR(enable_mongo),
#endif // MONGO_SUPPORT
NULL
}; };
maria_declare_plugin(connect) maria_declare_plugin(connect)
...@@ -7185,14 +7202,14 @@ maria_declare_plugin(connect) ...@@ -7185,14 +7202,14 @@ maria_declare_plugin(connect)
&connect_storage_engine, &connect_storage_engine,
"CONNECT", "CONNECT",
"Olivier Bertrand", "Olivier Bertrand",
"Management of External Data (SQL/MED), including many file formats", "Management of External Data (SQL/NOSQL/MED), including many file formats",
PLUGIN_LICENSE_GPL, PLUGIN_LICENSE_GPL,
connect_init_func, /* Plugin Init */ connect_init_func, /* Plugin Init */
connect_done_func, /* Plugin Deinit */ connect_done_func, /* Plugin Deinit */
0x0106, /* version number (1.05) */ 0x0106, /* version number (1.05) */
NULL, /* status variables */ NULL, /* status variables */
connect_system_variables, /* system variables */ connect_system_variables, /* system variables */
"1.06.0001", /* string version */ "1.06.0003", /* string version */
MariaDB_PLUGIN_MATURITY_BETA /* maturity */ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
} }
maria_declare_plugin_end; maria_declare_plugin_end;
/************ MONGO FAM C++ Program Source Code File (.CPP) ************/
/* PROGRAM NAME: mongofam.cpp */
/* ------------- */
/* Version 1.3 */
/* */
/* COPYRIGHT: */
/* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 20017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
/* This program are the MongoDB access method classes. */
/* */
/***********************************************************************/
/***********************************************************************/
/* Include relevant sections of the System header files. */
/***********************************************************************/
#include "my_global.h"
/***********************************************************************/
/* Include application header files: */
/* global.h is header containing all global declarations. */
/* plgdbsem.h is header containing the DB application declarations. */
/* filamtxt.h is header containing the file AM classes declarations. */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "reldef.h"
#include "filamtxt.h"
#include "tabdos.h"
#include "tabjson.h"
#include "mongofam.h"
#if defined(UNIX) || defined(UNIV_LINUX)
#include "osutil.h"
#endif
/* --------------------------- Class MGOFAM -------------------------- */
/***********************************************************************/
/* Constructors. */
/***********************************************************************/
MGOFAM::MGOFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
{
Cmgp = NULL;
Pcg.Tdbp = NULL;
if (tdp) {
Pcg.Uristr = tdp->Uri;
Pcg.Db_name = tdp->Schema;
Pcg.Coll_name = tdp->Collname;
Pcg.Options = tdp->Options;
Pcg.Filter = tdp->Filter;
Pcg.Pipe = tdp->Pipe && tdp->Options != NULL;
} else {
Pcg.Uristr = NULL;
Pcg.Db_name = NULL;
Pcg.Coll_name = NULL;
Pcg.Options = NULL;
Pcg.Filter = NULL;
Pcg.Pipe = false;
} // endif tdp
To_Fbt = NULL;
Mode = MODE_ANY;
Done = false;
Lrecl = tdp->Lrecl + tdp->Ending;
} // end of MGOFAM standard constructor
MGOFAM::MGOFAM(PMGOFAM tdfp) : DOSFAM(tdfp)
{
Pcg = tdfp->Pcg;
To_Fbt = tdfp->To_Fbt;
Mode = tdfp->Mode;
Done = tdfp->Done;
} // end of MGOFAM copy constructor
/***********************************************************************/
/* Reset: reset position values at the beginning of file. */
/***********************************************************************/
void MGOFAM::Reset(void)
{
TXTFAM::Reset();
Fpos = Tpos = Spos = 0;
} // end of Reset
/***********************************************************************/
/* MGO GetFileLength: returns file size in number of bytes. */
/***********************************************************************/
int MGOFAM::GetFileLength(PGLOBAL g)
{
return 0;
} // end of GetFileLength
/***********************************************************************/
/* Cardinality: returns the number of documents in the collection. */
/* 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)
{
if (!g)
return 1;
return (!Init(g)) ? Cmgp->CollSize(g) : 0;
} // end of Cardinality
/***********************************************************************/
/* Note: This function is not really implemented yet. */
/***********************************************************************/
int MGOFAM::MaxBlkSize(PGLOBAL, int s)
{
return s;
} // end of MaxBlkSize
/***********************************************************************/
/* Init: initialize MongoDB processing. */
/***********************************************************************/
bool MGOFAM::Init(PGLOBAL g)
{
if (Done)
return false;
/*********************************************************************/
/* Open an C connection for this table. */
/*********************************************************************/
if (!Cmgp) {
Pcg.Tdbp = Tdbp;
Cmgp = new(g) CMgoConn(g, &Pcg);
} else if (Cmgp->IsConnected())
Cmgp->Close();
if (Cmgp->Connect(g))
return true;
Done = true;
return false;
} // end of Init
/***********************************************************************/
/* OpenTableFile: Open a MongoDB table. */
/***********************************************************************/
bool MGOFAM::OpenTableFile(PGLOBAL g)
{
Mode = Tdbp->GetMode();
if (Pcg.Pipe && Mode != MODE_READ) {
strcpy(g->Message, "Pipeline tables are read only");
return true;
} // endif Pipe
if (Init(g))
return true;
if (Mode == MODE_DELETE && !Tdbp->GetNext())
// Delete all documents
return Cmgp->DocDelete(g);
else if (Mode == MODE_INSERT)
Cmgp->MakeColumnGroups(g);
return false;
} // end of OpenTableFile
/***********************************************************************/
/* GetRowID: return the RowID of last read record. */
/***********************************************************************/
int MGOFAM::GetRowID(void)
{
return Rows;
} // end of GetRowID
/***********************************************************************/
/* GetPos: return the position of last read record. */
/***********************************************************************/
int MGOFAM::GetPos(void)
{
return Fpos;
} // end of GetPos
/***********************************************************************/
/* GetNextPos: return the position of next record. */
/***********************************************************************/
int MGOFAM::GetNextPos(void)
{
return Fpos; // TODO
} // end of GetNextPos
/***********************************************************************/
/* SetPos: Replace the table at the specified position. */
/***********************************************************************/
bool MGOFAM::SetPos(PGLOBAL g, int pos)
{
Fpos = pos;
Placed = true;
return false;
} // end of SetPos
/***********************************************************************/
/* Record file position in case of UPDATE or DELETE. */
/***********************************************************************/
bool MGOFAM::RecordPos(PGLOBAL g)
{
strcpy(g->Message, "MGOFAM::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)
{
strcpy(g->Message, "MGOFAM::InitDelete NIY");
return RC_FX;
} // end of InitDelete
/***********************************************************************/
/* Skip one record in file. */
/***********************************************************************/
int MGOFAM::SkipRecord(PGLOBAL g, bool header)
{
return RC_OK; // Dummy
} // end of SkipRecord
/***********************************************************************/
/* ReadBuffer: Get next document from a collection. */
/***********************************************************************/
int MGOFAM::ReadBuffer(PGLOBAL g)
{
int rc = Cmgp->ReadNext(g);
if (rc != RC_OK)
return rc;
strncpy(Tdbp->GetLine(), Cmgp->GetDocument(g), Lrecl);
return RC_OK;
} // end of ReadBuffer
/***********************************************************************/
/* WriteBuffer: File write routine for MGO access method. */
/***********************************************************************/
int MGOFAM::WriteBuffer(PGLOBAL g)
{
return Cmgp->Write(g);
} // end of WriteBuffer
/***********************************************************************/
/* Data Base delete line routine for MGO and BLK access methods. */
/***********************************************************************/
int MGOFAM::DeleteRecords(PGLOBAL g, int irc)
{
return (irc == RC_OK) ? WriteBuffer(g) : RC_OK;
} // end of DeleteRecords
/***********************************************************************/
/* Table file close routine for MGO access method. */
/***********************************************************************/
void MGOFAM::CloseTableFile(PGLOBAL g, bool)
{
Cmgp->Close();
Done = false;
} // end of CloseTableFile
/***********************************************************************/
/* Rewind routine for MGO access method. */
/***********************************************************************/
void MGOFAM::Rewind(void)
{
Cmgp->Rewind();
} // end of Rewind
/************** MongoFam H Declares Source Code File (.H) **************/
/* Name: mongofam.h Version 1.4 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* */
/* This file contains the MongoDB access method classes declares. */
/***********************************************************************/
#include "cmgoconn.h"
typedef class TXTFAM *PTXF;
typedef class MGOFAM *PMGOFAM;
typedef class MGODEF *PMGODEF;
typedef class TDBMGO *PTDBMGO;
/***********************************************************************/
/* This is the MongoDB Access Method class declaration. */
/***********************************************************************/
class DllExport MGOFAM : public DOSFAM {
friend void mongo_init(bool);
public:
// Constructor
MGOFAM(PJDEF tdp);
MGOFAM(PMGOFAM txfp);
// Implementation
virtual AMT GetAmType(void) { return TYPE_AM_MGO; }
virtual bool GetUseTemp(void) { return false; }
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); }
void SetLrecl(int lrecl) { Lrecl = lrecl; }
// Methods
virtual void Reset(void);
virtual int GetFileLength(PGLOBAL g);
virtual int Cardinality(PGLOBAL g);
virtual int MaxBlkSize(PGLOBAL g, int s);
virtual bool AllocateBuffer(PGLOBAL g) { return false; }
virtual int GetRowID(void);
virtual bool RecordPos(PGLOBAL g);
virtual bool SetPos(PGLOBAL g, int recpos);
virtual int SkipRecord(PGLOBAL g, bool header);
virtual bool OpenTableFile(PGLOBAL g);
virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g, bool abort);
virtual void Rewind(void);
protected:
virtual bool OpenTempFile(PGLOBAL g) { return false; }
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b) { return false; }
virtual int RenameTempFile(PGLOBAL g) { return RC_OK; }
virtual int InitDelete(PGLOBAL g, int fpos, int spos);
bool Init(PGLOBAL g);
// Members
CMgoConn *Cmgp; // Points to a C Mongo connection class
CMGOPARM Pcg; // Parms passed to Cmgp
PFBLOCK To_Fbt; // Pointer to temp file block
MODE Mode;
bool Done; // Init done
}; // end of class MGOFAM
...@@ -111,6 +111,9 @@ ...@@ -111,6 +111,9 @@
extern "C" HINSTANCE s_hModule; // Saved module handle extern "C" HINSTANCE s_hModule; // Saved module handle
#endif // !__WIN__ #endif // !__WIN__
#if defined(MONGO_SUPPORT)
bool MongoEnabled(void);
#endif // MONGO_SUPPORT
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info); PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
/***********************************************************************/ /***********************************************************************/
...@@ -558,7 +561,13 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am) ...@@ -558,7 +561,13 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
case TAB_VIR: tdp= new(g) VIRDEF; break; case TAB_VIR: tdp= new(g) VIRDEF; break;
case TAB_JSON: tdp= new(g) JSONDEF; break; case TAB_JSON: tdp= new(g) JSONDEF; break;
#if defined(MONGO_SUPPORT) #if defined(MONGO_SUPPORT)
case TAB_MONGO: tdp = new(g) MGODEF; break; case TAB_MONGO:
if (MongoEnabled())
tdp = new(g) MGODEF;
else
strcpy(g->Message, "MONGO type not enabled");
break;
#endif // MONGO_SUPPORT #endif // MONGO_SUPPORT
#if defined(ZIP_SUPPORT) #if defined(ZIP_SUPPORT)
case TAB_ZIP: tdp= new(g) ZIPDEF; break; case TAB_ZIP: tdp= new(g) ZIPDEF; break;
......
...@@ -279,10 +279,57 @@ int TDBEXT::Decode(PCSZ txt, char *buf, size_t n) ...@@ -279,10 +279,57 @@ int TDBEXT::Decode(PCSZ txt, char *buf, size_t n)
} // end of Decode } // end of Decode
/***********************************************************************/ /***********************************************************************/
/* MakeSQL: make the SQL statement use with remote connection. */ /* MakeSrcdef: make the SQL statement from SRDEF option. */
/* TODO: when implementing remote filtering, column only used in */
/* local filter should be removed from column list. */
/***********************************************************************/ /***********************************************************************/
bool TDBEXT::MakeSrcdef(PGLOBAL g)
{
char *catp = strstr(Srcdef, "%s");
if (catp) {
char *fil1, *fil2;
PCSZ ph = ((EXTDEF*)To_Def)->Phpos;
if (!ph)
ph = (strstr(catp + 2, "%s")) ? "WH" : "W";
if (stricmp(ph, "H")) {
fil1 = (To_CondFil && *To_CondFil->Body)
? To_CondFil->Body : PlugDup(g, "1=1");
} // endif ph
if (stricmp(ph, "W")) {
fil2 = (To_CondFil && To_CondFil->Having && *To_CondFil->Having)
? To_CondFil->Having : PlugDup(g, "1=1");
} // endif ph
if (!stricmp(ph, "W")) {
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1));
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil1));
} else if (!stricmp(ph, "WH")) {
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2));
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil1, fil2));
} else if (!stricmp(ph, "H")) {
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil2));
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2));
} else if (!stricmp(ph, "HW")) {
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2));
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2, fil1));
} else {
strcpy(g->Message, "MakeSQL: Wrong place holders specification");
return true;
} // endif's ph
} else
Query = new(g)STRING(g, 0, Srcdef);
return false;
} // end of MakeSrcdef
/***********************************************************************/
/* MakeSQL: make the SQL statement use with remote connection. */
/* TODO: when implementing remote filtering, column only used in */
/* local filter should be removed from column list. */
/***********************************************************************/
bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt) bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
{ {
PCSZ schmp = NULL; PCSZ schmp = NULL;
...@@ -292,46 +339,8 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt) ...@@ -292,46 +339,8 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
PTABLE tablep = To_Table; PTABLE tablep = To_Table;
PCOL colp; PCOL colp;
if (Srcdef) { if (Srcdef)
if ((catp = strstr(Srcdef, "%s"))) { return MakeSrcdef(g);
char *fil1, *fil2;
PCSZ ph = ((EXTDEF*)To_Def)->Phpos;
if (!ph)
ph = (strstr(catp + 2, "%s")) ? "WH" : "W";
if (stricmp(ph, "H")) {
fil1 = (To_CondFil && *To_CondFil->Body)
? To_CondFil->Body : PlugDup(g, "1=1");
} // endif ph
if (stricmp(ph, "W")) {
fil2 = (To_CondFil && To_CondFil->Having && *To_CondFil->Having)
? To_CondFil->Having : PlugDup(g, "1=1");
} // endif ph
if (!stricmp(ph, "W")) {
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1));
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil1));
} else if (!stricmp(ph, "WH")) {
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2));
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil1, fil2));
} else if (!stricmp(ph, "H")) {
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil2));
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2));
} else if (!stricmp(ph, "HW")) {
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2));
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2, fil1));
} else {
strcpy(g->Message, "MakeSQL: Wrong place holders specification");
return true;
} // endif's ph
} else
Query = new(g)STRING(g, 0, Srcdef);
return false;
} // endif Srcdef
// Allocate the string used to contain the Query // Allocate the string used to contain the Query
Query = new(g)STRING(g, 1023, "SELECT "); Query = new(g)STRING(g, 1023, "SELECT ");
......
...@@ -126,6 +126,7 @@ class DllExport TDBEXT : public TDB { ...@@ -126,6 +126,7 @@ class DllExport TDBEXT : public TDB {
protected: protected:
// Internal functions // Internal functions
virtual bool MakeSrcdef(PGLOBAL g);
virtual bool MakeSQL(PGLOBAL g, bool cnt); virtual bool MakeSQL(PGLOBAL g, bool cnt);
//virtual bool MakeInsert(PGLOBAL g); //virtual bool MakeInsert(PGLOBAL g);
virtual bool MakeCommand(PGLOBAL g); virtual bool MakeCommand(PGLOBAL g);
......
/************** tabmgo C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: tabmgo Version 1.0 */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* This program are the MongoDB class DB execution routines. */
/***********************************************************************/
/***********************************************************************/
/* Include relevant sections of the MariaDB header file. */
/***********************************************************************/
#include <my_global.h>
/***********************************************************************/
/* Include application header files: */
/* global.h is header containing all global declarations. */
/* plgdbsem.h is header containing the DB application declarations. */
/* tdbdos.h is header containing the TDBDOS declarations. */
/* json.h is header containing the JSON classes declarations. */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "xtable.h"
#include "maputil.h"
#include "filamtxt.h"
#include "tabext.h"
#include "tabmgo.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);
/***********************************************************************/
/* MGOColumns: construct the result blocks containing the description */
/* of all the columns of a document contained inside MongoDB. */
/***********************************************************************/
PQRYRES MGOColumns(PGLOBAL g, char *db, 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;
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, 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
/***********************************************************************/
/* 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. */
/***********************************************************************/
int MGODISC::GetColumns(PGLOBAL g, char *db, PTOS topt)
{
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 = GetStringTableOption(g, topt, "Connect", "mongodb://localhost:27017");
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;
/*********************************************************************/
/* 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)
{
if (!doc || bson_iter_init(iter, doc)) {
const char *key;
char colname[65];
char fmt[129];
bool newcol;
while (bson_iter_next(iter)) {
key = bson_iter_key(iter);
newcol = true;
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);
bcol.Cbn = false;
if (BSON_ITER_HOLDS_UTF8(iter)) {
bcol.Type = TYPE_STRING;
bcol.Len = strlen(bson_iter_utf8(iter, NULL));
} else if (BSON_ITER_HOLDS_INT32(iter)) {
bcol.Type = TYPE_INT;
bcol.Len = 11; // bson_iter_int32(iter)
} else if (BSON_ITER_HOLDS_INT64(iter)) {
bcol.Type = TYPE_BIGINT;
bcol.Len = 22; // bson_iter_int64(iter)
} else if (BSON_ITER_HOLDS_DOUBLE(iter)) {
bcol.Type = TYPE_DOUBLE;
bcol.Len = 12;
bcol.Scale = 6; // bson_iter_double(iter)
} else if (BSON_ITER_HOLDS_DATE_TIME(iter)) {
bcol.Type = TYPE_DATE;
bcol.Len = 19; // bson_iter_date_time(iter)
} else if (BSON_ITER_HOLDS_BOOL(iter)) {
bcol.Type = TYPE_TINY;
bcol.Len = 1;
} else if (BSON_ITER_HOLDS_OID(iter)) {
bcol.Type = TYPE_STRING;
bcol.Len = 24; // bson_iter_oid(iter)
} else if (BSON_ITER_HOLDS_DECIMAL128(iter)) {
bcol.Type = TYPE_DECIM;
bcol.Len = 32; // bson_iter_decimal128(iter, &dec)
} else if (BSON_ITER_HOLDS_DOCUMENT(iter)) {
if (lvl < 0)
continue;
else if (lvl <= k) {
bcol.Type = TYPE_STRING;
bcol.Len = 512;
} else {
bson_iter_t child;
if (bson_iter_recurse(iter, &child))
if (FindInDoc(g, &child, NULL, colname, fmt, i, k + 1, false))
return true;
newcol = false;
} // endif lvl
} else if (BSON_ITER_HOLDS_ARRAY(iter)) {
if (lvl < 0)
continue;
else if (lvl <= k) {
bcol.Type = TYPE_STRING;
bcol.Len = 512;
} else {
bson_t *arr;
bson_iter_t itar;
const uint8_t *data = NULL;
uint32_t len = 0;
bson_iter_array(iter, &len, &data);
arr = bson_new_from_data(data, len);
if (FindInDoc(g, &itar, arr, colname, fmt, i, k + 1, !all))
return true;
newcol = false;
} // endif lvl
} // 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 (b)
break; // Test only first element of arrays
} // endwhile iter
} // endif doc
return false;
} // end of FindInDoc
/* --------------------------- Class TDBMGO -------------------------- */
/***********************************************************************/
/* Implementation of the TDBMGO class. */
/***********************************************************************/
TDBMGO::TDBMGO(MGODEF *tdp) : TDBEXT(tdp)
{
Cmgp = NULL;
Cnd = NULL;
Pcg.Tdbp = this;
if (tdp) {
Pcg.Uristr = tdp->Uri;
Pcg.Db_name = tdp->Tabschema;
Pcg.Coll_name = tdp->Tabname;
Pcg.Options = tdp->Colist;
Pcg.Filter = tdp->Filter;
Pcg.Pipe = tdp->Pipe && Options != NULL;
B = tdp->Base ? 1 : 0;
} else {
Pcg.Uristr = NULL;
Pcg.Db_name = NULL;
Pcg.Coll_name = NULL;
Pcg.Options = NULL;
Pcg.Filter = NULL;
Pcg.Pipe = false;
B = 0;
} // endif tdp
Fpos = -1;
N = 0;
Done = false;
} // end of TDBMGO standard constructor
TDBMGO::TDBMGO(TDBMGO *tdbp) : TDBEXT(tdbp)
{
Cmgp = tdbp->Cmgp;
Cnd = tdbp->Cnd;
Pcg = tdbp->Pcg;
B = tdbp->B;
Fpos = tdbp->Fpos;
N = tdbp->N;
Done = tdbp->Done;
} // end of TDBMGO copy constructor
// Used for update
PTDB TDBMGO::Clone(PTABS t)
{
PTDB tp;
PMGOCOL cp1, cp2;
PGLOBAL g = t->G;
tp = new(g) TDBMGO(this);
for (cp1 = (PMGOCOL)Columns; cp1; cp1 = (PMGOCOL)cp1->GetNext())
if (!cp1->IsSpecial()) {
cp2 = new(g) MGOCOL(cp1, tp); // Make a copy
NewPointer(t, cp1, cp2);
} // endif cp1
return tp;
} // end of Clone
/***********************************************************************/
/* Allocate JSN column description block. */
/***********************************************************************/
PCOL TDBMGO::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
{
PMGOCOL colp = new(g) MGOCOL(g, cdp, this, cprec, n);
return colp;
} // end of MakeCol
/***********************************************************************/
/* InsertSpecialColumn: Put a special column ahead of the column list.*/
/***********************************************************************/
PCOL TDBMGO::InsertSpecialColumn(PCOL colp)
{
if (!colp->IsSpecial())
return NULL;
colp->SetNext(Columns);
Columns = colp;
return colp;
} // end of InsertSpecialColumn
/***********************************************************************/
/* Init: initialize MongoDB processing. */
/***********************************************************************/
bool TDBMGO::Init(PGLOBAL g)
{
if (Done)
return false;
/*********************************************************************/
/* Open an C connection for this table. */
/*********************************************************************/
if (!Cmgp)
Cmgp = new(g) CMgoConn(g, &Pcg);
else if (Cmgp->IsConnected())
Cmgp->Close();
if (Cmgp->Connect(g))
return true;
Done = true;
return false;
} // end of Init
/***********************************************************************/
/* MONGO Cardinality: returns table size in number of rows. */
/***********************************************************************/
int TDBMGO::Cardinality(PGLOBAL g)
{
if (!g)
return 1;
else if (Cardinal < 0)
Cardinal = (!Init(g)) ? Cmgp->CollSize(g) : 0;
return Cardinal;
} // end of Cardinality
/***********************************************************************/
/* MONGO GetMaxSize: returns collection size estimate. */
/***********************************************************************/
int TDBMGO::GetMaxSize(PGLOBAL g)
{
if (MaxSize < 0)
MaxSize = Cardinality(g);
return MaxSize;
} // end of GetMaxSize
/***********************************************************************/
/* OpenDB: Data Base open routine for MONGO access method. */
/***********************************************************************/
bool TDBMGO::OpenDB(PGLOBAL g)
{
if (Use == USE_OPEN) {
/*******************************************************************/
/* Table already open replace it at its beginning. */
/*******************************************************************/
Cmgp->Rewind();
Fpos = -1;
return false;
} // endif Use
/*********************************************************************/
/* First opening. */
/*********************************************************************/
if (Pcg.Pipe && Mode != MODE_READ) {
strcpy(g->Message, "Pipeline tables are read only");
return true;
} // endif Pipe
if (Init(g))
return true;
if (Mode == MODE_DELETE && !Next)
// Delete all documents
return Cmgp->DocDelete(g);
else if (Mode == MODE_INSERT)
Cmgp->MakeColumnGroups(g);
return false;
} // end of OpenDB
/***********************************************************************/
/* Data Base indexed read routine for ODBC access method. */
/***********************************************************************/
bool TDBMGO::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
{
strcpy(g->Message, "MONGO tables are not indexable");
return true;
} // end of ReadKey
/***********************************************************************/
/* ReadDB: Get next document from a collection. */
/***********************************************************************/
int TDBMGO::ReadDB(PGLOBAL g)
{
return Cmgp->ReadNext(g);
} // end of ReadDB
/***********************************************************************/
/* WriteDB: Data Base write routine for MGO access method. */
/***********************************************************************/
int TDBMGO::WriteDB(PGLOBAL g)
{
return Cmgp->Write(g);
} // end of WriteDB
/***********************************************************************/
/* Data Base delete line routine for MGO access method. */
/***********************************************************************/
int TDBMGO::DeleteDB(PGLOBAL g, int irc)
{
return (irc == RC_OK) ? WriteDB(g) : RC_OK;
} // end of DeleteDB
/***********************************************************************/
/* Table close routine for MONGO tables. */
/***********************************************************************/
void TDBMGO::CloseDB(PGLOBAL g)
{
Cmgp->Close();
Done = false;
} // end of CloseDB
/* ----------------------------- MGOCOL ------------------------------ */
/***********************************************************************/
/* MGOCOL public constructor. */
/***********************************************************************/
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);
Jpath = cdp->GetFmt() ? cdp->GetFmt() : cdp->GetName();
} // end of MGOCOL constructor
/***********************************************************************/
/* MGOCOL constructor used for copying columns. */
/* tdbp is the pointer to the new table descriptor. */
/***********************************************************************/
MGOCOL::MGOCOL(MGOCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp)
{
Tmgp = col1->Tmgp;
Jpath = col1->Jpath;
} // end of MGOCOL copy constructor
/***********************************************************************/
/* Get path when proj is false or projection path when proj is true. */
/***********************************************************************/
PSZ MGOCOL::GetJpath(PGLOBAL g, bool proj)
{
if (Jpath) {
if (proj) {
char *p1, *p2, *projpath = PlugDup(g, Jpath);
int i = 0;
for (p1 = p2 = projpath; *p1; p1++)
if (*p1 == '.') {
if (!i)
*p2++ = *p1;
i = 1;
} else if (i) {
if (!isdigit(*p1)) {
*p2++ = *p1;
i = 0;
} // endif p1
} else
*p2++ = *p1;
*p2 = 0;
return projpath;
} else
return Jpath;
} else
return Name;
} // end of GetJpath
/***********************************************************************/
/* ReadColumn: */
/***********************************************************************/
void MGOCOL::ReadColumn(PGLOBAL g)
{
Tmgp->Cmgp->GetColumnValue(g, this);
} // end of ReadColumn
/***********************************************************************/
/* WriteColumn: */
/***********************************************************************/
void MGOCOL::WriteColumn(PGLOBAL g)
{
// Check whether this node must be written
if (Value != To_Val)
Value->SetValue_pval(To_Val, FALSE); // Convert the updated value
} // end of WriteColumn
/* ---------------------------TDBGOL class --------------------------- */
/***********************************************************************/
/* TDBGOL class constructor. */
/***********************************************************************/
TDBGOL::TDBGOL(PMGODEF tdp) : TDBCAT(tdp)
{
Topt = tdp->GetTopt();
Db = (char*)tdp->GetTabschema();
} // end of TDBJCL constructor
/***********************************************************************/
/* GetResult: Get the list the JSON file columns. */
/***********************************************************************/
PQRYRES TDBGOL::GetResult(PGLOBAL g)
{
return MGOColumns(g, Db, Topt, false);
} // end of GetResult
/* -------------------------- End of mongo --------------------------- */
/**************** tabmgo H Declares Source Code File (.H) **************/
/* Name: tabmgo.h Version 1.1 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* */
/* This file contains the MongoDB classes declares. */
/***********************************************************************/
#include "mongo.h"
#include "cmgoconn.h"
/***********************************************************************/
/* 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;
TDBMGO *tmgp;
int *length;
int n, k, lvl;
bool all;
}; // end of MGODISC
/* -------------------------- TDBMGO class --------------------------- */
/***********************************************************************/
/* This is the MongoDB Table Type class declaration. */
/* The table is a collection, each record being a document. */
/***********************************************************************/
class DllExport TDBMGO : public TDBEXT {
friend class MGOCOL;
friend class MGODEF;
friend class MGODISC;
friend PQRYRES MGOColumns(PGLOBAL, char *, PTOS, bool);
public:
// Constructor
TDBMGO(MGODEF *tdp);
TDBMGO(TDBMGO *tdbp);
// Implementation
virtual AMT GetAmType(void) {return TYPE_AM_MGO;}
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMGO(this);}
// Methods
virtual PTDB Clone(PTABS t);
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual PCOL InsertSpecialColumn(PCOL colp);
virtual int RowNumber(PGLOBAL g, bool b = FALSE) {return N;}
// Database routines
virtual int Cardinality(PGLOBAL g);
virtual int GetMaxSize(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g);
virtual bool ReadKey(PGLOBAL g, OPVAL op, const key_range *kr);
protected:
bool Init(PGLOBAL g);
// Members
CMgoConn *Cmgp; // Points to a C Mongo connection class
CMGOPARM Pcg; // Parms passed to Cmgp
const Item *Cnd; // The first condition
int Fpos; // The current row index
int N; // The current Rownum
int B; // Array index base
bool Done; // Init done
}; // end of class TDBMGO
/* --------------------------- MGOCOL class -------------------------- */
/***********************************************************************/
/* Class MGOCOL: MongoDB access method column descriptor. */
/***********************************************************************/
class DllExport MGOCOL : public EXTCOL {
friend class TDBMGO;
friend class FILTER;
public:
// Constructors
MGOCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i);
MGOCOL(MGOCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
virtual int GetAmType(void) { return Tmgp->GetAmType(); }
// Methods
virtual PSZ GetJpath(PGLOBAL g, bool proj);
virtual void ReadColumn(PGLOBAL g);
virtual void WriteColumn(PGLOBAL g);
protected:
// Default constructor not to be used
MGOCOL(void) {}
// Members
TDBMGO *Tmgp; // To the MGO table block
char *Jpath; // The json path
}; // end of class MGOCOL
/***********************************************************************/
/* This is the class declaration for the MONGO catalog table. */
/***********************************************************************/
class DllExport TDBGOL : public TDBCAT {
public:
// Constructor
TDBGOL(PMGODEF tdp);
protected:
// Specific routines
virtual PQRYRES GetResult(PGLOBAL g);
// Members
PTOS Topt;
char *Db;
}; // end of class TDBGOL
...@@ -513,18 +513,8 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx) ...@@ -513,18 +513,8 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
if (Query) if (Query)
return false; // already done return false; // already done
if (Srcdef) { if (Srcdef)
if (strstr(Srcdef, "%s")) { return MakeSrcdef(g);
char *fil;
fil = (To_CondFil) ? To_CondFil->Body : PlugDup(g, "1=1");
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil));
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil));
} else
Query = new(g)STRING(g, 0, Srcdef);
return false;
} // endif Srcdef
// Allocate the string used to contain Query // Allocate the string used to contain Query
Query = new(g) STRING(g, 1023, "SELECT "); Query = new(g) STRING(g, 1023, "SELECT ");
......
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