diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2021-04-05 17:01:43 +0200 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2021-04-05 17:01:43 +0200 |
commit | caff19ada53f7414b646d0b46a927e1b8a22fd8e (patch) | |
tree | 354209f246d407de2d0912db87210d1326600896 | |
parent | e85006e6708800b3b3cdc6a40b43acc43880e075 (diff) | |
download | mariadb-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.txt | 4 | ||||
-rw-r--r-- | storage/connect/Mongo2.jar | bin | 0 -> 623907 bytes | |||
-rw-r--r-- | storage/connect/Mongo3.jar | bin | 0 -> 1705776 bytes | |||
-rw-r--r-- | storage/connect/ha_connect.cc | 58 | ||||
-rw-r--r-- | storage/connect/javaconn.cpp | 21 | ||||
-rw-r--r-- | storage/connect/jmgoconn.cpp | 9 | ||||
-rw-r--r-- | storage/connect/tabjson.cpp | 23 | ||||
-rw-r--r-- | storage/connect/tabrest.cpp | 93 |
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 Binary files differnew file mode 100644 index 00000000000..9be654bd4c8 --- /dev/null +++ b/storage/connect/Mongo2.jar diff --git a/storage/connect/Mongo3.jar b/storage/connect/Mongo3.jar Binary files differnew file mode 100644 index 00000000000..2850177a668 --- /dev/null +++ b/storage/connect/Mongo3.jar 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; |