mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
- 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
This commit is contained in:
@@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
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
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/************ CMgoConn C++ Functions Source Code File (.CPP) ***********/
|
/************ CMgoConn C++ Functions Source Code File (.CPP) ***********/
|
||||||
/* Name: CMgoConn.CPP Version 1.0 */
|
/* Name: CMgoConn.CPP Version 1.1 */
|
||||||
/* */
|
/* */
|
||||||
/* (C) Copyright to the author Olivier BERTRAND 2017 */
|
/* (C) Copyright to the author Olivier BERTRAND 2017 - 2021 */
|
||||||
/* */
|
/* */
|
||||||
/* This file contains the MongoDB C connection classes functions. */
|
/* This file contains the MongoDB C connection classes functions. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
bool CMgoConn::IsInit = false;
|
bool CMgoConn::IsInit = false;
|
||||||
|
|
||||||
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 INCOL --------------------------- */
|
/* --------------------------- Class INCOL --------------------------- */
|
||||||
@@ -47,12 +47,13 @@ void INCOL::AddCol(PGLOBAL g, PCOL colp, char *jp)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (!kp) {
|
if (!kp) {
|
||||||
icp = new(g) INCOL(IsNum(p));
|
icp = new(g) INCOL();
|
||||||
kcp = (PKC)PlugSubAlloc(g, NULL, sizeof(KEYCOL));
|
kcp = (PKC)PlugSubAlloc(g, NULL, sizeof(KEYCOL));
|
||||||
kcp->Next = NULL;
|
kcp->Next = NULL;
|
||||||
kcp->Incolp = icp;
|
kcp->Incolp = icp;
|
||||||
kcp->Colp = NULL;
|
kcp->Colp = NULL;
|
||||||
kcp->Key = PlugDup(g, jp);
|
kcp->Key = PlugDup(g, jp);
|
||||||
|
kcp->Array = IsArray(p);
|
||||||
|
|
||||||
if (Klist) {
|
if (Klist) {
|
||||||
for (kp = Klist; kp->Next; kp = kp->Next);
|
for (kp = Klist; kp->Next; kp = kp->Next);
|
||||||
@@ -73,6 +74,7 @@ void INCOL::AddCol(PGLOBAL g, PCOL colp, char *jp)
|
|||||||
kcp->Incolp = NULL;
|
kcp->Incolp = NULL;
|
||||||
kcp->Colp = colp;
|
kcp->Colp = colp;
|
||||||
kcp->Key = jp;
|
kcp->Key = jp;
|
||||||
|
kcp->Array = IsArray(jp);
|
||||||
|
|
||||||
if (Klist) {
|
if (Klist) {
|
||||||
for (kp = Klist; kp->Next; kp = kp->Next);
|
for (kp = Klist; kp->Next; kp = kp->Next);
|
||||||
@@ -168,10 +170,11 @@ bool CMgoConn::Connect(PGLOBAL g)
|
|||||||
mongo_init(true);
|
mongo_init(true);
|
||||||
#endif // !__WIN__
|
#endif // !__WIN__
|
||||||
|
|
||||||
Uri = mongoc_uri_new(Pcg->Uristr);
|
Uri = mongoc_uri_new_with_error(Pcg->Uristr, &Error);
|
||||||
|
|
||||||
if (!Uri) {
|
if (!Uri) {
|
||||||
sprintf(g->Message, "Failed to parse URI: \"%s\"", Pcg->Uristr);
|
sprintf(g->Message, "Failed to parse URI: \"%s\" Msg: %s",
|
||||||
|
Pcg->Uristr, Error.message);
|
||||||
return true;
|
return true;
|
||||||
} // endif Uri
|
} // endif Uri
|
||||||
|
|
||||||
@@ -228,8 +231,8 @@ bool CMgoConn::Connect(PGLOBAL g)
|
|||||||
int CMgoConn::CollSize(PGLOBAL g)
|
int CMgoConn::CollSize(PGLOBAL g)
|
||||||
{
|
{
|
||||||
int cnt;
|
int cnt;
|
||||||
bson_t *query;
|
bson_t* query;
|
||||||
const char *jf = NULL;
|
const char* jf = NULL;
|
||||||
|
|
||||||
if (Pcg->Pipe)
|
if (Pcg->Pipe)
|
||||||
return 10;
|
return 10;
|
||||||
@@ -237,7 +240,7 @@ int CMgoConn::CollSize(PGLOBAL g)
|
|||||||
jf = Pcg->Filter;
|
jf = Pcg->Filter;
|
||||||
|
|
||||||
if (jf) {
|
if (jf) {
|
||||||
query = bson_new_from_json((const uint8_t *)jf, -1, &Error);
|
query = bson_new_from_json((const uint8_t*)jf, -1, &Error);
|
||||||
|
|
||||||
if (!query) {
|
if (!query) {
|
||||||
htrc("Wrong filter: %s", Error.message);
|
htrc("Wrong filter: %s", Error.message);
|
||||||
@@ -247,8 +250,17 @@ int CMgoConn::CollSize(PGLOBAL g)
|
|||||||
} else
|
} else
|
||||||
query = bson_new();
|
query = bson_new();
|
||||||
|
|
||||||
|
#if defined(NDEBUG)
|
||||||
cnt = (int)mongoc_collection_count(Collection,
|
cnt = (int)mongoc_collection_count(Collection,
|
||||||
MONGOC_QUERY_NONE, query, 0, 0, NULL, &Error);
|
MONGOC_QUERY_NONE, query, 0, 0, NULL, &Error);
|
||||||
|
#else
|
||||||
|
if (jf)
|
||||||
|
cnt = (int)mongoc_collection_count_documents(Collection,
|
||||||
|
query, NULL, NULL, NULL, &Error);
|
||||||
|
else
|
||||||
|
cnt = (int)mongoc_collection_estimated_document_count(
|
||||||
|
Collection, NULL, NULL, NULL, &Error);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (cnt < 0) {
|
if (cnt < 0) {
|
||||||
htrc("Collection count: %s", Error.message);
|
htrc("Collection count: %s", Error.message);
|
||||||
@@ -260,30 +272,81 @@ int CMgoConn::CollSize(PGLOBAL g)
|
|||||||
} // end of CollSize
|
} // end of CollSize
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* OpenDB: Data Base open routine for MONGO access method. */
|
/* Project: make the projection avoid path collision. */
|
||||||
|
/***********************************************************************/
|
||||||
|
void CMgoConn::Project(PGLOBAL g, PSTRG s)
|
||||||
|
{
|
||||||
|
bool m, b = false;
|
||||||
|
size_t n;
|
||||||
|
PSZ path;
|
||||||
|
PCOL cp;
|
||||||
|
PTDB tp = Pcg->Tdbp;
|
||||||
|
PTHP hp, php = NULL, * nphp = &php;
|
||||||
|
|
||||||
|
for (cp = tp->GetColumns(); cp; cp = cp->GetNext()) {
|
||||||
|
path = cp->GetJpath(g, true);
|
||||||
|
|
||||||
|
for (hp = php; hp; hp = hp->Next) {
|
||||||
|
if (strlen(path) < strlen(hp->Path)) {
|
||||||
|
n = strlen(path);
|
||||||
|
m = true;
|
||||||
|
} else {
|
||||||
|
n = strlen(hp->Path);
|
||||||
|
m = false;
|
||||||
|
} // endif path
|
||||||
|
|
||||||
|
if (!strncmp(path, hp->Path, n))
|
||||||
|
break;
|
||||||
|
|
||||||
|
} // endfor hp
|
||||||
|
|
||||||
|
if (!hp) {
|
||||||
|
// New path
|
||||||
|
hp = (PTHP)PlugSubAlloc(g, NULL, sizeof(PTH));
|
||||||
|
hp->Path = path;
|
||||||
|
hp->Next = NULL;
|
||||||
|
*nphp = hp;
|
||||||
|
nphp = &hp->Next;
|
||||||
|
} else if (m) // Smaller path must replace longer one
|
||||||
|
hp->Path = path;
|
||||||
|
|
||||||
|
} // endfor cp
|
||||||
|
|
||||||
|
for (hp = php; hp; hp = hp->Next) {
|
||||||
|
if (b)
|
||||||
|
s->Append(",\"");
|
||||||
|
else
|
||||||
|
b = true;
|
||||||
|
|
||||||
|
s->Append(hp->Path);
|
||||||
|
s->Append("\":1");
|
||||||
|
} // endfor hp
|
||||||
|
|
||||||
|
} // end of Project
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* MakeCursor: make the cursor used to retrieve documents. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool CMgoConn::MakeCursor(PGLOBAL g)
|
bool CMgoConn::MakeCursor(PGLOBAL g)
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
bool id, b = false, all = false;
|
bool id, all = false;
|
||||||
PCSZ options = Pcg->Options;
|
PCSZ options = Pcg->Options;
|
||||||
PTDB tp = Pcg->Tdbp;
|
PTDB tp = Pcg->Tdbp;
|
||||||
PCOL cp;
|
PCOL cp;
|
||||||
PSTRG s = NULL;
|
PSTRG s = NULL;
|
||||||
PFIL filp = tp->GetFilter();
|
PFIL filp = tp->GetFilter();
|
||||||
|
|
||||||
id = (tp->GetMode() != MODE_READ);
|
id = (tp->GetMode() == MODE_UPDATE || tp->GetMode() == MODE_DELETE);
|
||||||
|
|
||||||
if (options && !stricmp(options, "all")) {
|
if (options && !stricmp(options, "all")) {
|
||||||
options = NULL;
|
options = NULL;
|
||||||
all = true;
|
all = true;
|
||||||
} // endif Options
|
} else for (cp = tp->GetColumns(); cp && !all; cp = cp->GetNext())
|
||||||
|
if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*") && !options)
|
||||||
for (cp = tp->GetColumns(); cp; cp = cp->GetNext())
|
|
||||||
if (!strcmp(cp->GetName(), "_id"))
|
|
||||||
id = true;
|
|
||||||
else if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*") && !options)
|
|
||||||
all = true;
|
all = true;
|
||||||
|
else if (!id)
|
||||||
|
id = !strcmp(cp->GetFmt() ? cp->GetFmt() : cp->GetName(), "_id");
|
||||||
|
|
||||||
if (Pcg->Pipe) {
|
if (Pcg->Pipe) {
|
||||||
if (trace(1))
|
if (trace(1))
|
||||||
@@ -311,23 +374,14 @@ bool CMgoConn::MakeCursor(PGLOBAL g)
|
|||||||
tp->SetFilter(NULL); // Not needed anymore
|
tp->SetFilter(NULL); // Not needed anymore
|
||||||
} // endif To_Filter
|
} // endif To_Filter
|
||||||
|
|
||||||
if (!all && tp->GetColumns()) {
|
if (tp->GetColumns() && !strstr(s->GetStr(), "$project")) {
|
||||||
// Project list
|
// Project list
|
||||||
s->Append(",{\"$project\":{\"");
|
s->Append(",{\"$project\":{\"");
|
||||||
|
|
||||||
if (!id)
|
if (!id)
|
||||||
s->Append("_id\":0,\"");
|
s->Append("_id\":0,\"");
|
||||||
|
|
||||||
for (cp = tp->GetColumns(); cp; cp = cp->GetNext()) {
|
Project(g, s);
|
||||||
if (b)
|
|
||||||
s->Append(",\"");
|
|
||||||
else
|
|
||||||
b = true;
|
|
||||||
|
|
||||||
s->Append(cp->GetJpath(g, true));
|
|
||||||
s->Append("\":1");
|
|
||||||
} // endfor cp
|
|
||||||
|
|
||||||
s->Append("}}");
|
s->Append("}}");
|
||||||
} // endif all
|
} // endif all
|
||||||
|
|
||||||
@@ -377,7 +431,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g)
|
|||||||
|
|
||||||
if (MakeSelector(g, filp, s)) {
|
if (MakeSelector(g, filp, s)) {
|
||||||
strcpy(g->Message, "Failed making selector");
|
strcpy(g->Message, "Failed making selector");
|
||||||
return NULL;
|
return true;
|
||||||
} // endif Selector
|
} // endif Selector
|
||||||
|
|
||||||
tp->SetFilter(NULL); // Not needed anymore
|
tp->SetFilter(NULL); // Not needed anymore
|
||||||
@@ -391,7 +445,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g)
|
|||||||
|
|
||||||
if (!Query) {
|
if (!Query) {
|
||||||
sprintf(g->Message, "Wrong filter: %s", Error.message);
|
sprintf(g->Message, "Wrong filter: %s", Error.message);
|
||||||
return NULL;
|
return true;
|
||||||
} // endif Query
|
} // endif Query
|
||||||
|
|
||||||
} else
|
} else
|
||||||
@@ -413,16 +467,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g)
|
|||||||
if (!id)
|
if (!id)
|
||||||
s->Append("_id\":0,\"");
|
s->Append("_id\":0,\"");
|
||||||
|
|
||||||
for (cp = tp->GetColumns(); cp; cp = cp->GetNext()) {
|
Project(g, s);
|
||||||
if (b)
|
|
||||||
s->Append(",\"");
|
|
||||||
else
|
|
||||||
b = true;
|
|
||||||
|
|
||||||
s->Append(cp->GetJpath(g, true));
|
|
||||||
s->Append("\":1");
|
|
||||||
} // endfor cp
|
|
||||||
|
|
||||||
s->Append("}}");
|
s->Append("}}");
|
||||||
s->Resize(s->GetLength() + 1);
|
s->Resize(s->GetLength() + 1);
|
||||||
p = s->GetStr();
|
p = s->GetStr();
|
||||||
@@ -435,7 +480,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g)
|
|||||||
|
|
||||||
if (!Opts) {
|
if (!Opts) {
|
||||||
sprintf(g->Message, "Wrong options: %s", Error.message);
|
sprintf(g->Message, "Wrong options: %s", Error.message);
|
||||||
return NULL;
|
return true;
|
||||||
} // endif Opts
|
} // endif Opts
|
||||||
|
|
||||||
} // endif all
|
} // endif all
|
||||||
@@ -495,44 +540,54 @@ void CMgoConn::ShowDocument(bson_iter_t *iter, const bson_t *doc, const char *k)
|
|||||||
key = bson_iter_key(iter);
|
key = bson_iter_key(iter);
|
||||||
htrc("Found element key: \"%s\"\n", key);
|
htrc("Found element key: \"%s\"\n", key);
|
||||||
|
|
||||||
if (BSON_ITER_HOLDS_UTF8(iter))
|
switch (bson_iter_type(iter)) {
|
||||||
htrc("%s.%s=\"%s\"\n", k, key, bson_iter_utf8(iter, NULL));
|
case BSON_TYPE_UTF8:
|
||||||
else if (BSON_ITER_HOLDS_INT32(iter))
|
htrc("%s.%s=\"%s\"\n", k, key, bson_iter_utf8(iter, NULL));
|
||||||
htrc("%s.%s=%d\n", k, key, bson_iter_int32(iter));
|
break;
|
||||||
else if (BSON_ITER_HOLDS_INT64(iter))
|
case BSON_TYPE_INT32:
|
||||||
htrc("%s.%s=%lld\n", k, key, bson_iter_int64(iter));
|
htrc("%s.%s=%d\n", k, key, bson_iter_int32(iter));
|
||||||
else if (BSON_ITER_HOLDS_DOUBLE(iter))
|
break;
|
||||||
htrc("%s.%s=%g\n", k, key, bson_iter_double(iter));
|
case BSON_TYPE_INT64:
|
||||||
else if (BSON_ITER_HOLDS_DATE_TIME(iter))
|
htrc("%s.%s=%lld\n", k, key, bson_iter_int64(iter));
|
||||||
htrc("%s.%s=date(%lld)\n", k, key, bson_iter_date_time(iter));
|
break;
|
||||||
else if (BSON_ITER_HOLDS_OID(iter)) {
|
case BSON_TYPE_DOUBLE:
|
||||||
char str[25];
|
htrc("%s.%s=%g\n", k, key, bson_iter_double(iter));
|
||||||
|
break;
|
||||||
|
case BSON_TYPE_DATE_TIME:
|
||||||
|
htrc("%s.%s=date(%lld)\n", k, key, bson_iter_date_time(iter));
|
||||||
|
break;
|
||||||
|
case BSON_TYPE_OID: {
|
||||||
|
char str[25];
|
||||||
|
|
||||||
bson_oid_to_string(bson_iter_oid(iter), str);
|
bson_oid_to_string(bson_iter_oid(iter), str);
|
||||||
htrc("%s.%s=%s\n", k, key, str);
|
htrc("%s.%s=%s\n", k, key, str);
|
||||||
} else if (BSON_ITER_HOLDS_DECIMAL128(iter)) {
|
} break;
|
||||||
char *str = NULL;
|
case BSON_TYPE_DECIMAL128: {
|
||||||
bson_decimal128_t dec;
|
char* str = NULL;
|
||||||
|
bson_decimal128_t dec;
|
||||||
|
|
||||||
bson_iter_decimal128(iter, &dec);
|
bson_iter_decimal128(iter, &dec);
|
||||||
bson_decimal128_to_string(&dec, str);
|
bson_decimal128_to_string(&dec, str);
|
||||||
htrc("%s.%s=%s\n", k, key, str);
|
htrc("%s.%s=%s\n", k, key, str);
|
||||||
} else if (BSON_ITER_HOLDS_DOCUMENT(iter)) {
|
} break;
|
||||||
bson_iter_t child;
|
case BSON_TYPE_DOCUMENT: {
|
||||||
|
bson_iter_t child;
|
||||||
|
|
||||||
if (bson_iter_recurse(iter, &child))
|
if (bson_iter_recurse(iter, &child))
|
||||||
ShowDocument(&child, NULL, key);
|
ShowDocument(&child, NULL, key);
|
||||||
|
|
||||||
} else if (BSON_ITER_HOLDS_ARRAY(iter)) {
|
} break;
|
||||||
bson_t *arr;
|
case BSON_TYPE_ARRAY: {
|
||||||
bson_iter_t itar;
|
bson_t* arr;
|
||||||
const uint8_t *data = NULL;
|
bson_iter_t itar;
|
||||||
uint32_t len = 0;
|
const uint8_t* data = NULL;
|
||||||
|
uint32_t len = 0;
|
||||||
|
|
||||||
bson_iter_array(iter, &len, &data);
|
bson_iter_array(iter, &len, &data);
|
||||||
arr = bson_new_from_data(data, len);
|
arr = bson_new_from_data(data, len);
|
||||||
ShowDocument(&itar, arr, key);
|
ShowDocument(&itar, arr, key);
|
||||||
} // endif's
|
} break;
|
||||||
|
} // endswitch iter
|
||||||
|
|
||||||
} // endwhile bson_iter_next
|
} // endwhile bson_iter_next
|
||||||
|
|
||||||
@@ -545,7 +600,7 @@ void CMgoConn::ShowDocument(bson_iter_t *iter, const bson_t *doc, const char *k)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void CMgoConn::MakeColumnGroups(PGLOBAL g)
|
void CMgoConn::MakeColumnGroups(PGLOBAL g)
|
||||||
{
|
{
|
||||||
Fpc = new(g) INCOL(false);
|
Fpc = new(g) INCOL();
|
||||||
|
|
||||||
for (PCOL colp = Pcg->Tdbp->GetColumns(); colp; colp = colp->GetNext())
|
for (PCOL colp = Pcg->Tdbp->GetColumns(); colp; colp = colp->GetNext())
|
||||||
if (!colp->IsSpecial())
|
if (!colp->IsSpecial())
|
||||||
@@ -560,7 +615,7 @@ bool CMgoConn::DocWrite(PGLOBAL g, PINCOL icp)
|
|||||||
{
|
{
|
||||||
for (PKC kp = icp->Klist; kp; kp = kp->Next)
|
for (PKC kp = icp->Klist; kp; kp = kp->Next)
|
||||||
if (kp->Incolp) {
|
if (kp->Incolp) {
|
||||||
bool isdoc = !kp->Incolp->Array;
|
bool isdoc = !kp->Array;
|
||||||
|
|
||||||
if (isdoc)
|
if (isdoc)
|
||||||
BSON_APPEND_DOCUMENT_BEGIN(icp->Child, kp->Key, kp->Incolp->Child);
|
BSON_APPEND_DOCUMENT_BEGIN(icp->Child, kp->Key, kp->Incolp->Child);
|
||||||
@@ -582,7 +637,7 @@ bool CMgoConn::DocWrite(PGLOBAL g, PINCOL icp)
|
|||||||
} // end of DocWrite
|
} // end of DocWrite
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* WriteDB: Data Base write routine for DOS access method. */
|
/* WriteDB: Data Base write routine for CMGO access method. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int CMgoConn::Write(PGLOBAL g)
|
int CMgoConn::Write(PGLOBAL g)
|
||||||
{
|
{
|
||||||
@@ -590,22 +645,45 @@ int CMgoConn::Write(PGLOBAL g)
|
|||||||
PTDB tp = Pcg->Tdbp;
|
PTDB tp = Pcg->Tdbp;
|
||||||
|
|
||||||
if (tp->GetMode() == MODE_INSERT) {
|
if (tp->GetMode() == MODE_INSERT) {
|
||||||
Fpc->Init();
|
if (!Pcg->Line) {
|
||||||
|
Fpc->Init();
|
||||||
|
|
||||||
if (DocWrite(g, Fpc))
|
if (DocWrite(g, Fpc))
|
||||||
return RC_FX;
|
return RC_FX;
|
||||||
|
|
||||||
if (trace(2)) {
|
if (trace(2)) {
|
||||||
char *str = bson_as_json(Fpc->Child, NULL);
|
char* str = bson_as_json(Fpc->Child, NULL);
|
||||||
htrc("Inserting: %s\n", str);
|
htrc("Inserting: %s\n", str);
|
||||||
bson_free(str);
|
bson_free(str);
|
||||||
} // endif trace
|
} // endif trace
|
||||||
|
|
||||||
if (!mongoc_collection_insert(Collection, MONGOC_INSERT_NONE,
|
if (!mongoc_collection_insert(Collection, MONGOC_INSERT_NONE,
|
||||||
Fpc->Child, NULL, &Error)) {
|
Fpc->Child, NULL, &Error)) {
|
||||||
sprintf(g->Message, "Mongo insert: %s", Error.message);
|
sprintf(g->Message, "Mongo insert: %s", Error.message);
|
||||||
rc = RC_FX;
|
rc = RC_FX;
|
||||||
} // endif insert
|
} // endif insert
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const uint8_t* val = (const uint8_t*)Pcg->Line;
|
||||||
|
bson_t* doc = bson_new_from_json(val, -1, &Error);
|
||||||
|
|
||||||
|
if (doc && trace(2)) {
|
||||||
|
char* str = bson_as_json(doc, NULL);
|
||||||
|
htrc("Inserting: %s\n", str);
|
||||||
|
bson_free(str);
|
||||||
|
} // endif trace
|
||||||
|
|
||||||
|
if (!doc) {
|
||||||
|
sprintf(g->Message, "bson_new_from_json: %s", Error.message);
|
||||||
|
rc = RC_FX;
|
||||||
|
} else if (!mongoc_collection_insert(Collection,
|
||||||
|
MONGOC_INSERT_NONE, doc, NULL, &Error)) {
|
||||||
|
sprintf(g->Message, "Mongo insert: %s", Error.message);
|
||||||
|
bson_destroy(doc);
|
||||||
|
rc = RC_FX;
|
||||||
|
} // endif insert
|
||||||
|
|
||||||
|
} // endif Line
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
bool b = false;
|
bool b = false;
|
||||||
@@ -614,19 +692,26 @@ int CMgoConn::Write(PGLOBAL g)
|
|||||||
|
|
||||||
bson_iter_init(&iter, Document);
|
bson_iter_init(&iter, Document);
|
||||||
|
|
||||||
if (bson_iter_find(&iter, "_id")) {
|
if (bson_iter_find(&iter, "_id"))
|
||||||
if (BSON_ITER_HOLDS_OID(&iter))
|
switch (bson_iter_type(&iter)) {
|
||||||
b = BSON_APPEND_OID(query, "_id", bson_iter_oid(&iter));
|
case BSON_TYPE_OID:
|
||||||
else if (BSON_ITER_HOLDS_INT32(&iter))
|
b = BSON_APPEND_OID(query, "_id", bson_iter_oid(&iter));
|
||||||
b = BSON_APPEND_INT32(query, "_id", bson_iter_int32(&iter));
|
break;
|
||||||
else if (BSON_ITER_HOLDS_INT64(&iter))
|
case BSON_TYPE_UTF8:
|
||||||
b = BSON_APPEND_INT64(query, "_id", bson_iter_int64(&iter));
|
b = BSON_APPEND_UTF8(query, "_id", bson_iter_utf8(&iter, NULL));
|
||||||
else if (BSON_ITER_HOLDS_DOUBLE(&iter))
|
break;
|
||||||
b = BSON_APPEND_DOUBLE(query, "_id", bson_iter_double(&iter));
|
case BSON_TYPE_INT32:
|
||||||
else if (BSON_ITER_HOLDS_UTF8(&iter))
|
b = BSON_APPEND_INT32(query, "_id", bson_iter_int32(&iter));
|
||||||
b = BSON_APPEND_UTF8(query, "_id", bson_iter_utf8(&iter, NULL));
|
break;
|
||||||
|
case BSON_TYPE_INT64:
|
||||||
} // endif iter
|
b = BSON_APPEND_INT64(query, "_id", bson_iter_int64(&iter));
|
||||||
|
break;
|
||||||
|
case BSON_TYPE_DOUBLE:
|
||||||
|
b = BSON_APPEND_DOUBLE(query, "_id", bson_iter_double(&iter));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
} // endswitch iter
|
||||||
|
|
||||||
if (b) {
|
if (b) {
|
||||||
if (trace(2)) {
|
if (trace(2)) {
|
||||||
@@ -721,7 +806,7 @@ void CMgoConn::Close(void)
|
|||||||
char *CMgoConn::Mini(PGLOBAL g, PCOL colp, const bson_t *bson, bool b)
|
char *CMgoConn::Mini(PGLOBAL g, PCOL colp, const bson_t *bson, bool b)
|
||||||
{
|
{
|
||||||
char *s, *str = NULL;
|
char *s, *str = NULL;
|
||||||
char *Mbuf = (char*)PlugSubAlloc(g, NULL, colp->GetLength() + 1);
|
char *Mbuf = (char*)PlugSubAlloc(g, NULL, (size_t)colp->GetLength() + 1);
|
||||||
int i, k = 0;
|
int i, k = 0;
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
@@ -759,97 +844,100 @@ char *CMgoConn::Mini(PGLOBAL g, PCOL colp, const bson_t *bson, bool b)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void CMgoConn::GetColumnValue(PGLOBAL g, PCOL colp)
|
void CMgoConn::GetColumnValue(PGLOBAL g, PCOL colp)
|
||||||
{
|
{
|
||||||
char *jpath = colp->GetJpath(g, false);
|
char *jpath = colp->GetJpath(g, false);
|
||||||
PVAL value = colp->GetValue();
|
bool b = false;
|
||||||
|
PVAL value = colp->GetValue();
|
||||||
|
bson_iter_t Iter; // Used to retrieve column value
|
||||||
|
bson_iter_t Desc; // Descendant iter
|
||||||
|
|
||||||
if (!strcmp(jpath, "*")) {
|
if (!*jpath || !strcmp(jpath, "*")) {
|
||||||
value->SetValue_psz(Mini(g, colp, Document, false));
|
value->SetValue_psz(Mini(g, colp, Document, false));
|
||||||
} else if (bson_iter_init(&Iter, Document) &&
|
} else if (bson_iter_init(&Iter, Document) &&
|
||||||
bson_iter_find_descendant(&Iter, jpath, &Desc)) {
|
bson_iter_find_descendant(&Iter, jpath, &Desc)) {
|
||||||
if (BSON_ITER_HOLDS_UTF8(&Desc))
|
switch (bson_iter_type(&Desc)) {
|
||||||
value->SetValue_psz((PSZ)bson_iter_utf8(&Desc, NULL));
|
case BSON_TYPE_UTF8:
|
||||||
else if (BSON_ITER_HOLDS_INT32(&Desc))
|
value->SetValue_psz((PSZ)bson_iter_utf8(&Desc, NULL));
|
||||||
value->SetValue(bson_iter_int32(&Desc));
|
break;
|
||||||
else if (BSON_ITER_HOLDS_INT64(&Desc))
|
case BSON_TYPE_INT32:
|
||||||
value->SetValue(bson_iter_int64(&Desc));
|
value->SetValue(bson_iter_int32(&Desc));
|
||||||
else if (BSON_ITER_HOLDS_DOUBLE(&Desc))
|
break;
|
||||||
value->SetValue(bson_iter_double(&Desc));
|
case BSON_TYPE_INT64:
|
||||||
else if (BSON_ITER_HOLDS_DATE_TIME(&Desc))
|
value->SetValue(bson_iter_int64(&Desc));
|
||||||
value->SetValue(bson_iter_date_time(&Desc) / 1000);
|
break;
|
||||||
else if (BSON_ITER_HOLDS_BOOL(&Desc)) {
|
case BSON_TYPE_DOUBLE:
|
||||||
bool b = bson_iter_bool(&Desc);
|
value->SetValue(bson_iter_double(&Desc));
|
||||||
|
break;
|
||||||
|
case BSON_TYPE_DATE_TIME:
|
||||||
|
value->SetValue(bson_iter_date_time(&Desc) / 1000);
|
||||||
|
break;
|
||||||
|
case BSON_TYPE_BOOL:
|
||||||
|
b = bson_iter_bool(&Desc);
|
||||||
|
|
||||||
if (value->IsTypeNum())
|
if (value->IsTypeNum())
|
||||||
value->SetValue(b ? 1 : 0);
|
value->SetValue(b ? 1 : 0);
|
||||||
else
|
else
|
||||||
value->SetValue_psz(b ? "true" : "false");
|
value->SetValue_psz(b ? "true" : "false");
|
||||||
|
|
||||||
} else if (BSON_ITER_HOLDS_OID(&Desc)) {
|
break;
|
||||||
char str[25];
|
case BSON_TYPE_OID: {
|
||||||
|
char str[25];
|
||||||
|
|
||||||
bson_oid_to_string(bson_iter_oid(&Desc), str);
|
bson_oid_to_string(bson_iter_oid(&Desc), str);
|
||||||
value->SetValue_psz(str);
|
value->SetValue_psz(str);
|
||||||
} else if (BSON_ITER_HOLDS_NULL(&Iter)) {
|
} break;
|
||||||
// Apparently this does not work...
|
case BSON_TYPE_ARRAY:
|
||||||
value->Reset();
|
b = true;
|
||||||
value->SetNull(true);
|
// passthru
|
||||||
} else if (BSON_ITER_HOLDS_DECIMAL128(&Desc)) {
|
case BSON_TYPE_DOCUMENT:
|
||||||
char *str = NULL;
|
{ // All this because MongoDB can return the wrong type
|
||||||
bson_decimal128_t dec;
|
int i = 0;
|
||||||
|
const uint8_t *data = NULL;
|
||||||
|
uint32_t len = 0;
|
||||||
|
|
||||||
bson_iter_decimal128(&Desc, &dec);
|
for (; i < 2; i++) {
|
||||||
bson_decimal128_to_string(&dec, str);
|
if (b) // Try array first
|
||||||
value->SetValue_psz(str);
|
bson_iter_array(&Desc, &len, &data);
|
||||||
bson_free(str);
|
else
|
||||||
} else if (BSON_ITER_HOLDS_DOCUMENT(&Iter)) {
|
bson_iter_document(&Desc, &len, &data);
|
||||||
bson_t *doc;
|
|
||||||
const uint8_t *data = NULL;
|
|
||||||
uint32_t len = 0;
|
|
||||||
|
|
||||||
bson_iter_document(&Desc, &len, &data);
|
if (!data) {
|
||||||
|
len = 0;
|
||||||
|
b = !b;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
|
||||||
if (data) {
|
} // endfor i
|
||||||
doc = bson_new_from_data(data, len);
|
|
||||||
value->SetValue_psz(Mini(g, colp, doc, false));
|
|
||||||
bson_destroy(doc);
|
|
||||||
} else {
|
|
||||||
// ... but we can come here in case of NULL!
|
|
||||||
value->Reset();
|
|
||||||
value->SetNull(true);
|
|
||||||
} // endif data
|
|
||||||
|
|
||||||
} else if (BSON_ITER_HOLDS_ARRAY(&Iter)) {
|
|
||||||
bson_t *arr;
|
|
||||||
const uint8_t *data = NULL;
|
|
||||||
uint32_t len = 0;
|
|
||||||
|
|
||||||
bson_iter_array(&Desc, &len, &data);
|
|
||||||
|
|
||||||
if (data) {
|
|
||||||
arr = bson_new_from_data(data, len);
|
|
||||||
value->SetValue_psz(Mini(g, colp, arr, true));
|
|
||||||
bson_destroy(arr);
|
|
||||||
} else {
|
|
||||||
// This is a bug in returning the wrong type
|
|
||||||
// This fix is only for document items
|
|
||||||
bson_t *doc;
|
|
||||||
|
|
||||||
bson_iter_document(&Desc, &len, &data);
|
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
doc = bson_new_from_data(data, len);
|
bson_t *doc = bson_new_from_data(data, len);
|
||||||
value->SetValue_psz(Mini(g, colp, doc, false));
|
|
||||||
|
value->SetValue_psz(Mini(g, colp, doc, b));
|
||||||
bson_destroy(doc);
|
bson_destroy(doc);
|
||||||
} else {
|
} else {
|
||||||
// ... or we can also come here in case of NULL!
|
// ... or we can also come here in case of NULL!
|
||||||
value->Reset();
|
value->Reset();
|
||||||
value->SetNull(true);
|
value->SetNull(true);
|
||||||
} // endif data
|
} // endif data
|
||||||
|
|
||||||
} // endif data
|
} break;
|
||||||
|
case BSON_TYPE_NULL:
|
||||||
|
// Apparently this does not work...
|
||||||
|
value->Reset();
|
||||||
|
value->SetNull(true);
|
||||||
|
break;
|
||||||
|
case BSON_TYPE_DECIMAL128: {
|
||||||
|
char* str = NULL;
|
||||||
|
bson_decimal128_t dec;
|
||||||
|
|
||||||
} else
|
bson_iter_decimal128(&Desc, &dec);
|
||||||
value->Reset();
|
bson_decimal128_to_string(&dec, str);
|
||||||
|
value->SetValue_psz(str);
|
||||||
|
bson_free(str);
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
value->Reset();
|
||||||
|
break;
|
||||||
|
} // endswitch Desc
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Field does not exist
|
// Field does not exist
|
||||||
@@ -875,7 +963,28 @@ bool CMgoConn::AddValue(PGLOBAL g, PCOL colp, bson_t *doc, char *key, bool upd)
|
|||||||
|
|
||||||
} else switch (colp->GetResultType()) {
|
} else switch (colp->GetResultType()) {
|
||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
rc = BSON_APPEND_UTF8(doc, key, value->GetCharValue());
|
if (colp->Stringify()) {
|
||||||
|
const uint8_t *val = (const uint8_t*)value->GetCharValue();
|
||||||
|
bson_t *bsn = bson_new_from_json(val, -1, &Error);
|
||||||
|
|
||||||
|
if (!bsn) {
|
||||||
|
sprintf (g->Message, "AddValue: %s", Error.message);
|
||||||
|
return true;
|
||||||
|
} else if (*key) {
|
||||||
|
if (*val == '[')
|
||||||
|
rc = BSON_APPEND_ARRAY(doc, key, bsn);
|
||||||
|
else
|
||||||
|
rc = BSON_APPEND_DOCUMENT(doc, key, bsn);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
bson_copy_to (bsn, doc);
|
||||||
|
rc = true;
|
||||||
|
} // endif's
|
||||||
|
|
||||||
|
bson_free(bsn);
|
||||||
|
} else
|
||||||
|
rc = BSON_APPEND_UTF8(doc, key, value->GetCharValue());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_INT:
|
case TYPE_INT:
|
||||||
case TYPE_SHORT:
|
case TYPE_SHORT:
|
||||||
|
@@ -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 {
|
|||||||
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 @@ public:
|
|||||||
//Members
|
//Members
|
||||||
bson_t *Child;
|
bson_t *Child;
|
||||||
PKC Klist;
|
PKC Klist;
|
||||||
bool Array;
|
|
||||||
}; // end of INCOL;
|
}; // end of INCOL;
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -80,6 +84,7 @@ public:
|
|||||||
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 @@ protected:
|
|||||||
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 {
|
|||||||
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,
|
|||||||
} // 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("'");
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
/************ 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)
|
|||||||
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)
|
|||||||
} // 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) {
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/************ 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 @@
|
|||||||
|
|
||||||
#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)
|
|||||||
*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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
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)
|
|||||||
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)
|
|||||||
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 )
|
|||||||
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)
|
|||||||
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 (!Fpc || !(doc = MakeDoc(g, Fpc)))
|
if (line) {
|
||||||
|
int j;
|
||||||
|
jobject val = env->NewStringUTF(line);
|
||||||
|
|
||||||
|
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)
|
|||||||
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)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
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)
|
|||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
return RC_FX;
|
return RC_FX;
|
||||||
|
else if (Stringify(colp))
|
||||||
|
switch (*colp->GetCharValue()) {
|
||||||
|
case '{': j = 1; break;
|
||||||
|
case '[': j = 2; break;
|
||||||
|
default: break;
|
||||||
|
} // endswitch
|
||||||
|
|
||||||
if (env->CallBooleanMethod(job, docaddid, updlist, jkey, val))
|
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)
|
|||||||
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 {
|
|||||||
PCOL Colp;
|
PCOL Colp;
|
||||||
char *Key;
|
char *Key;
|
||||||
int N;
|
int N;
|
||||||
|
bool Array;
|
||||||
} *PJKC;
|
} *PJKC;
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -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 @@ public:
|
|||||||
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 @@ protected:
|
|||||||
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)
|
|||||||
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)
|
|||||||
} // 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)
|
|||||||
|
|
||||||
*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)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
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()
|
|||||||
} 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 {
|
|||||||
|
|
||||||
// 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
|
|||||||
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
|
|||||||
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;
|
|||||||
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;
|
|||||||
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;
|
|||||||
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;
|
|||||||
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;
|
|||||||
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;
|
|||||||
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'
|
||||||
|
Binary file not shown.
Binary file not shown.
@@ -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)
|
|||||||
|
|
||||||
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)
|
|||||||
#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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
break;
|
break;
|
||||||
} // endswitch p1;
|
} // endswitch p1;
|
||||||
|
|
||||||
|
if (*(p2 - 1) == '.')
|
||||||
|
p2--;
|
||||||
|
|
||||||
*p2 = 0;
|
*p2 = 0;
|
||||||
return mgopath;
|
return mgopath;
|
||||||
} else
|
} else
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*************** 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 @@ public:
|
|||||||
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 @@ protected:
|
|||||||
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 -------------------------- */
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/************** 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,
|
|||||||
|
|
||||||
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;
|
||||||
|
bcol.Len = 11; // bson_iter_int32(iter)
|
||||||
|
break;
|
||||||
|
case BSON_TYPE_INT64:
|
||||||
|
bcol.Type = TYPE_BIGINT;
|
||||||
|
bcol.Len = 22; // bson_iter_int64(iter)
|
||||||
|
break;
|
||||||
|
case BSON_TYPE_DOUBLE:
|
||||||
|
bcol.Type = TYPE_DOUBLE;
|
||||||
|
bcol.Len = 12;
|
||||||
|
bcol.Scale = 6; // bson_iter_double(iter)
|
||||||
|
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.Len = 24; // bson_iter_oid(iter)
|
||||||
|
break;
|
||||||
|
case BSON_TYPE_DECIMAL128:
|
||||||
|
bcol.Type = TYPE_DECIM;
|
||||||
|
bcol.Len = 32; // bson_iter_decimal128(iter, &dec)
|
||||||
|
break;
|
||||||
|
case BSON_TYPE_DOCUMENT:
|
||||||
|
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 (bson_iter_recurse(iter, &child))
|
||||||
if (FindInDoc(g, &child, NULL, colname, fmt, k + 1, false))
|
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;
|
return true;
|
||||||
|
|
||||||
newcol = false;
|
newcol = false;
|
||||||
} // endif lvl
|
} // endif lvl
|
||||||
|
|
||||||
} else if (BSON_ITER_HOLDS_ARRAY(iter)) {
|
break;
|
||||||
if (lvl < 0)
|
} // endswitch iter
|
||||||
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;
|
|
||||||
} // endif lvl
|
|
||||||
|
|
||||||
} // endif's
|
|
||||||
|
|
||||||
if (newcol)
|
if (newcol)
|
||||||
AddColumn(g, colname, fmt, k);
|
AddColumn(g, colname, fmt, k);
|
||||||
@@ -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)
|
|||||||
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)
|
|||||||
: 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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
} else
|
} else
|
||||||
*p2++ = *p1;
|
*p2++ = *p1;
|
||||||
|
|
||||||
|
if (*(p2 - 1) == '.')
|
||||||
|
p2--;
|
||||||
|
|
||||||
*p2 = 0;
|
*p2 = 0;
|
||||||
return projpath;
|
return projpath;
|
||||||
} else
|
} else
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/**************** 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 @@ public:
|
|||||||
|
|
||||||
// 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 @@ protected:
|
|||||||
// 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)
|
|||||||
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)
|
|||||||
: 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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
} else
|
} else
|
||||||
*p2++ = *p1;
|
*p2++ = *p1;
|
||||||
|
|
||||||
|
if (*(p2 - 1) == '.')
|
||||||
|
p2--;
|
||||||
|
|
||||||
*p2 = 0;
|
*p2 = 0;
|
||||||
return projpath;
|
return projpath;
|
||||||
} else
|
} else
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/**************** 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 @@ public:
|
|||||||
|
|
||||||
// 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 @@ protected:
|
|||||||
// 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
#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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
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 -------------------------- */
|
||||||
|
Reference in New Issue
Block a user