From e6fcd7230954c6111bba63e7f7201fc81e50178e Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sun, 2 Dec 2018 00:25:05 +0100 Subject: Squashed commit of connect/10.0: commit 6a6a1f37798 Author: Olivier Bertrand Date: Fri Jan 4 12:31:52 2019 +0100 - Fix a few bug mainly concerning discovery and call from OEM (and prepare new table types) modified: storage/connect/tabjson.cpp modified: storage/connect/tabjson.h modified: storage/connect/tabxml.cpp modified: storage/connect/tabxml.h - Fix wrong line estimate modified: storage/connect/mysql-test/connect/r/part_table.result modified: storage/connect/mysql-test/connect/t/part_table.test commit bd7d2e912d9 Author: Olivier Bertrand Date: Tue Dec 4 23:35:09 2018 +0100 Fix wrong version number commit 4933680e7ab Author: Olivier Bertrand Date: Sun Dec 2 00:25:05 2018 +0100 - Make PlugSubAlloc to be exportable Suppress unused parameter from PlugSubSet modified: storage/connect/global.h modified: storage/connect/plugutil.cpp modified: storage/connect/jsonudf.cpp modified: storage/connect/tabjson.cpp modified: storage/connect/user_connect.cc - Fix a bug making column catalog XML tables fail modified: storage/connect/tabxml.cpp - Comment out wrong message modified: storage/connect/ha_connect.cc - Update error message when sorting an ODBC table fails modified: storage/connect/tabodbc.cpp - Add error message when gettting an address from an OEM fails. modified: storage/connect/reldef.cpp - Make some modifications useful for OEM module writting Export discovery functions for CSV, JDBC and XML Remove unuseful include from tabjson.h Move TDBXML::data_charset function from header file to source modified: storage/connect/tabfmt.h modified: storage/connect/tabjson.h modified: storage/connect/tabxml.cpp modified: storage/connect/tabxml.h - Update test result modified: storage/connect/mysql-test/connect/r/jdbc_oracle.result --- storage/connect/global.h | 6 +- storage/connect/ha_connect.cc | 4 +- storage/connect/jsonudf.cpp | 12 +- .../mysql-test/connect/r/jdbc_oracle.result | 18 +- .../mysql-test/connect/r/jdbc_postgresql.result | 10 +- .../connect/mysql-test/connect/r/part_table.result | 4 +- .../connect/mysql-test/connect/t/part_table.test | 2 +- storage/connect/plugutil.cpp | 28 +- storage/connect/reldef.cpp | 11 +- storage/connect/tabfmt.h | 2 +- storage/connect/tabjson.cpp | 52 ++-- storage/connect/tabjson.h | 8 +- storage/connect/tabodbc.cpp | 317 +++++++++++---------- storage/connect/tabxml.cpp | 292 ++++++++++--------- storage/connect/tabxml.h | 6 +- storage/connect/user_connect.cc | 4 +- 16 files changed, 426 insertions(+), 350 deletions(-) diff --git a/storage/connect/global.h b/storage/connect/global.h index 36e8a311124..dc1e149745f 100644 --- a/storage/connect/global.h +++ b/storage/connect/global.h @@ -219,11 +219,11 @@ DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR prefix, LPCSTR name, LPCSTR dir); DllExport BOOL PlugIsAbsolutePath(LPCSTR path); DllExport bool AllocSarea(PGLOBAL, uint); DllExport void FreeSarea(PGLOBAL); -DllExport BOOL PlugSubSet(PGLOBAL, void *, uint); +DllExport BOOL PlugSubSet(void *, uint); +DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t); DllExport char *PlugDup(PGLOBAL g, const char *str); DllExport void *MakePtr(void *, OFFSET); DllExport void htrc(char const *fmt, ...); -//DllExport int GetTraceValue(void); DllExport uint GetTraceValue(void); #if defined(__cplusplus) @@ -233,6 +233,6 @@ DllExport uint GetTraceValue(void); /***********************************************************************/ /* Non exported routine declarations. */ /***********************************************************************/ -void *PlugSubAlloc(PGLOBAL, void *, size_t); // Does throw +//void *PlugSubAlloc(PGLOBAL, void *, size_t); // Does throw /*-------------------------- End of Global.H --------------------------*/ diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index bf890724d5e..1e826f67573 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -4191,7 +4191,7 @@ int ha_connect::rnd_pos(uchar *buf, uchar *pos) rc= rnd_next(buf); } else { PGLOBAL g = GetPlug((table) ? table->in_use : NULL, xp); - strcpy(g->Message, "Not supported by this table type"); +// strcpy(g->Message, "Not supported by this table type"); my_message(ER_ILLEGAL_HA, g->Message, MYF(0)); rc= HA_ERR_INTERNAL_ERROR; } // endif SetRecpos @@ -7307,7 +7307,7 @@ maria_declare_plugin(connect) PLUGIN_LICENSE_GPL, connect_init_func, /* Plugin Init */ connect_done_func, /* Plugin Deinit */ - 0x0107, /* version number (1.05) */ + 0x0106, /* version number (1.06) */ NULL, /* status variables */ connect_system_variables, /* system variables */ "1.06.0008", /* string version */ diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 26455d572b6..d5a3a840173 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -3055,7 +3055,7 @@ my_bool json_array_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message) PGLOBAL g = (PGLOBAL)initid->ptr; - PlugSubSet(g, g->Sarea, g->Sarea_Size); + PlugSubSet(g->Sarea, g->Sarea_Size); g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JAR); g->N = (int)n; return false; @@ -3098,7 +3098,7 @@ void json_array_grp_clear(UDF_INIT *initid, char*, char*) { PGLOBAL g = (PGLOBAL)initid->ptr; - PlugSubSet(g, g->Sarea, g->Sarea_Size); + PlugSubSet(g->Sarea, g->Sarea_Size); g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JAR); g->N = GetJsonGroupSize(); } // end of json_array_grp_clear @@ -3132,7 +3132,7 @@ my_bool json_object_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message) PGLOBAL g = (PGLOBAL)initid->ptr; - PlugSubSet(g, g->Sarea, g->Sarea_Size); + PlugSubSet(g->Sarea, g->Sarea_Size); g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JOB); g->N = (int)n; return false; @@ -3169,7 +3169,7 @@ void json_object_grp_clear(UDF_INIT *initid, char*, char*) { PGLOBAL g = (PGLOBAL)initid->ptr; - PlugSubSet(g, g->Sarea, g->Sarea_Size); + PlugSubSet(g->Sarea, g->Sarea_Size); g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JOB); g->N = GetJsonGroupSize(); } // end of json_object_grp_clear @@ -4418,7 +4418,7 @@ char *json_file(UDF_INIT *initid, UDF_ARGS *args, char *result, } else if (initid->const_item) g->N = 1; - PlugSubSet(g, g->Sarea, g->Sarea_Size); + PlugSubSet(g->Sarea, g->Sarea_Size); fn = MakePSZ(g, args, 0); if (args->arg_count > 1) { @@ -5662,7 +5662,7 @@ char *jbin_file(UDF_INIT *initid, UDF_ARGS *args, char *result, if (bsp && !bsp->Changed) goto fin; - PlugSubSet(g, g->Sarea, g->Sarea_Size); + PlugSubSet(g->Sarea, g->Sarea_Size); g->Xchk = NULL; fn = MakePSZ(g, args, 0); pretty = (args->arg_count > 2 && args->args[2]) ? (int)*(longlong*)args->args[2] : 3; diff --git a/storage/connect/mysql-test/connect/r/jdbc_oracle.result b/storage/connect/mysql-test/connect/r/jdbc_oracle.result index 2e36891a037..ec314c5f072 100644 --- a/storage/connect/mysql-test/connect/r/jdbc_oracle.result +++ b/storage/connect/mysql-test/connect/r/jdbc_oracle.result @@ -8,12 +8,19 @@ SELECT * FROM t2 WHERE command = 'drop table employee'; command number message drop table employee 0 Execute: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist +Warnings: +Warning 1105 Execute: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist + SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary number(8,2))'; command number message create table employee (id int not null, name varchar(32), title char(16), salary number(8,2)) 0 Affected rows +Warnings: +Warning 1105 Affected rows SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)"; command number message insert into employee values(4567,'Johnson', 'Engineer', 12560.50) 1 Affected rows +Warnings: +Warning 1105 Affected rows CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' OPTION_LIST='User=system,Password=manager'; @@ -27,8 +34,8 @@ OPTION_LIST='User=system,Password=manager'; SELECT * FROM t1; Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks NULL SYSTEM EMPLOYEE ID 3 NUMBER 38 0 0 10 0 NULL -NULL SYSTEM EMPLOYEE NAME 12 VARCHAR2 32 0 0 10 1 NULL -NULL SYSTEM EMPLOYEE TITLE 1 CHAR 16 0 0 10 1 NULL +NULL SYSTEM EMPLOYEE NAME 12 VARCHAR2 32 0 NULL 10 1 NULL +NULL SYSTEM EMPLOYEE TITLE 1 CHAR 16 0 NULL 10 1 NULL NULL SYSTEM EMPLOYEE SALARY 3 NUMBER 8 0 2 10 1 NULL DROP TABLE t1; CREATE SERVER 'oracle' FOREIGN DATA WRAPPER 'oracle.jdbc.driver.OracleDriver' OPTIONS ( @@ -52,7 +59,7 @@ Note 1105 EMPLOYEE: 1 affected rows SELECT * FROM t1; ID NAME TITLE SALARY 4567 Trump Engineer 12560.50 -6214 Clinton Retired 0.00 +6214 Clinton Retired NULL DELETE FROM t1 WHERE id = 6214; Warnings: Note 1105 EMPLOYEE: 1 affected rows @@ -63,8 +70,7 @@ DROP TABLE t1; SELECT * FROM t2 WHERE command = 'drop table employee'; command number message drop table employee 0 Affected rows +Warnings: +Warning 1105 Affected rows DROP TABLE t2; DROP SERVER 'oracle'; -SET GLOBAL connect_jvm_path=NULL; -SET GLOBAL connect_class_path=NULL; -SET GLOBAL time_zone = SYSTEM; diff --git a/storage/connect/mysql-test/connect/r/jdbc_postgresql.result b/storage/connect/mysql-test/connect/r/jdbc_postgresql.result index 7969672dd66..bec1dc8725b 100644 --- a/storage/connect/mysql-test/connect/r/jdbc_postgresql.result +++ b/storage/connect/mysql-test/connect/r/jdbc_postgresql.result @@ -1,4 +1,4 @@ -SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/JavaWrappers.jar;C:/Jconnectors/postgresql-42.2.1.jar'; +SET GLOBAL connect_class_path='C:/MariaDB-10.0/MariaDB/storage/connect/mysql-test/connect/std_data/JavaWrappers.jar;C:/Jconnectors/postgresql-42.2.1.jar'; CREATE TABLE t2 ( command varchar(128) not null, number int(5) not null flag=1, @@ -9,12 +9,18 @@ OPTION_LIST='Execsrc=1'; SELECT * FROM t2 WHERE command='drop table employee'; command number message drop table employee 0 Execute: org.postgresql.util.PSQLException: ERREUR: la table « employee » n'existe pas +Warnings: +Warning 1105 Execute: org.postgresql.util.PSQLException: ERREUR: la table « employee » n'existe pas SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary decimal(8,2))'; command number message create table employee (id int not null, name varchar(32), title char(16), salary decimal(8,2)) 0 Affected rows +Warnings: +Warning 1105 Affected rows SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)"; command number message insert into employee values(4567,'Johnson', 'Engineer', 12560.50) 1 Affected rows +Warnings: +Warning 1105 Affected rows CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables CONNECTION='jdbc:postgresql://localhost/test?user=postgres&password=tinono' OPTION_LIST='Tabtype=TABLE,Maxres=10'; @@ -63,4 +69,6 @@ DROP SERVER 'postgresql'; SELECT * FROM t2 WHERE command='drop table employee'; command number message drop table employee 0 Affected rows +Warnings: +Warning 1105 Affected rows DROP TABLE t2; diff --git a/storage/connect/mysql-test/connect/r/part_table.result b/storage/connect/mysql-test/connect/r/part_table.result index f3a556ae784..ee17a1d32b9 100644 --- a/storage/connect/mysql-test/connect/r/part_table.result +++ b/storage/connect/mysql-test/connect/r/part_table.result @@ -23,7 +23,7 @@ id msg CREATE TABLE xt3 ( id INT KEY NOT NULL, msg VARCHAR(32)) -ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=10; +ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=6; Warnings: Warning 1105 No file name. Table will use xt3.csv INSERT INTO xt3 VALUES(60,'sixty'),(81,'eighty one'),(72,'seventy two'); @@ -92,7 +92,7 @@ id msg EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id = 81; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 3 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t1 3 ALL NULL NULL NULL NULL 6 Using where DELETE FROM t1; Warnings: Note 1105 xt1: 4 affected rows diff --git a/storage/connect/mysql-test/connect/t/part_table.test b/storage/connect/mysql-test/connect/t/part_table.test index 5edd5766bd6..0fb2a11f0f9 100644 --- a/storage/connect/mysql-test/connect/t/part_table.test +++ b/storage/connect/mysql-test/connect/t/part_table.test @@ -22,7 +22,7 @@ SELECT * FROM xt2; CREATE TABLE xt3 ( id INT KEY NOT NULL, msg VARCHAR(32)) -ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=10; +ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=6; INSERT INTO xt3 VALUES(60,'sixty'),(81,'eighty one'),(72,'seventy two'); SELECT * FROM xt3; diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp index 887527e38ab..048f00be75f 100644 --- a/storage/connect/plugutil.cpp +++ b/storage/connect/plugutil.cpp @@ -514,27 +514,31 @@ void FreeSarea(PGLOBAL g) /* Here there should be some verification done such as validity of */ /* the address and size not larger than memory size. */ /***********************************************************************/ -BOOL PlugSubSet(PGLOBAL g __attribute__((unused)), void *memp, uint size) +BOOL PlugSubSet(void *memp, uint size) { PPOOLHEADER pph = (PPOOLHEADER)memp; pph->To_Free = (OFFSET)sizeof(POOLHEADER); pph->FreeBlk = size - pph->To_Free; - return FALSE; } /* end of PlugSubSet */ +/***********************************************************************/ +/* Use it to export a function that do throwing. */ +/***********************************************************************/ +void *DoThrow(int n) +{ + throw n; +} /* end of DoThrow */ + /***********************************************************************/ /* Program for sub-allocating one item in a storage area. */ -/* Note: SubAlloc routines of OS/2 are no more used to increase the */ -/* code portability and avoid problems when a grammar compiled under */ -/* one version of OS/2 is used under another version. */ -/* The simple way things are done here is also based on the fact */ -/* that no freeing of suballocated blocks is permitted in Plug. */ +/* The simple way things are done here is based on the fact */ +/* that no freeing of suballocated blocks is permitted in CONNECT. */ /***********************************************************************/ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) - { - PPOOLHEADER pph; /* Points on area header. */ +{ + PPOOLHEADER pph; /* Points on area header. */ if (!memp) /*******************************************************************/ @@ -559,8 +563,8 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) if (trace(1)) htrc("PlugSubAlloc: %s\n", g->Message); - throw 1234; - } /* endif size OS32 code */ + DoThrow(1234); + } /* endif size OS32 code */ /*********************************************************************/ /* Do the suballocation the simplest way. */ @@ -574,7 +578,7 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) memp, pph->To_Free, pph->FreeBlk); return (memp); - } /* end of PlugSubAlloc */ +} /* end of PlugSubAlloc */ /***********************************************************************/ /* Program for sub-allocating and copying a string in a storage area. */ diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp index e4f169575f8..30d8063d1a6 100644 --- a/storage/connect/reldef.cpp +++ b/storage/connect/reldef.cpp @@ -522,8 +522,15 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g) // Get the function returning an instance of the external DEF class if (!(getdef = (XGETDEF)GetProcAddress((HINSTANCE)Hdll, getname))) { - sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), getname); - FreeLibrary((HMODULE)Hdll); + char buf[256]; + DWORD rc = GetLastError(); + + sprintf(g->Message, MSG(PROCADD_ERROR), rc, getname); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0, + (LPTSTR)buf, sizeof(buf), NULL); + strcat(strcat(g->Message, ": "), buf); + FreeLibrary((HMODULE)Hdll); return NULL; } // endif getdef #else // !__WIN__ diff --git a/storage/connect/tabfmt.h b/storage/connect/tabfmt.h index 396bba568ff..10f0757c60b 100644 --- a/storage/connect/tabfmt.h +++ b/storage/connect/tabfmt.h @@ -13,7 +13,7 @@ typedef class TDBFMT *PTDBFMT; /***********************************************************************/ /* Functions used externally. */ /***********************************************************************/ -PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info); +DllExport PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info); /***********************************************************************/ /* CSV table. */ diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp index 9e4f5ab987d..c0d36efcf42 100644 --- a/storage/connect/tabjson.cpp +++ b/storage/connect/tabjson.cpp @@ -1,6 +1,6 @@ /************* tabjson C++ Program Source Code File (.CPP) *************/ -/* PROGRAM NAME: tabjson Version 1.5 */ -/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */ +/* PROGRAM NAME: tabjson Version 1.6 */ +/* (C) Copyright to the author Olivier BERTRAND 2014 - 2018 */ /* This program are the JSON class DB execution routines. */ /***********************************************************************/ @@ -173,6 +173,7 @@ JSONDISC::JSONDISC(PGLOBAL g, uint *lg) int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) { + char filename[_MAX_PATH]; bool mgo = (GetTypeID(topt->type) == TAB_MONGO); PCSZ level = GetStringTableOption(g, topt, "Level", NULL); @@ -209,6 +210,12 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) return 0; } // endif Fn + if (tdp->Fn) { + // We used the file name relative to recorded datapath + PlugSetPath(filename, tdp->Fn, tdp->GetPath()); + tdp->Fn = PlugDup(g, filename); + } // endif Fn + if (trace(1)) htrc("File %s objname=%s pretty=%d lvl=%d\n", tdp->Fn, tdp->Objname, tdp->Pretty, lvl); @@ -299,7 +306,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) memset(G, 0, sizeof(GLOBAL)); G->Sarea_Size = tdp->Lrecl * 10; G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size); - PlugSubSet(G, G->Sarea, G->Sarea_Size); + PlugSubSet(G->Sarea, G->Sarea_Size); G->jump_level = 0; tjnp->SetG(G); @@ -342,7 +349,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) strncpy(colname, jpp->GetKey(), 64); fmt[bf] = 0; - if (Find(g, jpp->GetVal(), MY_MIN(lvl, 0))) + if (Find(g, jpp->GetVal(), colname, MY_MIN(lvl, 0))) goto err; } // endfor jpp @@ -385,7 +392,7 @@ err: return 0; } // end of GetColumns -bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j) +bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j) { char *p, *pc = colname + strlen(colname); int ars; @@ -413,12 +420,14 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j) job = (PJOB)jsp; for (PJPR jrp = job->GetFirst(); jrp; jrp = jrp->GetNext()) { - if (*jrp->GetKey() != '$') { - strncat(strncat(fmt, sep, 128), jrp->GetKey(), 128); - strncat(strncat(colname, "_", 64), jrp->GetKey(), 64); + PCSZ k = jrp->GetKey(); + + if (*k != '$') { + strncat(strncat(fmt, sep, 128), k, 128); + strncat(strncat(colname, "_", 64), k, 64); } // endif Key - if (Find(g, jrp->GetVal(), j + 1)) + if (Find(g, jrp->GetVal(), k, j + 1)) return true; *p = *pc = 0; @@ -428,13 +437,13 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j) case TYPE_JAR: jar = (PJAR)jsp; - if (all || (tdp->Xcol && !stricmp(tdp->Xcol, colname))) + if (all || (tdp->Xcol && !stricmp(tdp->Xcol, key))) ars = jar->GetSize(false); else ars = MY_MIN(jar->GetSize(false), 1); for (int k = 0; k < ars; k++) { - if (!tdp->Xcol || stricmp(tdp->Xcol, colname)) { + if (!tdp->Xcol || stricmp(tdp->Xcol, key)) { sprintf(buf, "%d", k); if (tdp->Uri) @@ -448,7 +457,7 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, int j) } else strncat(fmt, (tdp->Uri ? sep : "[*]"), 128); - if (Find(g, jar->GetValue(k), j)) + if (Find(g, jar->GetValue(k), "", j)) return true; *p = *pc = 0; @@ -522,7 +531,9 @@ void JSONDISC::AddColumn(PGLOBAL g) n++; } // endif jcp - pjcp = jcp; + if (jcp) + pjcp = jcp; + } // end of AddColumn @@ -549,7 +560,7 @@ JSONDEF::JSONDEF(void) /***********************************************************************/ /* DefineAM: define specific AM block values. */ /***********************************************************************/ -bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR, int poff) +bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) { Schema = GetStringCatInfo(g, "DBname", Schema); Jmode = (JMODE)GetIntCatInfo("Jmode", MODE_OBJECT); @@ -561,7 +572,8 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR, int poff) Sep = *GetStringCatInfo(g, "Separator", "."); Accept = GetBoolCatInfo("Accept", false); - if (Uri = GetStringCatInfo(g, "Connect", NULL)) { + // Don't use url as uri when called from REST OEM module + if (stricmp(am, "REST") && (Uri = GetStringCatInfo(g, "Connect", NULL))) { #if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT) Collname = GetStringCatInfo(g, "Name", (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); @@ -670,7 +682,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m) memset(G, 0, sizeof(GLOBAL)); G->Sarea_Size = Lrecl * 10; G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size); - PlugSubSet(G, G->Sarea, G->Sarea_Size); + PlugSubSet(G->Sarea, G->Sarea_Size); G->jump_level = 0; ((TDBJSN*)tdbp)->G = G; } else { @@ -963,7 +975,7 @@ int TDBJSN::ReadDB(PGLOBAL g) return rc; // Recover the memory used for parsing - PlugSubSet(G, G->Sarea, G->Sarea_Size); + PlugSubSet(G->Sarea, G->Sarea_Size); if ((Row = ParseJson(G, To_Line, strlen(To_Line), &Pretty, &Comma))) { Row = FindRow(g); @@ -1079,13 +1091,13 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp) } // end of PrepareWriting /***********************************************************************/ -/* WriteDB: Data Base write routine for DOS access method. */ +/* WriteDB: Data Base write routine for JSON access method. */ /***********************************************************************/ int TDBJSN::WriteDB(PGLOBAL g) { int rc = TDBDOS::WriteDB(g); - PlugSubSet(G, G->Sarea, G->Sarea_Size); + PlugSubSet(G->Sarea, G->Sarea_Size); Row->Clear(); return rc; } // end of WriteDB @@ -2340,7 +2352,7 @@ void TDBJSON::CloseDB(PGLOBAL g) TDBJCL::TDBJCL(PJDEF tdp) : TDBCAT(tdp) { Topt = tdp->GetTopt(); - Db = tdp->Schema; + Db = tdp->Schema; Dsn = tdp->Uri; } // end of TDBJCL constructor diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h index 2ff72905e86..8721a2a5ab7 100644 --- a/storage/connect/tabjson.h +++ b/storage/connect/tabjson.h @@ -1,11 +1,11 @@ /*************** tabjson H Declares Source Code File (.H) **************/ /* Name: tabjson.h Version 1.3 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */ +/* (C) Copyright to the author Olivier BERTRAND 2014 - 2018 */ /* */ /* This file contains the JSON classes declares. */ /***********************************************************************/ -#include "osutil.h" +//#include "osutil.h" // Unuseful and bad for OEM #include "block.h" #include "colblk.h" #include "json.h" @@ -16,7 +16,7 @@ typedef class JSONDEF *PJDEF; typedef class TDBJSON *PJTDB; typedef class JSONCOL *PJCOL; class TDBJSN; -PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info); +DllExport PQRYRES JSONColumns(PGLOBAL, PCSZ, PCSZ, PTOS, bool); /***********************************************************************/ /* The JSON tree node. Can be an Object or an Array. */ @@ -52,7 +52,7 @@ public: // Functions int GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt); - bool Find(PGLOBAL g, PJVAL jvp, int j); + bool Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j); void AddColumn(PGLOBAL g); // Members diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp index fddfb0c0420..0fa117c3d2f 100644 --- a/storage/connect/tabodbc.cpp +++ b/storage/connect/tabodbc.cpp @@ -5,7 +5,7 @@ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2000-2017 */ +/* (C) Copyright to the author Olivier BERTRAND 2000-2018 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -95,23 +95,23 @@ bool ExactInfo(void); /* Constructor. */ /***********************************************************************/ ODBCDEF::ODBCDEF(void) - { +{ Connect = NULL; Catver = 0; UseCnc = false; - } // end of ODBCDEF constructor +} // end of ODBCDEF constructor /***********************************************************************/ /* DefineAM: define specific AM block values from XDB file. */ /***********************************************************************/ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) - { +{ Desc = Connect = GetStringCatInfo(g, "Connect", NULL); if (!Connect && !Catfunc) { sprintf(g->Message, "Missing connection for ODBC table %s", Name); return true; - } // endif Connect + } // endif Connect if (EXTDEF::DefineAM(g, am, poff)) return true; @@ -123,13 +123,13 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT); UseCnc = GetBoolCatInfo("UseDSN", false); return false; - } // end of DefineAM +} // end of DefineAM /***********************************************************************/ /* GetTable: makes a new Table Description Block. */ /***********************************************************************/ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m) - { +{ PTDB tdbp = NULL; /*********************************************************************/ @@ -158,10 +158,10 @@ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m) tdbp = new(g) TDBMUL(tdbp); else if (Multiple == 2) strcpy(g->Message, MSG(NO_ODBC_MUL)); - } // endswitch Catfunc + } // endswitch Catfunc return tdbp; - } // end of GetTable +} // end of GetTable /* -------------------------- Class TDBODBC -------------------------- */ @@ -169,7 +169,7 @@ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m) /* Implementation of the TDBODBC class. */ /***********************************************************************/ TDBODBC::TDBODBC(PODEF tdp) : TDBEXT(tdp) - { +{ Ocp = NULL; Cnp = NULL; @@ -191,19 +191,19 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBEXT(tdp) Ops.UseCnc = false; } // endif tdp - } // end of TDBODBC standard constructor +} // end of TDBODBC standard constructor TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBEXT(tdbp) - { +{ Ocp = tdbp->Ocp; // is that right ? Cnp = tdbp->Cnp; Connect = tdbp->Connect; Ops = tdbp->Ops; - } // end of TDBODBC copy constructor +} // end of TDBODBC copy constructor // Method PTDB TDBODBC::Clone(PTABS t) - { +{ PTDB tp; PODBCCOL cp1, cp2; PGLOBAL g = t->G; // Is this really useful ??? @@ -213,18 +213,18 @@ PTDB TDBODBC::Clone(PTABS t) for (cp1 = (PODBCCOL)Columns; cp1; cp1 = (PODBCCOL)cp1->GetNext()) { cp2 = new(g) ODBCCOL(cp1, tp); // Make a copy NewPointer(t, cp1, cp2); - } // endfor cp1 + } // endfor cp1 return tp; - } // end of CopyOne +} // end of CopyOne /***********************************************************************/ /* Allocate ODBC column description block. */ /***********************************************************************/ PCOL TDBODBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) - { +{ return new(g) ODBCCOL(cdp, this, cprec, n); - } // end of MakeCol +} // end of MakeCol /***********************************************************************/ /* Extract the filename from connect string and return it. */ @@ -232,7 +232,7 @@ PCOL TDBODBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) /* with a place holder to be used by SetFile. */ /***********************************************************************/ PCSZ TDBODBC::GetFile(PGLOBAL g) - { +{ if (Connect) { char *p1, *p2; int i; @@ -263,18 +263,18 @@ PCSZ TDBODBC::GetFile(PGLOBAL g) memcpy(MulConn, Connect, p1 - Connect); MulConn[p1 - Connect] = '\0'; strcat(strcat(MulConn, "%s"), (p2) ? p2 : ";"); - } // endif p1 + } // endif p1 - } // endif Connect + } // endif Connect return (DBQ) ? DBQ : (PSZ)"???"; - } // end of GetFile +} // end of GetFile /***********************************************************************/ /* Set DBQ and get the new file name into the connect string. */ /***********************************************************************/ void TDBODBC::SetFile(PGLOBAL g, PCSZ fn) - { +{ if (MulConn) { int n = strlen(MulConn) + strlen(fn) - 1; @@ -283,20 +283,20 @@ void TDBODBC::SetFile(PGLOBAL g, PCSZ fn) // of having to reallocate it is reduced. BufSize = n + 6; Connect = (char*)PlugSubAlloc(g, NULL, BufSize); - } // endif n + } // endif n // Make the complete connect string sprintf(Connect, MulConn, fn); - } // endif MultConn + } // endif MultConn DBQ = PlugDup(g, fn); - } // end of SetFile +} // end of SetFile /***********************************************************************/ /* MakeInsert: make the Insert statement used with ODBC connection. */ /***********************************************************************/ bool TDBODBC::MakeInsert(PGLOBAL g) - { +{ PCSZ schmp = NULL; char *catp = NULL, buf[NAM_LEN * 3]; int len = 0; @@ -377,7 +377,7 @@ bool TDBODBC::MakeInsert(PGLOBAL g) } else Query->Append(buf); - } // endfor colp + } // endfor colp Query->Append(") VALUES ("); @@ -390,32 +390,32 @@ bool TDBODBC::MakeInsert(PGLOBAL g) Query->RepLast(')'); return oom; - } // end of MakeInsert +} // end of MakeInsert /***********************************************************************/ /* ODBC Bind Parameter function. */ /***********************************************************************/ bool TDBODBC::BindParameters(PGLOBAL g) - { - PODBCCOL colp; +{ + PODBCCOL colp; - for (colp = (PODBCCOL)Columns; colp; colp = (PODBCCOL)colp->Next) { - colp->AllocateBuffers(g, 0); + for (colp = (PODBCCOL)Columns; colp; colp = (PODBCCOL)colp->Next) { + colp->AllocateBuffers(g, 0); - if (Ocp->BindParam(colp)) - return true; + if (Ocp->BindParam(colp)) + return true; - } // endfor colp + } // endfor colp - return false; - } // end of BindParameters + return false; +} // end of BindParameters #if 0 /***********************************************************************/ /* MakeUpdate: make the SQL statement to send to ODBC connection. */ /***********************************************************************/ char *TDBODBC::MakeUpdate(PGLOBAL g) - { +{ char *qc, *stmt = NULL, cmd[8], tab[96], end[1024]; stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64); @@ -440,60 +440,60 @@ char *TDBODBC::MakeUpdate(PGLOBAL g) strcat(stmt, end); return stmt; - } // end of MakeUpdate +} // end of MakeUpdate /***********************************************************************/ /* MakeDelete: make the SQL statement to send to ODBC connection. */ /***********************************************************************/ char *TDBODBC::MakeDelete(PGLOBAL g) - { - char *qc, *stmt = NULL, cmd[8], from[8], tab[96], end[512]; - - stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64); - memset(end, 0, sizeof(end)); - - if (sscanf(Qrystr, "%s %s `%[^`]`%511c", cmd, from, tab, end) > 2 || - sscanf(Qrystr, "%s %s \"%[^\"]\"%511c", cmd, from, tab, end) > 2) - qc = Ocp->GetQuoteChar(); - else if (sscanf(Qrystr, "%s %s %s%511c", cmd, from, tab, end) > 2) - qc = (Quoted) ? Quote : ""; - else { - strcpy(g->Message, "Cannot use this DELETE command"); - return NULL; - } // endif sscanf - - assert(!stricmp(cmd, "delete") && !stricmp(from, "from")); - strcat(strcat(strcat(strcpy(stmt, "DELETE FROM "), qc), TableName), qc); - - if (*end) { - for (int i = 0; end[i]; i++) - if (end[i] == '`') - end[i] = *qc; - - strcat(stmt, end); - } // endif end - - return stmt; - } // end of MakeDelete +{ + char *qc, *stmt = NULL, cmd[8], from[8], tab[96], end[512]; + + stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64); + memset(end, 0, sizeof(end)); + + if (sscanf(Qrystr, "%s %s `%[^`]`%511c", cmd, from, tab, end) > 2 || + sscanf(Qrystr, "%s %s \"%[^\"]\"%511c", cmd, from, tab, end) > 2) + qc = Ocp->GetQuoteChar(); + else if (sscanf(Qrystr, "%s %s %s%511c", cmd, from, tab, end) > 2) + qc = (Quoted) ? Quote : ""; + else { + strcpy(g->Message, "Cannot use this DELETE command"); + return NULL; + } // endif sscanf + + assert(!stricmp(cmd, "delete") && !stricmp(from, "from")); + strcat(strcat(strcat(strcpy(stmt, "DELETE FROM "), qc), TableName), qc); + + if (*end) { + for (int i = 0; end[i]; i++) + if (end[i] == '`') + end[i] = *qc; + + strcat(stmt, end); + } // endif end + + return stmt; +} // end of MakeDelete #endif // 0 /***********************************************************************/ /* ResetSize: call by TDBMUL when calculating size estimate. */ /***********************************************************************/ void TDBODBC::ResetSize(void) - { +{ MaxSize = -1; if (Ocp && Ocp->IsOpen()) Ocp->Close(); - } // end of ResetSize +} // end of ResetSize /***********************************************************************/ /* ODBC Cardinality: returns table size in number of rows. */ /***********************************************************************/ int TDBODBC::Cardinality(PGLOBAL g) - { +{ if (!g) return (Mode == MODE_ANY && !Srcdef) ? 1 : 0; @@ -526,7 +526,7 @@ int TDBODBC::Cardinality(PGLOBAL g) Cardinal = 10; // To make MySQL happy return Cardinal; - } // end of Cardinality +} // end of Cardinality /***********************************************************************/ /* ODBC Access Method opening routine. */ @@ -535,7 +535,7 @@ int TDBODBC::Cardinality(PGLOBAL g) /* join block of next table if it exists or else are discarted. */ /***********************************************************************/ bool TDBODBC::OpenDB(PGLOBAL g) - { +{ bool rc = true; if (trace(1)) @@ -571,7 +571,7 @@ bool TDBODBC::OpenDB(PGLOBAL g) Fpos = 0; Curpos = 1; return false; - } // endif use + } // endif use /*********************************************************************/ /* Open an ODBC connection for this table. */ @@ -593,7 +593,7 @@ bool TDBODBC::OpenDB(PGLOBAL g) Use = USE_OPEN; // Do it now in case we are recursively called /*********************************************************************/ - /* Make the command and allocate whatever is used for getting results. */ + /* Make the command and allocate whatever is used for getting results*/ /*********************************************************************/ if (Mode == MODE_READ || Mode == MODE_READX) { if (Memory > 1 && !Srcdef) { @@ -624,7 +624,7 @@ bool TDBODBC::OpenDB(PGLOBAL g) } else return true; - } // endif Memory + } // endif Memory if (!(rc = MakeSQL(g, false))) { for (PODBCCOL colp = (PODBCCOL)Columns; colp; @@ -635,7 +635,7 @@ bool TDBODBC::OpenDB(PGLOBAL g) rc = (Mode == MODE_READ) ? ((Rows = Ocp->ExecDirectSQL(Query->GetStr(), (PODBCCOL)Columns)) < 0) : false; - } // endif rc + } // endif rc } else if (Mode == MODE_INSERT) { if (!(rc = MakeInsert(g))) { @@ -645,7 +645,7 @@ bool TDBODBC::OpenDB(PGLOBAL g) } else rc = BindParameters(g); - } // endif rc + } // endif rc } else if (Mode == MODE_UPDATE || Mode == MODE_DELETE) { rc = false; // wait for CheckCond before calling MakeCommand(g); @@ -655,30 +655,30 @@ bool TDBODBC::OpenDB(PGLOBAL g) if (rc) { Ocp->Close(); return true; - } // endif rc + } // endif rc /*********************************************************************/ /* Reset statistics values. */ /*********************************************************************/ num_read = num_there = num_eq[0] = num_eq[1] = 0; return false; - } // end of OpenDB +} // end of OpenDB #if 0 /***********************************************************************/ /* GetRecpos: return the position of last read record. */ /***********************************************************************/ int TDBODBC::GetRecpos(void) - { +{ return Fpos; - } // end of GetRecpos +} // end of GetRecpos #endif // 0 /***********************************************************************/ /* SetRecpos: set the position of next read record. */ /***********************************************************************/ bool TDBODBC::SetRecpos(PGLOBAL g, int recpos) - { +{ if (Ocp->m_Full) { Fpos = 0; CurNum = recpos - 1; @@ -696,14 +696,15 @@ bool TDBODBC::SetRecpos(PGLOBAL g, int recpos) } // endif recpos } else { - strcpy(g->Message, "This action requires a scrollable cursor"); + strcpy(g->Message, + "This action requires Memory setting or a scrollable cursor"); return true; } // endif's // Indicate the table position was externally set Placed = true; return false; - } // end of SetRecpos +} // end of SetRecpos /***********************************************************************/ /* Data Base indexed read routine for ODBC access method. */ @@ -721,7 +722,7 @@ bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr) Rows = Ocp->ExecDirectSQL((char*)Query->GetStr(), (PODBCCOL)Columns); Mode = MODE_READ; return (Rows < 0); - } // endif key + } // endif key return false; } else { @@ -737,7 +738,7 @@ bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr) if ((To_CondFil = hc->CheckCond(g, To_CondFil, Cond))) PlugSubAlloc(g, NULL, strlen(To_CondFil->Body) + 1); - } // endif active_index + } // endif active_index if (To_CondFil) if (Query->Append(" AND ") || Query->Append(To_CondFil->Body)) { @@ -762,7 +763,7 @@ bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr) /* VRDNDOS: Data Base read routine for odbc access method. */ /***********************************************************************/ int TDBODBC::ReadDB(PGLOBAL g) - { +{ int rc; if (trace(2)) @@ -784,7 +785,7 @@ int TDBODBC::ReadDB(PGLOBAL g) } else return RC_FX; // Error - } // endif Mode + } // endif Mode /*********************************************************************/ /* Now start the reading process. */ @@ -813,7 +814,7 @@ int TDBODBC::ReadDB(PGLOBAL g) Qrp->Nblin++; Fpos++; // Used for memory and pos - } // endif rc + } // endif rc } // endif Placed @@ -821,13 +822,13 @@ int TDBODBC::ReadDB(PGLOBAL g) htrc(" Read: Rbuf=%d rc=%d\n", Rbuf, rc); return rc; - } // end of ReadDB +} // end of ReadDB /***********************************************************************/ /* Data Base Insert write routine for ODBC access method. */ /***********************************************************************/ int TDBODBC::WriteDB(PGLOBAL g) - { +{ int n = Ocp->ExecuteSQL(); if (n < 0) { @@ -837,13 +838,13 @@ int TDBODBC::WriteDB(PGLOBAL g) AftRows += n; return RC_OK; - } // end of WriteDB +} // end of WriteDB /***********************************************************************/ /* Data Base delete line routine for ODBC access method. */ /***********************************************************************/ int TDBODBC::DeleteDB(PGLOBAL g, int irc) - { +{ if (irc == RC_FX) { if (!Query && MakeCommand(g)) return RC_FX; @@ -863,13 +864,13 @@ int TDBODBC::DeleteDB(PGLOBAL g, int irc) } else return RC_OK; // Ignore - } // end of DeleteDB +} // end of DeleteDB /***********************************************************************/ /* Data Base close routine for ODBC access method. */ /***********************************************************************/ void TDBODBC::CloseDB(PGLOBAL g) - { +{ if (Ocp) Ocp->Close(); @@ -877,7 +878,7 @@ void TDBODBC::CloseDB(PGLOBAL g) if (trace(1)) htrc("ODBC CloseDB: closing %s\n", Name); - } // end of CloseDB +} // end of CloseDB /* --------------------------- ODBCCOL ------------------------------- */ @@ -886,33 +887,33 @@ void TDBODBC::CloseDB(PGLOBAL g) /***********************************************************************/ ODBCCOL::ODBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am) : EXTCOL(cdp, tdbp, cprec, i, am) - { +{ // Set additional ODBC access method information for column. Slen = 0; StrLen = &Slen; Sqlbuf = NULL; - } // end of ODBCCOL constructor +} // end of ODBCCOL constructor /***********************************************************************/ /* ODBCCOL private constructor. */ /***********************************************************************/ ODBCCOL::ODBCCOL(void) : EXTCOL() - { +{ Slen = 0; StrLen = &Slen; Sqlbuf = NULL; - } // end of ODBCCOL constructor +} // end of ODBCCOL constructor /***********************************************************************/ /* ODBCCOL constructor used for copying columns. */ /* tdbp is the pointer to the new table descriptor. */ /***********************************************************************/ ODBCCOL::ODBCCOL(ODBCCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp) - { +{ Slen = col1->Slen; StrLen = col1->StrLen; Sqlbuf = col1->Sqlbuf; - } // end of ODBCCOL copy constructor +} // end of ODBCCOL copy constructor /***********************************************************************/ /* ReadColumn: when SQLFetch is used there is nothing to do as the */ @@ -920,7 +921,7 @@ ODBCCOL::ODBCCOL(ODBCCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp) /* when calculating MaxSize (Bufp is NULL even when Rows is not). */ /***********************************************************************/ void ODBCCOL::ReadColumn(PGLOBAL g) - { +{ PTDBODBC tdbp = (PTDBODBC)To_Tdb; int i = tdbp->Fpos - 1, n = tdbp->CurNum; @@ -953,7 +954,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g) else Value->SetValue_pvblk(Blkp, n); - } // endif Bufp + } // endif Bufp if (Buf_Type == TYPE_DATE) { struct tm dbtime; @@ -980,7 +981,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g) htrc("ODBC Column %s: rows=%d buf=%p type=%d value=%s\n", Name, tdbp->Rows, Bufp, Buf_Type, Value->GetCharString(buf)); - } // endif trace + } // endif trace put: if (tdbp->Memory != 2) @@ -997,7 +998,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g) } else Crp->Kdata->SetValue(Value, i); - } // end of ReadColumn +} // end of ReadColumn /***********************************************************************/ /* AllocateBuffers: allocate the extended buffer for SQLExtendedFetch */ @@ -1005,7 +1006,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g) /* for the ending null character. */ /***********************************************************************/ void ODBCCOL::AllocateBuffers(PGLOBAL g, int rows) - { +{ if (Buf_Type == TYPE_DATE) Sqlbuf = (TIMESTAMP_STRUCT*)PlugSubAlloc(g, NULL, sizeof(TIMESTAMP_STRUCT)); @@ -1019,31 +1020,31 @@ void ODBCCOL::AllocateBuffers(PGLOBAL g, int rows) Blkp = AllocValBlock(g, NULL, Buf_Type, rows, GetBuflen(), GetScale(), true, false, false); Bufp = Blkp->GetValPointer(); - } // endelse + } // endelse if (rows > 1) StrLen = (SQLLEN *)PlugSubAlloc(g, NULL, rows * sizeof(SQLLEN)); - } // end of AllocateBuffers +} // end of AllocateBuffers /***********************************************************************/ /* Returns the buffer to use for Fetch or Extended Fetch. */ /***********************************************************************/ void *ODBCCOL::GetBuffer(DWORD rows) - { +{ if (rows && To_Tdb) { assert(rows == (DWORD)((TDBODBC*)To_Tdb)->Rows); return Bufp; } else return (Buf_Type == TYPE_DATE) ? Sqlbuf : Value->GetTo_Val(); - } // end of GetBuffer +} // end of GetBuffer /***********************************************************************/ /* Returns the buffer length to use for Fetch or Extended Fetch. */ /***********************************************************************/ SWORD ODBCCOL::GetBuflen(void) - { +{ SWORD flen; switch (Buf_Type) { @@ -1059,13 +1060,13 @@ SWORD ODBCCOL::GetBuflen(void) } // endswitch Buf_Type return flen; - } // end of GetBuflen +} // end of GetBuflen /***********************************************************************/ /* WriteColumn: make sure the bind buffer is updated. */ /***********************************************************************/ void ODBCCOL::WriteColumn(PGLOBAL g) - { +{ /*********************************************************************/ /* Do convert the column value if necessary. */ /*********************************************************************/ @@ -1095,7 +1096,7 @@ void ODBCCOL::WriteColumn(PGLOBAL g) *StrLen = (Value->IsNull()) ? SQL_NULL_DATA : (IsTypeChar(Buf_Type)) ? SQL_NTS : 0; - } // end of WriteColumn +} // end of WriteColumn /* -------------------------- Class TDBXDBC -------------------------- */ @@ -1119,7 +1120,7 @@ TDBXDBC::TDBXDBC(PTDBXDBC tdbp) : TDBODBC(tdbp) } // end of TDBXDBC copy constructor PTDB TDBXDBC::Clone(PTABS t) - { +{ PTDB tp; PXSRCCOL cp1, cp2; PGLOBAL g = t->G; // Is this really useful ??? @@ -1129,29 +1130,29 @@ PTDB TDBXDBC::Clone(PTABS t) for (cp1 = (PXSRCCOL)Columns; cp1; cp1 = (PXSRCCOL)cp1->GetNext()) { cp2 = new(g) XSRCCOL(cp1, tp); // Make a copy NewPointer(t, cp1, cp2); - } // endfor cp1 + } // endfor cp1 return tp; - } // end of CopyOne +} // end of CopyOne /***********************************************************************/ /* Allocate XSRC column description block. */ /***********************************************************************/ PCOL TDBXDBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) - { +{ PXSRCCOL colp = new(g) XSRCCOL(cdp, this, cprec, n); if (!colp->Flag) Cmdcol = colp->GetName(); return colp; - } // end of MakeCol +} // end of MakeCol /***********************************************************************/ /* MakeCMD: make the SQL statement to send to ODBC connection. */ /***********************************************************************/ PCMD TDBXDBC::MakeCMD(PGLOBAL g) - { +{ PCMD xcmd = NULL; if (To_CondFil) { @@ -1171,14 +1172,14 @@ PCMD TDBXDBC::MakeCMD(PGLOBAL g) xcmd = new(g) CMD(g, Srcdef); return xcmd; - } // end of MakeCMD +} // end of MakeCMD #if 0 /***********************************************************************/ /* ODBC Bind Parameter function. */ /***********************************************************************/ bool TDBXDBC::BindParameters(PGLOBAL g) - { +{ PODBCCOL colp; for (colp = (PODBCCOL)Columns; colp; colp = (PODBCCOL)colp->Next) { @@ -1190,19 +1191,19 @@ bool TDBXDBC::BindParameters(PGLOBAL g) } // endfor colp return false; - } // end of BindParameters +} // end of BindParameters #endif // 0 /***********************************************************************/ /* XDBC GetMaxSize: returns table size (not always one row). */ /***********************************************************************/ int TDBXDBC::GetMaxSize(PGLOBAL g) - { +{ if (MaxSize < 0) MaxSize = 10; // Just a guess return MaxSize; - } // end of GetMaxSize +} // end of GetMaxSize /***********************************************************************/ /* ODBC Access Method opening routine. */ @@ -1211,7 +1212,7 @@ int TDBXDBC::GetMaxSize(PGLOBAL g) /* join block of next table if it exists or else are discarted. */ /***********************************************************************/ bool TDBXDBC::OpenDB(PGLOBAL g) - { +{ bool rc = false; if (trace(1)) @@ -1221,7 +1222,7 @@ bool TDBXDBC::OpenDB(PGLOBAL g) if (Use == USE_OPEN) { strcpy(g->Message, "Multiple execution is not allowed"); return true; - } // endif use + } // endif use /*********************************************************************/ /* Open an ODBC connection for this table. */ @@ -1243,7 +1244,7 @@ bool TDBXDBC::OpenDB(PGLOBAL g) if (Mode != MODE_READ && Mode != MODE_READX) { strcpy(g->Message, "No INSERT/DELETE/UPDATE of XDBC tables"); return true; - } // endif Mode + } // endif Mode /*********************************************************************/ /* Get the command to execute. */ @@ -1256,13 +1257,13 @@ bool TDBXDBC::OpenDB(PGLOBAL g) Rows = 1; return false; - } // end of OpenDB +} // end of OpenDB /***********************************************************************/ /* ReadDB: Data Base read routine for xdbc access method. */ /***********************************************************************/ int TDBXDBC::ReadDB(PGLOBAL g) - { +{ if (Cmdlist) { if (!Query) Query = new(g)STRING(g, 0, Cmdlist->Cmd); @@ -1280,25 +1281,25 @@ int TDBXDBC::ReadDB(PGLOBAL g) return RC_EF; } // endif Cmdlist - } // end of ReadDB +} // end of ReadDB /***********************************************************************/ -/* Data Base delete line routine for ODBC access method. */ +/* Data Base write line routine for XDBC access method. */ /***********************************************************************/ int TDBXDBC::WriteDB(PGLOBAL g) - { +{ strcpy(g->Message, "Execsrc tables are read only"); return RC_FX; - } // end of DeleteDB +} // end of DeleteDB /***********************************************************************/ -/* Data Base delete line routine for ODBC access method. */ +/* Data Base delete line routine for XDBC access method. */ /***********************************************************************/ int TDBXDBC::DeleteDB(PGLOBAL g, int irc) - { +{ strcpy(g->Message, MSG(NO_ODBC_DELETE)); return RC_FX; - } // end of DeleteDB +} // end of DeleteDB /* --------------------------- XSRCCOL ------------------------------- */ @@ -1307,25 +1308,25 @@ int TDBXDBC::DeleteDB(PGLOBAL g, int irc) /***********************************************************************/ XSRCCOL::XSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am) : ODBCCOL(cdp, tdbp, cprec, i, am) - { +{ // Set additional ODBC access method information for column. Flag = cdp->GetOffset(); - } // end of XSRCCOL constructor +} // end of XSRCCOL constructor /***********************************************************************/ /* XSRCCOL constructor used for copying columns. */ /* tdbp is the pointer to the new table descriptor. */ /***********************************************************************/ XSRCCOL::XSRCCOL(XSRCCOL *col1, PTDB tdbp) : ODBCCOL(col1, tdbp) - { +{ Flag = col1->Flag; - } // end of XSRCCOL copy constructor +} // end of XSRCCOL copy constructor /***********************************************************************/ /* ReadColumn: set column value according to Flag. */ /***********************************************************************/ void XSRCCOL::ReadColumn(PGLOBAL g) - { +{ PTDBXDBC tdbp = (PTDBXDBC)To_Tdb; switch (Flag) { @@ -1335,15 +1336,15 @@ void XSRCCOL::ReadColumn(PGLOBAL g) default: Value->SetValue_psz("Invalid Flag"); break; } // endswitch Flag - } // end of ReadColumn +} // end of ReadColumn /***********************************************************************/ /* WriteColumn: Should never be called. */ /***********************************************************************/ void XSRCCOL::WriteColumn(PGLOBAL g) - { +{ // Should never be called - } // end of WriteColumn +} // end of WriteColumn /* ---------------------------TDBDRV class --------------------------- */ @@ -1351,9 +1352,9 @@ void XSRCCOL::WriteColumn(PGLOBAL g) /* GetResult: Get the list of ODBC drivers. */ /***********************************************************************/ PQRYRES TDBDRV::GetResult(PGLOBAL g) - { +{ return ODBCDrivers(g, Maxres, false); - } // end of GetResult +} // end of GetResult /* ---------------------------TDBSRC class --------------------------- */ @@ -1361,9 +1362,9 @@ PQRYRES TDBDRV::GetResult(PGLOBAL g) /* GetResult: Get the list of ODBC data sources. */ /***********************************************************************/ PQRYRES TDBSRC::GetResult(PGLOBAL g) - { +{ return ODBCDataSources(g, Maxres, false); - } // end of GetResult +} // end of GetResult /* ---------------------------TDBOTB class --------------------------- */ @@ -1371,7 +1372,7 @@ PQRYRES TDBSRC::GetResult(PGLOBAL g) /* TDBOTB class constructor. */ /***********************************************************************/ TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp) - { +{ Dsn = tdp->GetConnect(); Schema = tdp->GetTabschema(); Tab = tdp->GetTabname(); @@ -1381,15 +1382,15 @@ TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp) Ops.Cto = tdp->Cto; Ops.Qto = tdp->Qto; Ops.UseCnc = tdp->UseCnc; - } // end of TDBOTB constructor +} // end of TDBOTB constructor /***********************************************************************/ /* GetResult: Get the list of ODBC tables. */ /***********************************************************************/ PQRYRES TDBOTB::GetResult(PGLOBAL g) - { +{ return ODBCTables(g, Dsn, Schema, Tab, Tabtyp, Maxres, false, &Ops); - } // end of GetResult +} // end of GetResult /* ---------------------------TDBOCL class --------------------------- */ @@ -1405,8 +1406,8 @@ TDBOCL::TDBOCL(PODEF tdp) : TDBOTB(tdp) /* GetResult: Get the list of ODBC table columns. */ /***********************************************************************/ PQRYRES TDBOCL::GetResult(PGLOBAL g) - { +{ return ODBCColumns(g, Dsn, Schema, Tab, Colpat, Maxres, false, &Ops); - } // end of GetResult +} // end of GetResult /* ------------------------ End of Tabodbc --------------------------- */ diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp index c96e0844497..d808bd5ecd4 100644 --- a/storage/connect/tabxml.cpp +++ b/storage/connect/tabxml.cpp @@ -163,8 +163,11 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) return NULL; tdp->Tabname = tab; + tdp->Tabname = (char*)GetStringTableOption(g, topt, "Tabname", tab); + tdp->Rowname = (char*)GetStringTableOption(g, topt, "Rownode", NULL); tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false); tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL); + tdp->Skip = GetBooleanTableOption(g, topt, "Skipnull", false); if (!(op = GetStringTableOption(g, topt, "Xmlsup", NULL))) #if defined(__WIN__) @@ -280,7 +283,9 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) if (!vp->atp) node = vp->nl->GetItem(g, vp->k++, tdp->Usedom ? node : NULL); - strncat(fmt, colname, XLEN(fmt)); + if (!j) + strncat(fmt, colname, XLEN(fmt)); + strncat(fmt, "/", XLEN(fmt)); strncat(xcol->Name, "_", XLEN(xcol->Name)); j++; @@ -302,6 +307,7 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) case RC_INFO: PushWarning(g, txmp); case RC_OK: + xcol->Cbn = !strlen(buf); break; default: goto err; @@ -327,9 +333,9 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) xcp->Len = MY_MAX(xcp->Len, xcol->Len); xcp->Scale = MY_MAX(xcp->Scale, xcol->Scale); - xcp->Cbn |= xcol->Cbn; + xcp->Cbn |= (xcol->Cbn || !xcol->Len); xcp->Found = true; - } else { + } else if(xcol->Len || !tdp->Skip) { // New column xcp = new(g) XMCOL(g, xcol, fmt, i); length[0] = MY_MAX(length[0], strlen(xcol->Name)); @@ -344,7 +350,8 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) n++; } // endif xcp - pxcp = xcp; + if (xcp) + pxcp = xcp; if (vp->atp) vp->atp = vp->atp->GetNext(g); @@ -445,6 +452,7 @@ XMLDEF::XMLDEF(void) Usedom = false; Zipped = false; Mulentries = false; + Skip = false; } // end of XMLDEF constructor /***********************************************************************/ @@ -681,6 +689,14 @@ PTDB TDBXML::Clone(PTABS t) return tp; } // end of Clone +/***********************************************************************/ +/* Must not be in tabxml.h because of OEM tables */ +/***********************************************************************/ +const CHARSET_INFO *TDBXML::data_charset() +{ + return &my_charset_utf8_general_ci; +} // end of data_charset + /***********************************************************************/ /* Allocate XML column description block. */ /***********************************************************************/ @@ -806,127 +822,141 @@ bool TDBXML::Initialize(PGLOBAL g) } // endif Bufdone #if !defined(UNIX) - if (!Root) try { + if (!Root) try { #else - if (!Root) { + if (!Root) { #endif - char tabpath[64], filename[_MAX_PATH]; - - // We used the file name relative to recorded datapath - PlugSetPath(filename, Xfile, GetPath()); - - // Load or re-use the table file - rc = LoadTableFile(g, filename); - - if (rc == RC_OK) { - // Get root node - if (!(Root = Docp->GetRoot(g))) { - // This should never happen as load should have failed - strcpy(g->Message, MSG(EMPTY_DOC)); - goto error; - } // endif Root - - // If tabname is not an Xpath, - // construct one that will find it anywhere - if (!strchr(Tabname, '/')) - strcat(strcpy(tabpath, "//"), Tabname); - else - strcpy(tabpath, Tabname); - - // Evaluate table xpath - if ((TabNode = Root->SelectSingleNode(g, tabpath))) { - if (TabNode->GetType() != XML_ELEMENT_NODE) { - sprintf(g->Message, MSG(BAD_NODE_TYPE), TabNode->GetType()); - goto error; - } // endif Type - - } else if (Mode == MODE_INSERT && XmlDB) { - // We are adding a new table to a multi-table file - - // If XmlDB is not an Xpath, - // construct one that will find it anywhere - if (!strchr(XmlDB, '/')) - strcat(strcpy(tabpath, "//"), XmlDB); - else - strcpy(tabpath, XmlDB); - - if (!(DBnode = Root->SelectSingleNode(g, tabpath))) { - // DB node does not exist yet; we cannot create it - // because we don't know where it should be placed - sprintf(g->Message, MSG(MISSING_NODE), XmlDB, Xfile); - goto error; - } // endif DBnode - - if (!(TabNode = DBnode->AddChildNode(g, Tabname))) { - sprintf(g->Message, MSG(FAIL_ADD_NODE), Tabname); - goto error; - } // endif TabNode - - DBnode->AddText(g, "\n"); - } else - TabNode = Root; // Try this ? - - } else if (rc == RC_NF || rc == RC_EF) { - // The XML file does not exist or is void - if (Mode == MODE_INSERT) { - // New Document - char buf[64]; - - // Create the XML node - if (Docp->NewDoc(g, "1.0")) { - strcpy(g->Message, MSG(NEW_DOC_FAILED)); - goto error; - } // endif NewDoc - - // Now we can link the Xblock - To_Xb = Docp->LinkXblock(g, Mode, rc, filename); - - // Add a CONNECT comment node - strcpy(buf, " Created by the MariaDB CONNECT Storage Engine"); - Docp->AddComment(g, buf); - - if (XmlDB) { - // This is a multi-table file - DBnode = Root = Docp->NewRoot(g, XmlDB); - DBnode->AddText(g, "\n"); - TabNode = DBnode->AddChildNode(g, Tabname); - DBnode->AddText(g, "\n"); - } else - TabNode = Root = Docp->NewRoot(g, Tabname); - - if (TabNode == NULL || Root == NULL) { - strcpy(g->Message, MSG(XML_INIT_ERROR)); - goto error; - } else if (SetTabNode(g)) - goto error; - - } else { - sprintf(g->Message, MSG(FILE_UNFOUND), Xfile); - - if (Mode == MODE_READ) { - PushWarning(g, this); - Void = true; - } // endif Mode - - goto error; - } // endif Mode - - } else if (rc == RC_INFO) { - // Loading failed - sprintf(g->Message, MSG(LOADING_FAILED), Xfile); - goto error; - } else // (rc == RC_FX) - goto error; - - // Get row node list - if (Rowname) - Nlist = TabNode->SelectNodes(g, Rowname); - else - Nlist = TabNode->GetChildElements(g); - - Docp->SetNofree(true); // For libxml2 + char tabpath[64], filename[_MAX_PATH]; + + // We used the file name relative to recorded datapath + PlugSetPath(filename, Xfile, GetPath()); + + // Load or re-use the table file + rc = LoadTableFile(g, filename); + + if (rc == RC_OK) { + // Get root node + if (!(Root = Docp->GetRoot(g))) { + // This should never happen as load should have failed + strcpy(g->Message, MSG(EMPTY_DOC)); + goto error; + } // endif Root + + // If tabname is not an Xpath, + // construct one that will find it anywhere + if (!strchr(Tabname, '/')) + strcat(strcpy(tabpath, "//"), Tabname); + else + strcpy(tabpath, Tabname); + + // Evaluate table xpath + if ((TabNode = Root->SelectSingleNode(g, tabpath))) { + if (TabNode->GetType() != XML_ELEMENT_NODE) { + sprintf(g->Message, MSG(BAD_NODE_TYPE), TabNode->GetType()); + goto error; + } // endif Type + + } else if (Mode == MODE_INSERT && XmlDB) { + // We are adding a new table to a multi-table file + + // If XmlDB is not an Xpath, + // construct one that will find it anywhere + if (!strchr(XmlDB, '/')) + strcat(strcpy(tabpath, "//"), XmlDB); + else + strcpy(tabpath, XmlDB); + + if (!(DBnode = Root->SelectSingleNode(g, tabpath))) { + // DB node does not exist yet; we cannot create it + // because we don't know where it should be placed + sprintf(g->Message, MSG(MISSING_NODE), XmlDB, Xfile); + goto error; + } // endif DBnode + + if (!(TabNode = DBnode->AddChildNode(g, Tabname))) { + sprintf(g->Message, MSG(FAIL_ADD_NODE), Tabname); + goto error; + } // endif TabNode + + DBnode->AddText(g, "\n"); + } else { + TabNode = Root; // Try this ? + Tabname = TabNode->GetName(g); + } // endif's + + } else if (rc == RC_NF || rc == RC_EF) { + // The XML file does not exist or is void + if (Mode == MODE_INSERT) { + // New Document + char buf[64]; + + // Create the XML node + if (Docp->NewDoc(g, "1.0")) { + strcpy(g->Message, MSG(NEW_DOC_FAILED)); + goto error; + } // endif NewDoc + + // Now we can link the Xblock + To_Xb = Docp->LinkXblock(g, Mode, rc, filename); + + // Add a CONNECT comment node + strcpy(buf, " Created by the MariaDB CONNECT Storage Engine"); + Docp->AddComment(g, buf); + + if (XmlDB) { + // This is a multi-table file + DBnode = Root = Docp->NewRoot(g, XmlDB); + DBnode->AddText(g, "\n"); + TabNode = DBnode->AddChildNode(g, Tabname); + DBnode->AddText(g, "\n"); + } else + TabNode = Root = Docp->NewRoot(g, Tabname); + + if (TabNode == NULL || Root == NULL) { + strcpy(g->Message, MSG(XML_INIT_ERROR)); + goto error; + } else if (SetTabNode(g)) + goto error; + + } else { + sprintf(g->Message, MSG(FILE_UNFOUND), Xfile); + + if (Mode == MODE_READ) { + PushWarning(g, this); + Void = true; + } // endif Mode + + goto error; + } // endif Mode + + } else if (rc == RC_INFO) { + // Loading failed + sprintf(g->Message, MSG(LOADING_FAILED), Xfile); + goto error; + } else // (rc == RC_FX) + goto error; + + if (!Rowname) { + for (PXNODE n = TabNode->GetChild(g); n; n = n->GetNext(g)) + if (n->GetType() == XML_ELEMENT_NODE) { + Rowname = n->GetName(g); + break; + } // endif Type + + if (!Rowname) + Rowname = TabNode->GetName(g); + } // endif Rowname + + // Get row node list + if (strcmp(Rowname, Tabname)) + Nlist = TabNode->SelectNodes(g, Rowname); + else + Nrow = 1; + + + Docp->SetNofree(true); // For libxml2 #if defined(__WIN__) - } catch(_com_error e) { + } catch (_com_error e) { // We come here if a DOM command threw an error char buf[128]; @@ -1213,10 +1243,14 @@ int TDBXML::ReadDB(PGLOBAL g) htrc("TDBXML ReadDB: Irow=%d RowNode=%p\n", Irow, RowNode); // Get the new row node - if ((RowNode = Nlist->GetItem(g, Irow, RowNode)) == NULL) { - sprintf(g->Message, MSG(MISSING_ROWNODE), Irow); - return RC_FX; - } // endif RowNode + if (Nlist) { + if ((RowNode = Nlist->GetItem(g, Irow, RowNode)) == NULL) { + sprintf(g->Message, MSG(MISSING_ROWNODE), Irow); + return RC_FX; + } // endif RowNode + + } else + RowNode = TabNode; if (Colname && Coltype == 2) Clist = RowNode->SelectNodes(g, Colname, Clist); @@ -1271,6 +1305,7 @@ int TDBXML::WriteDB(PGLOBAL g) /***********************************************************************/ int TDBXML::DeleteDB(PGLOBAL g, int irc) { + // TODO: Handle null Nlist if (irc == RC_FX) { // Delete all rows for (Irow = 0; Irow < Nrow; Irow++) @@ -2209,8 +2244,9 @@ void XPOSCOL::WriteColumn(PGLOBAL g) TDBXCT::TDBXCT(PXMLDEF tdp) : TDBCAT(tdp) { Topt = tdp->GetTopt(); - Db = (char*)tdp->GetDB(); - Tabn = tdp->Tabname; + //Db = (char*)tdp->GetDB(); + Db = (char*)tdp->Schema; + Tabn = tdp->Tabname; } // end of TDBXCT constructor /***********************************************************************/ diff --git a/storage/connect/tabxml.h b/storage/connect/tabxml.h index f55b7d98de7..fb3913f08ea 100644 --- a/storage/connect/tabxml.h +++ b/storage/connect/tabxml.h @@ -9,6 +9,8 @@ typedef class XMLDEF *PXMLDEF; typedef class TDBXML *PTDBXML; typedef class XMLCOL *PXMLCOL; +DllExport PQRYRES XMLColumns(PGLOBAL, char *, char *, PTOS, bool); + /* --------------------------- XML classes --------------------------- */ /***********************************************************************/ @@ -50,6 +52,7 @@ class DllExport XMLDEF : public TABDEF { /* Logical table description */ bool Usedom; /* True: DOM, False: libxml2 */ bool Zipped; /* True: Zipped XML file(s) */ bool Mulentries; /* True: multiple entries in zip file*/ + bool Skip; /* Skip null columns */ }; // end of XMLDEF #if defined(INCLUDE_TDBXML) @@ -100,8 +103,7 @@ class DllExport TDBXML : public TDBASE { virtual int DeleteDB(PGLOBAL g, int irc); virtual void CloseDB(PGLOBAL g); virtual int CheckWrite(PGLOBAL g) {Checked = true; return 0;} - virtual const CHARSET_INFO *data_charset() - {return &my_charset_utf8_general_ci;} + virtual const CHARSET_INFO *data_charset(); protected: // Members diff --git a/storage/connect/user_connect.cc b/storage/connect/user_connect.cc index e2d3b664aeb..a2a8faf9b38 100644 --- a/storage/connect/user_connect.cc +++ b/storage/connect/user_connect.cc @@ -107,7 +107,7 @@ bool user_connect::user_init() g= PlugInit(NULL, worksize); // Check whether the initialization is complete - if (!g || !g->Sarea || PlugSubSet(g, g->Sarea, g->Sarea_Size) + if (!g || !g->Sarea || PlugSubSet(g->Sarea, g->Sarea_Size) || !(dup= PlgMakeUser(g))) { if (g) printf("%s\n", g->Message); @@ -172,7 +172,7 @@ bool user_connect::CheckCleanup(bool force) } // endif worksize - PlugSubSet(g, g->Sarea, g->Sarea_Size); + PlugSubSet(g->Sarea, g->Sarea_Size); g->Xchk = NULL; g->Createas = 0; g->Alchecked = 0; -- cgit v1.2.1