summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2021-04-05 17:01:43 +0200
committerOlivier Bertrand <bertrandop@gmail.com>2021-04-05 17:01:43 +0200
commitcaff19ada53f7414b646d0b46a927e1b8a22fd8e (patch)
tree354209f246d407de2d0912db87210d1326600896
parente85006e6708800b3b3cdc6a40b43acc43880e075 (diff)
downloadmariadb-git-caff19ada53f7414b646d0b46a927e1b8a22fd8e.tar.gz
- Copy Mongo2.jar and Mongo3.jar in plugin directory
modified: storage/connect/CMakeLists.txt modified: storage/connect/javaconn.cpp - Check privileges while creating tables with Discovery modified: storage/connect/ha_connect.cc - Calculate LRECL for JSON tables created with Discovery modified: storage/connect/tabjson.cpp - Use CreateProcess (Windows) or fork/exec (linux) to retrieve the result from REST queries modified: storage/connect/tabrest.cpp - Typo modified: storage/connect/jmgoconn.cpp
-rw-r--r--storage/connect/CMakeLists.txt4
-rw-r--r--storage/connect/Mongo2.jarbin0 -> 623907 bytes
-rw-r--r--storage/connect/Mongo3.jarbin0 -> 1705776 bytes
-rw-r--r--storage/connect/ha_connect.cc58
-rw-r--r--storage/connect/javaconn.cpp21
-rw-r--r--storage/connect/jmgoconn.cpp9
-rw-r--r--storage/connect/tabjson.cpp23
-rw-r--r--storage/connect/tabrest.cpp93
8 files changed, 161 insertions, 47 deletions
diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
index 77e77227e21..72934aa953c 100644
--- a/storage/connect/CMakeLists.txt
+++ b/storage/connect/CMakeLists.txt
@@ -409,6 +409,10 @@ IF(CONNECT_WITH_JDBC AND JAVA_FOUND AND JNI_FOUND)
INSTALL(FILES
${CMAKE_CURRENT_SOURCE_DIR}/JavaWrappers.jar
${CMAKE_CURRENT_BINARY_DIR}/JdbcInterface.jar
+ IF(CONNECT_WITH_MONGO)
+ ${CMAKE_CURRENT_SOURCE_DIR}/Mongo2.jar
+ ${CMAKE_CURRENT_SOURCE_DIR}/Mongo3.jar
+ ENDIF()
DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
ENDIF()
diff --git a/storage/connect/Mongo2.jar b/storage/connect/Mongo2.jar
new file mode 100644
index 00000000000..9be654bd4c8
--- /dev/null
+++ b/storage/connect/Mongo2.jar
Binary files differ
diff --git a/storage/connect/Mongo3.jar b/storage/connect/Mongo3.jar
new file mode 100644
index 00000000000..2850177a668
--- /dev/null
+++ b/storage/connect/Mongo3.jar
Binary files differ
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 7682063c410..2686bb4338e 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -170,7 +170,7 @@
#define JSONMAX 10 // JSON Default max grp size
extern "C" {
- char version[]= "Version 1.07.0002 January 27, 2021";
+ char version[]= "Version 1.07.0002 March 22, 2021";
#if defined(__WIN__)
char compver[]= "Version 1.07.0002 " __DATE__ " " __TIME__;
char slash= '\\';
@@ -277,6 +277,10 @@ static handler *connect_create_handler(handlerton *hton,
TABLE_SHARE *table,
MEM_ROOT *mem_root);
+static bool checkPrivileges(THD* thd, TABTYPE type, PTOS options,
+ const char* db, TABLE* table = NULL,
+ bool quick = false);
+
static int connect_assisted_discovery(handlerton *hton, THD* thd,
TABLE_SHARE *table_s,
HA_CREATE_INFO *info);
@@ -757,10 +761,10 @@ DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR name, LPCSTR dir)
used by the default rename_table and delete_table method in
handler.cc.
- For engines that have two file name extentions (separate meta/index file
+ For engines that have two file name extensions (separate meta/index file
and data file), the order of elements is relevant. First element of engine
- file name extentions array should be meta/index file extention. Second
- element - data file extention. This order is assumed by
+ file name extensions array should be meta/index file extension. Second
+ element - data file extension. This order is assumed by
prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued.
@see
@@ -1296,9 +1300,9 @@ PCSZ GetStringTableOption(PGLOBAL g, PTOS options, PCSZ opname, PCSZ sdef)
else if (!stricmp(opname, "Data_charset"))
opval= options->data_charset;
else if (!stricmp(opname, "Http") || !stricmp(opname, "URL"))
- opval = options->http;
+ opval= options->http;
else if (!stricmp(opname, "Uri"))
- opval = options->uri;
+ opval= options->uri;
if (!opval && options->oplist)
opval= GetListOption(g, opname, options->oplist);
@@ -1612,7 +1616,7 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
pcf->Opt= (fop) ? (int)fop->opt : 0;
if (fp->field_length >= 0) {
- pcf->Length = fp->field_length;
+ pcf->Length= fp->field_length;
// length is bytes for Connect, not characters
if (!strnicmp(chset, "utf8", 4))
@@ -1627,7 +1631,7 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
pcf->Offset= (int)fop->offset;
pcf->Freq= (int)fop->freq;
pcf->Datefmt= (char*)fop->dateformat;
- pcf->Fieldfmt = fop->fieldformat ? (char*)fop->fieldformat
+ pcf->Fieldfmt= fop->fieldformat ? (char*)fop->fieldformat
: fop->jsonpath ? (char*)fop->jsonpath : (char*)fop->xmlpath;
} else {
pcf->Offset= -1;
@@ -4511,11 +4515,9 @@ int ha_connect::delete_all_rows()
} // end of delete_all_rows
-bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn, bool quick)
+static bool checkPrivileges(THD *thd, TABTYPE type, PTOS options,
+ const char *db, TABLE *table, bool quick)
{
- const char *db= (dbn && *dbn) ? dbn : NULL;
- TABTYPE type=GetRealType(options);
-
switch (type) {
case TAB_UNDEF:
// case TAB_CATLG:
@@ -4598,6 +4600,15 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn, bool quick)
my_printf_error(ER_UNKNOWN_ERROR, "check_privileges failed", MYF(0));
return true;
+} // end of checkPrivileges
+
+// Check whether the user has required (file) privileges
+bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn, bool quick)
+{
+ const char *db= (dbn && *dbn) ? dbn : NULL;
+ TABTYPE type=GetRealType(options);
+
+ return checkPrivileges(thd, type, options, db, table, quick);
} // end of check_privileges
// Check that two indexes are equivalent
@@ -5727,6 +5738,29 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#endif // REST_SUPPORT
} // endif ttp
+ if (fn && *fn)
+ switch (ttp) {
+ case TAB_FMT:
+ case TAB_DBF:
+ case TAB_XML:
+ case TAB_INI:
+ case TAB_VEC:
+ case TAB_REST:
+ case TAB_JSON:
+#if defined(BSON_SUPPORT)
+ case TAB_BSON:
+#endif // BSON_SUPPORT
+ if (checkPrivileges(thd, ttp, topt, db)) {
+ strcpy(g->Message, "This operation requires the FILE privilege");
+ rc= HA_ERR_INTERNAL_ERROR;
+ goto err;
+ } // endif check_privileges
+
+ break;
+ default:
+ break;
+ } // endswitch ttp
+
if (!tab) {
if (ttp == TAB_TBL) {
// Make tab the first table of the list
diff --git a/storage/connect/javaconn.cpp b/storage/connect/javaconn.cpp
index f919344f20b..3737c82a02e 100644
--- a/storage/connect/javaconn.cpp
+++ b/storage/connect/javaconn.cpp
@@ -1,7 +1,7 @@
/************ Javaconn C++ Functions Source Code File (.CPP) ***********/
-/* Name: JAVAConn.CPP Version 1.0 */
+/* Name: JAVAConn.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 JAVA connection classes functions. */
/***********************************************************************/
@@ -400,24 +400,35 @@ bool JAVAConn::Open(PGLOBAL g)
jpop->Append(ClassPath);
} // endif ClassPath
- // Java source will be compiled as a jar file installed in the plugin dir
+#if 0
+ // Java source will be compiled as a jar file installed in the plugin dir
jpop->Append(sep);
jpop->Append(GetPluginDir());
jpop->Append("JdbcInterface.jar");
+#endif // 0
// All wrappers are pre-compiled in JavaWrappers.jar in the plugin dir
jpop->Append(sep);
jpop->Append(GetPluginDir());
jpop->Append("JavaWrappers.jar");
+#if defined(MONGO_SUPPORT)
+ jpop->Append(sep);
+ jpop->Append(GetPluginDir());
+ jpop->Append("Mongo3.jar");
+ jpop->Append(sep);
+ jpop->Append(GetPluginDir());
+ jpop->Append("Mongo2.jar");
+#endif // MONGO_SUPPORT
+
if ((cp = getenv("CLASSPATH"))) {
jpop->Append(sep);
jpop->Append(cp);
} // endif cp
if (trace(1)) {
- htrc("ClassPath=%s\n", ClassPath);
- htrc("CLASSPATH=%s\n", cp);
+ htrc("ClassPath=%s\n", ClassPath ? ClassPath : "null");
+ htrc("CLASSPATH=%s\n", cp ? cp : "null");
htrc("%s\n", jpop->GetStr());
} // endif trace
diff --git a/storage/connect/jmgoconn.cpp b/storage/connect/jmgoconn.cpp
index 8a12fffbd05..0af91bc78cd 100644
--- a/storage/connect/jmgoconn.cpp
+++ b/storage/connect/jmgoconn.cpp
@@ -121,20 +121,21 @@ JMgoConn::JMgoConn(PGLOBAL g, PCSZ collname, PCSZ wrapper)
/***********************************************************************/
void JMgoConn::AddJars(PSTRG jpop, char sep)
{
-#if defined(BSON_SUPPORT)
+#if defined(DEVELOPMENT)
if (m_Version == 2) {
jpop->Append(sep);
// jpop->Append("C:/Eclipse/workspace/MongoWrap2/bin");
- jpop->Append(sep);
+// jpop->Append(sep);
jpop->Append("C:/mongo-java-driver/mongo-java-driver-2.13.3.jar");
} else {
jpop->Append(sep);
// jpop->Append("C:/Eclipse/workspace/MongoWrap3/bin");
+// jpop->Append(sep);
// jpop->Append("C:/Program Files/MariaDB 10.1/lib/plugin/JavaWrappers.jar");
- jpop->Append(sep);
+// jpop->Append(sep);
jpop->Append("C:/mongo-java-driver/mongo-java-driver-3.4.2.jar");
} // endif m_Version
-#endif // BSON_SUPPORT
+#endif // DEVELOPMENT
} // end of AddJars
/***********************************************************************/
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index 185ad3ebc8b..dee4b737a89 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -9,6 +9,8 @@
/* Include relevant sections of the MariaDB header file. */
/***********************************************************************/
#include <my_global.h>
+#include <mysqld.h>
+#include <sql_error.h>
/***********************************************************************/
/* Include application header files: */
@@ -168,6 +170,7 @@ JSONDISC::JSONDISC(PGLOBAL g, uint *lg)
int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
{
char filename[_MAX_PATH];
+ size_t reclg = 0;
bool mgo = (GetTypeID(topt->type) == TAB_MONGO);
PGLOBAL G = NULL;
@@ -252,11 +255,11 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
jsp = (tjsp->GetDoc()) ? tjsp->GetDoc()->GetArrayValue(0) : NULL;
} else {
if (!((tdp->Lrecl = GetIntegerTableOption(g, topt, "Lrecl", 0)))) {
- if (!mgo) {
+ if (!mgo && !tdp->Uri) {
sprintf(g->Message, "LRECL must be specified for pretty=%d", tdp->Pretty);
return 0;
- } else
- tdp->Lrecl = 8192; // Should be enough
+ } else
+ tdp->Lrecl = 8192; // Should be enough
} // endif Lrecl
@@ -315,7 +318,9 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
case RC_FX:
goto err;
default:
-// jsp = tjnp->FindRow(g); // FindRow was done in ReadDB
+ if (tdp->Pretty != 2)
+ reclg = strlen(tjnp->To_Line);
+
jsp = tjnp->Row;
} // endswitch ReadDB
@@ -366,7 +371,9 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
case RC_FX:
goto err;
default:
-// jsp = tjnp->FindRow(g);
+ if (tdp->Pretty != 2 && reclg < strlen(tjnp->To_Line))
+ reclg = strlen(tjnp->To_Line);
+
jsp = tjnp->Row;
} // endswitch ReadDB
@@ -378,8 +385,12 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
} // endfor i
- if (tdp->Pretty != 2)
+ if (tdp->Pretty != 2) {
+ if (!topt->lrecl)
+ topt->lrecl = reclg + 10;
+
tjnp->CloseDB(g);
+ } // endif Pretty
return n;
diff --git a/storage/connect/tabrest.cpp b/storage/connect/tabrest.cpp
index f0230ef7229..3ac86388ab2 100644
--- a/storage/connect/tabrest.cpp
+++ b/storage/connect/tabrest.cpp
@@ -1,6 +1,6 @@
/************** tabrest C++ Program Source Code File (.CPP) ************/
-/* PROGRAM NAME: tabrest Version 1.8 */
-/* (C) Copyright to the author Olivier BERTRAND 2018 - 2020 */
+/* PROGRAM NAME: tabrest Version 1.9 */
+/* (C) Copyright to the author Olivier BERTRAND 2018 - 2021 */
/* This program is the REST Web API support for MariaDB. */
/* When compiled without MARIADB defined, it is the EOM module code. */
/* The way Connect handles NOSQL data returned by REST queries is */
@@ -53,10 +53,10 @@
#define PUSH_WARNING(M) htrc(M)
#endif
-#if defined(__WIN__) || defined(_WINDOWS)
+#if 0
#define popen _popen
#define pclose _pclose
-#endif
+#endif // 0
static XGETREST getRestFnc = NULL;
static int Xcurl(PGLOBAL g, PCSZ Http, PCSZ Uri, PCSZ filename);
@@ -93,34 +93,87 @@ PTABDEF __stdcall GetREST(PGLOBAL g, void *memp)
/***********************************************************************/
int Xcurl(PGLOBAL g, PCSZ Http, PCSZ Uri, PCSZ filename)
{
- char buf[1024];
- int rc;
+ char buf[512];
+ int rc = 0;
FILE *pipe;
+ if ((pipe = popen("curl --version", "r"))) {
+ if (trace(515))
+ while (fgets(buf, sizeof(buf), pipe)) {
+ htrc("%s", buf);
+ } // endwhile
+
+ pclose(pipe);
+ } else {
+ sprintf(g->Message, "curl not available, errno=%d", errno);
+ return 1;
+ } // endif pipe
+
+ if (strchr(filename, '"')) {
+ strcpy(g->Message, "Invalid file name");
+ return 1;
+ } // endif filename
+
if (Uri) {
if (*Uri == '/' || Http[strlen(Http) - 1] == '/')
- sprintf(buf, "curl \"%s%s\" -o %s", Http, Uri, filename);
+ sprintf(buf, "%s%s", Http, Uri);
else
- sprintf(buf, "curl \"%s/%s\" -o %s", Http, Uri, filename);
+ sprintf(buf, "%s/%s", Http, Uri);
} else
- sprintf(buf, "curl \"%s\" -o %s", Http, filename);
+ strcpy(buf, Http);
- if ((pipe = popen(buf, "rt"))) {
- if (trace(515))
- while (fgets(buf, sizeof(buf), pipe)) {
- htrc("%s", buf);
- } // endwhile
+#if defined(__WIN__)
+ char cmd[1024];
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
- pclose(pipe);
- rc = 0;
+ sprintf(cmd, "curl \"%s\" -o \"%s\"", buf, filename);
+
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+ ZeroMemory(&pi, sizeof(pi));
+
+ // Start the child process.
+ if (CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
+ // Wait until child process exits.
+ WaitForSingleObject(pi.hProcess, INFINITE);
+
+ // Close process and thread handles.
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
} else {
- sprintf(g->Message, "curl failed, errno =%d", errno);
+ sprintf(g->Message, "CreateProcess curl failed (%d)", GetLastError());
rc = 1;
- } // endif pipe
+ } // endif CreateProcess
+#else // !__WIN__
+ char fn[600];
+ int rcd;
+ pid_t pID = vfork();
+
+ sprintf(fn, "-o%s", filename);
+
+ if (pID == 0) {
+ // Code executed by child process
+ execlp("curl", "curl", buf, fn, (char*)NULL);
+ // If execlp() is successful, we should not reach this next line.
+ strcpy(g->Message, explain_execlp());
+ rc = 1;
+ exit(rc);
+ } // endif execlp
+
+ } else if (pID < 0) {
+ // failed to fork
+ strcpy(g->Message, "Failed to fork");
+ rc = 1;
+ } else {
+ // Parent process
+ wait(0); // Wait for the child to terminate
+ } // endif pID
+#endif // !__WIN__
return rc;
-} // end od Xcurl
+} // end of Xcurl
/***********************************************************************/
/* GetREST: load the Rest lib and get the Rest function. */
@@ -319,7 +372,7 @@ bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
} // endelse
if (rc) {
- strcpy(g->Message, "Cannot access to curl nor casablanca");
+ // strcpy(g->Message, "Cannot access to curl nor casablanca");
return true;
} else switch (n) {
case 1: Tdp = new (g) JSONDEF; break;