Commit 950bf6ab authored by Olivier Bertrand's avatar Olivier Bertrand

- Begin implementation of BSON

  modified:   storage/connect/bson.cpp
  modified:   storage/connect/bson.h
  modified:   storage/connect/bsonudf.cpp
  modified:   storage/connect/bsonudf.h
  modified:   storage/connect/jsonudf.cpp
parent b656d3d3
...@@ -653,7 +653,7 @@ PSZ BDOC::Serialize(PGLOBAL g, PBVAL bvp, char* fn, int pretty) { ...@@ -653,7 +653,7 @@ PSZ BDOC::Serialize(PGLOBAL g, PBVAL bvp, char* fn, int pretty) {
err = SerializeValue(MVP(bvp->To_Val)); err = SerializeValue(MVP(bvp->To_Val));
break; break;
default: default:
strcpy(g->Message, "Invalid json tree"); err = SerializeValue(bvp);
} // endswitch Type } // endswitch Type
if (fs) { if (fs) {
...@@ -760,7 +760,7 @@ bool BDOC::SerializeObject(OFFSET obp) { ...@@ -760,7 +760,7 @@ bool BDOC::SerializeObject(OFFSET obp) {
bool BDOC::SerializeValue(PBVAL jvp) { bool BDOC::SerializeValue(PBVAL jvp) {
char buf[64]; char buf[64];
switch (jvp->Type) { if (jvp) switch (jvp->Type) {
case TYPE_JAR: case TYPE_JAR:
return SerializeArray(jvp->To_Val, false); return SerializeArray(jvp->To_Val, false);
case TYPE_JOB: case TYPE_JOB:
...@@ -788,8 +788,7 @@ bool BDOC::SerializeValue(PBVAL jvp) { ...@@ -788,8 +788,7 @@ bool BDOC::SerializeValue(PBVAL jvp) {
return jp->WriteStr("???"); // TODO return jp->WriteStr("???"); // TODO
} // endswitch Type } // endswitch Type
strcpy(jp->g->Message, "Unrecognized value"); return jp->WriteStr("null");
return true;
} // end of SerializeValue } // end of SerializeValue
/* --------------------------- Class BJSON --------------------------- */ /* --------------------------- Class BJSON --------------------------- */
...@@ -860,7 +859,7 @@ int BJSON::GetObjectSize(PBPR bop, bool b) ...@@ -860,7 +859,7 @@ int BJSON::GetObjectSize(PBPR bop, bool b)
/***********************************************************************/ /***********************************************************************/
PBPR BJSON::AddPair(PGLOBAL g, PBPR bop, PSZ key, OFFSET val) PBPR BJSON::AddPair(PGLOBAL g, PBPR bop, PSZ key, OFFSET val)
{ {
PBPR brp, nrp = SubAllocPair(g, MOF(key), val); PBPR brp, nrp = SubAllocPair(g, key, val);
if (bop) { if (bop) {
for (brp = bop; brp->Next; brp = MPP(brp->Next)); for (brp = bop; brp->Next; brp = MPP(brp->Next));
...@@ -995,10 +994,10 @@ PBPR BJSON::SetKeyValue(PGLOBAL g, PBPR bop, OFFSET bvp, PSZ key) ...@@ -995,10 +994,10 @@ PBPR BJSON::SetKeyValue(PGLOBAL g, PBPR bop, OFFSET bvp, PSZ key)
prp = brp; prp = brp;
if (!brp) if (!brp)
prp->Vlp = MOF(SubAllocPair(g, MOF(key), bvp)); prp->Vlp = MOF(SubAllocPair(g, key, bvp));
} else } else
bop = SubAllocPair(g, MOF(key), bvp); bop = SubAllocPair(g, key, bvp);
// Return the first pair of this object // Return the first pair of this object
return bop; return bop;
...@@ -1094,7 +1093,7 @@ PBVAL BJSON::AddArrayValue(PGLOBAL g, PBVAL bap, PBVAL nvp, int* x) ...@@ -1094,7 +1093,7 @@ PBVAL BJSON::AddArrayValue(PGLOBAL g, PBVAL bap, PBVAL nvp, int* x)
nvp = SubAllocVal(g); nvp = SubAllocVal(g);
if (bap) { if (bap) {
int i = 0, n = *x; int i = 0, n = (x) ? *x : INT_MAX32;
PBVAL bvp; PBVAL bvp;
for (bvp = bap; bvp; bvp = MVP(bvp->Next), i++) for (bvp = bap; bvp; bvp = MVP(bvp->Next), i++)
...@@ -1240,7 +1239,7 @@ PBVAL BJSON::SubAllocVal(PGLOBAL g) ...@@ -1240,7 +1239,7 @@ PBVAL BJSON::SubAllocVal(PGLOBAL g)
bvp->To_Val = 0; bvp->To_Val = 0;
bvp->Nd = 0; bvp->Nd = 0;
bvp->Type = TYPE_UNKNOWN; bvp->Type = TYPE_NULL;
bvp->Next = 0; bvp->Next = 0;
return bvp; return bvp;
} // end of SubAllocVal } // end of SubAllocVal
......
...@@ -76,8 +76,14 @@ class BJSON : public BLOCK { ...@@ -76,8 +76,14 @@ class BJSON : public BLOCK {
// SubAlloc functions // SubAlloc functions
void* BsonSubAlloc(PGLOBAL g, size_t size); void* BsonSubAlloc(PGLOBAL g, size_t size);
PBPR SubAllocPair(PGLOBAL g, OFFSET key, OFFSET val = 0); PBPR SubAllocPair(PGLOBAL g, OFFSET key, OFFSET val = 0);
PBPR SubAllocPair(PGLOBAL g, PSZ key, OFFSET val = 0)
{return SubAllocPair(g, MOF(key), val);}
PBVAL SubAllocVal(PGLOBAL g); PBVAL SubAllocVal(PGLOBAL g);
PBVAL SubAllocVal(PGLOBAL g, OFFSET toval, int type = TYPE_UNKNOWN, short nd = 0); PBVAL SubAllocVal(PGLOBAL g, OFFSET toval, int type = TYPE_NULL, short nd = 0);
PBVAL SubAllocVal(PGLOBAL g, PBVAL toval, int type = TYPE_NULL, short nd = 0)
{return SubAllocVal(g, MOF(toval), type, nd);}
PBVAL SubAllocVal(PGLOBAL g, PSZ str, int type = TYPE_STRG, short nd = 0)
{return SubAllocVal(g, MOF(str), type, nd);}
PBVAL SubAllocVal(PGLOBAL g, PVAL valp); PBVAL SubAllocVal(PGLOBAL g, PVAL valp);
PBVAL DupVal(PGLOBAL g, PBVAL bvp); PBVAL DupVal(PGLOBAL g, PBVAL bvp);
......
/****************** bsonudf C++ Program Source Code File (.CPP) ******************/ /****************** bsonudf C++ Program Source Code File (.CPP) ******************/
/* PROGRAM NAME: bsonudf Version 1.0 */ /* PROGRAM NAME: bsonudf Version 1.0 */
/* (C) Copyright to the author Olivier BERTRAND 2020 */ /* (C) Copyright to the author Olivier BERTRAND 2020 */
/* This program are the BSON User Defined Functions . */ /* This program are the BSON User Defined Functions. */
/*********************************************************************************/ /*********************************************************************************/
/*********************************************************************************/ /*********************************************************************************/
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#else #else
#define PUSH_WARNING(M) htrc(M) #define PUSH_WARNING(M) htrc(M)
#endif #endif
#define M 9 #define M 6
/* --------------------------------- JSON UDF ---------------------------------- */ /* --------------------------------- JSON UDF ---------------------------------- */
...@@ -49,7 +49,8 @@ inline void JsonFreeMem(PGLOBAL g) { ...@@ -49,7 +49,8 @@ inline void JsonFreeMem(PGLOBAL g) {
/*********************************************************************************/ /*********************************************************************************/
/* SubAlloc a new BJNX class with protection against memory exhaustion. */ /* SubAlloc a new BJNX class with protection against memory exhaustion. */
/*********************************************************************************/ /*********************************************************************************/
static PBJNX BjnxNew(PGLOBAL g, PBVAL vlp, int type, int len) { static PBJNX BjnxNew(PGLOBAL g, PBVAL vlp, int type, int len)
{
PBJNX bjnx; PBJNX bjnx;
try { try {
...@@ -71,7 +72,8 @@ static PBJNX BjnxNew(PGLOBAL g, PBVAL vlp, int type, int len) { ...@@ -71,7 +72,8 @@ static PBJNX BjnxNew(PGLOBAL g, PBVAL vlp, int type, int len) {
/* BSNX public constructor. */ /* BSNX public constructor. */
/*********************************************************************************/ /*********************************************************************************/
BJNX::BJNX(PGLOBAL g, PBVAL row, int type, int len, int prec, my_bool wr) BJNX::BJNX(PGLOBAL g, PBVAL row, int type, int len, int prec, my_bool wr)
: BDOC(g->Sarea) { : BDOC(g->Sarea)
{
Row = row; Row = row;
Bvalp = NULL; Bvalp = NULL;
Jpnp = NULL; Jpnp = NULL;
...@@ -99,7 +101,8 @@ BJNX::BJNX(PGLOBAL g, PBVAL row, int type, int len, int prec, my_bool wr) ...@@ -99,7 +101,8 @@ BJNX::BJNX(PGLOBAL g, PBVAL row, int type, int len, int prec, my_bool wr)
/*********************************************************************************/ /*********************************************************************************/
/* SetJpath: set and parse the json path. */ /* SetJpath: set and parse the json path. */
/*********************************************************************************/ /*********************************************************************************/
my_bool BJNX::SetJpath(PGLOBAL g, char* path, my_bool jb) { my_bool BJNX::SetJpath(PGLOBAL g, char* path, my_bool jb)
{
// Check Value was allocated // Check Value was allocated
if (!Value) if (!Value)
return true; return true;
...@@ -117,7 +120,8 @@ my_bool BJNX::SetJpath(PGLOBAL g, char* path, my_bool jb) { ...@@ -117,7 +120,8 @@ my_bool BJNX::SetJpath(PGLOBAL g, char* path, my_bool jb) {
/*********************************************************************************/ /*********************************************************************************/
/* Analyse array processing options. */ /* Analyse array processing options. */
/*********************************************************************************/ /*********************************************************************************/
my_bool BJNX::SetArrayOptions(PGLOBAL g, char* p, int i, PSZ nm) { my_bool BJNX::SetArrayOptions(PGLOBAL g, char* p, int i, PSZ nm)
{
int n = (int)strlen(p); int n = (int)strlen(p);
my_bool dg = true, b = false; my_bool dg = true, b = false;
PJNODE jnp = &Nodes[i]; PJNODE jnp = &Nodes[i];
...@@ -243,7 +247,8 @@ my_bool BJNX::SetArrayOptions(PGLOBAL g, char* p, int i, PSZ nm) { ...@@ -243,7 +247,8 @@ my_bool BJNX::SetArrayOptions(PGLOBAL g, char* p, int i, PSZ nm) {
/* creating the table. It permits to indicate the position of the node */ /* creating the table. It permits to indicate the position of the node */
/* corresponding to that column. */ /* corresponding to that column. */
/*********************************************************************************/ /*********************************************************************************/
my_bool BJNX::ParseJpath(PGLOBAL g) { my_bool BJNX::ParseJpath(PGLOBAL g)
{
char* p, * p1 = NULL, * p2 = NULL, * pbuf = NULL; char* p, * p1 = NULL, * p2 = NULL, * pbuf = NULL;
int i; int i;
my_bool a, mul = false; my_bool a, mul = false;
...@@ -329,7 +334,8 @@ my_bool BJNX::ParseJpath(PGLOBAL g) { ...@@ -329,7 +334,8 @@ my_bool BJNX::ParseJpath(PGLOBAL g) {
/*********************************************************************************/ /*********************************************************************************/
/* MakeJson: Serialize the json item and set value to it. */ /* MakeJson: Serialize the json item and set value to it. */
/*********************************************************************************/ /*********************************************************************************/
PVAL BJNX::MakeJson(PGLOBAL g, PBVAL bvp) { PVAL BJNX::MakeJson(PGLOBAL g, PBVAL bvp)
{
if (Value->IsTypeNum()) { if (Value->IsTypeNum()) {
strcpy(g->Message, "Cannot make Json for a numeric value"); strcpy(g->Message, "Cannot make Json for a numeric value");
Value->Reset(); Value->Reset();
...@@ -345,7 +351,8 @@ PVAL BJNX::MakeJson(PGLOBAL g, PBVAL bvp) { ...@@ -345,7 +351,8 @@ PVAL BJNX::MakeJson(PGLOBAL g, PBVAL bvp) {
/*********************************************************************************/ /*********************************************************************************/
/* SetValue: Set a value from a JVALUE contains. */ /* SetValue: Set a value from a JVALUE contains. */
/*********************************************************************************/ /*********************************************************************************/
void BJNX::SetJsonValue(PGLOBAL g, PVAL vp, PBVAL vlp) { void BJNX::SetJsonValue(PGLOBAL g, PVAL vp, PBVAL vlp)
{
if (vlp) { if (vlp) {
vp->SetNull(false); vp->SetNull(false);
...@@ -396,21 +403,24 @@ void BJNX::SetJsonValue(PGLOBAL g, PVAL vp, PBVAL vlp) { ...@@ -396,21 +403,24 @@ void BJNX::SetJsonValue(PGLOBAL g, PVAL vp, PBVAL vlp) {
/*********************************************************************************/ /*********************************************************************************/
/* GetJson: */ /* GetJson: */
/*********************************************************************************/ /*********************************************************************************/
PBVAL BJNX::GetJson(PGLOBAL g) { PBVAL BJNX::GetJson(PGLOBAL g)
{
return GetRowValue(g, Row, 0); return GetRowValue(g, Row, 0);
} // end of GetJson } // end of GetJson
/*********************************************************************************/ /*********************************************************************************/
/* ReadValue: */ /* ReadValue: */
/*********************************************************************************/ /*********************************************************************************/
void BJNX::ReadValue(PGLOBAL g) { void BJNX::ReadValue(PGLOBAL g)
{
Value->SetValue_pval(GetColumnValue(g, Row, 0)); Value->SetValue_pval(GetColumnValue(g, Row, 0));
} // end of ReadValue } // end of ReadValue
/*********************************************************************************/ /*********************************************************************************/
/* GetColumnValue: */ /* GetColumnValue: */
/*********************************************************************************/ /*********************************************************************************/
PVAL BJNX::GetColumnValue(PGLOBAL g, PBVAL row, int i) { PVAL BJNX::GetColumnValue(PGLOBAL g, PBVAL row, int i)
{
PBVAL vlp = GetRowValue(g, row, i); PBVAL vlp = GetRowValue(g, row, i);
SetJsonValue(g, Value, vlp); SetJsonValue(g, Value, vlp);
...@@ -420,7 +430,8 @@ PVAL BJNX::GetColumnValue(PGLOBAL g, PBVAL row, int i) { ...@@ -420,7 +430,8 @@ PVAL BJNX::GetColumnValue(PGLOBAL g, PBVAL row, int i) {
/*********************************************************************************/ /*********************************************************************************/
/* GetRowValue: */ /* GetRowValue: */
/*********************************************************************************/ /*********************************************************************************/
PBVAL BJNX::GetRowValue(PGLOBAL g, PBVAL row, int i, my_bool b) { PBVAL BJNX::GetRowValue(PGLOBAL g, PBVAL row, int i, my_bool b)
{
my_bool expd = false; my_bool expd = false;
PBVAL bap; PBVAL bap;
PBVAL vlp = NULL; PBVAL vlp = NULL;
...@@ -488,7 +499,8 @@ PBVAL BJNX::GetRowValue(PGLOBAL g, PBVAL row, int i, my_bool b) { ...@@ -488,7 +499,8 @@ PBVAL BJNX::GetRowValue(PGLOBAL g, PBVAL row, int i, my_bool b) {
/*********************************************************************************/ /*********************************************************************************/
/* ExpandArray: */ /* ExpandArray: */
/*********************************************************************************/ /*********************************************************************************/
PVAL BJNX::ExpandArray(PGLOBAL g, PBVAL arp, int n) { PVAL BJNX::ExpandArray(PGLOBAL g, PBVAL arp, int n)
{
strcpy(g->Message, "Expand cannot be done by this function"); strcpy(g->Message, "Expand cannot be done by this function");
return NULL; return NULL;
} // end of ExpandArray } // end of ExpandArray
...@@ -496,7 +508,8 @@ PVAL BJNX::ExpandArray(PGLOBAL g, PBVAL arp, int n) { ...@@ -496,7 +508,8 @@ PVAL BJNX::ExpandArray(PGLOBAL g, PBVAL arp, int n) {
/*********************************************************************************/ /*********************************************************************************/
/* CalculateArray: NIY */ /* CalculateArray: NIY */
/*********************************************************************************/ /*********************************************************************************/
PVAL BJNX::CalculateArray(PGLOBAL g, PBVAL bap, int n) { PVAL BJNX::CalculateArray(PGLOBAL g, PBVAL bap, int n)
{
#if 0 #if 0
int i, ars = GetArraySize(bap), nv = 0; int i, ars = GetArraySize(bap), nv = 0;
bool err; bool err;
...@@ -592,7 +605,8 @@ PVAL BJNX::CalculateArray(PGLOBAL g, PBVAL bap, int n) { ...@@ -592,7 +605,8 @@ PVAL BJNX::CalculateArray(PGLOBAL g, PBVAL bap, int n) {
/*********************************************************************************/ /*********************************************************************************/
/* CheckPath: Checks whether the path exists in the document. */ /* CheckPath: Checks whether the path exists in the document. */
/*********************************************************************************/ /*********************************************************************************/
my_bool BJNX::CheckPath(PGLOBAL g) { my_bool BJNX::CheckPath(PGLOBAL g)
{
PBVAL val = NULL; PBVAL val = NULL;
PBVAL row = Row; PBVAL row = Row;
...@@ -632,7 +646,8 @@ my_bool BJNX::CheckPath(PGLOBAL g) { ...@@ -632,7 +646,8 @@ my_bool BJNX::CheckPath(PGLOBAL g) {
/***********************************************************************/ /***********************************************************************/
/* GetRow: Set the complete path of the object to be set. */ /* GetRow: Set the complete path of the object to be set. */
/***********************************************************************/ /***********************************************************************/
PBVAL BJNX::GetRow(PGLOBAL g) { PBVAL BJNX::GetRow(PGLOBAL g)
{
PBVAL val = NULL; PBVAL val = NULL;
PBVAL arp; PBVAL arp;
PBVAL nwr, row = Row; PBVAL nwr, row = Row;
...@@ -711,7 +726,8 @@ PBVAL BJNX::GetRow(PGLOBAL g) { ...@@ -711,7 +726,8 @@ PBVAL BJNX::GetRow(PGLOBAL g) {
/***********************************************************************/ /***********************************************************************/
/* WriteValue: */ /* WriteValue: */
/***********************************************************************/ /***********************************************************************/
my_bool BJNX::WriteValue(PGLOBAL g, PBVAL jvalp) { my_bool BJNX::WriteValue(PGLOBAL g, PBVAL jvalp)
{
PBPR objp = NULL; PBPR objp = NULL;
PBVAL arp = NULL; PBVAL arp = NULL;
PBVAL jvp = NULL; PBVAL jvp = NULL;
...@@ -751,7 +767,8 @@ my_bool BJNX::WriteValue(PGLOBAL g, PBVAL jvalp) { ...@@ -751,7 +767,8 @@ my_bool BJNX::WriteValue(PGLOBAL g, PBVAL jvalp) {
/*********************************************************************************/ /*********************************************************************************/
/* Locate a value in a JSON tree: */ /* Locate a value in a JSON tree: */
/*********************************************************************************/ /*********************************************************************************/
PSZ BJNX::Locate(PGLOBAL g, PBVAL jsp, PBVAL jvp, int k) { PSZ BJNX::Locate(PGLOBAL g, PBVAL jsp, PBVAL jvp, int k)
{
PSZ str = NULL; PSZ str = NULL;
my_bool b = false, err = true; my_bool b = false, err = true;
...@@ -808,7 +825,8 @@ PSZ BJNX::Locate(PGLOBAL g, PBVAL jsp, PBVAL jvp, int k) { ...@@ -808,7 +825,8 @@ PSZ BJNX::Locate(PGLOBAL g, PBVAL jsp, PBVAL jvp, int k) {
/*********************************************************************************/ /*********************************************************************************/
/* Locate in a JSON Array. */ /* Locate in a JSON Array. */
/*********************************************************************************/ /*********************************************************************************/
my_bool BJNX::LocateArray(PGLOBAL g, PBVAL jarp) { my_bool BJNX::LocateArray(PGLOBAL g, PBVAL jarp)
{
char s[16]; char s[16];
int n = GetArraySize(jarp); int n = GetArraySize(jarp);
size_t m = Jp->N; size_t m = Jp->N;
...@@ -831,7 +849,8 @@ my_bool BJNX::LocateArray(PGLOBAL g, PBVAL jarp) { ...@@ -831,7 +849,8 @@ my_bool BJNX::LocateArray(PGLOBAL g, PBVAL jarp) {
/*********************************************************************************/ /*********************************************************************************/
/* Locate in a JSON Object. */ /* Locate in a JSON Object. */
/*********************************************************************************/ /*********************************************************************************/
my_bool BJNX::LocateObject(PGLOBAL g, PBPR jobp) { my_bool BJNX::LocateObject(PGLOBAL g, PBPR jobp)
{
size_t m; size_t m;
if (Jp->WriteChr('.')) if (Jp->WriteChr('.'))
...@@ -856,7 +875,8 @@ my_bool BJNX::LocateObject(PGLOBAL g, PBPR jobp) { ...@@ -856,7 +875,8 @@ my_bool BJNX::LocateObject(PGLOBAL g, PBPR jobp) {
/*********************************************************************************/ /*********************************************************************************/
/* Locate a JSON Value. */ /* Locate a JSON Value. */
/*********************************************************************************/ /*********************************************************************************/
my_bool BJNX::LocateValue(PGLOBAL g, PBVAL jvp) { my_bool BJNX::LocateValue(PGLOBAL g, PBVAL jvp)
{
if (CompareTree(g, Bvalp, jvp)) if (CompareTree(g, Bvalp, jvp))
Found = (--K == 0); Found = (--K == 0);
else if (jvp->Type == TYPE_JAR) else if (jvp->Type == TYPE_JAR)
...@@ -870,7 +890,8 @@ my_bool BJNX::LocateValue(PGLOBAL g, PBVAL jvp) { ...@@ -870,7 +890,8 @@ my_bool BJNX::LocateValue(PGLOBAL g, PBVAL jvp) {
/*********************************************************************************/ /*********************************************************************************/
/* Locate all occurrences of a value in a JSON tree: */ /* Locate all occurrences of a value in a JSON tree: */
/*********************************************************************************/ /*********************************************************************************/
PSZ BJNX::LocateAll(PGLOBAL g, PBVAL jsp, PBVAL bvp, int mx) { PSZ BJNX::LocateAll(PGLOBAL g, PBVAL jsp, PBVAL bvp, int mx)
{
PSZ str = NULL; PSZ str = NULL;
my_bool b = false, err = true; my_bool b = false, err = true;
PJPN jnp; PJPN jnp;
...@@ -930,7 +951,8 @@ PSZ BJNX::LocateAll(PGLOBAL g, PBVAL jsp, PBVAL bvp, int mx) { ...@@ -930,7 +951,8 @@ PSZ BJNX::LocateAll(PGLOBAL g, PBVAL jsp, PBVAL bvp, int mx) {
/*********************************************************************************/ /*********************************************************************************/
/* Locate in a JSON Array. */ /* Locate in a JSON Array. */
/*********************************************************************************/ /*********************************************************************************/
my_bool BJNX::LocateArrayAll(PGLOBAL g, PBVAL jarp) { my_bool BJNX::LocateArrayAll(PGLOBAL g, PBVAL jarp)
{
int i = 0; int i = 0;
if (I < Imax) { if (I < Imax) {
...@@ -954,7 +976,8 @@ my_bool BJNX::LocateArrayAll(PGLOBAL g, PBVAL jarp) { ...@@ -954,7 +976,8 @@ my_bool BJNX::LocateArrayAll(PGLOBAL g, PBVAL jarp) {
/*********************************************************************************/ /*********************************************************************************/
/* Locate in a JSON Object. */ /* Locate in a JSON Object. */
/*********************************************************************************/ /*********************************************************************************/
my_bool BJNX::LocateObjectAll(PGLOBAL g, PBPR jobp) { my_bool BJNX::LocateObjectAll(PGLOBAL g, PBPR jobp)
{
if (I < Imax) { if (I < Imax) {
Jpnp[++I].Type = TYPE_JOB; Jpnp[++I].Type = TYPE_JOB;
...@@ -975,7 +998,8 @@ my_bool BJNX::LocateObjectAll(PGLOBAL g, PBPR jobp) { ...@@ -975,7 +998,8 @@ my_bool BJNX::LocateObjectAll(PGLOBAL g, PBPR jobp) {
/*********************************************************************************/ /*********************************************************************************/
/* Locate a JSON Value. */ /* Locate a JSON Value. */
/*********************************************************************************/ /*********************************************************************************/
my_bool BJNX::LocateValueAll(PGLOBAL g, PBVAL jvp) { my_bool BJNX::LocateValueAll(PGLOBAL g, PBVAL jvp)
{
if (CompareTree(g, Bvalp, jvp)) if (CompareTree(g, Bvalp, jvp))
return AddPath(); return AddPath();
else if (jvp->Type == TYPE_JAR) else if (jvp->Type == TYPE_JAR)
...@@ -989,7 +1013,8 @@ my_bool BJNX::LocateValueAll(PGLOBAL g, PBVAL jvp) { ...@@ -989,7 +1013,8 @@ my_bool BJNX::LocateValueAll(PGLOBAL g, PBVAL jvp) {
/*********************************************************************************/ /*********************************************************************************/
/* Compare two JSON trees. */ /* Compare two JSON trees. */
/*********************************************************************************/ /*********************************************************************************/
my_bool BJNX::CompareTree(PGLOBAL g, PBVAL jp1, PBVAL jp2) { my_bool BJNX::CompareTree(PGLOBAL g, PBVAL jp1, PBVAL jp2)
{
if (!jp1 || !jp2 || jp1->Type != jp2->Type || GetSize(jp1) != GetSize(jp2)) if (!jp1 || !jp2 || jp1->Type != jp2->Type || GetSize(jp1) != GetSize(jp2))
return false; return false;
...@@ -1017,7 +1042,8 @@ my_bool BJNX::CompareTree(PGLOBAL g, PBVAL jp1, PBVAL jp2) { ...@@ -1017,7 +1042,8 @@ my_bool BJNX::CompareTree(PGLOBAL g, PBVAL jp1, PBVAL jp2) {
/*********************************************************************************/ /*********************************************************************************/
/* Compare two VAL values and return true if they are equal. */ /* Compare two VAL values and return true if they are equal. */
/*********************************************************************************/ /*********************************************************************************/
my_bool BJNX::CompareValues(PGLOBAL g, PBVAL v1, PBVAL v2) { my_bool BJNX::CompareValues(PGLOBAL g, PBVAL v1, PBVAL v2)
{
my_bool b = false; my_bool b = false;
if (v1 && v2) if (v1 && v2)
...@@ -1091,7 +1117,8 @@ my_bool BJNX::CompareValues(PGLOBAL g, PBVAL v1, PBVAL v2) { ...@@ -1091,7 +1117,8 @@ my_bool BJNX::CompareValues(PGLOBAL g, PBVAL v1, PBVAL v2) {
/*********************************************************************************/ /*********************************************************************************/
/* Add the found path to the list. */ /* Add the found path to the list. */
/*********************************************************************************/ /*********************************************************************************/
my_bool BJNX::AddPath(void) { my_bool BJNX::AddPath(void)
{
char s[16]; char s[16];
if (Jp->WriteStr("\"$")) if (Jp->WriteStr("\"$"))
...@@ -1121,86 +1148,270 @@ my_bool BJNX::AddPath(void) { ...@@ -1121,86 +1148,270 @@ my_bool BJNX::AddPath(void) {
return false; return false;
} // end of AddPath } // end of AddPath
/* -----------------------------Utility functions ------------------------------ */
/*********************************************************************************/ /*********************************************************************************/
/* Make a BVAL value from the passed argument. */ /* Make a BVAL value from the passed argument. */
/*********************************************************************************/ /*********************************************************************************/
static PBVAL MakeBinValue(PGLOBAL g, UDF_ARGS* args, uint i) { static PBVAL MakeBinValue(PGLOBAL g, UDF_ARGS* args, uint i)
{
char* sap = (args->arg_count > i) ? args->args[i] : NULL; char* sap = (args->arg_count > i) ? args->args[i] : NULL;
int n, len; int n, len;
int ci; int ci;
longlong bigint; longlong bigint;
void* Base = g->Sarea; // Required by MOF BDOC doc(g->Sarea);
BDOC doc(Base); PBVAL bp, bvp = doc.SubAllocVal(g);
PBVAL bp;
PBVAL bvp = doc.SubAllocVal(g); if (sap) {
if (args->arg_type[i] == STRING_RESULT) {
if (sap) switch (args->arg_type[i]) { if ((len = args->lengths[i])) {
case STRING_RESULT: if ((n = IsJson(args, i)) < 3)
if ((len = args->lengths[i])) { sap = MakePSZ(g, args, i);
if ((n = IsJson(args, i)) < 3)
sap = MakePSZ(g, args, i); if (n) {
if (n == 2) {
if (n) { if (!(sap = GetJsonFile(g, sap))) {
if (n == 2) { PUSH_WARNING(g->Message);
if (!(sap = GetJsonFile(g, sap))) { return NULL;
} // endif sap
len = strlen(sap);
} // endif 2
if (!(bp = doc.ParseJson(g, sap, strlen(sap)))) {
PUSH_WARNING(g->Message); PUSH_WARNING(g->Message);
return NULL; return NULL;
} // endif sap } else
bvp = bp;
len = strlen(sap);
} // endif 2
if (!(bp = doc.ParseJson(g, sap, strlen(sap)))) } else {
PUSH_WARNING(g->Message); // Check whether this string is a valid json string
JsonMemSave(g);
bvp = bp; if (!(bp = doc.ParseJson(g, sap, strlen(sap)))) {
} else { // Recover suballocated memory
// Check whether this string is a valid json string JsonSubSet(g);
JsonMemSave(g); ci = (strnicmp(args->attributes[i], "ci", 2)) ? 0 : 1;
doc.SetString(bvp, sap, ci);
} else
bvp = bp;
if (!(bvp = doc.ParseJson(g, sap, strlen(sap)))) {
// Recover suballocated memory
JsonSubSet(g);
ci = (strnicmp(args->attributes[i], "ci", 2)) ? 0 : 1;
bvp = doc.SubAllocVal(g, MOF(sap), TYPE_STRG, ci);
} else
g->Saved_Size = 0; g->Saved_Size = 0;
} // endif n
} // endif n } // endif len
} // endif len
break; } else switch (args->arg_type[i]) {
case INT_RESULT: case INT_RESULT:
bigint = *(longlong*)sap; bigint = *(longlong*)sap;
if ((bigint == 0LL && !strcmp(args->attributes[i], "FALSE")) ||
(bigint == 1LL && !strcmp(args->attributes[i], "TRUE")))
doc.SetBool(bvp, (bool)bigint);
else
doc.SetBigint(g, bvp, bigint);
break; if ((bigint == 0LL && !strcmp(args->attributes[i], "FALSE")) ||
case REAL_RESULT: (bigint == 1LL && !strcmp(args->attributes[i], "TRUE")))
doc.SetFloat(bvp, *(double*)sap); doc.SetBool(bvp, (bool)bigint);
break; else
case DECIMAL_RESULT: doc.SetBigint(g, bvp, bigint);
doc.SetFloat(bvp, atof(MakePSZ(g, args, i)));
break; break;
case TIME_RESULT: case REAL_RESULT:
case ROW_RESULT: doc.SetFloat(bvp, *(double*)sap);
default: break;
bvp = NULL; case DECIMAL_RESULT:
break; doc.SetFloat(bvp, atof(MakePSZ(g, args, i)));
} // endswitch arg_type break;
case TIME_RESULT:
case ROW_RESULT:
default:
bvp->Type = TYPE_UNKNOWN;
break;
} // endswitch arg_type
} // endif sap
return bvp; return bvp;
} // end of MakeBinValue } // end of MakeBinValue
/* ------------------------- Now the new Bin UDF's ----------------------------- */
/*********************************************************************************/
/* Make a Json value containing the parameter. */
/*********************************************************************************/
my_bool bsonvalue_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
{
unsigned long reslen, memlen;
if (args->arg_count > 1) {
strcpy(message, "Cannot accept more than 1 argument");
return true;
} else
CalcLen(args, false, reslen, memlen);
return JsonInit(initid, args, message, false, reslen, memlen);
} // end of bsonvalue_init
char* bsonvalue(UDF_INIT* initid, UDF_ARGS* args, char* result,
unsigned long* res_length, char*, char*)
{
char *str;
PGLOBAL g = (PGLOBAL)initid->ptr;
if (!g->Xchk) {
if (!CheckMemory(g, initid, args, 1, false)) {
BDOC doc(g->Sarea);
PBVAL bvp = MakeBinValue(g, args, 0);
if (!(str = doc.Serialize(g, bvp, NULL, 0)))
str = strcpy(result, g->Message);
} else
str = strcpy(result, g->Message);
// Keep result of constant function
g->Xchk = (initid->const_item) ? str : NULL;
} else
str = (char*)g->Xchk;
*res_length = strlen(str);
return str;
} // end of bsonValue
void bsonvalue_deinit(UDF_INIT* initid) {
JsonFreeMem((PGLOBAL)initid->ptr);
} // end of bsonvalue_deinit
/*********************************************************************************/
/* Make a Bson array containing all the parameters. */
/*********************************************************************************/
my_bool bson_make_array_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
{
unsigned long reslen, memlen;
CalcLen(args, false, reslen, memlen);
return JsonInit(initid, args, message, false, reslen, memlen);
} // end of bson_make_array_init
char* bson_make_array(UDF_INIT* initid, UDF_ARGS* args, char* result,
unsigned long* res_length, char*, char*)
{
char* str = NULL;
PGLOBAL g = (PGLOBAL)initid->ptr;
if (!g->Xchk) {
if (!CheckMemory(g, initid, args, args->arg_count, false)) {
BDOC doc(g->Sarea);
PBVAL bvp = NULL, arp = NULL;
for (uint i = 0; i < args->arg_count; i++)
bvp = doc.AddArrayValue(g, bvp, MakeBinValue(g, args, i));
arp = doc.SubAllocVal(g, bvp, TYPE_JAR);
if (!(str = doc.Serialize(g, arp, NULL, 0)))
str = strcpy(result, g->Message);
} else
str = strcpy(result, g->Message);
// Keep result of constant function
g->Xchk = (initid->const_item) ? str : NULL;
} else
str = (char*)g->Xchk;
*res_length = strlen(str);
return str;
} // end of bson_make_array
void bson_make_array_deinit(UDF_INIT* initid) {
JsonFreeMem((PGLOBAL)initid->ptr);
} // end of bson_make_array_deinit
/*********************************************************************************/
/* Add one or several values to a Bson array. */
/*********************************************************************************/
my_bool bson_array_add_values_init(UDF_INIT* initid, UDF_ARGS* args, char* message) {
unsigned long reslen, memlen;
if (args->arg_count < 2) {
strcpy(message, "This function must have at least 2 arguments");
return true;
//} else if (!IsJson(args, 0, true)) {
// strcpy(message, "First argument must be a valid json string or item");
// return true;
} else
CalcLen(args, false, reslen, memlen);
if (!JsonInit(initid, args, message, true, reslen, memlen)) {
PGLOBAL g = (PGLOBAL)initid->ptr;
// This is a constant function
g->N = (initid->const_item) ? 1 : 0;
// This is to avoid double execution when using prepared statements
if (IsJson(args, 0) > 1)
initid->const_item = 0;
return false;
} else
return true;
} // end of bson_array_add_values_init
char* bson_array_add_values(UDF_INIT* initid, UDF_ARGS* args, char* result,
unsigned long* res_length, char* is_null, char*) {
char* str = NULL;
PGLOBAL g = (PGLOBAL)initid->ptr;
if (!g->Xchk) {
if (!CheckMemory(g, initid, args, args->arg_count, true)) {
uint n = 1;
bool b = false;
BDOC doc(g->Sarea);
PBVAL bvp = NULL, arp = MakeBinValue(g, args, 0);
if (arp->Type == TYPE_JAR) {
bvp = doc.GetArray(arp);
b = !bvp;
} else
n = 0;
for (uint i = n; i < args->arg_count; i++)
bvp = doc.AddArrayValue(g, bvp, MakeBinValue(g, args, i));
if (!n)
arp = doc.SubAllocVal(g, bvp, TYPE_JAR);
else if (b)
doc.SetValueArr(arp, bvp);
// str = MakeResult(g, args, top, args->arg_count);
str = doc.Serialize(g, arp, NULL, 0);
} // endif CheckMemory
if (!str) {
PUSH_WARNING(g->Message);
str = args->args[0];
} // endif str
// Keep result of constant function
g->Xchk = (g->N) ? str : NULL;
} else
str = (char*)g->Xchk;
if (!str) {
*res_length = 0;
*is_null = 1;
} else
*res_length = strlen(str);
return str;
} // end of bson_array_add_values
void bson_array_add_values_deinit(UDF_INIT* initid) {
JsonFreeMem((PGLOBAL)initid->ptr);
} // end of bson_array_add_values_deinit
/*********************************************************************************/ /*********************************************************************************/
/* Test BJSON parse and serialize. */ /* Test BJSON parse and serialize. */
/*********************************************************************************/ /*********************************************************************************/
my_bool json_test_bson_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { my_bool bson_test_init(UDF_INIT* initid, UDF_ARGS* args, char* message) {
unsigned long reslen, memlen, more = 1000; unsigned long reslen, memlen, more = 1000;
if (args->arg_count == 0) { if (args->arg_count == 0) {
...@@ -1213,9 +1424,9 @@ my_bool json_test_bson_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { ...@@ -1213,9 +1424,9 @@ my_bool json_test_bson_init(UDF_INIT* initid, UDF_ARGS* args, char* message) {
CalcLen(args, false, reslen, memlen); CalcLen(args, false, reslen, memlen);
return JsonInit(initid, args, message, true, reslen, memlen, more); return JsonInit(initid, args, message, true, reslen, memlen, more);
} // end of json_test_bson_init } // end of bson_test_init
char* json_test_bson(UDF_INIT* initid, UDF_ARGS* args, char* result, char* bson_test(UDF_INIT* initid, UDF_ARGS* args, char* result,
unsigned long* res_length, char* is_null, char* error) { unsigned long* res_length, char* is_null, char* error) {
char* str = NULL, * sap = NULL, * fn = NULL; char* str = NULL, * sap = NULL, * fn = NULL;
int pretty = 1; int pretty = 1;
...@@ -1281,16 +1492,16 @@ char* json_test_bson(UDF_INIT* initid, UDF_ARGS* args, char* result, ...@@ -1281,16 +1492,16 @@ char* json_test_bson(UDF_INIT* initid, UDF_ARGS* args, char* result,
*res_length = strlen(str); *res_length = strlen(str);
return str; return str;
} // end of json_test_bson } // end of bson_test
void json_test_bson_deinit(UDF_INIT* initid) { void bson_test_deinit(UDF_INIT* initid) {
JsonFreeMem((PGLOBAL)initid->ptr); JsonFreeMem((PGLOBAL)initid->ptr);
} // end of json_test_bson_deinit } // end of bson_test_deinit
/*********************************************************************************/ /*********************************************************************************/
/* Locate a value in a Json tree. */ /* Locate a value in a Json tree. */
/*********************************************************************************/ /*********************************************************************************/
my_bool jsonlocate_bson_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { my_bool bsonlocate_init(UDF_INIT* initid, UDF_ARGS* args, char* message) {
unsigned long reslen, memlen, more = 1000; unsigned long reslen, memlen, more = 1000;
if (args->arg_count < 2) { if (args->arg_count < 2) {
...@@ -1311,11 +1522,11 @@ my_bool jsonlocate_bson_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { ...@@ -1311,11 +1522,11 @@ my_bool jsonlocate_bson_init(UDF_INIT* initid, UDF_ARGS* args, char* message) {
more = 0; more = 0;
return JsonInit(initid, args, message, true, reslen, memlen, more); return JsonInit(initid, args, message, true, reslen, memlen, more);
} // end of jsonlocate_bson_init } // end of bsonlocate_init
char* jsonlocate_bson(UDF_INIT* initid, UDF_ARGS* args, char* result, char* bsonlocate(UDF_INIT* initid, UDF_ARGS* args, char* result,
unsigned long* res_length, char* is_null, char* error) { unsigned long* res_length, char* is_null, char* error) {
char* path = NULL; char *path = NULL;
int k; int k;
PBVAL bvp, bvp2; PBVAL bvp, bvp2;
PBJNX bnxp; PBJNX bnxp;
...@@ -1358,7 +1569,10 @@ char* jsonlocate_bson(UDF_INIT* initid, UDF_ARGS* args, char* result, ...@@ -1358,7 +1569,10 @@ char* jsonlocate_bson(UDF_INIT* initid, UDF_ARGS* args, char* result,
bvp = (PBVAL)g->Xchk; bvp = (PBVAL)g->Xchk;
// The item to locate // The item to locate
bvp2 = MakeBinValue(g, args, 1); if (!(bvp2 = MakeBinValue(g, args, 1))) {
PUSH_WARNING("Invalid second argument");
goto err;
} // endif bvp
k = (args->arg_count > 2) ? (int)*(long long*)args->args[2] : 1; k = (args->arg_count > 2) ? (int)*(long long*)args->args[2] : 1;
...@@ -1389,16 +1603,16 @@ char* jsonlocate_bson(UDF_INIT* initid, UDF_ARGS* args, char* result, ...@@ -1389,16 +1603,16 @@ char* jsonlocate_bson(UDF_INIT* initid, UDF_ARGS* args, char* result,
*res_length = strlen(path); *res_length = strlen(path);
return path; return path;
} // end of jsonlocate_bson } // end of bsonlocate
void jsonlocate_bson_deinit(UDF_INIT* initid) { void bsonlocate_deinit(UDF_INIT* initid) {
JsonFreeMem((PGLOBAL)initid->ptr); JsonFreeMem((PGLOBAL)initid->ptr);
} // end of jsonlocate_bson_deinit } // end of bsonlocate_deinit
/*********************************************************************************/ /*********************************************************************************/
/* Locate all occurences of a value in a Json tree. */ /* Locate all occurences of a value in a Json tree. */
/*********************************************************************************/ /*********************************************************************************/
my_bool json_locate_all_bson_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { my_bool bson_locate_all_init(UDF_INIT* initid, UDF_ARGS* args, char* message) {
unsigned long reslen, memlen, more = 1000; unsigned long reslen, memlen, more = 1000;
if (args->arg_count < 2) { if (args->arg_count < 2) {
...@@ -1419,9 +1633,9 @@ my_bool json_locate_all_bson_init(UDF_INIT* initid, UDF_ARGS* args, char* messag ...@@ -1419,9 +1633,9 @@ my_bool json_locate_all_bson_init(UDF_INIT* initid, UDF_ARGS* args, char* messag
more = 0; more = 0;
return JsonInit(initid, args, message, true, reslen, memlen, more); return JsonInit(initid, args, message, true, reslen, memlen, more);
} // end of json_locate_all_bson_init } // end of bson_locate_all_init
char* json_locate_all_bson(UDF_INIT* initid, UDF_ARGS* args, char* result, char* bson_locate_all(UDF_INIT* initid, UDF_ARGS* args, char* result,
unsigned long* res_length, char* is_null, char* error) { unsigned long* res_length, char* is_null, char* error) {
char* path = NULL; char* path = NULL;
int mx = 10; int mx = 10;
...@@ -1467,7 +1681,10 @@ char* json_locate_all_bson(UDF_INIT* initid, UDF_ARGS* args, char* result, ...@@ -1467,7 +1681,10 @@ char* json_locate_all_bson(UDF_INIT* initid, UDF_ARGS* args, char* result,
bvp = (PBVAL)g->Xchk; bvp = (PBVAL)g->Xchk;
// The item to locate // The item to locate
bvp2 = MakeBinValue(g, args, 1); if (!(bvp2 = MakeBinValue(g, args, 1))) {
PUSH_WARNING("Invalid second argument");
goto err;
} // endif bvp
if (args->arg_count > 2) if (args->arg_count > 2)
mx = (int)*(long long*)args->args[2]; mx = (int)*(long long*)args->args[2];
...@@ -1499,9 +1716,9 @@ char* json_locate_all_bson(UDF_INIT* initid, UDF_ARGS* args, char* result, ...@@ -1499,9 +1716,9 @@ char* json_locate_all_bson(UDF_INIT* initid, UDF_ARGS* args, char* result,
*res_length = strlen(path); *res_length = strlen(path);
return path; return path;
} // end of json_locate_all_bson } // end of bson_locate_all
void json_locate_all_bson_deinit(UDF_INIT* initid) { void bson_locate_all_deinit(UDF_INIT* initid) {
JsonFreeMem((PGLOBAL)initid->ptr); JsonFreeMem((PGLOBAL)initid->ptr);
} // end of json_locate_all_bson_deinit } // end of bson_locate_all_deinit
...@@ -83,16 +83,28 @@ class BJNX : public BDOC { ...@@ -83,16 +83,28 @@ class BJNX : public BDOC {
}; // end of class BJNX }; // end of class BJNX
extern "C" { extern "C" {
DllExport my_bool json_test_bson_init(UDF_INIT*, UDF_ARGS*, char*); DllExport my_bool bson_test_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char* json_test_bson(UDF_EXEC_ARGS); DllExport char* bson_test(UDF_EXEC_ARGS);
DllExport void json_test_bson_deinit(UDF_INIT*); DllExport void bson_test_deinit(UDF_INIT*);
DllExport my_bool jsonlocate_bson_init(UDF_INIT*, UDF_ARGS*, char*); DllExport my_bool bsonvalue_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char* jsonlocate_bson(UDF_EXEC_ARGS); DllExport char* bsonvalue(UDF_EXEC_ARGS);
DllExport void jsonlocate_bson_deinit(UDF_INIT*); DllExport void bsonvalue_deinit(UDF_INIT*);
DllExport my_bool json_locate_all_bson_init(UDF_INIT*, UDF_ARGS*, char*); DllExport my_bool bson_make_array_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char* json_locate_all_bson(UDF_EXEC_ARGS); DllExport char* bson_make_array(UDF_EXEC_ARGS);
DllExport void json_locate_all_bson_deinit(UDF_INIT*); DllExport void bson_make_array_deinit(UDF_INIT*);
DllExport my_bool bson_array_add_values_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char* bson_array_add_values(UDF_EXEC_ARGS);
DllExport void bson_array_add_values_deinit(UDF_INIT*);
DllExport my_bool bsonlocate_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char* bsonlocate(UDF_EXEC_ARGS);
DllExport void bsonlocate_deinit(UDF_INIT*);
DllExport my_bool bson_locate_all_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char* bson_locate_all(UDF_EXEC_ARGS);
DllExport void bson_locate_all_deinit(UDF_INIT*);
} // extern "C" } // extern "C"
...@@ -1950,6 +1950,8 @@ static PJVAL MakeTypedValue(PGLOBAL g, UDF_ARGS *args, uint i, ...@@ -1950,6 +1950,8 @@ static PJVAL MakeTypedValue(PGLOBAL g, UDF_ARGS *args, uint i,
return jvp; return jvp;
} // end of MakeTypedValue } // end of MakeTypedValue
/* ------------------------------ The JSON UDF's ------------------------------- */
/*********************************************************************************/ /*********************************************************************************/
/* Make a Json value containing the parameter. */ /* Make a Json value containing the parameter. */
/*********************************************************************************/ /*********************************************************************************/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment