Commit ef0829ef authored by Olivier Bertrand's avatar Olivier Bertrand

- Major update of the json/bson/mongo table types programs.

  Fix several bugs, chiefly concerning CURL operations.
        modified:   storage/connect/bson.cpp
        modified:   storage/connect/cmgfam.cpp
        modified:   storage/connect/cmgoconn.cpp
        modified:   storage/connect/cmgoconn.h
        modified:   storage/connect/colblk.h
        modified:   storage/connect/ha_connect.cc
        modified:   storage/connect/jmgfam.cpp
        modified:   storage/connect/jmgoconn.cpp
        modified:   storage/connect/jmgoconn.h
        modified:   storage/connect/json.cpp
        modified:   storage/connect/json.h
        modified:   storage/connect/mysql-test/connect/r/bson_mongo_c.result
        modified:   storage/connect/mysql-test/connect/r/json_mongo_c.result
        modified:   storage/connect/mysql-test/connect/r/mongo_c.result
        modified:   storage/connect/mysql-test/connect/r/mongo_java_2.result
        modified:   storage/connect/mysql-test/connect/r/mongo_java_3.result
        modified:   storage/connect/mysql-test/connect/std_data/Mongo2.jar
        modified:   storage/connect/mysql-test/connect/std_data/Mongo3.jar
        modified:   storage/connect/tabbson.cpp
        modified:   storage/connect/tabbson.h
        modified:   storage/connect/tabcmg.cpp
        modified:   storage/connect/tabcmg.h
        modified:   storage/connect/tabjmg.cpp
        modified:   storage/connect/tabjmg.h
        modified:   storage/connect/tabjson.cpp
        modified:   storage/connect/tabjson.h
