diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2017-07-02 22:29:31 +0200 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2017-07-02 22:41:11 +0200 |
commit | 94e5d7de85a2964e7dd9a02e91a71522ccc66f94 (patch) | |
tree | 45164d08bff5a905f88da27762fcf3c089299cd7 /storage/connect/tabjmg.cpp | |
parent | c51548d6b4234d1b9bf7548125f63c5975f37d35 (diff) | |
download | mariadb-git-94e5d7de85a2964e7dd9a02e91a71522ccc66f94.tar.gz |
- Add Support of the MongoDB Java Driver.
modified: storage/connect/CMakeLists.txt
modified: storage/connect/JavaWrappers.jar
modified: storage/connect/colblk.h
modified: storage/connect/filter.cpp
modified: storage/connect/filter.h
modified: storage/connect/ha_connect.cc
modified: storage/connect/ha_connect.h
modified: storage/connect/jdbccat.h
modified: storage/connect/jdbconn.cpp
modified: storage/connect/jdbconn.h
modified: storage/connect/mongofam.cpp
modified: storage/connect/mongofam.h
modified: storage/connect/mycat.cc
modified: storage/connect/mycat.h
modified: storage/connect/tabext.h
modified: storage/connect/tabjdbc.cpp
modified: storage/connect/tabjdbc.h
modified: storage/connect/tabjson.cpp
modified: storage/connect/tabjson.h
modified: storage/connect/tabmgo.cpp
modified: storage/connect/tabmgo.h
created: storage/connect/Mongo2Interface.java
created: storage/connect/Mongo3Interface.java
created: storage/connect/cmgoconn.cpp
created: storage/connect/cmgoconn.h
created: storage/connect/javaconn.cpp
created: storage/connect/javaconn.h
created: storage/connect/jmgfam.cpp
created: storage/connect/jmgfam.h
created: storage/connect/jmgoconn.cpp
created: storage/connect/jmgoconn.h
created: storage/connect/mongo.cpp
created: storage/connect/mongo.h
created: storage/connect/tabjmg.cpp
created: storage/connect/tabjmg.h
- tdbp not initialized when catched exception
in CntGetTDB (connect.cc line 188)
modified: storage/connect/connect.h
- CheckCleanup should sometimes doing cleanup on pure info
Sometimes MariaDB loops on info to get the size of all tables in a database.
This can sometimes fail by exhausted memory.
CheckCleanup now have a force boolean parameter (defaulting to false)
modified: storage/connect/ha_connect.cc
modified: storage/connect/user_connect.cc
modified: storage/connect/user_connect.h
Change the copyright of some source files
modified: storage/connect/connect.cc
modified: storage/connect/connect.h
modified: storage/connect/engmsg.h
modified: storage/connect/global.h
modified: storage/connect/ha_connect.cc
modified: storage/connect/ha_connect.h
modified: storage/connect/msgid.h
modified: storage/connect/mycat.cc
modified: storage/connect/mycat.h
modified: storage/connect/os.h
modified: storage/connect/osutil.c
modified: storage/connect/osutil.h
modified: storage/connect/user_connect.cc
modified: storage/connect/user_connect.h
Diffstat (limited to 'storage/connect/tabjmg.cpp')
-rw-r--r-- | storage/connect/tabjmg.cpp | 505 |
1 files changed, 505 insertions, 0 deletions
diff --git a/storage/connect/tabjmg.cpp b/storage/connect/tabjmg.cpp new file mode 100644 index 00000000000..c784fa9b3c0 --- /dev/null +++ b/storage/connect/tabjmg.cpp @@ -0,0 +1,505 @@ +/************** tabjmg C++ Program Source Code File (.CPP) *************/ +/* PROGRAM NAME: tabjmg Version 1.2 */ +/* (C) Copyright to the author Olivier BERTRAND 2017 */ +/* This file contains the MongoDB classes using the Java Driver. */ +/***********************************************************************/ + +/***********************************************************************/ +/* Include relevant sections of the MariaDB header file. */ +/***********************************************************************/ +#include <my_global.h> + +/***********************************************************************/ +/* Include application header files: */ +/* global.h is header containing all global declarations. */ +/* plgdbsem.h is header containing the DB application declarations. */ +/***********************************************************************/ +#include "global.h" +#include "plgdbsem.h" +#include "xtable.h" +#include "maputil.h" +#include "filamtxt.h" +#include "tabext.h" +#include "tabjmg.h" +#include "tabmul.h" +#include "checklvl.h" +#include "resource.h" +#include "mycat.h" // for FNC_COL +#include "filter.h" + +/***********************************************************************/ +/* This should be an option. */ +/***********************************************************************/ +#define MAXCOL 200 /* Default max column nb in result */ +#define TYPE_UNKNOWN 12 /* Must be greater than other types */ + +/* --------------------------- Class TDBJMG -------------------------- */ + +/***********************************************************************/ +/* Implementation of the TDBJMG class. */ +/***********************************************************************/ +TDBJMG::TDBJMG(PMGODEF tdp) : TDBEXT(tdp) +{ + Jcp = NULL; +//Cnp = NULL; + + if (tdp) { + Ops.Driver = tdp->Tabschema; + Ops.Url = tdp->Uri; + Ops.Version = tdp->Version; + Uri = tdp->Uri; + Db_name = tdp->Tabschema; + Wrapname = tdp->Wrapname; + Coll_name = tdp->Tabname; + Options = tdp->Colist; + Filter = tdp->Filter; + B = tdp->Base ? 1 : 0; + Pipe = tdp->Pipe && Options != NULL; + } else { + Ops.Driver = NULL; + Ops.Url = NULL; + Ops.Version = 0; + Uri = NULL; + Db_name = NULL; + Coll_name = NULL; + Options = NULL; + Filter = NULL; + B = 0; + Pipe = false; + } // endif tdp + + Ops.User = NULL; + Ops.Pwd = NULL; + Ops.Scrollable = false; + Ops.Fsize = Ops.CheckSize(Rows); + Fpos = -1; + N = 0; + Done = false; +} // end of TDBJMG standard constructor + +TDBJMG::TDBJMG(TDBJMG *tdbp) : TDBEXT(tdbp) +{ + Uri = tdbp->Uri; +//Pool = tdbp->Pool; +//Client = tdbp->Client; +//Database = NULL; +//Collection = tdbp->Collection; +//Cursor = tdbp->Cursor; +//Query = tdbp->Query; +//Opts = tdbp->Opts; +//Fpc = tdbp->Fpc; +//Cnd = tdbp->Cnd; +//Uristr = tdbp->Uristr; + Db_name = tdbp->Db_name;; + Coll_name = tdbp->Coll_name; + Options = tdbp->Options; + Filter = tdbp->Filter; + B = tdbp->B; + Fpos = tdbp->Fpos; + N = tdbp->N; + Done = tdbp->Done; + Pipe = tdbp->Pipe; +} // end of TDBJMG copy constructor + +// Used for update +PTDB TDBJMG::Clone(PTABS t) +{ + PTDB tp; + PJMGCOL cp1, cp2; + PGLOBAL g = t->G; + + tp = new(g) TDBJMG(this); + + for (cp1 = (PJMGCOL)Columns; cp1; cp1 = (PJMGCOL)cp1->GetNext()) + if (!cp1->IsSpecial()) { + cp2 = new(g) JMGCOL(cp1, tp); // Make a copy + NewPointer(t, cp1, cp2); + } // endif cp1 + + return tp; +} // end of Clone + +/***********************************************************************/ +/* Allocate JSN column description block. */ +/***********************************************************************/ +PCOL TDBJMG::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) +{ + PJMGCOL colp = new(g) JMGCOL(g, cdp, this, cprec, n); + +//colp->Mbuf = (char*)PlugSubAlloc(g, NULL, colp->Long + 1); + return colp; + //return (colp->ParseJpath(g)) ? NULL : colp; +} // end of MakeCol + +/***********************************************************************/ +/* InsertSpecialColumn: Put a special column ahead of the column list.*/ +/***********************************************************************/ +PCOL TDBJMG::InsertSpecialColumn(PCOL colp) +{ + if (!colp->IsSpecial()) + return NULL; + + colp->SetNext(Columns); + Columns = colp; + return colp; +} // end of InsertSpecialColumn + +/***********************************************************************/ +/* MONGO Cardinality: returns table size in number of rows. */ +/***********************************************************************/ +int TDBJMG::Cardinality(PGLOBAL g) +{ + if (!g) + return 1; + else if (Cardinal < 0) + Cardinal = (!Init(g)) ? Jcp->CollSize(g) : 0; + + return Cardinal; +} // end of Cardinality + +/***********************************************************************/ +/* MONGO GetMaxSize: returns collection size estimate. */ +/***********************************************************************/ +int TDBJMG::GetMaxSize(PGLOBAL g) +{ + if (MaxSize < 0) + MaxSize = Cardinality(g); + + return MaxSize; +} // end of GetMaxSize + +/***********************************************************************/ +/* Init: initialize MongoDB processing. */ +/***********************************************************************/ +bool TDBJMG::Init(PGLOBAL g) +{ + if (Done) + return false; + + /*********************************************************************/ + /* Open an JDBC connection for this table. */ + /* Note: this may not be the proper way to do. Perhaps it is better */ + /* to test whether a connection is already open for this datasource */ + /* and if so to allocate just a new result set. But this only for */ + /* drivers allowing concurency in getting results ??? */ + /*********************************************************************/ + if (!Jcp) + Jcp = new(g) JMgoConn(g, Coll_name, Wrapname); + else if (Jcp->IsOpen()) + Jcp->Close(); + + if (Jcp->Connect(&Ops)) + return true; + + Done = true; + return false; +} // end of Init + +/***********************************************************************/ +/* OpenDB: Data Base open routine for MONGO access method. */ +/***********************************************************************/ +bool TDBJMG::OpenDB(PGLOBAL g) +{ + if (Use == USE_OPEN) { + /*******************************************************************/ + /* Table already open replace it at its beginning. */ + /*******************************************************************/ + if (Jcp->Rewind()) + return true; + + Fpos = -1; + return false; + } // endif Use + + /*********************************************************************/ + /* First opening. */ + /*********************************************************************/ + if (Pipe && Mode != MODE_READ) { + strcpy(g->Message, "Pipeline tables are read only"); + return true; + } // endif Pipe + + if (Init(g)) + return true; + + if (Jcp->GetMethodId(g, Mode)) + return true; + + if (Mode == MODE_DELETE && !Next) { + // Delete all documents + if (!Jcp->MakeCursor(g, this, "all", Filter, false)) + if (Jcp->DocDelete(g, true) == RC_OK) + return false; + + return true; + } // endif Mode + + if (Mode == MODE_INSERT) + Jcp->MakeColumnGroups(g, this); + + if (Mode != MODE_UPDATE) + return Jcp->MakeCursor(g, this, Options, Filter, Pipe); + + return false; +} // end of OpenDB + +/***********************************************************************/ +/* Data Base indexed read routine for ODBC access method. */ +/***********************************************************************/ +bool TDBJMG::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr) +{ + strcpy(g->Message, "MONGO tables are not indexable"); + return true; +} // end of ReadKey + +/***********************************************************************/ +/* ReadDB: Get next document from a collection. */ +/***********************************************************************/ +int TDBJMG::ReadDB(PGLOBAL g) +{ + int rc = RC_OK; + + if (!N && Mode == MODE_UPDATE) + if (Jcp->MakeCursor(g, this, Options, Filter, Pipe)) + return RC_FX; + + if (++CurNum >= Rbuf) { + Rbuf = Jcp->Fetch(); + Curpos = Fpos + 1; + CurNum = 0; + N++; + } // endif CurNum + + rc = (Rbuf > 0) ? RC_OK : (Rbuf == 0) ? RC_EF : RC_FX; + + return rc; +} // end of ReadDB + +/***********************************************************************/ +/* WriteDB: Data Base write routine for DOS access method. */ +/***********************************************************************/ +int TDBJMG::WriteDB(PGLOBAL g) +{ + int rc = RC_OK; + + if (Mode == MODE_INSERT) { + rc = Jcp->DocWrite(g); + } else if (Mode == MODE_DELETE) { + rc = Jcp->DocDelete(g, false); + } else if (Mode == MODE_UPDATE) { + rc = Jcp->DocUpdate(g, this); + } // endif Mode + + return rc; +} // end of WriteDB + +/***********************************************************************/ +/* Data Base delete line routine for ODBC access method. */ +/***********************************************************************/ +int TDBJMG::DeleteDB(PGLOBAL g, int irc) +{ + return (irc == RC_OK) ? WriteDB(g) : RC_OK; +} // end of DeleteDB + +/***********************************************************************/ +/* Table close routine for MONGO tables. */ +/***********************************************************************/ +void TDBJMG::CloseDB(PGLOBAL g) +{ + Jcp->Close(); + Done = false; +} // end of CloseDB + +/* ----------------------------- JMGCOL ------------------------------ */ + +/***********************************************************************/ +/* JMGCOL public constructor. */ +/***********************************************************************/ +JMGCOL::JMGCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i) + : EXTCOL(cdp, tdbp, cprec, i, "MGO") +{ + Tmgp = (PTDBJMG)(tdbp->GetOrig() ? tdbp->GetOrig() : tdbp); + Jpath = cdp->GetFmt() ? cdp->GetFmt() : cdp->GetName(); +//Mbuf = NULL; +} // end of JMGCOL constructor + +/***********************************************************************/ +/* JMGCOL constructor used for copying columns. */ +/* tdbp is the pointer to the new table descriptor. */ +/***********************************************************************/ +JMGCOL::JMGCOL(JMGCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp) +{ + Tmgp = col1->Tmgp; + Jpath = col1->Jpath; +//Mbuf = col1->Mbuf; +} // end of JMGCOL copy constructor + +/***********************************************************************/ +/* Get path when proj is false or projection path when proj is true. */ +/***********************************************************************/ +PSZ JMGCOL::GetJpath(PGLOBAL g, bool proj) +{ + if (Jpath) { + if (proj) { + char *p1, *p2, *projpath = PlugDup(g, Jpath); + int i = 0; + + for (p1 = p2 = projpath; *p1; p1++) + if (*p1 == '.') { + if (!i) + *p2++ = *p1; + + i = 1; + } else if (i) { + if (!isdigit(*p1)) { + *p2++ = *p1; + i = 0; + } // endif p1 + + } else + *p2++ = *p1; + + *p2 = 0; + return projpath; + } else + return Jpath; + + } else + return Name; + +} // end of GetJpath + +#if 0 +/***********************************************************************/ +/* Mini: used to suppress blanks to json strings. */ +/***********************************************************************/ +char *JMGCOL::Mini(PGLOBAL g, const bson_t *bson, bool b) +{ + char *s, *str = NULL; + int i, k = 0; + bool ok = true; + + if (b) + s = str = bson_array_as_json(bson, NULL); + else + s = str = bson_as_json(bson, NULL); + + for (i = 0; i < Long && s[i]; i++) { + switch (s[i]) { + case ' ': + if (ok) continue; + case '"': + ok = !ok; + default: + break; + } // endswitch s[i] + + Mbuf[k++] = s[i]; + } // endfor i + + bson_free(str); + + if (i >= Long) { + sprintf(g->Message, "Value too long for column %s", Name); + throw (int)TYPE_AM_MGO; + } // endif i + + Mbuf[k] = 0; + return Mbuf; +} // end of Mini +#endif // 0 + +/***********************************************************************/ +/* ReadColumn: */ +/***********************************************************************/ +void JMGCOL::ReadColumn(PGLOBAL g) +{ + Value->SetValue_psz(Tmgp->Jcp->GetColumnValue(Jpath)); +} // end of ReadColumn + +/***********************************************************************/ +/* WriteColumn: */ +/***********************************************************************/ +void JMGCOL::WriteColumn(PGLOBAL g) +{ + // Check whether this node must be written + if (Value != To_Val) + Value->SetValue_pval(To_Val, FALSE); // Convert the updated value + +} // end of WriteColumn + +#if 0 +/***********************************************************************/ +/* AddValue: Add column value to the document to insert or update. */ +/***********************************************************************/ +bool JMGCOL::AddValue(PGLOBAL g, bson_t *doc, char *key, bool upd) +{ + bool rc = false; + + if (Value->IsNull()) { + if (upd) + rc = BSON_APPEND_NULL(doc, key); + else + return false; + + } else switch (Buf_Type) { + case TYPE_STRING: + rc = BSON_APPEND_UTF8(doc, key, Value->GetCharValue()); + break; + case TYPE_INT: + case TYPE_SHORT: + rc = BSON_APPEND_INT32(doc, key, Value->GetIntValue()); + break; + case TYPE_TINY: + rc = BSON_APPEND_BOOL(doc, key, Value->GetIntValue()); + break; + case TYPE_BIGINT: + rc = BSON_APPEND_INT64(doc, key, Value->GetBigintValue()); + break; + case TYPE_DOUBLE: + rc = BSON_APPEND_DOUBLE(doc, key, Value->GetFloatValue()); + break; + case TYPE_DECIM: + {bson_decimal128_t dec; + + if (bson_decimal128_from_string(Value->GetCharValue(), &dec)) + rc = BSON_APPEND_DECIMAL128(doc, key, &dec); + + } break; + case TYPE_DATE: + rc = BSON_APPEND_DATE_TIME(doc, key, Value->GetBigintValue() * 1000); + break; + default: + sprintf(g->Message, "Type %d not supported yet", Buf_Type); + return true; + } // endswitch Buf_Type + + if (!rc) { + strcpy(g->Message, "Adding value failed"); + return true; + } else + return false; + +} // end of AddValue + +/* ---------------------------TDBGOL class --------------------------- */ + +/***********************************************************************/ +/* TDBGOL class constructor. */ +/***********************************************************************/ +TDBGOL::TDBGOL(PMGODEF tdp) : TDBCAT(tdp) +{ + Topt = tdp->GetTopt(); + Db = (char*)tdp->GetTabschema(); +} // end of TDBJCL constructor + + /***********************************************************************/ + /* GetResult: Get the list the JSON file columns. */ + /***********************************************************************/ +PQRYRES TDBGOL::GetResult(PGLOBAL g) +{ + return MGOColumns(g, Db, Topt, false); +} // end of GetResult +#endif // 0 + + /* -------------------------- End of mongo --------------------------- */ |