parent 4df6952c
...@@ -1205,15 +1205,14 @@ void BJSON::SetArrayValue(PBVAL bap, PBVAL nvp, int n) ...@@ -1205,15 +1205,14 @@ void BJSON::SetArrayValue(PBVAL bap, PBVAL nvp, int n)
int i = 0; int i = 0;
PBVAL bvp = NULL; PBVAL bvp = NULL;
if (bap->To_Val) for (bvp = GetArray(bap); i < n; i++, bvp = bvp ? GetNext(bvp) : NULL)
for (bvp = GetArray(bap); bvp; i++, bvp = GetNext(bvp)) if (!bvp)
if (i == n) { AddArrayValue(bap, NewVal());
SetValueVal(bvp, nvp);
return;
}
if (!bvp) if (!bvp)
AddArrayValue(bap, MOF(nvp)); AddArrayValue(bap, MOF(nvp));
else
SetValueVal(bvp, nvp);
} // end of SetValue } // end of SetValue
......
...@@ -56,6 +56,7 @@ CMGFAM::CMGFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL) ...@@ -56,6 +56,7 @@ CMGFAM::CMGFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
Pcg.Coll_name = tdp->Collname; Pcg.Coll_name = tdp->Collname;
Pcg.Options = tdp->Options; Pcg.Options = tdp->Options;
Pcg.Filter = tdp->Filter; Pcg.Filter = tdp->Filter;
Pcg.Line = NULL;
Pcg.Pipe = tdp->Pipe && tdp->Options != NULL; Pcg.Pipe = tdp->Pipe && tdp->Options != NULL;
Lrecl = tdp->Lrecl + tdp->Ending; Lrecl = tdp->Lrecl + tdp->Ending;
} else { } else {
...@@ -64,6 +65,7 @@ CMGFAM::CMGFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL) ...@@ -64,6 +65,7 @@ CMGFAM::CMGFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
Pcg.Coll_name = NULL; Pcg.Coll_name = NULL;
Pcg.Options = NULL; Pcg.Options = NULL;
Pcg.Filter = NULL; Pcg.Filter = NULL;
Pcg.Line = NULL;
Pcg.Pipe = false; Pcg.Pipe = false;
Lrecl = 0; Lrecl = 0;
} // endif tdp } // endif tdp
...@@ -88,6 +90,7 @@ CMGFAM::CMGFAM(PBDEF tdp) : DOSFAM((PDOSDEF)NULL) ...@@ -88,6 +90,7 @@ CMGFAM::CMGFAM(PBDEF tdp) : DOSFAM((PDOSDEF)NULL)
Pcg.Coll_name = tdp->Collname; Pcg.Coll_name = tdp->Collname;
Pcg.Options = tdp->Options; Pcg.Options = tdp->Options;
Pcg.Filter = tdp->Filter; Pcg.Filter = tdp->Filter;
Pcg.Line = NULL;
Pcg.Pipe = tdp->Pipe && tdp->Options != NULL; Pcg.Pipe = tdp->Pipe && tdp->Options != NULL;
Lrecl = tdp->Lrecl + tdp->Ending; Lrecl = tdp->Lrecl + tdp->Ending;
} else { } else {
...@@ -96,6 +99,7 @@ CMGFAM::CMGFAM(PBDEF tdp) : DOSFAM((PDOSDEF)NULL) ...@@ -96,6 +99,7 @@ CMGFAM::CMGFAM(PBDEF tdp) : DOSFAM((PDOSDEF)NULL)
Pcg.Coll_name = NULL; Pcg.Coll_name = NULL;
Pcg.Options = NULL; Pcg.Options = NULL;
Pcg.Filter = NULL; Pcg.Filter = NULL;
Pcg.Line = NULL;
Pcg.Pipe = false; Pcg.Pipe = false;
Lrecl = 0; Lrecl = 0;
} // endif tdp } // endif tdp
...@@ -280,6 +284,7 @@ int CMGFAM::ReadBuffer(PGLOBAL g) ...@@ -280,6 +284,7 @@ int CMGFAM::ReadBuffer(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
int CMGFAM::WriteBuffer(PGLOBAL g) int CMGFAM::WriteBuffer(PGLOBAL g)
{ {
Pcg.Line = Tdbp->GetLine();
return Cmgp->Write(g); return Cmgp->Write(g);
} // end of WriteBuffer } // end of WriteBuffer
......
This diff is collapsed.
...@@ -28,11 +28,8 @@ typedef struct mongo_parms { ...@@ -28,11 +28,8 @@ typedef struct mongo_parms {
PCSZ Coll_name; PCSZ Coll_name;
PCSZ Options; PCSZ Options;
PCSZ Filter; PCSZ Filter;
PCSZ Line;
bool Pipe; bool Pipe;
//PCSZ User; // User connect info
//PCSZ Pwd; // Password connect info
//int Fsize; // Fetch size
//bool Scrollable; // Scrollable cursor
} CMGOPARM, *PCPARM; } CMGOPARM, *PCPARM;
typedef struct KEYCOL { typedef struct KEYCOL {
...@@ -40,15 +37,23 @@ typedef struct KEYCOL { ...@@ -40,15 +37,23 @@ typedef struct KEYCOL {
PINCOL Incolp; PINCOL Incolp;
PCOL Colp; PCOL Colp;
char *Key; char *Key;
bool Array;
} *PKC; } *PKC;
typedef struct _path_list *PTHP;
typedef struct _path_list {
PSZ Path;
PTHP Next;
} PTH;
/***********************************************************************/ /***********************************************************************/
/* Used when inserting values in a MongoDB collection. */ /* Used when inserting values in a MongoDB collection. */
/***********************************************************************/ /***********************************************************************/
class INCOL : public BLOCK { class INCOL : public BLOCK {
public: public:
// Constructor // Constructor
INCOL(bool ar) { Child = bson_new(); Klist = NULL; Array = ar; } INCOL(void) { Child = bson_new(); Klist = NULL; }
// Methods // Methods
void AddCol(PGLOBAL g, PCOL colp, char *jp); void AddCol(PGLOBAL g, PCOL colp, char *jp);
...@@ -58,7 +63,6 @@ class INCOL : public BLOCK { ...@@ -58,7 +63,6 @@ class INCOL : public BLOCK {
//Members //Members
bson_t *Child; bson_t *Child;
PKC Klist; PKC Klist;
bool Array;
}; // end of INCOL; }; // end of INCOL;
/***********************************************************************/ /***********************************************************************/
...@@ -80,6 +84,7 @@ class CMgoConn : public BLOCK { ...@@ -80,6 +84,7 @@ class CMgoConn : public BLOCK {
bool IsConnected(void) { return m_Connected; } bool IsConnected(void) { return m_Connected; }
bool Connect(PGLOBAL g); bool Connect(PGLOBAL g);
int CollSize(PGLOBAL g); int CollSize(PGLOBAL g);
void CMgoConn::Project(PGLOBAL g, PSTRG s);
bool MakeCursor(PGLOBAL g); bool MakeCursor(PGLOBAL g);
int ReadNext(PGLOBAL g); int ReadNext(PGLOBAL g);
PSZ GetDocument(PGLOBAL g); PSZ GetDocument(PGLOBAL g);
...@@ -108,8 +113,6 @@ class CMgoConn : public BLOCK { ...@@ -108,8 +113,6 @@ class CMgoConn : public BLOCK {
bson_t *Query; // MongoDB cursor filter bson_t *Query; // MongoDB cursor filter
bson_t *Opts; // MongoDB cursor options bson_t *Opts; // MongoDB cursor options
bson_error_t Error; bson_error_t Error;
bson_iter_t Iter; // Used to retrieve column value
bson_iter_t Desc; // Descendant iter
PINCOL Fpc; // To insert INCOL classes PINCOL Fpc; // To insert INCOL classes
PFBLOCK fp; PFBLOCK fp;
bool m_Connected; bool m_Connected;
......
...@@ -38,7 +38,8 @@ class DllExport COLBLK : public XOBJECT { ...@@ -38,7 +38,8 @@ class DllExport COLBLK : public XOBJECT {
virtual PTDB GetTo_Tdb(void) {return To_Tdb;} virtual PTDB GetTo_Tdb(void) {return To_Tdb;}
virtual int GetClustered(void) {return 0;} virtual int GetClustered(void) {return 0;}
virtual int IsClustered(void) {return FALSE;} virtual int IsClustered(void) {return FALSE;}
virtual PSZ GetJpath(PGLOBAL g, bool proj) {return NULL;} virtual bool Stringify(void) {return FALSE;}
virtual PSZ GetJpath(PGLOBAL g, bool proj) {return NULL;}
PCOL GetNext(void) {return Next;} PCOL GetNext(void) {return Next;}
PSZ GetName(void) {return Name;} PSZ GetName(void) {return Name;}
int GetIndex(void) {return Index;} int GetIndex(void) {return Index;}
......
...@@ -5470,14 +5470,13 @@ static bool add_field(String* sql, TABTYPE ttp, const char* field_name, int typ, ...@@ -5470,14 +5470,13 @@ static bool add_field(String* sql, TABTYPE ttp, const char* field_name, int typ,
} // endif rem } // endif rem
if (fmt && *fmt) { if (fmt && *fmt) {
switch (ttp) { switch (ttp) {
case TAB_JSON: error |= sql->append(" JPATH='"); break; case TAB_MONGO:
#if defined(BSON_SUPPORT) case TAB_BSON:
case TAB_BSON: error |= sql->append(" JPATH='"); break; case TAB_JSON: error |= sql->append(" JPATH='"); break;
#endif // BSON_SUPPORT case TAB_XML: error |= sql->append(" XPATH='"); break;
case TAB_XML: error |= sql->append(" XPATH='"); break; default: error |= sql->append(" FIELD_FORMAT='");
default: error |= sql->append(" FIELD_FORMAT='"); } // endswitch ttp
} // endswitch ttp
error |= sql->append_for_single_quote(fmt, strlen(fmt)); error |= sql->append_for_single_quote(fmt, strlen(fmt));
error |= sql->append("'"); error |= sql->append("'");
......
/************ JMONGO FAM C++ Program Source Code File (.CPP) ***********/ /************ JMONGO FAM C++ Program Source Code File (.CPP) ***********/
/* PROGRAM NAME: jmgfam.cpp */ /* PROGRAM NAME: jmgfam.cpp */
/* ------------- */ /* ------------- */
/* Version 1.1 */ /* Version 1.2 */
/* */ /* */
/* COPYRIGHT: */ /* COPYRIGHT: */
/* ---------- */ /* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 20017 - 2020 */ /* (C) Copyright to the author Olivier BERTRAND 20017 - 2021 */
/* */ /* */
/* WHAT THIS PROGRAM DOES: */ /* WHAT THIS PROGRAM DOES: */
/* ----------------------- */ /* ----------------------- */
...@@ -241,8 +241,8 @@ bool JMGFAM::OpenTableFile(PGLOBAL g) ...@@ -241,8 +241,8 @@ bool JMGFAM::OpenTableFile(PGLOBAL g)
return true; return true;
} // endif Mode } // endif Mode
if (Mode == MODE_INSERT) //if (Mode == MODE_INSERT)
Jcp->MakeColumnGroups(g, Tdbp); // Jcp->MakeColumnGroups(g, Tdbp);
if (Mode != MODE_UPDATE) if (Mode != MODE_UPDATE)
return Jcp->MakeCursor(g, Tdbp, Options, Filter, Pipe); return Jcp->MakeCursor(g, Tdbp, Options, Filter, Pipe);
...@@ -346,14 +346,14 @@ int JMGFAM::ReadBuffer(PGLOBAL g) ...@@ -346,14 +346,14 @@ int JMGFAM::ReadBuffer(PGLOBAL g)
} // end of ReadBuffer } // end of ReadBuffer
/***********************************************************************/ /***********************************************************************/
/* WriteBuffer: File write routine for MGO access method. */ /* WriteBuffer: File write routine for JMG access method. */
/***********************************************************************/ /***********************************************************************/
int JMGFAM::WriteBuffer(PGLOBAL g) int JMGFAM::WriteBuffer(PGLOBAL g)
{ {
int rc = RC_OK; int rc = RC_OK;
if (Mode == MODE_INSERT) { if (Mode == MODE_INSERT) {
rc = Jcp->DocWrite(g); rc = Jcp->DocWrite(g, Tdbp->GetLine());
} else if (Mode == MODE_DELETE) { } else if (Mode == MODE_DELETE) {
rc = Jcp->DocDelete(g, false); rc = Jcp->DocDelete(g, false);
} else if (Mode == MODE_UPDATE) { } else if (Mode == MODE_UPDATE) {
......
/************ JMgoConn C++ Functions Source Code File (.CPP) ***********/ /************ JMgoConn C++ Functions Source Code File (.CPP) ***********/
/* Name: JMgoConn.CPP Version 1.1 */ /* Name: JMgoConn.CPP Version 1.2 */
/* */ /* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */ /* (C) Copyright to the author Olivier BERTRAND 2017 - 2021 */
/* */ /* */
/* This file contains the MongoDB Java connection classes functions. */ /* This file contains the MongoDB Java connection classes functions. */
/***********************************************************************/ /***********************************************************************/
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#define nullptr 0 #define nullptr 0
bool IsNum(PSZ s); bool IsArray(PSZ s);
bool MakeSelector(PGLOBAL g, PFIL fp, PSTRG s); bool MakeSelector(PGLOBAL g, PFIL fp, PSTRG s);
/* --------------------------- Class JNCOL --------------------------- */ /* --------------------------- Class JNCOL --------------------------- */
...@@ -43,19 +43,21 @@ void JNCOL::AddCol(PGLOBAL g, PCOL colp, PSZ jp) ...@@ -43,19 +43,21 @@ void JNCOL::AddCol(PGLOBAL g, PCOL colp, PSZ jp)
*p++ = 0; *p++ = 0;
for (kp = Klist; kp; kp = kp->Next) for (kp = Klist; kp; kp = kp->Next)
if (kp->Jncolp && !strcmp(jp, kp->Key)) if (kp->Jncolp && ((kp->Key && !strcmp(jp, kp->Key))
|| (!kp->Key && IsArray(jp) && kp->N == atoi(jp))))
break; break;
if (!kp) { if (!kp) {
icp = new(g) JNCOL(IsNum(p)); icp = new(g) JNCOL();
kcp = (PJKC)PlugSubAlloc(g, NULL, sizeof(JKCOL)); kcp = (PJKC)PlugSubAlloc(g, NULL, sizeof(JKCOL));
kcp->Next = NULL; kcp->Next = NULL;
kcp->Jncolp = icp; kcp->Jncolp = icp;
kcp->Colp = NULL; kcp->Colp = NULL;
kcp->Array = IsArray(jp);
if (Array) { if (kcp->Array) {
kcp->Key = NULL; kcp->Key = NULL;
kcp->N = atoi(p); kcp->N = atoi(jp);
} else { } else {
kcp->Key = PlugDup(g, jp); kcp->Key = PlugDup(g, jp);
kcp->N = 0; kcp->N = 0;
...@@ -75,12 +77,12 @@ void JNCOL::AddCol(PGLOBAL g, PCOL colp, PSZ jp) ...@@ -75,12 +77,12 @@ void JNCOL::AddCol(PGLOBAL g, PCOL colp, PSZ jp)
icp->AddCol(g, colp, p); icp->AddCol(g, colp, p);
} else { } else {
kcp = (PJKC)PlugSubAlloc(g, NULL, sizeof(JKCOL)); kcp = (PJKC)PlugSubAlloc(g, NULL, sizeof(JKCOL));
kcp->Next = NULL; kcp->Next = NULL;
kcp->Jncolp = NULL; kcp->Jncolp = NULL;
kcp->Colp = colp; kcp->Colp = colp;
kcp->Array = IsArray(jp);
if (Array) { if (kcp->Array) {
kcp->Key = NULL; kcp->Key = NULL;
kcp->N = atoi(jp); kcp->N = atoi(jp);
} else { } else {
...@@ -108,7 +110,7 @@ JMgoConn::JMgoConn(PGLOBAL g, PCSZ collname, PCSZ wrapper) ...@@ -108,7 +110,7 @@ JMgoConn::JMgoConn(PGLOBAL g, PCSZ collname, PCSZ wrapper)
CollName = collname; CollName = collname;
readid = fetchid = getdocid = objfldid = fcollid = acollid = readid = fetchid = getdocid = objfldid = fcollid = acollid =
mkdocid = docaddid = mkarid = araddid = insertid = updateid = mkdocid = docaddid = mkarid = araddid = insertid = updateid =
deleteid = gcollid = countid = rewindid = nullptr; deleteid = gcollid = countid = rewindid = mkbsonid = nullptr;
DiscFunc = "MongoDisconnect"; DiscFunc = "MongoDisconnect";
Fpc = NULL; Fpc = NULL;
m_Fetch = 0; m_Fetch = 0;
...@@ -235,7 +237,7 @@ bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options, ...@@ -235,7 +237,7 @@ bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options,
PCSZ filter, bool pipe) PCSZ filter, bool pipe)
{ {
const char *p; const char *p;
bool b = false, id = (tdbp->GetMode() != MODE_READ), all = false; bool id, b = false, all = false;
uint len; uint len;
PCOL cp; PCOL cp;
PSZ jp; PSZ jp;
...@@ -246,13 +248,14 @@ bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options, ...@@ -246,13 +248,14 @@ bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options,
if (Options && !stricmp(Options, "all")) { if (Options && !stricmp(Options, "all")) {
Options = NULL; Options = NULL;
all = true; all = true;
} // endif Options } else
id = (tdbp->GetMode() == MODE_UPDATE || tdbp->GetMode() == MODE_DELETE);
for (cp = tdbp->GetColumns(); cp; cp = cp->GetNext()) for (cp = tdbp->GetColumns(); cp && !all; cp = cp->GetNext())
if (!strcmp(cp->GetName(), "_id")) if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*") && (!Options || pipe))
id = true;
else if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*") && (!Options || pipe))
all = true; all = true;
else if (!id)
id = !strcmp(cp->GetJpath(g, false), "_id");
if (pipe && Options) { if (pipe && Options) {
if (trace(1)) if (trace(1))
...@@ -535,7 +538,7 @@ PSZ JMgoConn::GetDocument(void) ...@@ -535,7 +538,7 @@ PSZ JMgoConn::GetDocument(void)
/***********************************************************************/ /***********************************************************************/
void JMgoConn::MakeColumnGroups(PGLOBAL g, PTDB tdbp) void JMgoConn::MakeColumnGroups(PGLOBAL g, PTDB tdbp)
{ {
Fpc = new(g) JNCOL(false); Fpc = new(g) JNCOL();
for (PCOL colp = tdbp->GetColumns(); colp; colp = colp->GetNext()) for (PCOL colp = tdbp->GetColumns(); colp; colp = colp->GetNext())
if (!colp->IsSpecial()) if (!colp->IsSpecial())
...@@ -553,7 +556,7 @@ bool JMgoConn::GetMethodId(PGLOBAL g, MODE mode) ...@@ -553,7 +556,7 @@ bool JMgoConn::GetMethodId(PGLOBAL g, MODE mode)
return true; return true;
if (gmID(g, docaddid, "DocAdd", if (gmID(g, docaddid, "DocAdd",
"(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z")) "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;I)Z"))
return true; return true;
if (gmID(g, updateid, "CollUpdate", "(Ljava/lang/Object;)J")) if (gmID(g, updateid, "CollUpdate", "(Ljava/lang/Object;)J"))
...@@ -563,14 +566,19 @@ bool JMgoConn::GetMethodId(PGLOBAL g, MODE mode) ...@@ -563,14 +566,19 @@ bool JMgoConn::GetMethodId(PGLOBAL g, MODE mode)
if (gmID(g, mkdocid, "MakeDocument", "()Ljava/lang/Object;")) if (gmID(g, mkdocid, "MakeDocument", "()Ljava/lang/Object;"))
return true; return true;
if (gmID(g, mkbsonid, "MakeBson",
"(Ljava/lang/String;I)Ljava/lang/Object;"))
return true;
if (gmID(g, docaddid, "DocAdd", if (gmID(g, docaddid, "DocAdd",
"(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z")) "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;I)Z"))
return true; return true;
if (gmID(g, mkarid, "MakeArray", "()Ljava/lang/Object;")) if (gmID(g, mkarid, "MakeArray", "()Ljava/lang/Object;"))
return true; return true;
if (gmID(g, araddid, "ArrayAdd", "(Ljava/lang/Object;ILjava/lang/Object;)Z")) if (gmID(g, araddid, "ArrayAdd",
"(Ljava/lang/Object;ILjava/lang/Object;I)Z"))
return true; return true;
if (gmID(g, insertid, "CollInsert", "(Ljava/lang/Object;)Z")) if (gmID(g, insertid, "CollInsert", "(Ljava/lang/Object;)Z"))
...@@ -638,49 +646,82 @@ jobject JMgoConn::MakeObject(PGLOBAL g, PCOL colp, bool&error ) ...@@ -638,49 +646,82 @@ jobject JMgoConn::MakeObject(PGLOBAL g, PCOL colp, bool&error )
return val; return val;
} // end of MakeObject } // end of MakeObject
/***********************************************************************/
/* Stringify. */
/***********************************************************************/
bool JMgoConn::Stringify(PCOL colp)
{
bool b = false;
if (colp)
b = (colp->Stringify() && colp->GetResultType() == TYPE_STRING);
return b;
} // end of Stringify
/***********************************************************************/ /***********************************************************************/
/* MakeDoc. */ /* MakeDoc. */
/***********************************************************************/ /***********************************************************************/
jobject JMgoConn::MakeDoc(PGLOBAL g, PJNCOL jcp) jobject JMgoConn::MakeDoc(PGLOBAL g, PJNCOL jcp)
{ {
bool error = false; int j;
bool b, error = false;
jobject parent, child, val; jobject parent, child, val;
jstring jkey; jstring jkey;
PJKC kp = jcp->Klist;
if (jcp->Array)
if (kp->Array)
parent = env->CallObjectMethod(job, mkarid); parent = env->CallObjectMethod(job, mkarid);
else else
parent = env->CallObjectMethod(job, mkdocid); parent = env->CallObjectMethod(job, mkdocid);
for (PJKC kp = jcp->Klist; kp; kp = kp->Next) for (j = 0; kp; j = 0, kp = kp->Next) {
if (Stringify(kp->Colp)) {
switch (*kp->Colp->GetCharValue()) {
case '{': j = 1; break;
case '[': j = 2; break;
default: break;
} // endswitch
b = (!kp->Key || !*kp->Key || *kp->Key == '*');
} else
b = false;
if (kp->Jncolp) { if (kp->Jncolp) {
if (!(child = MakeDoc(g, kp->Jncolp))) if (!(child = MakeDoc(g, kp->Jncolp)))
return NULL; return NULL;
if (!jcp->Array) { if (!kp->Array) {
jkey = env->NewStringUTF(kp->Key); jkey = env->NewStringUTF(kp->Key);
if (env->CallBooleanMethod(job, docaddid, parent, jkey, child)) if (env->CallBooleanMethod(job, docaddid, parent, jkey, child, j))
return NULL; return NULL;
env->DeleteLocalRef(jkey); env->DeleteLocalRef(jkey);
} else } else
if (env->CallBooleanMethod(job, araddid, parent, kp->N, child)) if (env->CallBooleanMethod(job, araddid, parent, kp->N, child, j))
return NULL; return NULL;
env->DeleteLocalRef(child);
} else { } else {
if (!(val = MakeObject(g, kp->Colp, error))) { if (!(val = MakeObject(g, kp->Colp, error))) {
if (error) if (error)
return NULL; return NULL;
} else if (!jcp->Array) { } else if (!kp->Array) {
jkey = env->NewStringUTF(kp->Key); if (!b) {
jkey = env->NewStringUTF(kp->Key);
if (env->CallBooleanMethod(job, docaddid, parent, jkey, val)) if (env->CallBooleanMethod(job, docaddid, parent, jkey, val, j))
return NULL; return NULL;
env->DeleteLocalRef(jkey); env->DeleteLocalRef(jkey);
} else if (env->CallBooleanMethod(job, araddid, parent, kp->N, val)) { } else {
env->DeleteLocalRef(parent);
parent = env->CallObjectMethod(job, mkbsonid, val, j);
} // endif b
} else if (env->CallBooleanMethod(job, araddid, parent, kp->N, val, j)) {
if (Check(-1)) if (Check(-1))
sprintf(g->Message, "ArrayAdd: %s", Msg); sprintf(g->Message, "ArrayAdd: %s", Msg);
else else
...@@ -689,19 +730,38 @@ jobject JMgoConn::MakeDoc(PGLOBAL g, PJNCOL jcp) ...@@ -689,19 +730,38 @@ jobject JMgoConn::MakeDoc(PGLOBAL g, PJNCOL jcp)
return NULL; return NULL;
} // endif ArrayAdd } // endif ArrayAdd
env->DeleteLocalRef(val);
} // endif Jncolp } // endif Jncolp
} // endfor kp
return parent; return parent;
} // end of MakeDoc } // end of MakeDoc
/***********************************************************************/ /***********************************************************************/
/* Insert a new document in the collation. */ /* Insert a new document in the collation. */
/***********************************************************************/ /***********************************************************************/
int JMgoConn::DocWrite(PGLOBAL g) int JMgoConn::DocWrite(PGLOBAL g, PCSZ line)
{ {
jobject doc; int rc = RC_OK;
jobject doc = nullptr;
if (line) {
int j;
jobject val = env->NewStringUTF(line);
if (!Fpc || !(doc = MakeDoc(g, Fpc))) switch (*line) {
case '{': j = 1; break;
case '[': j = 2; break;
default: j = 0; break;
} // endswitch line
doc = env->CallObjectMethod(job, mkbsonid, val, j);
env->DeleteLocalRef(val);
} else if (Fpc)
doc = MakeDoc(g, Fpc);
if (!doc)
return RC_FX; return RC_FX;
if (env->CallBooleanMethod(job, insertid, doc)) { if (env->CallBooleanMethod(job, insertid, doc)) {
...@@ -710,10 +770,11 @@ int JMgoConn::DocWrite(PGLOBAL g) ...@@ -710,10 +770,11 @@ int JMgoConn::DocWrite(PGLOBAL g)
else else
sprintf(g->Message, "CollInsert: unknown error"); sprintf(g->Message, "CollInsert: unknown error");
return RC_FX; rc = RC_FX;
} // endif Insert } // endif Insert
return RC_OK; env->DeleteLocalRef(doc);
return rc;
} // end of DocWrite } // end of DocWrite
/***********************************************************************/ /***********************************************************************/
...@@ -721,7 +782,7 @@ int JMgoConn::DocWrite(PGLOBAL g) ...@@ -721,7 +782,7 @@ int JMgoConn::DocWrite(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
int JMgoConn::DocUpdate(PGLOBAL g, PTDB tdbp) int JMgoConn::DocUpdate(PGLOBAL g, PTDB tdbp)
{ {
int rc = RC_OK; int j = 0, rc = RC_OK;
bool error; bool error;
PCOL colp; PCOL colp;
jstring jkey; jstring jkey;
...@@ -734,8 +795,14 @@ int JMgoConn::DocUpdate(PGLOBAL g, PTDB tdbp) ...@@ -734,8 +795,14 @@ int JMgoConn::DocUpdate(PGLOBAL g, PTDB tdbp)
if (error) if (error)
return RC_FX; return RC_FX;
else if (Stringify(colp))
if (env->CallBooleanMethod(job, docaddid, updlist, jkey, val)) switch (*colp->GetCharValue()) {
case '{': j = 1; break;
case '[': j = 2; break;
default: break;
} // endswitch
if (env->CallBooleanMethod(job, docaddid, updlist, jkey, val, j))
return RC_OK; return RC_OK;
env->DeleteLocalRef(jkey); env->DeleteLocalRef(jkey);
...@@ -745,7 +812,7 @@ int JMgoConn::DocUpdate(PGLOBAL g, PTDB tdbp) ...@@ -745,7 +812,7 @@ int JMgoConn::DocUpdate(PGLOBAL g, PTDB tdbp)
upd = env->CallObjectMethod(job, mkdocid); upd = env->CallObjectMethod(job, mkdocid);
jkey = env->NewStringUTF("$set"); jkey = env->NewStringUTF("$set");
if (env->CallBooleanMethod(job, docaddid, upd, jkey, updlist)) if (env->CallBooleanMethod(job, docaddid, upd, jkey, updlist, 0))
return RC_OK; return RC_OK;
env->DeleteLocalRef(jkey); env->DeleteLocalRef(jkey);
......
...@@ -25,6 +25,7 @@ typedef struct JKCOL { ...@@ -25,6 +25,7 @@ typedef struct JKCOL {
PCOL Colp; PCOL Colp;
char *Key; char *Key;
int N; int N;
bool Array;
} *PJKC; } *PJKC;
/***********************************************************************/ /***********************************************************************/
...@@ -33,18 +34,18 @@ typedef struct JKCOL { ...@@ -33,18 +34,18 @@ typedef struct JKCOL {
class JNCOL : public BLOCK { class JNCOL : public BLOCK {
public: public:
// Constructor // Constructor
JNCOL(bool ar) { Klist = NULL; Array = ar; } //JNCOL(bool ar) { Klist = NULL; Array = ar; }
JNCOL(void) { Klist = NULL; }
// Methods // Methods
void AddCol(PGLOBAL g, PCOL colp, PSZ jp); void AddCol(PGLOBAL g, PCOL colp, PSZ jp);
//Members //Members
PJKC Klist; PJKC Klist;
bool Array;
}; // end of JNCOL; }; // end of JNCOL;
/***********************************************************************/ /***********************************************************************/
/* JMgoConn class. */ /* JMgoConn class. */
/***********************************************************************/ /***********************************************************************/
class JMgoConn : public JAVAConn { class JMgoConn : public JAVAConn {
friend class TDBJMG; friend class TDBJMG;
...@@ -81,11 +82,12 @@ class JMgoConn : public JAVAConn { ...@@ -81,11 +82,12 @@ class JMgoConn : public JAVAConn {
bool GetMethodId(PGLOBAL g, MODE mode); bool GetMethodId(PGLOBAL g, MODE mode);
jobject MakeObject(PGLOBAL g, PCOL colp, bool& error); jobject MakeObject(PGLOBAL g, PCOL colp, bool& error);
jobject MakeDoc(PGLOBAL g, PJNCOL jcp); jobject MakeDoc(PGLOBAL g, PJNCOL jcp);
int DocWrite(PGLOBAL g); int DocWrite(PGLOBAL g, PCSZ line);
int DocUpdate(PGLOBAL g, PTDB tdbp); int DocUpdate(PGLOBAL g, PTDB tdbp);
int DocDelete(PGLOBAL g, bool all); int DocDelete(PGLOBAL g, bool all);
bool Rewind(void); bool Rewind(void);
PSZ GetDocument(void); PSZ GetDocument(void);
bool Stringify(PCOL colp);
protected: protected:
// Members // Members
...@@ -100,6 +102,7 @@ class JMgoConn : public JAVAConn { ...@@ -100,6 +102,7 @@ class JMgoConn : public JAVAConn {
jmethodID getdocid; // The GetDoc method ID jmethodID getdocid; // The GetDoc method ID
jmethodID objfldid; // The ObjectField method ID jmethodID objfldid; // The ObjectField method ID
jmethodID mkdocid; // The MakeDocument method ID jmethodID mkdocid; // The MakeDocument method ID
jmethodID mkbsonid; // The MakeBson method ID
jmethodID docaddid; // The DocAdd method ID jmethodID docaddid; // The DocAdd method ID
jmethodID mkarid; // The MakeArray method ID jmethodID mkarid; // The MakeArray method ID
jmethodID araddid; // The ArrayAdd method ID jmethodID araddid; // The ArrayAdd method ID
......
...@@ -77,6 +77,24 @@ bool IsNum(PSZ s) ...@@ -77,6 +77,24 @@ bool IsNum(PSZ s)
return true; return true;
} // end of IsNum } // end of IsNum
/***********************************************************************/
/* IsArray: check whether this is a Mongo array path. */
/***********************************************************************/
bool IsArray(PSZ s)
{
char* p = s;
if (!p || !*p)
return false;
else for (; *p; p++)
if (*p == '.')
break;
else if (!isdigit(*p))
return false;
return true;
} // end of IsArray
/***********************************************************************/ /***********************************************************************/
/* NextChr: return the first found '[' or Sep pointer. */ /* NextChr: return the first found '[' or Sep pointer. */
/***********************************************************************/ /***********************************************************************/
...@@ -1326,9 +1344,9 @@ bool JARRAY::Merge(PGLOBAL g, PJSON jsp) ...@@ -1326,9 +1344,9 @@ bool JARRAY::Merge(PGLOBAL g, PJSON jsp)
} // end of Merge } // end of Merge
/***********************************************************************/ /***********************************************************************/
/* Set the nth Value of the Array Value list. */ /* Set the nth Value of the Array Value list or add it. */
/***********************************************************************/ /***********************************************************************/
bool JARRAY::SetArrayValue(PGLOBAL g, PJVAL jvp, int n) void JARRAY::SetArrayValue(PGLOBAL g, PJVAL jvp, int n)
{ {
int i = 0; int i = 0;
PJVAL jp, *jpp = &First; PJVAL jp, *jpp = &First;
...@@ -1339,7 +1357,6 @@ bool JARRAY::SetArrayValue(PGLOBAL g, PJVAL jvp, int n) ...@@ -1339,7 +1357,6 @@ bool JARRAY::SetArrayValue(PGLOBAL g, PJVAL jvp, int n)
*jpp = jvp; *jpp = jvp;
jvp->Next = (jp ? jp->Next : NULL); jvp->Next = (jp ? jp->Next : NULL);
return false;
} // end of SetValue } // end of SetValue
/***********************************************************************/ /***********************************************************************/
...@@ -1417,7 +1434,7 @@ bool JARRAY::IsNull(void) ...@@ -1417,7 +1434,7 @@ bool JARRAY::IsNull(void)
/***********************************************************************/ /***********************************************************************/
JVALUE::JVALUE(PJSON jsp) : JSON() JVALUE::JVALUE(PJSON jsp) : JSON()
{ {
if (jsp->GetType() == TYPE_JVAL) { if (jsp && jsp->GetType() == TYPE_JVAL) {
PJVAL jvp = (PJVAL)jsp; PJVAL jvp = (PJVAL)jsp;
// Val = ((PJVAL)jsp)->GetVal(); // Val = ((PJVAL)jsp)->GetVal();
...@@ -1434,7 +1451,7 @@ JVALUE::JVALUE(PJSON jsp) : JSON() ...@@ -1434,7 +1451,7 @@ JVALUE::JVALUE(PJSON jsp) : JSON()
} else { } else {
Jsp = jsp; Jsp = jsp;
// Val = NULL; // Val = NULL;
DataType = TYPE_JSON; DataType = Jsp ? TYPE_JSON : TYPE_NULL;
Nd = 0; Nd = 0;
} // endif Type } // endif Type
......
...@@ -184,7 +184,7 @@ class JARRAY : public JSON { ...@@ -184,7 +184,7 @@ class JARRAY : public JSON {
// Specific // Specific
PJVAL AddArrayValue(PGLOBAL g, PJVAL jvp = NULL, int* x = NULL); PJVAL AddArrayValue(PGLOBAL g, PJVAL jvp = NULL, int* x = NULL);
bool SetArrayValue(PGLOBAL g, PJVAL jvp, int i); void SetArrayValue(PGLOBAL g, PJVAL jvp, int i);
void InitArray(PGLOBAL g); void InitArray(PGLOBAL g);
protected: protected:
......
...@@ -363,7 +363,7 @@ _id item prices_0 prices_1 prices_2 prices_3 prices_4 ...@@ -363,7 +363,7 @@ _id item prices_0 prices_1 prices_2 prices_3 prices_4
1 journal 87 45 63 12 78 1 journal 87 45 63 12 78
2 notebook 123 456 789 NULL NULL 2 notebook 123 456 789 NULL NULL
3 paper 5 7 3 8 NULL 3 paper 5 7 3 8 NULL
4 planner 25 71 44 27 NULL 4 planner 25 71 NULL 44 27
5 postcard 5 7 3 8 NULL 5 postcard 5 7 3 8 NULL
DROP TABLE t1; DROP TABLE t1;
# #
......
...@@ -363,7 +363,7 @@ _id item prices_0 prices_1 prices_2 prices_3 prices_4 ...@@ -363,7 +363,7 @@ _id item prices_0 prices_1 prices_2 prices_3 prices_4
1 journal 87 45 63 12 78 1 journal 87 45 63 12 78
2 notebook 123 456 789 NULL NULL 2 notebook 123 456 789 NULL NULL
3 paper 5 7 3 8 NULL 3 paper 5 7 3 8 NULL
4 planner 25 71 44 27 NULL 4 planner 25 71 NULL 44 27
5 postcard 5 7 3 8 NULL 5 postcard 5 7 3 8 NULL
DROP TABLE t1; DROP TABLE t1;
# #
......
...@@ -64,23 +64,23 @@ SHOW CREATE TABLE t1; ...@@ -64,23 +64,23 @@ SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL, `_id` char(24) NOT NULL,
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building', `address_building` char(10) NOT NULL `JPATH`='address.building',
`address_coord` varchar(512) NOT NULL `FIELD_FORMAT`='address.coord', `address_coord` varchar(512) NOT NULL `JPATH`='address.coord',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street', `address_street` char(38) NOT NULL `JPATH`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL, `borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL, `cuisine` char(64) NOT NULL,
`grades_0` varchar(512) DEFAULT NULL `FIELD_FORMAT`='grades.0', `grades_0` varchar(512) DEFAULT NULL `JPATH`='grades.0',
`name` char(98) NOT NULL, `name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL `restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `OPTION_LIST`='Depth=1,Driver=C,Version=0' `DATA_CHARSET`='utf8' ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `OPTION_LIST`='Depth=1,Driver=C,Version=0' `DATA_CHARSET`='utf8'
SELECT * FROM t1 LIMIT 5; SELECT * FROM t1 LIMIT 5;
_id address_building address_coord address_street address_zipcode borough cuisine grades_0 name restaurant_id _id address_building address_coord address_street address_zipcode borough cuisine grades_0 name restaurant_id
58ada47de5a51ddfcd5ed51c 1007 Morris Park Ave 10462 Bronx Bakery {"date":{"$date":1393804800000},"grade":"A","score":2} Morris Park Bake Shop 30075445 58ada47de5a51ddfcd5ed51c 1007 [-73.856076999999999089,40.848447000000000173] Morris Park Ave 10462 Bronx Bakery {"date":{"$date":1393804800000},"grade":"A","score":2} Morris Park Bake Shop 30075445
58ada47de5a51ddfcd5ed51d 469 Flatbush Avenue 11225 Brooklyn Hamburgers {"date":{"$date":1419897600000},"grade":"A","score":8} Wendy'S 30112340 58ada47de5a51ddfcd5ed51d 469 [-73.96170399999999745,40.66294200000000103] Flatbush Avenue 11225 Brooklyn Hamburgers {"date":{"$date":1419897600000},"grade":"A","score":8} Wendy'S 30112340
58ada47de5a51ddfcd5ed51e 351 West 57 Street 10019 Manhattan Irish {"date":{"$date":1409961600000},"grade":"A","score":2} Dj Reynolds Pub And Restaurant 30191841 58ada47de5a51ddfcd5ed51e 351 [-73.985135599999992451,40.767691900000002647] West 57 Street 10019 Manhattan Irish {"date":{"$date":1409961600000},"grade":"A","score":2} Dj Reynolds Pub And Restaurant 30191841
58ada47de5a51ddfcd5ed51f 2780 Stillwell Avenue 11224 Brooklyn American {"date":{"$date":1402358400000},"grade":"A","score":5} Riviera Caterer 40356018 58ada47de5a51ddfcd5ed51f 2780 [-73.982419999999990523,40.579504999999997494] Stillwell Avenue 11224 Brooklyn American {"date":{"$date":1402358400000},"grade":"A","score":5} Riviera Caterer 40356018
58ada47de5a51ddfcd5ed520 97-22 63 Road 11374 Queens Jewish/Kosher {"date":{"$date":1416787200000},"grade":"Z","score":20} Tov Kosher Kitchen 40356068 58ada47de5a51ddfcd5ed520 97-22 [-73.860115199999995639,40.731173900000001709] 63 Road 11374 Queens Jewish/Kosher {"date":{"$date":1416787200000},"grade":"Z","score":20} Tov Kosher Kitchen 40356068
DROP TABLE t1; DROP TABLE t1;
# #
# Dropping a column # Dropping a column
...@@ -249,14 +249,14 @@ SHOW CREATE TABLE t1; ...@@ -249,14 +249,14 @@ SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL, `_id` char(24) NOT NULL,
`address_building` char(6) NOT NULL `FIELD_FORMAT`='address.building', `address_building` char(6) NOT NULL `JPATH`='address.building',
`address_coord_0` double(12,6) NOT NULL `FIELD_FORMAT`='address.coord.0', `address_coord_0` double(12,6) NOT NULL `JPATH`='address.coord.0',
`address_street` char(25) NOT NULL `FIELD_FORMAT`='address.street', `address_street` char(25) NOT NULL `JPATH`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL, `borough` char(13) NOT NULL,
`grades_0_date` datetime NOT NULL `FIELD_FORMAT`='grades.0.date', `grades_0_date` datetime NOT NULL `JPATH`='grades.0.date',
`grades_0_grade` char(14) NOT NULL `FIELD_FORMAT`='grades.0.grade', `grades_0_grade` char(14) NOT NULL `JPATH`='grades.0.grade',
`grades_0_score` int(11) NOT NULL `FIELD_FORMAT`='grades.0.score', `grades_0_score` int(11) NOT NULL `JPATH`='grades.0.score',
`name` char(32) NOT NULL, `name` char(32) NOT NULL,
`restaurant_id` char(8) NOT NULL `restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `COLIST`='{"projection":{"cuisine":0}}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=C,level=2,version=0' ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `COLIST`='{"projection":{"cuisine":0}}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=C,level=2,version=0'
......
...@@ -64,13 +64,13 @@ SHOW CREATE TABLE t1; ...@@ -64,13 +64,13 @@ SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL, `_id` char(24) NOT NULL,
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building', `address_building` char(10) NOT NULL `JPATH`='address.building',
`address_coord` char(41) NOT NULL `FIELD_FORMAT`='address.coord', `address_coord` char(41) NOT NULL `JPATH`='address.coord',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street', `address_street` char(38) NOT NULL `JPATH`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL, `borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL, `cuisine` char(64) NOT NULL,
`grades_0` char(99) DEFAULT NULL `FIELD_FORMAT`='grades.0', `grades_0` char(99) DEFAULT NULL `JPATH`='grades.0',
`name` char(98) NOT NULL, `name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL `restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `OPTION_LIST`='Depth=1,Driver=Java,Version=2' `DATA_CHARSET`='utf8' ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `OPTION_LIST`='Depth=1,Driver=Java,Version=2' `DATA_CHARSET`='utf8'
...@@ -249,14 +249,14 @@ SHOW CREATE TABLE t1; ...@@ -249,14 +249,14 @@ SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL, `_id` char(24) NOT NULL,
`address_building` char(6) NOT NULL `FIELD_FORMAT`='address.building', `address_building` char(6) NOT NULL `JPATH`='address.building',
`address_coord_0` double(18,14) NOT NULL `FIELD_FORMAT`='address.coord.0', `address_coord_0` double(18,14) NOT NULL `JPATH`='address.coord.0',
`address_street` char(25) NOT NULL `FIELD_FORMAT`='address.street', `address_street` char(25) NOT NULL `JPATH`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL, `borough` char(13) NOT NULL,
`grades_0_date` datetime NOT NULL `FIELD_FORMAT`='grades.0.date', `grades_0_date` datetime NOT NULL `JPATH`='grades.0.date',
`grades_0_grade` char(14) NOT NULL `FIELD_FORMAT`='grades.0.grade', `grades_0_grade` char(14) NOT NULL `JPATH`='grades.0.grade',
`grades_0_score` int(2) NOT NULL `FIELD_FORMAT`='grades.0.score', `grades_0_score` int(2) NOT NULL `JPATH`='grades.0.score',
`name` char(32) NOT NULL, `name` char(32) NOT NULL,
`restaurant_id` char(8) NOT NULL `restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=2' ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=2'
......
...@@ -64,13 +64,13 @@ SHOW CREATE TABLE t1; ...@@ -64,13 +64,13 @@ SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL, `_id` char(24) NOT NULL,
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building', `address_building` char(10) NOT NULL `JPATH`='address.building',
`address_coord` char(39) NOT NULL `FIELD_FORMAT`='address.coord', `address_coord` char(39) NOT NULL `JPATH`='address.coord',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street', `address_street` char(38) NOT NULL `JPATH`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL, `borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL, `cuisine` char(64) NOT NULL,
`grades_0` char(84) DEFAULT NULL `FIELD_FORMAT`='grades.0', `grades_0` char(84) DEFAULT NULL `JPATH`='grades.0',
`name` char(98) NOT NULL, `name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL `restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `OPTION_LIST`='Depth=1,Driver=Java,Version=3' `DATA_CHARSET`='utf8' ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `OPTION_LIST`='Depth=1,Driver=Java,Version=3' `DATA_CHARSET`='utf8'
...@@ -249,14 +249,14 @@ SHOW CREATE TABLE t1; ...@@ -249,14 +249,14 @@ SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL, `_id` char(24) NOT NULL,
`address_building` char(6) NOT NULL `FIELD_FORMAT`='address.building', `address_building` char(6) NOT NULL `JPATH`='address.building',
`address_coord_0` double(18,14) NOT NULL `FIELD_FORMAT`='address.coord.0', `address_coord_0` double(18,14) NOT NULL `JPATH`='address.coord.0',
`address_street` char(25) NOT NULL `FIELD_FORMAT`='address.street', `address_street` char(25) NOT NULL `JPATH`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL, `borough` char(13) NOT NULL,
`grades_0_date` datetime NOT NULL `FIELD_FORMAT`='grades.0.date', `grades_0_date` datetime NOT NULL `JPATH`='grades.0.date',
`grades_0_grade` char(14) NOT NULL `FIELD_FORMAT`='grades.0.grade', `grades_0_grade` char(14) NOT NULL `JPATH`='grades.0.grade',
`grades_0_score` int(2) NOT NULL `FIELD_FORMAT`='grades.0.score', `grades_0_score` int(2) NOT NULL `JPATH`='grades.0.score',
`name` char(32) NOT NULL, `name` char(32) NOT NULL,
`restaurant_id` char(8) NOT NULL `restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=3' ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=3'
......
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
...@@ -1171,7 +1171,7 @@ bool BSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -1171,7 +1171,7 @@ bool BSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Collname = GetStringCatInfo(g, "Name", Collname = GetStringCatInfo(g, "Name",
(Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
Collname = GetStringCatInfo(g, "Tabname", Collname); Collname = GetStringCatInfo(g, "Tabname", Collname);
Options = GetStringCatInfo(g, "Colist", NULL); Options = GetStringCatInfo(g, "Colist", Xcol ? "all" : NULL);
Filter = GetStringCatInfo(g, "Filter", NULL); Filter = GetStringCatInfo(g, "Filter", NULL);
Pipe = GetBoolCatInfo("Pipeline", false); Pipe = GetBoolCatInfo("Pipeline", false);
Driver = GetStringCatInfo(g, "Driver", NULL); Driver = GetStringCatInfo(g, "Driver", NULL);
...@@ -1215,7 +1215,7 @@ PTDB BSONDEF::GetTable(PGLOBAL g, MODE m) ...@@ -1215,7 +1215,7 @@ PTDB BSONDEF::GetTable(PGLOBAL g, MODE m)
if (Lrecl) { if (Lrecl) {
// Allocate the parse work memory // Allocate the parse work memory
G = PlugInit(NULL, (size_t)Lrecl * (Pretty < 0 ? 2 : 4)); G = PlugInit(NULL, (size_t)Lrecl * (Pretty < 0 ? 3 : 5));
} else { } else {
strcpy(g->Message, "LRECL is not defined"); strcpy(g->Message, "LRECL is not defined");
return NULL; return NULL;
...@@ -1249,6 +1249,7 @@ PTDB BSONDEF::GetTable(PGLOBAL g, MODE m) ...@@ -1249,6 +1249,7 @@ PTDB BSONDEF::GetTable(PGLOBAL g, MODE m)
#endif // !MONGO_SUPPORT #endif // !MONGO_SUPPORT
} // endif Driver } // endif Driver
Pretty = 4; // Not a file
} else if (Zipped) { } else if (Zipped) {
#if defined(ZIP_SUPPORT) #if defined(ZIP_SUPPORT)
if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) { if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) {
...@@ -1676,6 +1677,7 @@ BSONCOL::BSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i) ...@@ -1676,6 +1677,7 @@ BSONCOL::BSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
Xpd = false; Xpd = false;
Parsed = false; Parsed = false;
Warned = false; Warned = false;
Sgfy = false;
} // end of BSONCOL constructor } // end of BSONCOL constructor
/***********************************************************************/ /***********************************************************************/
...@@ -1695,6 +1697,7 @@ BSONCOL::BSONCOL(BSONCOL* col1, PTDB tdbp) : DOSCOL(col1, tdbp) ...@@ -1695,6 +1697,7 @@ BSONCOL::BSONCOL(BSONCOL* col1, PTDB tdbp) : DOSCOL(col1, tdbp)
Xpd = col1->Xpd; Xpd = col1->Xpd;
Parsed = col1->Parsed; Parsed = col1->Parsed;
Warned = col1->Warned; Warned = col1->Warned;
Sgfy = col1->Sgfy;
} // end of BSONCOL copy constructor } // end of BSONCOL copy constructor
/***********************************************************************/ /***********************************************************************/
...@@ -1966,8 +1969,10 @@ PSZ BSONCOL::GetJpath(PGLOBAL g, bool proj) ...@@ -1966,8 +1969,10 @@ PSZ BSONCOL::GetJpath(PGLOBAL g, bool proj)
if (*p1 == '$') p1++; if (*p1 == '$') p1++;
if (*p1 == '.') p1++; if (*p1 == '.') p1++;
mgopath = PlugDup(g, p1); mgopath = PlugDup(g, p1);
} else } else {
Sgfy = true;
return NULL; return NULL;
} // endif
for (p1 = p2 = mgopath; *p1; p1++) for (p1 = p2 = mgopath; *p1; p1++)
if (i) { // Inside [] if (i) { // Inside []
...@@ -2005,6 +2010,7 @@ PSZ BSONCOL::GetJpath(PGLOBAL g, bool proj) ...@@ -2005,6 +2010,7 @@ PSZ BSONCOL::GetJpath(PGLOBAL g, bool proj)
case '*': case '*':
if (*(p2 - 1) == '.' && !*(p1 + 1)) { if (*(p2 - 1) == '.' && !*(p1 + 1)) {
p2--; // Suppress last :* p2--; // Suppress last :*
Sgfy = true;
break; break;
} // endif p2 } // endif p2
...@@ -2013,6 +2019,9 @@ PSZ BSONCOL::GetJpath(PGLOBAL g, bool proj) ...@@ -2013,6 +2019,9 @@ PSZ BSONCOL::GetJpath(PGLOBAL g, bool proj)
break; break;
} // endswitch p1; } // endswitch p1;
if (*(p2 - 1) == '.')
p2--;
*p2 = 0; *p2 = 0;
return mgopath; return mgopath;
} else } else
......
/*************** tabbson H Declares Source Code File (.H) **************/ /*************** tabbson H Declares Source Code File (.H) **************/
/* Name: tabbson.h Version 1.0 */ /* Name: tabbson.h Version 1.1 */
/* */ /* */
/* (C) Copyright to the author Olivier BERTRAND 2020 */ /* (C) Copyright to the author Olivier BERTRAND 2020 - 2021 */
/* */ /* */
/* This file contains the BSON classes declares. */ /* This file contains the BSON classes declares. */
/***********************************************************************/ /***********************************************************************/
...@@ -242,7 +242,8 @@ class DllExport BSONCOL : public DOSCOL { ...@@ -242,7 +242,8 @@ class DllExport BSONCOL : public DOSCOL {
BSONCOL(BSONCOL* colp, PTDB tdbp); // Constructor used in copy process BSONCOL(BSONCOL* colp, PTDB tdbp); // Constructor used in copy process
// Implementation // Implementation
virtual int GetAmType(void) { return Tbp->GetAmType(); } virtual int GetAmType(void) { return Tbp->GetAmType(); }
virtual bool Stringify(void) { return Sgfy; }
// Methods // Methods
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check); virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
...@@ -270,6 +271,7 @@ class DllExport BSONCOL : public DOSCOL { ...@@ -270,6 +271,7 @@ class DllExport BSONCOL : public DOSCOL {
bool Xpd; // True for expandable column bool Xpd; // True for expandable column
bool Parsed; // True when parsed bool Parsed; // True when parsed
bool Warned; // True when warning issued bool Warned; // True when warning issued
bool Sgfy; // True if stringified
}; // end of class BSONCOL }; // end of class BSONCOL
/* -------------------------- TDBBSON class -------------------------- */ /* -------------------------- TDBBSON class -------------------------- */
......
/************** tabcmg C++ Program Source Code File (.CPP) *************/ /************** tabcmg C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: tabcmg Version 1.1 */ /* PROGRAM NAME: tabcmg Version 1.2 */
/* (C) Copyright to the author Olivier BERTRAND 2017 */ /* (C) Copyright to the author Olivier BERTRAND 2017 - 2021 */
/* This program are the C MongoDB class DB execution routines. */ /* This program are the C MongoDB class DB execution routines. */
/***********************************************************************/ /***********************************************************************/
...@@ -84,69 +84,80 @@ bool CMGDISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc, ...@@ -84,69 +84,80 @@ bool CMGDISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc,
bcol.Cbn = false; bcol.Cbn = false;
if (BSON_ITER_HOLDS_UTF8(iter)) { switch (bson_iter_type(iter)) {
bcol.Type = TYPE_STRING; case BSON_TYPE_UTF8:
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.Type = TYPE_STRING;
bcol.Len = 512; bcol.Len = strlen(bson_iter_utf8(iter, NULL));
} else { break;
bson_iter_t child; case BSON_TYPE_INT32:
bcol.Type = TYPE_INT;
if (bson_iter_recurse(iter, &child)) bcol.Len = 11; // bson_iter_int32(iter)
if (FindInDoc(g, &child, NULL, colname, fmt, k + 1, false)) break;
return true; case BSON_TYPE_INT64:
bcol.Type = TYPE_BIGINT;
newcol = false; bcol.Len = 22; // bson_iter_int64(iter)
} // endif lvl break;
case BSON_TYPE_DOUBLE:
} else if (BSON_ITER_HOLDS_ARRAY(iter)) { bcol.Type = TYPE_DOUBLE;
if (lvl < 0) bcol.Len = 12;
continue; bcol.Scale = 6; // bson_iter_double(iter)
else if (lvl <= k) { break;
case BSON_TYPE_DATE_TIME:
bcol.Type = TYPE_DATE;
bcol.Len = 19; // bson_iter_date_time(iter)
break;
case BSON_TYPE_BOOL:
bcol.Type = TYPE_TINY;
bcol.Len = 1;
break;
case BSON_TYPE_OID:
bcol.Type = TYPE_STRING; bcol.Type = TYPE_STRING;
bcol.Len = 512; bcol.Len = 24; // bson_iter_oid(iter)
} else { break;
bson_t *arr; case BSON_TYPE_DECIMAL128:
bson_iter_t itar; bcol.Type = TYPE_DECIM;
const uint8_t *data = NULL; bcol.Len = 32; // bson_iter_decimal128(iter, &dec)
uint32_t len = 0; break;
case BSON_TYPE_DOCUMENT:
bson_iter_array(iter, &len, &data); if (lvl < 0)
arr = bson_new_from_data(data, len); continue;
else if (lvl <= k) {
if (FindInDoc(g, &itar, arr, colname, fmt, k + 1, !all)) bcol.Type = TYPE_STRING;
return true; bcol.Len = 512;
} else {
bson_iter_t child;
if (bson_iter_recurse(iter, &child))
if (FindInDoc(g, &child, NULL, colname, fmt, k + 1, false))
return true;
newcol = false;
} // endif lvl
break;
case BSON_TYPE_ARRAY:
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, k + 1, !all))
return true;
newcol = false; newcol = false;
} // endif lvl } // endif lvl
} // endif's break;
} // endswitch iter
if (newcol) if (newcol)
AddColumn(g, colname, fmt, k); AddColumn(g, colname, fmt, k);
...@@ -178,6 +189,7 @@ TDBCMG::TDBCMG(MGODEF *tdp) : TDBEXT(tdp) ...@@ -178,6 +189,7 @@ TDBCMG::TDBCMG(MGODEF *tdp) : TDBEXT(tdp)
Pcg.Coll_name = tdp->Tabname; Pcg.Coll_name = tdp->Tabname;
Pcg.Options = tdp->Colist; Pcg.Options = tdp->Colist;
Pcg.Filter = tdp->Filter; Pcg.Filter = tdp->Filter;
Pcg.Line = NULL;
Pcg.Pipe = tdp->Pipe && tdp->Colist != NULL; Pcg.Pipe = tdp->Pipe && tdp->Colist != NULL;
B = tdp->Base ? 1 : 0; B = tdp->Base ? 1 : 0;
} else { } else {
...@@ -186,6 +198,7 @@ TDBCMG::TDBCMG(MGODEF *tdp) : TDBEXT(tdp) ...@@ -186,6 +198,7 @@ TDBCMG::TDBCMG(MGODEF *tdp) : TDBEXT(tdp)
Pcg.Coll_name = NULL; Pcg.Coll_name = NULL;
Pcg.Options = NULL; Pcg.Options = NULL;
Pcg.Filter = NULL; Pcg.Filter = NULL;
Pcg.Line = NULL;
Pcg.Pipe = false; Pcg.Pipe = false;
B = 0; B = 0;
} // endif tdp } // endif tdp
...@@ -381,7 +394,21 @@ MGOCOL::MGOCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i) ...@@ -381,7 +394,21 @@ MGOCOL::MGOCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
: EXTCOL(cdp, tdbp, cprec, i, "MGO") : EXTCOL(cdp, tdbp, cprec, i, "MGO")
{ {
Tmgp = (PTDBCMG)(tdbp->GetOrig() ? tdbp->GetOrig() : tdbp); Tmgp = (PTDBCMG)(tdbp->GetOrig() ? tdbp->GetOrig() : tdbp);
Jpath = cdp->GetFmt() ? cdp->GetFmt() : cdp->GetName(); Sgfy = false;
if ((Jpath = cdp->GetFmt())) {
int n = strlen(Jpath) - 1;
if (Jpath[n] == '*') {
Jpath = PlugDup(g, cdp->GetFmt());
if (Jpath[n - 1] == '.') n--;
Jpath[n] = 0;
Sgfy = true;
} // endif Jpath
} else
Jpath = cdp->GetName();
} // end of MGOCOL constructor } // end of MGOCOL constructor
/***********************************************************************/ /***********************************************************************/
...@@ -392,6 +419,7 @@ MGOCOL::MGOCOL(MGOCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp) ...@@ -392,6 +419,7 @@ MGOCOL::MGOCOL(MGOCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp)
{ {
Tmgp = col1->Tmgp; Tmgp = col1->Tmgp;
Jpath = col1->Jpath; Jpath = col1->Jpath;
Sgfy = col1->Sgfy;
} // end of MGOCOL copy constructor } // end of MGOCOL copy constructor
/***********************************************************************/ /***********************************************************************/
...@@ -419,6 +447,9 @@ PSZ MGOCOL::GetJpath(PGLOBAL g, bool proj) ...@@ -419,6 +447,9 @@ PSZ MGOCOL::GetJpath(PGLOBAL g, bool proj)
} else } else
*p2++ = *p1; *p2++ = *p1;
if (*(p2 - 1) == '.')
p2--;
*p2 = 0; *p2 = 0;
return projpath; return projpath;
} else } else
......
/**************** tabcmg H Declares Source Code File (.H) **************/ /**************** tabcmg H Declares Source Code File (.H) **************/
/* Name: tabcmg.h Version 1.2 */ /* Name: tabcmg.h Version 1.3 */
/* */ /* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */ /* (C) Copyright to the author Olivier BERTRAND 2017 - 2021 */
/* */ /* */
/* This file contains the MongoDB classes declares. */ /* This file contains the MongoDB classes declares. */
/***********************************************************************/ /***********************************************************************/
...@@ -96,6 +96,7 @@ class DllExport MGOCOL : public EXTCOL { ...@@ -96,6 +96,7 @@ class DllExport MGOCOL : public EXTCOL {
// Implementation // Implementation
virtual int GetAmType(void) { return Tmgp->GetAmType(); } virtual int GetAmType(void) { return Tmgp->GetAmType(); }
virtual bool Stringify(void) { return Sgfy; }
// Methods // Methods
virtual PSZ GetJpath(PGLOBAL g, bool proj); virtual PSZ GetJpath(PGLOBAL g, bool proj);
...@@ -109,6 +110,7 @@ class DllExport MGOCOL : public EXTCOL { ...@@ -109,6 +110,7 @@ class DllExport MGOCOL : public EXTCOL {
// Members // Members
TDBCMG *Tmgp; // To the MGO table block TDBCMG *Tmgp; // To the MGO table block
char *Jpath; // The json path char *Jpath; // The json path
bool Sgfy; // True if stringified
}; // end of class MGOCOL }; // end of class MGOCOL
/***********************************************************************/ /***********************************************************************/
......
...@@ -384,7 +384,7 @@ int TDBJMG::WriteDB(PGLOBAL g) ...@@ -384,7 +384,7 @@ int TDBJMG::WriteDB(PGLOBAL g)
int rc = RC_OK; int rc = RC_OK;
if (Mode == MODE_INSERT) { if (Mode == MODE_INSERT) {
rc = Jcp->DocWrite(g); rc = Jcp->DocWrite(g, NULL);
} else if (Mode == MODE_DELETE) { } else if (Mode == MODE_DELETE) {
rc = Jcp->DocDelete(g, false); rc = Jcp->DocDelete(g, false);
} else if (Mode == MODE_UPDATE) { } else if (Mode == MODE_UPDATE) {
...@@ -420,8 +420,21 @@ JMGCOL::JMGCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i) ...@@ -420,8 +420,21 @@ JMGCOL::JMGCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
: EXTCOL(cdp, tdbp, cprec, i, "MGO") : EXTCOL(cdp, tdbp, cprec, i, "MGO")
{ {
Tmgp = (PTDBJMG)(tdbp->GetOrig() ? tdbp->GetOrig() : tdbp); Tmgp = (PTDBJMG)(tdbp->GetOrig() ? tdbp->GetOrig() : tdbp);
Jpath = cdp->GetFmt() ? cdp->GetFmt() : cdp->GetName(); Sgfy = false;
//Mbuf = NULL;
if ((Jpath = cdp->GetFmt())) {
int n = strlen(Jpath) - 1;
if (Jpath[n] == '*') {
Jpath = PlugDup(g, cdp->GetFmt());
if (Jpath[n - 1] == '.') n--;
Jpath[n] = 0;
Sgfy = true;
} // endif Jpath
} else
Jpath = cdp->GetName();
} // end of JMGCOL constructor } // end of JMGCOL constructor
/***********************************************************************/ /***********************************************************************/
...@@ -432,7 +445,7 @@ JMGCOL::JMGCOL(JMGCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp) ...@@ -432,7 +445,7 @@ JMGCOL::JMGCOL(JMGCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp)
{ {
Tmgp = col1->Tmgp; Tmgp = col1->Tmgp;
Jpath = col1->Jpath; Jpath = col1->Jpath;
//Mbuf = col1->Mbuf; Sgfy = col1->Sgfy;
} // end of JMGCOL copy constructor } // end of JMGCOL copy constructor
/***********************************************************************/ /***********************************************************************/
...@@ -442,7 +455,7 @@ PSZ JMGCOL::GetJpath(PGLOBAL g, bool proj) ...@@ -442,7 +455,7 @@ PSZ JMGCOL::GetJpath(PGLOBAL g, bool proj)
{ {
if (Jpath) { if (Jpath) {
if (proj) { if (proj) {
char *p1, *p2, *projpath = PlugDup(g, Jpath); char* p1, * p2, * projpath = PlugDup(g, Jpath);
int i = 0; int i = 0;
for (p1 = p2 = projpath; *p1; p1++) for (p1 = p2 = projpath; *p1; p1++)
...@@ -460,6 +473,9 @@ PSZ JMGCOL::GetJpath(PGLOBAL g, bool proj) ...@@ -460,6 +473,9 @@ PSZ JMGCOL::GetJpath(PGLOBAL g, bool proj)
} else } else
*p2++ = *p1; *p2++ = *p1;
if (*(p2 - 1) == '.')
p2--;
*p2 = 0; *p2 = 0;
return projpath; return projpath;
} else } else
......
/**************** tabjmg H Declares Source Code File (.H) **************/ /**************** tabjmg H Declares Source Code File (.H) **************/
/* Name: tabjmg.h Version 1.1 */ /* Name: tabjmg.h Version 1.2 */
/* */ /* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */ /* (C) Copyright to the author Olivier BERTRAND 2017 - 2021 */
/* */ /* */
/* This file contains the MongoDB classes using the Java Driver. */ /* This file contains the MongoDB classes using the Java Driver. */
/***********************************************************************/ /***********************************************************************/
...@@ -106,6 +106,7 @@ class DllExport JMGCOL : public EXTCOL { ...@@ -106,6 +106,7 @@ class DllExport JMGCOL : public EXTCOL {
// Implementation // Implementation
virtual int GetAmType(void) {return Tmgp->GetAmType();} virtual int GetAmType(void) {return Tmgp->GetAmType();}
virtual bool Stringify(void) { return Sgfy; }
// Methods // Methods
//virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check); //virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
...@@ -123,7 +124,7 @@ class DllExport JMGCOL : public EXTCOL { ...@@ -123,7 +124,7 @@ class DllExport JMGCOL : public EXTCOL {
// Members // Members
TDBJMG *Tmgp; // To the MGO table block TDBJMG *Tmgp; // To the MGO table block
char *Jpath; // The json path char *Jpath; // The json path
//char *Mbuf; // The Mini buffer bool Sgfy; // True if stringified
}; // end of class JMGCOL }; // end of class JMGCOL
/***********************************************************************/ /***********************************************************************/
......
...@@ -178,7 +178,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) ...@@ -178,7 +178,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
lvl = GetIntegerTableOption(g, topt, "Depth", lvl); lvl = GetIntegerTableOption(g, topt, "Depth", lvl);
sep = GetStringTableOption(g, topt, "Separator", "."); sep = GetStringTableOption(g, topt, "Separator", ".");
strfy = GetStringTableOption(g, topt, "Stringify", NULL); strfy = GetStringTableOption(g, topt, "Stringify", NULL);
sz = GetIntegerTableOption(g, topt, "Jsize", 250); sz = GetIntegerTableOption(g, topt, "Jsize", 1024);
limit = GetIntegerTableOption(g, topt, "Limit", 10); limit = GetIntegerTableOption(g, topt, "Limit", 10);
/*********************************************************************/ /*********************************************************************/
...@@ -647,7 +647,7 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -647,7 +647,7 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Collname = GetStringCatInfo(g, "Name", Collname = GetStringCatInfo(g, "Name",
(Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
Collname = GetStringCatInfo(g, "Tabname", Collname); Collname = GetStringCatInfo(g, "Tabname", Collname);
Options = GetStringCatInfo(g, "Colist", NULL); Options = GetStringCatInfo(g, "Colist", Xcol ? "all" : NULL);
Filter = GetStringCatInfo(g, "Filter", NULL); Filter = GetStringCatInfo(g, "Filter", NULL);
Pipe = GetBoolCatInfo("Pipeline", false); Pipe = GetBoolCatInfo("Pipeline", false);
Driver = GetStringCatInfo(g, "Driver", NULL); Driver = GetStringCatInfo(g, "Driver", NULL);
...@@ -716,6 +716,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m) ...@@ -716,6 +716,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
#endif // !MONGO_SUPPORT #endif // !MONGO_SUPPORT
} // endif Driver } // endif Driver
Pretty = 4; // Not a file
} else if (Zipped) { } else if (Zipped) {
#if defined(ZIP_SUPPORT) #if defined(ZIP_SUPPORT)
if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) { if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) {
...@@ -761,7 +762,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m) ...@@ -761,7 +762,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
G->jump_level = 0; G->jump_level = 0;
((TDBJSN*)tdbp)->G = G; ((TDBJSN*)tdbp)->G = G;
#endif // 0 #endif // 0
((TDBJSN*)tdbp)->G = PlugInit(NULL, (size_t)Lrecl * (Pretty >= 0 ? 10 : 2)); ((TDBJSN*)tdbp)->G = PlugInit(NULL, (size_t)Lrecl * (Pretty >= 0 ? 12 : 4));
} else { } else {
strcpy(g->Message, "LRECL is not defined"); strcpy(g->Message, "LRECL is not defined");
return NULL; return NULL;
...@@ -1277,6 +1278,7 @@ JSONCOL::JSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i) ...@@ -1277,6 +1278,7 @@ JSONCOL::JSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
Xpd = false; Xpd = false;
Parsed = false; Parsed = false;
Warned = false; Warned = false;
Sgfy = false;
} // end of JSONCOL constructor } // end of JSONCOL constructor
/***********************************************************************/ /***********************************************************************/
...@@ -1296,6 +1298,7 @@ JSONCOL::JSONCOL(JSONCOL *col1, PTDB tdbp) : DOSCOL(col1, tdbp) ...@@ -1296,6 +1298,7 @@ JSONCOL::JSONCOL(JSONCOL *col1, PTDB tdbp) : DOSCOL(col1, tdbp)
Xpd = col1->Xpd; Xpd = col1->Xpd;
Parsed = col1->Parsed; Parsed = col1->Parsed;
Warned = col1->Warned; Warned = col1->Warned;
Sgfy = col1->Sgfy;
} // end of JSONCOL copy constructor } // end of JSONCOL copy constructor
/***********************************************************************/ /***********************************************************************/
...@@ -1568,8 +1571,10 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj) ...@@ -1568,8 +1571,10 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj)
if (*p1 == '$') p1++; if (*p1 == '$') p1++;
if (*p1 == '.') p1++; if (*p1 == '.') p1++;
mgopath = PlugDup(g, p1); mgopath = PlugDup(g, p1);
} else } else {
Sgfy = true;
return NULL; return NULL;
} // endif
for (p1 = p2 = mgopath; *p1; p1++) for (p1 = p2 = mgopath; *p1; p1++)
if (i) { // Inside [] if (i) { // Inside []
...@@ -1607,6 +1612,7 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj) ...@@ -1607,6 +1612,7 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj)
case '*': case '*':
if (*(p2 - 1) == '.' && !*(p1 + 1)) { if (*(p2 - 1) == '.' && !*(p1 + 1)) {
p2--; // Suppress last :* p2--; // Suppress last :*
Sgfy = true;
break; break;
} // endif p2 } // endif p2
...@@ -1615,6 +1621,9 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj) ...@@ -1615,6 +1621,9 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj)
break; break;
} // endswitch p1; } // endswitch p1;
if (*(p2 - 1) == '.')
p2--;
*p2 = 0; *p2 = 0;
return mgopath; return mgopath;
} else } else
...@@ -2127,10 +2136,14 @@ void JSONCOL::WriteColumn(PGLOBAL g) ...@@ -2127,10 +2136,14 @@ void JSONCOL::WriteColumn(PGLOBAL g)
if (Nodes[Nod-1].Op == OP_XX) { if (Nodes[Nod-1].Op == OP_XX) {
s = Value->GetCharValue(); s = Value->GetCharValue();
if (!(jsp = ParseJson(G, s, strlen(s)))) { if (s && *s) {
strcpy(g->Message, s); if (!(jsp = ParseJson(G, s, strlen(s)))) {
throw 666; strcpy(g->Message, s);
} // endif jsp throw 666;
} // endif jsp
} else
jsp = NULL;
if (arp) { if (arp) {
if (Nod > 1 && Nodes[Nod-2].Op == OP_EQ) if (Nod > 1 && Nodes[Nod-2].Op == OP_EQ)
...@@ -2560,8 +2573,8 @@ int TDBJSON::WriteDB(PGLOBAL g) ...@@ -2560,8 +2573,8 @@ int TDBJSON::WriteDB(PGLOBAL g)
if (Mode == MODE_INSERT) { if (Mode == MODE_INSERT) {
Doc->AddArrayValue(g, vp); Doc->AddArrayValue(g, vp);
Row = new(g) JOBJECT; Row = new(g) JOBJECT;
} else if (Doc->SetArrayValue(g, vp, Fpos)) } else
return RC_FX; Doc->SetArrayValue(g, vp, Fpos);
} else if (Jmode == MODE_ARRAY) { } else if (Jmode == MODE_ARRAY) {
PJVAL vp = new(g) JVALUE(Row); PJVAL vp = new(g) JVALUE(Row);
...@@ -2569,15 +2582,15 @@ int TDBJSON::WriteDB(PGLOBAL g) ...@@ -2569,15 +2582,15 @@ int TDBJSON::WriteDB(PGLOBAL g)
if (Mode == MODE_INSERT) { if (Mode == MODE_INSERT) {
Doc->AddArrayValue(g, vp); Doc->AddArrayValue(g, vp);
Row = new(g) JARRAY; Row = new(g) JARRAY;
} else if (Doc->SetArrayValue(g, vp, Fpos)) } else
return RC_FX; Doc->SetArrayValue(g, vp, Fpos);
} else { // if (Jmode == MODE_VALUE) } else { // if (Jmode == MODE_VALUE)
if (Mode == MODE_INSERT) { if (Mode == MODE_INSERT) {
Doc->AddArrayValue(g, (PJVAL)Row); Doc->AddArrayValue(g, (PJVAL)Row);
Row = new(g) JVALUE; Row = new(g) JVALUE;
} else if (Doc->SetArrayValue(g, (PJVAL)Row, Fpos)) } else
return RC_FX; Doc->SetArrayValue(g, (PJVAL)Row, Fpos);
} // endif Jmode } // endif Jmode
......
...@@ -216,7 +216,8 @@ class DllExport JSONCOL : public DOSCOL { ...@@ -216,7 +216,8 @@ class DllExport JSONCOL : public DOSCOL {
JSONCOL(JSONCOL *colp, PTDB tdbp); // Constructor used in copy process JSONCOL(JSONCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation // Implementation
virtual int GetAmType(void) {return Tjp->GetAmType();} virtual int GetAmType(void) {return Tjp->GetAmType();}
virtual bool Stringify(void) { return Sgfy; }
// Methods // Methods
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check); virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
...@@ -251,6 +252,7 @@ class DllExport JSONCOL : public DOSCOL { ...@@ -251,6 +252,7 @@ class DllExport JSONCOL : public DOSCOL {
bool Xpd; // True for expandable column bool Xpd; // True for expandable column
bool Parsed; // True when parsed bool Parsed; // True when parsed
bool Warned; // True when warning issued bool Warned; // True when warning issued
bool Sgfy; // True if stringified
}; // end of class JSONCOL }; // end of class JSONCOL
/* -------------------------- TDBJSON class -------------------------- */ /* -------------------------- TDBJSON class -------------------------- */
......
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