Merging from 10.0-connect
added: storage/connect/mysql-test/connect/r/mul.result storage/connect/mysql-test/connect/t/mul.test modified: storage/connect/domdoc.h storage/connect/filamfix.cpp storage/connect/filamtxt.cpp storage/connect/filamvct.cpp storage/connect/fmdlex.c storage/connect/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h storage/connect/inihandl.c storage/connect/inihandl.h storage/connect/libdoc.cpp storage/connect/libdoc.h storage/connect/mycat.cc storage/connect/myconn.cpp storage/connect/mysql-test/connect/r/dbf.result storage/connect/mysql-test/connect/t/odbc_sqlite3.test storage/connect/myutil.cpp storage/connect/odbconn.cpp storage/connect/osutil.c storage/connect/plgdbsem.h storage/connect/plgdbutl.cpp storage/connect/plgxml.h storage/connect/plugutil.c storage/connect/tabdos.cpp storage/connect/tabfix.cpp storage/connect/tabmul.cpp* storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/taboccur.cpp storage/connect/taboccur.h storage/connect/tabodbc.cpp storage/connect/tabpivot.h storage/connect/tabsys.cpp storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabvct.cpp storage/connect/tabxml.cpp storage/connect/valblk.cpp storage/connect/value.cpp storage/connect/xindex.cpp pending merges: Olivier Bertrand 2013-07-08 - Suppressing wrong code (INI tables are not... Alexander Barkov 2013-07-08 Adding instructions on how to install sq... Alexander Barkov 2013-07-08 Fixing some of the memory leaks in ODBCC... Alexander Barkov 2013-07-08 Fixing a warning: Alexander Barkov 2013-07-08 Fixing warnings: Alexander Barkov 2013-07-08 Fixing a warning: Alexander Barkov 2013-07-08 Fixing warnings: Alexander Barkov 2013-07-08 Fixing a warning: Alexander Barkov 2013-07-08 Fixing warnings: Alexander Barkov 2013-07-08 Fixing warnings: Alexander Barkov 2013-07-08 fixing warnings: Alexander Barkov 2013-07-08 Fixing a typo in the previous push Alexander Barkov 2013-07-08 fixing warnings: Alexander Barkov 2013-07-08 Fixing the "no previous declaration for ... Alexander Barkov 2013-07-08 Fixing numerous "variable is set but nev... Olivier Bertrand 2013-07-06 - Remove unuseful option causing valgrin... Olivier Bertrand 2013-07-05 - Try to fix a uninitialised valgrind wa... Olivier Bertrand 2013-07-04 - Make sure Remark is initialised Olivier Bertrand 2013-07-04 - Make sure Remark is initialised in ha_... Olivier Bertrand 2013-07-03 - Makes memory check conditionally Olivier Bertrand 2013-07-03 - Make sure result are ordered the same ... Olivier Bertrand 2013-07-02 - Fix memory leak in libdoc.cpp in LIBXM... Olivier Bertrand 2013-06-30 - Working on eliminating valgrind warnin... Olivier Bertrand 2013-06-30 - Trying to get rid of some valgrind war... Olivier Bertrand 2013-06-29 - Release storage allocated by flex Olivier Bertrand 2013-06-29 - Add the PROFILE_End function in inihan... Olivier Bertrand 2013-06-28 - Release memory allocated by inihandl i... Olivier Bertrand 2013-06-26 - Trying to remove those warnings about ... Olivier Bertrand 2013-06-26 - In connect_assisted_discovery the test... Olivier Bertrand 2013-06-26 - Fix potential bug in MYSQLCOL::WriteCo... Olivier Bertrand 2013-06-16 - Implemented: The use of Federated serv... Olivier Bertrand 2013-06-14 - Add a test case for multiple tables Olivier Bertrand 2013-06-14 - Fix regression error for multiple 2 ta... Olivier Bertrand 2013-06-12 - To avoid crashing in debug mode, the e... Olivier Bertrand 2013-06-12 - Suballocate filename in TDBMUL::InitFi... Olivier Bertrand 2013-06-12 - Add trace in TDBMUL::GetMaxSize. Olivier Bertrand 2013-06-12 - Fix MDEV-4638 Olivier Bertrand 2013-06-08 [merge] - Commit merged changes Alexander Barkov 2013-06-08 Enabling Connect tests Olivier Bertrand 2013-06-08 - Set timeout values in MYSQLC::Open
This commit is contained in:
commit
17f3ae267f
@ -35,6 +35,7 @@ class DOMDOC : public XMLDOCUMENT {
|
|||||||
// Properties
|
// Properties
|
||||||
virtual short GetDocType(void) {return TYPE_FB_XML;}
|
virtual short GetDocType(void) {return TYPE_FB_XML;}
|
||||||
virtual void *GetDocPtr(void) {return Docp;}
|
virtual void *GetDocPtr(void) {return Docp;}
|
||||||
|
virtual void SetNofree(bool b) {} // Only libxml2
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
virtual bool Initialize(PGLOBAL g);
|
virtual bool Initialize(PGLOBAL g);
|
||||||
|
@ -425,9 +425,9 @@ int FIXFAM::DeleteRecords(PGLOBAL g, int irc)
|
|||||||
/* for compatibility with Text files and other OS's. */
|
/* for compatibility with Text files and other OS's. */
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
char filename[_MAX_PATH];
|
char filename[_MAX_PATH];
|
||||||
int rc, h;
|
int h;
|
||||||
|
|
||||||
rc = PlugCloseFile(g, To_Fb);
|
/*rc= */PlugCloseFile(g, To_Fb);
|
||||||
PlugSetPath(filename, To_File, Tdbp->GetPath());
|
PlugSetPath(filename, To_File, Tdbp->GetPath());
|
||||||
|
|
||||||
if ((h= global_open(g, MSGID_OPEN_STRERROR, filename, O_WRONLY)) <= 0)
|
if ((h= global_open(g, MSGID_OPEN_STRERROR, filename, O_WRONLY)) <= 0)
|
||||||
|
@ -786,10 +786,10 @@ int DOSFAM::DeleteRecords(PGLOBAL g, int irc)
|
|||||||
/* for compatibility with Text files and other OS's. */
|
/* for compatibility with Text files and other OS's. */
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
char filename[_MAX_PATH];
|
char filename[_MAX_PATH];
|
||||||
int h, rc; // File handle, return code
|
int h; // File handle, return code
|
||||||
|
|
||||||
PlugSetPath(filename, To_File, Tdbp->GetPath());
|
PlugSetPath(filename, To_File, Tdbp->GetPath());
|
||||||
rc = PlugCloseFile(g, To_Fb);
|
/*rc=*/ PlugCloseFile(g, To_Fb);
|
||||||
|
|
||||||
if ((h= global_open(g, MSGID_OPEN_STRERROR, filename, O_WRONLY)) <= 0)
|
if ((h= global_open(g, MSGID_OPEN_STRERROR, filename, O_WRONLY)) <= 0)
|
||||||
return RC_FX;
|
return RC_FX;
|
||||||
|
@ -10,15 +10,15 @@
|
|||||||
/* WHAT THIS PROGRAM DOES: */
|
/* WHAT THIS PROGRAM DOES: */
|
||||||
/* ----------------------- */
|
/* ----------------------- */
|
||||||
/* This program are the VCT file access method classes. */
|
/* This program are the VCT file access method classes. */
|
||||||
/* Added in version 2: F */
|
/* Added in version 2: F */
|
||||||
/* - Split Vec format. */
|
/* - Split Vec format. */
|
||||||
/* - Partial delete. */
|
/* - Partial delete. */
|
||||||
/* - Use of tempfile for update. */
|
/* - Use of tempfile for update. */
|
||||||
/* */
|
/* */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Include relevant MariaDB header file. */
|
/* Include relevant MariaDB header file. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
#include "my_global.h"
|
#include "my_global.h"
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
@ -35,7 +35,6 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
//#define strerror(X) _strerror(X)
|
|
||||||
#define NO_ERROR 0
|
#define NO_ERROR 0
|
||||||
#else // !UNIX
|
#else // !UNIX
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
@ -204,7 +203,6 @@ bool VCTFAM::SetBlockInfo(PGLOBAL g)
|
|||||||
{
|
{
|
||||||
char filename[_MAX_PATH];
|
char filename[_MAX_PATH];
|
||||||
bool rc = false;
|
bool rc = false;
|
||||||
int k;
|
|
||||||
size_t n;
|
size_t n;
|
||||||
VECHEADER vh;
|
VECHEADER vh;
|
||||||
FILE *s;
|
FILE *s;
|
||||||
@ -216,7 +214,7 @@ bool VCTFAM::SetBlockInfo(PGLOBAL g)
|
|||||||
s = Stream;
|
s = Stream;
|
||||||
|
|
||||||
if (Header == 1)
|
if (Header == 1)
|
||||||
k = fseek(s, 0, SEEK_SET);
|
/*k =*/ fseek(s, 0, SEEK_SET);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
s= global_fopen(g, MSGID_CANNOT_OPEN, filename, "r+b");
|
s= global_fopen(g, MSGID_CANNOT_OPEN, filename, "r+b");
|
||||||
@ -230,7 +228,7 @@ bool VCTFAM::SetBlockInfo(PGLOBAL g)
|
|||||||
sprintf(g->Message, "Error opening header file %s", filename);
|
sprintf(g->Message, "Error opening header file %s", filename);
|
||||||
return true;
|
return true;
|
||||||
} else if (Header == 3)
|
} else if (Header == 3)
|
||||||
k = fseek(s, -(int)sizeof(VECHEADER), SEEK_END);
|
/*k =*/ fseek(s, -(int)sizeof(VECHEADER), SEEK_END);
|
||||||
|
|
||||||
vh.MaxRec = MaxBlk * Bsize;
|
vh.MaxRec = MaxBlk * Bsize;
|
||||||
vh.NumRec = (Block - 1) * Nrec + Last;
|
vh.NumRec = (Block - 1) * Nrec + Last;
|
||||||
@ -775,10 +773,10 @@ int VCTFAM::DeleteRecords(PGLOBAL g, int irc)
|
|||||||
/* checked for compatibility with Text files and other OS's. */
|
/* checked for compatibility with Text files and other OS's. */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
char filename[_MAX_PATH];
|
char filename[_MAX_PATH];
|
||||||
int rc, h;
|
int h;
|
||||||
|
|
||||||
rc = CleanUnusedSpace(g); // Clean last block
|
/*rc =*/ CleanUnusedSpace(g); // Clean last block
|
||||||
rc = PlugCloseFile(g, To_Fb);
|
/*rc =*/ PlugCloseFile(g, To_Fb);
|
||||||
Stream = NULL; // For SetBlockInfo
|
Stream = NULL; // For SetBlockInfo
|
||||||
PlugSetPath(filename, To_File, Tdbp->GetPath());
|
PlugSetPath(filename, To_File, Tdbp->GetPath());
|
||||||
|
|
||||||
@ -1705,7 +1703,7 @@ int VCMFAM::DeleteRecords(PGLOBAL g, int irc)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void VCMFAM::CloseTableFile(PGLOBAL g)
|
void VCMFAM::CloseTableFile(PGLOBAL g)
|
||||||
{
|
{
|
||||||
int rc = 0, wrc = RC_OK;
|
int wrc = RC_OK;
|
||||||
MODE mode = Tdbp->GetMode();
|
MODE mode = Tdbp->GetMode();
|
||||||
|
|
||||||
if (mode == MODE_INSERT) {
|
if (mode == MODE_INSERT) {
|
||||||
@ -1728,7 +1726,7 @@ void VCMFAM::CloseTableFile(PGLOBAL g)
|
|||||||
PlugCloseFile(g, To_Fb);
|
PlugCloseFile(g, To_Fb);
|
||||||
|
|
||||||
if (wrc != RC_FX)
|
if (wrc != RC_FX)
|
||||||
rc = ResetTableSize(g, Block, Last);
|
/*rc =*/ ResetTableSize(g, Block, Last);
|
||||||
|
|
||||||
} else if (mode != MODE_DELETE)
|
} else if (mode != MODE_DELETE)
|
||||||
PlugCloseFile(g, To_Fb);
|
PlugCloseFile(g, To_Fb);
|
||||||
@ -1823,7 +1821,7 @@ bool VECFAM::OpenTableFile(PGLOBAL g)
|
|||||||
{
|
{
|
||||||
char opmode[4];
|
char opmode[4];
|
||||||
int i;
|
int i;
|
||||||
bool b;
|
bool b= false;
|
||||||
PCOLDEF cdp;
|
PCOLDEF cdp;
|
||||||
PVCTCOL cp;
|
PVCTCOL cp;
|
||||||
MODE mode = Tdbp->GetMode();
|
MODE mode = Tdbp->GetMode();
|
||||||
@ -2205,11 +2203,11 @@ int VECFAM::DeleteRecords(PGLOBAL g, int irc)
|
|||||||
/* for compatibility with other OS's. */
|
/* for compatibility with other OS's. */
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
char filename[_MAX_PATH];
|
char filename[_MAX_PATH];
|
||||||
int h, rc; // File handle, return code
|
int h; // File handle, return code
|
||||||
|
|
||||||
for (int i = 0; i < Ncol; i++) {
|
for (int i = 0; i < Ncol; i++) {
|
||||||
sprintf(filename, Colfn, i + 1);
|
sprintf(filename, Colfn, i + 1);
|
||||||
rc = PlugCloseFile(g, To_Fbs[i]);
|
/*rc =*/ PlugCloseFile(g, To_Fbs[i]);
|
||||||
|
|
||||||
if ((h= global_open(g, MSGID_OPEN_STRERROR, filename, O_WRONLY)) <= 0)
|
if ((h= global_open(g, MSGID_OPEN_STRERROR, filename, O_WRONLY)) <= 0)
|
||||||
return RC_FX;
|
return RC_FX;
|
||||||
@ -3118,7 +3116,6 @@ int BGVFAM::GetBlockInfo(PGLOBAL g)
|
|||||||
{
|
{
|
||||||
char filename[_MAX_PATH];
|
char filename[_MAX_PATH];
|
||||||
int n;
|
int n;
|
||||||
bool b;
|
|
||||||
VECHEADER vh;
|
VECHEADER vh;
|
||||||
HANDLE h;
|
HANDLE h;
|
||||||
|
|
||||||
@ -3162,7 +3159,7 @@ int BGVFAM::GetBlockInfo(PGLOBAL g)
|
|||||||
|
|
||||||
return n;
|
return n;
|
||||||
} else if (Header == 3)
|
} else if (Header == 3)
|
||||||
b = BigSeek(g, h, -(BIGINT)sizeof(vh), true);
|
/*b = */ BigSeek(g, h, -(BIGINT)sizeof(vh), true);
|
||||||
|
|
||||||
if (BigRead(g, h, &vh, sizeof(vh))) {
|
if (BigRead(g, h, &vh, sizeof(vh))) {
|
||||||
sprintf(g->Message, "Error reading header file %s", filename);
|
sprintf(g->Message, "Error reading header file %s", filename);
|
||||||
@ -3190,7 +3187,7 @@ int BGVFAM::GetBlockInfo(PGLOBAL g)
|
|||||||
bool BGVFAM::SetBlockInfo(PGLOBAL g)
|
bool BGVFAM::SetBlockInfo(PGLOBAL g)
|
||||||
{
|
{
|
||||||
char filename[_MAX_PATH];
|
char filename[_MAX_PATH];
|
||||||
bool bk, b = false, rc = false;
|
bool b = false, rc = false;
|
||||||
VECHEADER vh;
|
VECHEADER vh;
|
||||||
HANDLE h = INVALID_HANDLE_VALUE;
|
HANDLE h = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
@ -3201,7 +3198,7 @@ bool BGVFAM::SetBlockInfo(PGLOBAL g)
|
|||||||
h = Hfile;
|
h = Hfile;
|
||||||
|
|
||||||
if (Header == 1)
|
if (Header == 1)
|
||||||
bk = BigSeek(g, h, (BIGINT)0);
|
/*bk =*/ BigSeek(g, h, (BIGINT)0);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
b = true;
|
b = true;
|
||||||
@ -3230,7 +3227,7 @@ bool BGVFAM::SetBlockInfo(PGLOBAL g)
|
|||||||
} // endif h
|
} // endif h
|
||||||
|
|
||||||
if (Header == 3)
|
if (Header == 3)
|
||||||
bk = BigSeek(g, h, -(BIGINT)sizeof(vh), true);
|
/*bk =*/ BigSeek(g, h, -(BIGINT)sizeof(vh), true);
|
||||||
|
|
||||||
vh.MaxRec = MaxBlk * Bsize;
|
vh.MaxRec = MaxBlk * Bsize;
|
||||||
vh.NumRec = (Block - 1) * Nrec + Last;
|
vh.NumRec = (Block - 1) * Nrec + Last;
|
||||||
|
@ -20,12 +20,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define FLEX_SCANNER
|
#define FLEX_SCANNER
|
||||||
|
|
||||||
#if WIN32
|
#if WIN32
|
||||||
#define __STDC__ 1
|
#define __STDC__ 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#ifndef WIN32
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
|
/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
|
||||||
@ -47,7 +48,7 @@
|
|||||||
/* The "const" storage-class-modifier is valid. */
|
/* The "const" storage-class-modifier is valid. */
|
||||||
#define YY_USE_CONST
|
#define YY_USE_CONST
|
||||||
|
|
||||||
#else /* ! __cplusplus */
|
#else /* ! __cplusplus */
|
||||||
|
|
||||||
#ifdef __STDC__
|
#ifdef __STDC__
|
||||||
|
|
||||||
@ -131,7 +132,7 @@ extern "C" {
|
|||||||
* int a single C statement (which needs a semi-colon terminator). This
|
* int a single C statement (which needs a semi-colon terminator). This
|
||||||
* avoids problems with code like:
|
* avoids problems with code like:
|
||||||
*
|
*
|
||||||
* if ( condition_holds )
|
* if ( condition_holds )
|
||||||
* yyless( 5 );
|
* yyless( 5 );
|
||||||
* else
|
* else
|
||||||
* do_something_else();
|
* do_something_else();
|
||||||
@ -161,7 +162,7 @@ struct yy_buffer_state
|
|||||||
FILE *yy_input_file;
|
FILE *yy_input_file;
|
||||||
|
|
||||||
char *yy_ch_buf; /* input buffer */
|
char *yy_ch_buf; /* input buffer */
|
||||||
char *yy_buf_pos; /* current position in input buffer */
|
char *yy_buf_pos; /* current position in input buffer */
|
||||||
|
|
||||||
/* Size of input buffer in bytes, not including room for EOB
|
/* Size of input buffer in bytes, not including room for EOB
|
||||||
* characters.
|
* characters.
|
||||||
@ -220,7 +221,7 @@ int yyleng;
|
|||||||
|
|
||||||
/* Points to current character in buffer. */
|
/* Points to current character in buffer. */
|
||||||
static char *yy_c_buf_p = (char *) 0;
|
static char *yy_c_buf_p = (char *) 0;
|
||||||
static int yy_init = 1; /* whether we need to initialize */
|
static int yy_init = 1; /* whether we need to initialize */
|
||||||
static int yy_start = 0; /* start state number */
|
static int yy_start = 0; /* start state number */
|
||||||
|
|
||||||
/* Flag which is used to allow yywrap()'s to do buffer switches
|
/* Flag which is used to allow yywrap()'s to do buffer switches
|
||||||
@ -394,7 +395,6 @@ char *yytext;
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "preparse.h"
|
#include "preparse.h"
|
||||||
|
|
||||||
#define isatty _isatty
|
|
||||||
#define fileno _fileno
|
#define fileno _fileno
|
||||||
#undef YY_DECL
|
#undef YY_DECL
|
||||||
#define YY_DECL int yylex YY_PROTO((PDTP ppp))
|
#define YY_DECL int yylex YY_PROTO((PDTP ppp))
|
||||||
@ -406,6 +406,8 @@ char *yytext;
|
|||||||
#undef yywrap
|
#undef yywrap
|
||||||
#define yywrap ddwrap
|
#define yywrap ddwrap
|
||||||
#endif /* UNIX */
|
#endif /* UNIX */
|
||||||
|
int yywrap(void);
|
||||||
|
|
||||||
static PDTP pp;
|
static PDTP pp;
|
||||||
static void MakeParm(int n);
|
static void MakeParm(int n);
|
||||||
static void MakeMMDD(int n);
|
static void MakeMMDD(int n);
|
||||||
@ -520,10 +522,7 @@ YY_DECL
|
|||||||
if (pp->InFmt) {*pp->InFmt = '\0'; pp->InFmt[pp->Outsize -1] = '\0'; }
|
if (pp->InFmt) {*pp->InFmt = '\0'; pp->InFmt[pp->Outsize -1] = '\0'; }
|
||||||
if (pp->OutFmt) {*pp->OutFmt = '\0'; pp->OutFmt[pp->Outsize -1] = '\0'; }
|
if (pp->OutFmt) {*pp->OutFmt = '\0'; pp->OutFmt[pp->Outsize -1] = '\0'; }
|
||||||
pp->Curp = pp->Format;
|
pp->Curp = pp->Format;
|
||||||
if (!yy_init) { /* Restart that stupid Flex otherwise parsing last input */
|
yy_init = 1; /* This is a new input */
|
||||||
yy_init_buffer( yy_current_buffer, yyin );
|
|
||||||
yy_load_buffer_state();
|
|
||||||
} // endif yy_init
|
|
||||||
|
|
||||||
|
|
||||||
if ( yy_init )
|
if ( yy_init )
|
||||||
@ -533,7 +532,7 @@ YY_DECL
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( ! yy_start )
|
if ( ! yy_start )
|
||||||
yy_start = 1; /* first start state */
|
yy_start = 1; /* first start state */
|
||||||
|
|
||||||
if ( ! yyin )
|
if ( ! yyin )
|
||||||
yyin = stdin;
|
yyin = stdin;
|
||||||
@ -552,7 +551,7 @@ YY_DECL
|
|||||||
yy_init = 0;
|
yy_init = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( 1 ) /* loops until end-of-file is reached */
|
while ( 1 ) /* loops until end-of-file is reached */
|
||||||
{
|
{
|
||||||
yy_cp = yy_c_buf_p;
|
yy_cp = yy_c_buf_p;
|
||||||
|
|
||||||
@ -1114,7 +1113,7 @@ static int input()
|
|||||||
}
|
}
|
||||||
|
|
||||||
c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
|
c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
|
||||||
*yy_c_buf_p = '\0'; /* preserve yytext */
|
*yy_c_buf_p = '\0'; /* preserve yytext */
|
||||||
yy_hold_char = *++yy_c_buf_p;
|
yy_hold_char = *++yy_c_buf_p;
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
@ -1520,6 +1519,10 @@ void Quotout(char *text)
|
|||||||
|
|
||||||
int yywrap(void)
|
int yywrap(void)
|
||||||
{
|
{
|
||||||
|
/* Avoid memory leak */
|
||||||
|
if (yy_current_buffer)
|
||||||
|
yy_delete_buffer(yy_current_buffer);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
} /* end of yywrap */
|
} /* end of yywrap */
|
||||||
|
|
||||||
|
@ -244,6 +244,7 @@ DllExport BOOL PlugIsAbsolutePath(LPCSTR path);
|
|||||||
DllExport void *PlugAllocMem(PGLOBAL, uint);
|
DllExport void *PlugAllocMem(PGLOBAL, uint);
|
||||||
DllExport BOOL PlugSubSet(PGLOBAL, void *, uint);
|
DllExport BOOL PlugSubSet(PGLOBAL, void *, uint);
|
||||||
DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t);
|
DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t);
|
||||||
|
DllExport char *PlugDup(PGLOBAL g, const char *str);
|
||||||
DllExport void *MakePtr(void *, OFFSET);
|
DllExport void *MakePtr(void *, OFFSET);
|
||||||
DllExport void htrc(char const *fmt, ...);
|
DllExport void htrc(char const *fmt, ...);
|
||||||
|
|
||||||
|
@ -146,10 +146,13 @@
|
|||||||
#define my_stricmp(a,b) my_strcasecmp(default_charset_info, (a), (b))
|
#define my_stricmp(a,b) my_strcasecmp(default_charset_info, (a), (b))
|
||||||
|
|
||||||
#ifdef LIBXML2_SUPPORT
|
#ifdef LIBXML2_SUPPORT
|
||||||
void XmlInitParserLib(void);
|
#include "libdoc.h"
|
||||||
void XmlCleanupParserLib(void);
|
|
||||||
#endif // LIBXML2_SUPPORT
|
#endif // LIBXML2_SUPPORT
|
||||||
|
|
||||||
|
#include "taboccur.h"
|
||||||
|
#include "tabpivot.h"
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* DB static variables. */
|
/* DB static variables. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -167,16 +170,6 @@ extern "C" {
|
|||||||
int trace= 0; // The general trace value
|
int trace= 0; // The general trace value
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
||||||
bool OcrColumns(PGLOBAL g, PQRYRES qrp, const char *col,
|
|
||||||
const char *ocr, const char *rank);
|
|
||||||
bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col,
|
|
||||||
const char *ocr, const char *rank);
|
|
||||||
PQRYRES PivotColumns(PGLOBAL g, const char *tab, const char *src,
|
|
||||||
const char *picol, const char *fncol,
|
|
||||||
const char *host, const char *db,
|
|
||||||
const char *user, const char *pwd,
|
|
||||||
int port);
|
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/* Initialize the ha_connect static members. */
|
/* Initialize the ha_connect static members. */
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
@ -360,6 +353,9 @@ static int connect_init_func(void *p)
|
|||||||
trace= xtrace;
|
trace= xtrace;
|
||||||
} // endif xtrace
|
} // endif xtrace
|
||||||
|
|
||||||
|
#if !defined(WIN32)
|
||||||
|
PROFILE_Close(connectini);
|
||||||
|
#endif // !WIN32
|
||||||
|
|
||||||
init_connect_psi_keys();
|
init_connect_psi_keys();
|
||||||
|
|
||||||
@ -394,6 +390,10 @@ static int connect_done_func(void *p)
|
|||||||
XmlCleanupParserLib();
|
XmlCleanupParserLib();
|
||||||
#endif // LIBXML2_SUPPORT
|
#endif // LIBXML2_SUPPORT
|
||||||
|
|
||||||
|
#if !defined(WIN32)
|
||||||
|
PROFILE_End();
|
||||||
|
#endif // !WIN32
|
||||||
|
|
||||||
for (pc= user_connect::to_users; pc; pc= pn) {
|
for (pc= user_connect::to_users; pc; pc= pn) {
|
||||||
if (pc->g)
|
if (pc->g)
|
||||||
PlugCleanup(pc->g, true);
|
PlugCleanup(pc->g, true);
|
||||||
@ -666,8 +666,7 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
|
|||||||
else if (!stricmp(opname, "Separator"))
|
else if (!stricmp(opname, "Separator"))
|
||||||
opval= (char*)options->separator;
|
opval= (char*)options->separator;
|
||||||
else if (!stricmp(opname, "Connect"))
|
else if (!stricmp(opname, "Connect"))
|
||||||
// opval= (char*)options->connect;
|
opval= (tshp) ? tshp->connect_string.str : table->s->connect_string.str;
|
||||||
opval= table->s->connect_string.str;
|
|
||||||
else if (!stricmp(opname, "Qchar"))
|
else if (!stricmp(opname, "Qchar"))
|
||||||
opval= (char*)options->qchar;
|
opval= (char*)options->qchar;
|
||||||
else if (!stricmp(opname, "Module"))
|
else if (!stricmp(opname, "Module"))
|
||||||
@ -845,7 +844,7 @@ PFOS ha_connect::GetFieldOptionStruct(Field *fdp)
|
|||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/* Returns the column description structure used to make the column. */
|
/* Returns the column description structure used to make the column. */
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
void *ha_connect::GetColumnOption(void *field, PCOLINFO pcf)
|
void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
|
||||||
{
|
{
|
||||||
const char *cp;
|
const char *cp;
|
||||||
ha_field_option_struct *fop;
|
ha_field_option_struct *fop;
|
||||||
@ -900,6 +899,7 @@ void *ha_connect::GetColumnOption(void *field, PCOLINFO pcf)
|
|||||||
case MYSQL_TYPE_VARCHAR:
|
case MYSQL_TYPE_VARCHAR:
|
||||||
case MYSQL_TYPE_VAR_STRING:
|
case MYSQL_TYPE_VAR_STRING:
|
||||||
pcf->Flags |= U_VAR;
|
pcf->Flags |= U_VAR;
|
||||||
|
/* no break */
|
||||||
case MYSQL_TYPE_STRING:
|
case MYSQL_TYPE_STRING:
|
||||||
pcf->Type= TYPE_STRING;
|
pcf->Type= TYPE_STRING;
|
||||||
|
|
||||||
@ -963,6 +963,7 @@ void *ha_connect::GetColumnOption(void *field, PCOLINFO pcf)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pcf->Type=TYPE_ERROR;
|
pcf->Type=TYPE_ERROR;
|
||||||
|
break;
|
||||||
} // endswitch type
|
} // endswitch type
|
||||||
|
|
||||||
// This is used to skip null bit
|
// This is used to skip null bit
|
||||||
@ -974,7 +975,15 @@ void *ha_connect::GetColumnOption(void *field, PCOLINFO pcf)
|
|||||||
pcf->Flags |= U_VIRTUAL;
|
pcf->Flags |= U_VIRTUAL;
|
||||||
|
|
||||||
pcf->Key= 0; // Not used when called from MySQL
|
pcf->Key= 0; // Not used when called from MySQL
|
||||||
pcf->Remark= fp->comment.str;
|
|
||||||
|
// Get the comment if any
|
||||||
|
if (fp->comment.str && fp->comment.length) {
|
||||||
|
pcf->Remark= (char*)PlugSubAlloc(g, NULL, fp->comment.length + 1);
|
||||||
|
memcpy(pcf->Remark, fp->comment.str, fp->comment.length);
|
||||||
|
pcf->Remark[fp->comment.length] = 0;
|
||||||
|
} else
|
||||||
|
pcf->Remark= NULL;
|
||||||
|
|
||||||
return fldp;
|
return fldp;
|
||||||
} // end of GetColumnOption
|
} // end of GetColumnOption
|
||||||
|
|
||||||
@ -1324,6 +1333,7 @@ int ha_connect::MakeRecord(char *buf)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fmt= "%Y-%m-%d %H:%M:%S";
|
fmt= "%Y-%m-%d %H:%M:%S";
|
||||||
|
break;
|
||||||
} // endswitch type
|
} // endswitch type
|
||||||
|
|
||||||
// Get date in the format required by MySQL fields
|
// Get date in the format required by MySQL fields
|
||||||
@ -1337,6 +1347,7 @@ int ha_connect::MakeRecord(char *buf)
|
|||||||
// Passthru
|
// Passthru
|
||||||
default:
|
default:
|
||||||
p= value->GetCharString(val);
|
p= value->GetCharString(val);
|
||||||
|
break;
|
||||||
} // endswitch Type
|
} // endswitch Type
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
@ -1456,6 +1467,7 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *buf)
|
|||||||
attribute.charset(), charset, &cnv_errors);
|
attribute.charset(), charset, &cnv_errors);
|
||||||
value->SetValue_psz(data_charset_value.c_ptr_safe());
|
value->SetValue_psz(data_charset_value.c_ptr_safe());
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
} // endswitch Type
|
} // endswitch Type
|
||||||
|
|
||||||
#ifdef NEWCHANGE
|
#ifdef NEWCHANGE
|
||||||
@ -1563,6 +1575,7 @@ const char *ha_connect::GetValStr(OPVAL vop, bool neg)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
val= " ? ";
|
val= " ? ";
|
||||||
|
break;
|
||||||
} /* endswitch */
|
} /* endswitch */
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
@ -2165,6 +2178,7 @@ int ha_connect::ReadIndexed(uchar *buf, OPVAL op, const uchar *key, uint key_len
|
|||||||
DBUG_PRINT("ReadIndexed", ("%s", xp->g->Message));
|
DBUG_PRINT("ReadIndexed", ("%s", xp->g->Message));
|
||||||
printf("ReadIndexed: %s\n", xp->g->Message);
|
printf("ReadIndexed: %s\n", xp->g->Message);
|
||||||
rc= HA_ERR_INTERNAL_ERROR;
|
rc= HA_ERR_INTERNAL_ERROR;
|
||||||
|
break;
|
||||||
} // endswitch RC
|
} // endswitch RC
|
||||||
|
|
||||||
if (xtrace > 1)
|
if (xtrace > 1)
|
||||||
@ -2207,7 +2221,7 @@ int ha_connect::index_read(uchar * buf, const uchar * key, uint key_len,
|
|||||||
case HA_READ_KEY_EXACT: op= OP_EQ; break;
|
case HA_READ_KEY_EXACT: op= OP_EQ; break;
|
||||||
case HA_READ_AFTER_KEY: op= OP_GT; break;
|
case HA_READ_AFTER_KEY: op= OP_GT; break;
|
||||||
case HA_READ_KEY_OR_NEXT: op= OP_GE; break;
|
case HA_READ_KEY_OR_NEXT: op= OP_GE; break;
|
||||||
default: DBUG_RETURN(-1);
|
default: DBUG_RETURN(-1); break;
|
||||||
} // endswitch find_flag
|
} // endswitch find_flag
|
||||||
|
|
||||||
if (xtrace > 1)
|
if (xtrace > 1)
|
||||||
@ -2830,6 +2844,7 @@ int ha_connect::external_lock(THD *thd, int lock_type)
|
|||||||
case F_UNLCK:
|
case F_UNLCK:
|
||||||
default:
|
default:
|
||||||
newmode= MODE_ANY;
|
newmode= MODE_ANY;
|
||||||
|
break;
|
||||||
} // endswitch mode
|
} // endswitch mode
|
||||||
|
|
||||||
if (newmode == MODE_ANY) {
|
if (newmode == MODE_ANY) {
|
||||||
@ -2920,8 +2935,17 @@ int ha_connect::external_lock(THD *thd, int lock_type)
|
|||||||
|
|
||||||
} // endelse Xchk
|
} // endelse Xchk
|
||||||
|
|
||||||
if (CloseTable(g))
|
if (CloseTable(g)) {
|
||||||
|
// This is an error while builing index
|
||||||
|
#if defined(_DEBUG)
|
||||||
|
// Make it a warning to avoid crash
|
||||||
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message);
|
||||||
|
rc= 0;
|
||||||
|
#else // !_DEBUG
|
||||||
|
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||||
rc= HA_ERR_INTERNAL_ERROR;
|
rc= HA_ERR_INTERNAL_ERROR;
|
||||||
|
#endif // !DEBUG
|
||||||
|
} // endif Close
|
||||||
|
|
||||||
DBUG_RETURN(rc);
|
DBUG_RETURN(rc);
|
||||||
} // endif MODE_ANY
|
} // endif MODE_ANY
|
||||||
@ -2978,6 +3002,7 @@ int ha_connect::external_lock(THD *thd, int lock_type)
|
|||||||
printf("Unsupported sql_command=%d", thd_sql_command(thd));
|
printf("Unsupported sql_command=%d", thd_sql_command(thd));
|
||||||
sprintf(g->Message, "Unsupported sql_command=%d", thd_sql_command(thd));
|
sprintf(g->Message, "Unsupported sql_command=%d", thd_sql_command(thd));
|
||||||
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
||||||
|
break;
|
||||||
} // endswitch newmode
|
} // endswitch newmode
|
||||||
|
|
||||||
} else if (newmode == MODE_READ) {
|
} else if (newmode == MODE_READ) {
|
||||||
@ -3015,6 +3040,7 @@ int ha_connect::external_lock(THD *thd, int lock_type)
|
|||||||
printf("Unsupported sql_command=%d", thd_sql_command(thd));
|
printf("Unsupported sql_command=%d", thd_sql_command(thd));
|
||||||
sprintf(g->Message, "Unsupported sql_command=%d", thd_sql_command(thd));
|
sprintf(g->Message, "Unsupported sql_command=%d", thd_sql_command(thd));
|
||||||
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
||||||
|
break;
|
||||||
} // endswitch newmode
|
} // endswitch newmode
|
||||||
|
|
||||||
} // endif's newmode
|
} // endif's newmode
|
||||||
@ -3432,7 +3458,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
fnc= GetFuncID(fncn);
|
fnc= GetFuncID(fncn);
|
||||||
sep= topt->separator;
|
sep= topt->separator;
|
||||||
spc= (!sep || !strcmp(sep, "\\t")) ? '\t' : *sep;
|
spc= (!sep || !strcmp(sep, "\\t")) ? '\t' : *sep;
|
||||||
qch= topt->qchar ? *topt->qchar : topt->quoted >= 0 ? '"' : 0;
|
qch= topt->qchar ? *topt->qchar : (signed)topt->quoted >= 0 ? '"' : 0;
|
||||||
hdr= (int)topt->header;
|
hdr= (int)topt->header;
|
||||||
tbl= topt->tablist;
|
tbl= topt->tablist;
|
||||||
col= topt->colist;
|
col= topt->colist;
|
||||||
@ -3571,6 +3597,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sprintf(g->Message, "Cannot get column info for table type %s", topt->type);
|
sprintf(g->Message, "Cannot get column info for table type %s", topt->type);
|
||||||
|
break;
|
||||||
} // endif ttp
|
} // endif ttp
|
||||||
|
|
||||||
// Check for supported catalog function
|
// Check for supported catalog function
|
||||||
@ -3631,6 +3658,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sprintf(g->Message, "invalid catfunc %s", fncn);
|
sprintf(g->Message, "invalid catfunc %s", fncn);
|
||||||
|
break;
|
||||||
} // endswitch info
|
} // endswitch info
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -3967,7 +3995,8 @@ int ha_connect::create(const char *name, TABLE *table_arg,
|
|||||||
} // endif tabname
|
} // endif tabname
|
||||||
|
|
||||||
default: /* do nothing */;
|
default: /* do nothing */;
|
||||||
} // endswitch ttp
|
break;
|
||||||
|
} // endswitch ttp
|
||||||
|
|
||||||
if (type == TAB_XML) {
|
if (type == TAB_XML) {
|
||||||
bool dom; // True: MS-DOM, False libxml2
|
bool dom; // True: MS-DOM, False libxml2
|
||||||
@ -3989,6 +4018,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dom= false;
|
dom= false;
|
||||||
|
break;
|
||||||
} // endswitch xsup
|
} // endswitch xsup
|
||||||
|
|
||||||
#if !defined(DOMDOC_SUPPORT)
|
#if !defined(DOMDOC_SUPPORT)
|
||||||
@ -4027,6 +4057,14 @@ int ha_connect::create(const char *name, TABLE *table_arg,
|
|||||||
DBUG_RETURN(rc);
|
DBUG_RETURN(rc);
|
||||||
} // endif flags
|
} // endif flags
|
||||||
|
|
||||||
|
if (fp->flags & (BLOB_FLAG | ENUM_FLAG | SET_FLAG)) {
|
||||||
|
sprintf(g->Message, "Unsupported type for column %s",
|
||||||
|
fp->field_name);
|
||||||
|
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||||
|
rc= HA_ERR_INTERNAL_ERROR;
|
||||||
|
DBUG_RETURN(rc);
|
||||||
|
} // endif flags
|
||||||
|
|
||||||
switch (fp->type()) {
|
switch (fp->type()) {
|
||||||
case MYSQL_TYPE_SHORT:
|
case MYSQL_TYPE_SHORT:
|
||||||
case MYSQL_TYPE_LONG:
|
case MYSQL_TYPE_LONG:
|
||||||
@ -4066,6 +4104,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
|
|||||||
"Unsupported type for column '%s'",
|
"Unsupported type for column '%s'",
|
||||||
MYF(0), fp->field_name);
|
MYF(0), fp->field_name);
|
||||||
DBUG_RETURN(rc);
|
DBUG_RETURN(rc);
|
||||||
|
break;
|
||||||
} // endswitch type
|
} // endswitch type
|
||||||
|
|
||||||
if ((fp)->real_maybe_null() && !IsTypeNullable(type)) {
|
if ((fp)->real_maybe_null() && !IsTypeNullable(type)) {
|
||||||
|
@ -154,7 +154,7 @@ public:
|
|||||||
int GetIntegerOption(char *opname);
|
int GetIntegerOption(char *opname);
|
||||||
bool SetIntegerOption(char *opname, int n);
|
bool SetIntegerOption(char *opname, int n);
|
||||||
PFOS GetFieldOptionStruct(Field *fp);
|
PFOS GetFieldOptionStruct(Field *fp);
|
||||||
void *GetColumnOption(void *field, PCOLINFO pcf);
|
void *GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf);
|
||||||
PIXDEF GetIndexInfo(void);
|
PIXDEF GetIndexInfo(void);
|
||||||
const char *GetDBName(const char *name);
|
const char *GetDBName(const char *name);
|
||||||
const char *GetTableName(void);
|
const char *GetTableName(void);
|
||||||
|
@ -608,6 +608,31 @@ void PROFILE_Close(LPCSTR filename)
|
|||||||
} // end of PROFILE_Close
|
} // end of PROFILE_Close
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* PROFILE_End
|
||||||
|
*
|
||||||
|
* Terminate and release the cache.
|
||||||
|
***********************************************************************/
|
||||||
|
void PROFILE_End(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("PROFILE_End: CurProfile=%p N=%d\n", CurProfile, N_CACHED_PROFILES);
|
||||||
|
|
||||||
|
/* Close all opened files and free the cache structure */
|
||||||
|
for (i = 0; i < N_CACHED_PROFILES; i++) {
|
||||||
|
if (trace)
|
||||||
|
htrc("MRU=%s i=%d\n", SVP(MRUProfile[i]->filename), i);
|
||||||
|
|
||||||
|
CurProfile = MRUProfile[i];
|
||||||
|
PROFILE_ReleaseFile();
|
||||||
|
free(MRUProfile[i]);
|
||||||
|
} // endfor i
|
||||||
|
|
||||||
|
} // end of PROFILE_End
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* PROFILE_DeleteSection
|
* PROFILE_DeleteSection
|
||||||
*
|
*
|
||||||
|
@ -8,6 +8,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void PROFILE_Close(LPCSTR filename);
|
void PROFILE_Close(LPCSTR filename);
|
||||||
|
void PROFILE_End(void);
|
||||||
|
|
||||||
int GetPrivateProfileString(
|
int GetPrivateProfileString(
|
||||||
LPCTSTR lpAppName, // section name
|
LPCTSTR lpAppName, // section name
|
||||||
|
@ -25,11 +25,207 @@
|
|||||||
|
|
||||||
#include "sql_string.h"
|
#include "sql_string.h"
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* Declaration of XML document processing using libxml2 */
|
||||||
|
/* Author: Olivier Bertrand 2007-2012 */
|
||||||
|
/******************************************************************/
|
||||||
|
#include "plgxml.h"
|
||||||
|
|
||||||
|
typedef class LIBXMLDOC *PXDOC2;
|
||||||
|
typedef class XML2NODE *PNODE2;
|
||||||
|
typedef class XML2ATTR *PATTR2;
|
||||||
|
typedef class XML2NODELIST *PLIST2;
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* XML2 block. Must have the same layout than FBLOCK up to Type. */
|
||||||
|
/******************************************************************/
|
||||||
|
typedef struct _x2block { /* Loaded XML file block */
|
||||||
|
struct _x2block *Next;
|
||||||
|
LPCSTR Fname; /* Point on file name */
|
||||||
|
size_t Length; /* Used to tell if read mode */
|
||||||
|
short Count; /* Nb of times file is used */
|
||||||
|
short Type; /* TYPE_FB_XML */
|
||||||
|
int Retcode; /* Return code from Load */
|
||||||
|
xmlDocPtr Docp; /* Document interface pointer */
|
||||||
|
// xmlXPathContextPtr Ctxp;
|
||||||
|
// xmlXPathObjectPtr Xop;
|
||||||
|
} X2BLOCK, *PX2BLOCK;
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* Declaration of libxml2 document. */
|
||||||
|
/******************************************************************/
|
||||||
|
class LIBXMLDOC : public XMLDOCUMENT {
|
||||||
|
friend class XML2NODE;
|
||||||
|
friend class XML2ATTR;
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
LIBXMLDOC(char *nsl, char *nsdf, char *enc, PFBLOCK fp);
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
virtual short GetDocType(void) {return TYPE_FB_XML2;}
|
||||||
|
virtual void *GetDocPtr(void) {return Docp;}
|
||||||
|
virtual void SetNofree(bool b) {Nofreelist = b;}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
virtual bool Initialize(PGLOBAL g);
|
||||||
|
virtual bool ParseFile(char *fn);
|
||||||
|
virtual bool NewDoc(PGLOBAL g, char *ver);
|
||||||
|
virtual void AddComment(PGLOBAL g, char *com);
|
||||||
|
virtual PXNODE GetRoot(PGLOBAL g);
|
||||||
|
virtual PXNODE NewRoot(PGLOBAL g, char *name);
|
||||||
|
virtual PXNODE NewPnode(PGLOBAL g, char *name);
|
||||||
|
virtual PXATTR NewPattr(PGLOBAL g);
|
||||||
|
virtual PXLIST NewPlist(PGLOBAL g);
|
||||||
|
virtual int DumpDoc(PGLOBAL g, char *ofn);
|
||||||
|
virtual void CloseDoc(PGLOBAL g, PFBLOCK xp);
|
||||||
|
virtual PFBLOCK LinkXblock(PGLOBAL g, MODE m, int rc, char *fn);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// bool CheckDocument(FILE *of, xmlNodePtr np);
|
||||||
|
xmlNodeSetPtr GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp);
|
||||||
|
int Decode(xmlChar *cnt, char *buf, int n);
|
||||||
|
xmlChar *Encode(PGLOBAL g, char *txt);
|
||||||
|
|
||||||
|
// Members
|
||||||
|
xmlDocPtr Docp;
|
||||||
|
xmlNodeSetPtr Nlist;
|
||||||
|
xmlXPathContextPtr Ctxp;
|
||||||
|
xmlXPathObjectPtr Xop;
|
||||||
|
char *Buf; // Temporary
|
||||||
|
bool Nofreelist;
|
||||||
|
}; // end of class LIBXMLDOC
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* Declaration of libxml2 node. */
|
||||||
|
/******************************************************************/
|
||||||
|
class XML2NODE : public XMLNODE {
|
||||||
|
friend class LIBXMLDOC;
|
||||||
|
friend class XML2NODELIST;
|
||||||
|
public:
|
||||||
|
// Properties
|
||||||
|
virtual char *GetName(PGLOBAL g) {return (char*)Nodep->name;}
|
||||||
|
virtual int GetType(void);
|
||||||
|
virtual PXNODE GetNext(PGLOBAL g);
|
||||||
|
virtual PXNODE GetChild(PGLOBAL g);
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
virtual RCODE GetContent(PGLOBAL g, char *buf, int len);
|
||||||
|
virtual bool SetContent(PGLOBAL g, char *txtp, int len);
|
||||||
|
virtual PXNODE Clone(PGLOBAL g, PXNODE np);
|
||||||
|
virtual PXLIST GetChildElements(PGLOBAL g, char *xp, PXLIST lp);
|
||||||
|
virtual PXLIST SelectNodes(PGLOBAL g, char *xp, PXLIST lp);
|
||||||
|
virtual PXNODE SelectSingleNode(PGLOBAL g, char *xp, PXNODE np);
|
||||||
|
virtual PXATTR GetAttribute(PGLOBAL g, char *name, PXATTR ap);
|
||||||
|
virtual PXNODE AddChildNode(PGLOBAL g, char *name, PXNODE np);
|
||||||
|
virtual PXATTR AddProperty(PGLOBAL g, char *name, PXATTR ap);
|
||||||
|
virtual void AddText(PGLOBAL g, char *txtp);
|
||||||
|
virtual void DeleteChild(PGLOBAL g, PXNODE dnp);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Constructor
|
||||||
|
XML2NODE(PXDOC dp, xmlNodePtr np);
|
||||||
|
|
||||||
|
// Members
|
||||||
|
xmlDocPtr Docp;
|
||||||
|
xmlChar *Content;
|
||||||
|
xmlNodePtr Nodep;
|
||||||
|
}; // end of class XML2NODE
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* Declaration of libxml2 node list. */
|
||||||
|
/******************************************************************/
|
||||||
|
class XML2NODELIST : public XMLNODELIST {
|
||||||
|
friend class LIBXMLDOC;
|
||||||
|
friend class XML2NODE;
|
||||||
|
public:
|
||||||
|
// Methods
|
||||||
|
virtual int GetLength(void);
|
||||||
|
virtual PXNODE GetItem(PGLOBAL g, int n, PXNODE np);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Constructor
|
||||||
|
XML2NODELIST(PXDOC dp, xmlNodeSetPtr lp);
|
||||||
|
|
||||||
|
// Members
|
||||||
|
xmlNodeSetPtr Listp;
|
||||||
|
}; // end of class XML2NODELIST
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* Declaration of libxml2 attribute. */
|
||||||
|
/******************************************************************/
|
||||||
|
class XML2ATTR : public XMLATTRIBUTE {
|
||||||
|
friend class LIBXMLDOC;
|
||||||
|
friend class XML2NODE;
|
||||||
|
public:
|
||||||
|
// Properties
|
||||||
|
//virtual char *GetText(void);
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
virtual bool SetText(PGLOBAL g, char *txtp, int len);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Constructor
|
||||||
|
XML2ATTR(PXDOC dp, xmlAttrPtr ap, xmlNodePtr np);
|
||||||
|
|
||||||
|
// Members
|
||||||
|
xmlAttrPtr Atrp;
|
||||||
|
xmlNodePtr Parent;
|
||||||
|
}; // end of class XML2ATTR
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
extern char version[];
|
extern char version[];
|
||||||
extern int trace;
|
extern int trace;
|
||||||
} // "C"
|
} // "C"
|
||||||
|
|
||||||
|
#if defined(MEMORY_TRACE)
|
||||||
|
static xmlFreeFunc Free;
|
||||||
|
static xmlMallocFunc Malloc;
|
||||||
|
static xmlMallocFunc MallocA;
|
||||||
|
static xmlReallocFunc Realloc;
|
||||||
|
static xmlStrdupFunc Strdup;
|
||||||
|
|
||||||
|
void xmlMyFree(void *mem)
|
||||||
|
{
|
||||||
|
if (trace)
|
||||||
|
htrc("Freeing at %p\n", mem);
|
||||||
|
Free(mem);
|
||||||
|
} // end of xmlMyFree
|
||||||
|
|
||||||
|
void *xmlMyMalloc(size_t size)
|
||||||
|
{
|
||||||
|
void *p = Malloc(size);
|
||||||
|
if (trace)
|
||||||
|
htrc("Allocating %.5d at %p\n", size, p);
|
||||||
|
return p;
|
||||||
|
} // end of xmlMyMalloc
|
||||||
|
|
||||||
|
void *xmlMyMallocAtomic(size_t size)
|
||||||
|
{
|
||||||
|
void *p = MallocA(size);
|
||||||
|
if (trace)
|
||||||
|
htrc("Atom alloc %.5d at %p\n", size, p);
|
||||||
|
return p;
|
||||||
|
} // end of xmlMyMallocAtomic
|
||||||
|
|
||||||
|
void *xmlMyRealloc(void *mem, size_t size)
|
||||||
|
{
|
||||||
|
void *p = Realloc(mem, size);
|
||||||
|
if (trace)
|
||||||
|
htrc("ReAlloc %.5d to %p from %p\n", size, p, mem);
|
||||||
|
return p;
|
||||||
|
} // end of xmlMyRealloc
|
||||||
|
|
||||||
|
char *xmlMyStrdup(const char *str)
|
||||||
|
{
|
||||||
|
char *p = Strdup(str);
|
||||||
|
if (trace)
|
||||||
|
htrc("Duplicating to %p from %p %s\n", p, str, str);
|
||||||
|
return p;
|
||||||
|
} // end of xmlMyStrdup
|
||||||
|
#endif // MEMORY_TRACE
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
/* Return a LIBXMLDOC as a XMLDOC. */
|
/* Return a LIBXMLDOC as a XMLDOC. */
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
@ -44,6 +240,17 @@ PXDOC GetLibxmlDoc(PGLOBAL g, char *nsl, char *nsdf,
|
|||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
void XmlInitParserLib(void)
|
void XmlInitParserLib(void)
|
||||||
{
|
{
|
||||||
|
#if defined(MEMORY_TRACE)
|
||||||
|
int rc = xmlGcMemGet(&Free, &Malloc, &MallocA, &Realloc, &Strdup);
|
||||||
|
|
||||||
|
if (!rc)
|
||||||
|
rc = xmlGcMemSetup(xmlMyFree,
|
||||||
|
xmlMyMalloc,
|
||||||
|
xmlMyMallocAtomic,
|
||||||
|
xmlMyRealloc,
|
||||||
|
xmlMyStrdup);
|
||||||
|
|
||||||
|
#endif // MEMORY_TRACE
|
||||||
xmlInitParser();
|
xmlInitParser();
|
||||||
} // end of XmlInitParserLib
|
} // end of XmlInitParserLib
|
||||||
|
|
||||||
@ -63,6 +270,9 @@ void CloseXML2File(PGLOBAL g, PFBLOCK fp, bool all)
|
|||||||
{
|
{
|
||||||
PX2BLOCK xp = (PX2BLOCK)fp;
|
PX2BLOCK xp = (PX2BLOCK)fp;
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("CloseXML2File: xp=%p count=%d\n", xp, (xp) ? xp->Count : 0);
|
||||||
|
|
||||||
if (xp && xp->Count > 1 && !all) {
|
if (xp && xp->Count > 1 && !all) {
|
||||||
xp->Count--;
|
xp->Count--;
|
||||||
} else if (xp && xp->Count > 0) {
|
} else if (xp && xp->Count > 0) {
|
||||||
@ -85,6 +295,8 @@ LIBXMLDOC::LIBXMLDOC(char *nsl, char *nsdf, char *enc, PFBLOCK fp)
|
|||||||
Nlist = NULL;
|
Nlist = NULL;
|
||||||
Ctxp = NULL;
|
Ctxp = NULL;
|
||||||
Xop = NULL;
|
Xop = NULL;
|
||||||
|
Buf = NULL;
|
||||||
|
Nofreelist = false;
|
||||||
} // end of LIBXMLDOC constructor
|
} // end of LIBXMLDOC constructor
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
@ -101,6 +313,9 @@ bool LIBXMLDOC::Initialize(PGLOBAL g)
|
|||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
bool LIBXMLDOC::ParseFile(char *fn)
|
bool LIBXMLDOC::ParseFile(char *fn)
|
||||||
{
|
{
|
||||||
|
if (trace)
|
||||||
|
htrc("ParseFile\n");
|
||||||
|
|
||||||
if ((Docp = xmlParseFile(fn))) {
|
if ((Docp = xmlParseFile(fn))) {
|
||||||
if (Docp->encoding)
|
if (Docp->encoding)
|
||||||
Encoding = (char*)Docp->encoding;
|
Encoding = (char*)Docp->encoding;
|
||||||
@ -149,6 +364,9 @@ bool LIBXMLDOC::NewDoc(PGLOBAL g, char *ver)
|
|||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
void LIBXMLDOC::AddComment(PGLOBAL g, char *txtp)
|
void LIBXMLDOC::AddComment(PGLOBAL g, char *txtp)
|
||||||
{
|
{
|
||||||
|
if (trace)
|
||||||
|
htrc("AddComment: %s\n", txtp);
|
||||||
|
|
||||||
xmlNodePtr cp = xmlNewDocComment(Docp, BAD_CAST txtp);
|
xmlNodePtr cp = xmlNewDocComment(Docp, BAD_CAST txtp);
|
||||||
xmlAddChild((xmlNodePtr)Docp, cp);
|
xmlAddChild((xmlNodePtr)Docp, cp);
|
||||||
} // end of AddText
|
} // end of AddText
|
||||||
@ -158,6 +376,9 @@ void LIBXMLDOC::AddComment(PGLOBAL g, char *txtp)
|
|||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
PXNODE LIBXMLDOC::GetRoot(PGLOBAL g)
|
PXNODE LIBXMLDOC::GetRoot(PGLOBAL g)
|
||||||
{
|
{
|
||||||
|
if (trace)
|
||||||
|
htrc("GetRoot\n");
|
||||||
|
|
||||||
xmlNodePtr root = xmlDocGetRootElement(Docp);
|
xmlNodePtr root = xmlDocGetRootElement(Docp);
|
||||||
|
|
||||||
if (!root)
|
if (!root)
|
||||||
@ -171,6 +392,9 @@ PXNODE LIBXMLDOC::GetRoot(PGLOBAL g)
|
|||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
PXNODE LIBXMLDOC::NewRoot(PGLOBAL g, char *name)
|
PXNODE LIBXMLDOC::NewRoot(PGLOBAL g, char *name)
|
||||||
{
|
{
|
||||||
|
if (trace)
|
||||||
|
htrc("NewRoot: %s\n", name);
|
||||||
|
|
||||||
xmlNodePtr root = xmlNewDocNode(Docp, NULL, BAD_CAST name, NULL);
|
xmlNodePtr root = xmlNewDocNode(Docp, NULL, BAD_CAST name, NULL);
|
||||||
|
|
||||||
if (root) {
|
if (root) {
|
||||||
@ -186,6 +410,9 @@ PXNODE LIBXMLDOC::NewRoot(PGLOBAL g, char *name)
|
|||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
PXNODE LIBXMLDOC::NewPnode(PGLOBAL g, char *name)
|
PXNODE LIBXMLDOC::NewPnode(PGLOBAL g, char *name)
|
||||||
{
|
{
|
||||||
|
if (trace)
|
||||||
|
htrc("NewNode: %s\n", name);
|
||||||
|
|
||||||
xmlNodePtr nop;
|
xmlNodePtr nop;
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
@ -224,6 +451,9 @@ int LIBXMLDOC::DumpDoc(PGLOBAL g, char *ofn)
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
FILE *of;
|
FILE *of;
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("DumpDoc: %s\n", ofn);
|
||||||
|
|
||||||
if (!(of= global_fopen(g, MSGID_CANNOT_OPEN, ofn, "w")))
|
if (!(of= global_fopen(g, MSGID_CANNOT_OPEN, ofn, "w")))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -264,7 +494,13 @@ int LIBXMLDOC::DumpDoc(PGLOBAL g, char *ofn)
|
|||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
void LIBXMLDOC::CloseDoc(PGLOBAL g, PFBLOCK xp)
|
void LIBXMLDOC::CloseDoc(PGLOBAL g, PFBLOCK xp)
|
||||||
{
|
{
|
||||||
|
if (trace)
|
||||||
|
htrc("CloseDoc: xp=%p count=%d\n", xp, (xp) ? xp->Count : 0);
|
||||||
|
|
||||||
if (xp && xp->Count == 1) {
|
if (xp && xp->Count == 1) {
|
||||||
|
if (Nlist)
|
||||||
|
xmlXPathFreeNodeSet(Nlist);
|
||||||
|
|
||||||
if (Xop)
|
if (Xop)
|
||||||
xmlXPathFreeObject(Xop);
|
xmlXPathFreeObject(Xop);
|
||||||
|
|
||||||
@ -284,12 +520,18 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp)
|
|||||||
xmlNodeSetPtr nl;
|
xmlNodeSetPtr nl;
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("GetNodeList %s np=%p\n", xp, np);
|
htrc("GetNodeList: %s np=%p\n", xp, np);
|
||||||
|
|
||||||
if (!Ctxp) {
|
if (!Ctxp) {
|
||||||
// Init Xpath
|
// Init Xpath
|
||||||
|
if (trace)
|
||||||
|
htrc("Calling xmlPathInit\n");
|
||||||
|
|
||||||
xmlXPathInit();
|
xmlXPathInit();
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("Calling xmlXPathNewContext Docp=%p\n", Docp);
|
||||||
|
|
||||||
// Create xpath evaluation context
|
// Create xpath evaluation context
|
||||||
if (!(Ctxp = xmlXPathNewContext(Docp))) {
|
if (!(Ctxp = xmlXPathNewContext(Docp))) {
|
||||||
strcpy(g->Message, MSG(XPATH_CNTX_ERR));
|
strcpy(g->Message, MSG(XPATH_CNTX_ERR));
|
||||||
@ -301,7 +543,11 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp)
|
|||||||
} // endif xpathCtx
|
} // endif xpathCtx
|
||||||
|
|
||||||
// Register namespaces from list (if any)
|
// Register namespaces from list (if any)
|
||||||
for (PNS nsp = Namespaces; nsp; nsp = nsp->Next)
|
for (PNS nsp = Namespaces; nsp; nsp = nsp->Next) {
|
||||||
|
if (trace)
|
||||||
|
htrc("Calling xmlXPathRegisterNs Prefix=%s Uri=%s\n",
|
||||||
|
nsp->Prefix, nsp->Uri);
|
||||||
|
|
||||||
if (xmlXPathRegisterNs(Ctxp, BAD_CAST nsp->Prefix,
|
if (xmlXPathRegisterNs(Ctxp, BAD_CAST nsp->Prefix,
|
||||||
BAD_CAST nsp->Uri)) {
|
BAD_CAST nsp->Uri)) {
|
||||||
sprintf(g->Message, MSG(REGISTER_ERR), nsp->Prefix, nsp->Uri);
|
sprintf(g->Message, MSG(REGISTER_ERR), nsp->Prefix, nsp->Uri);
|
||||||
@ -312,12 +558,27 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp)
|
|||||||
return NULL;
|
return NULL;
|
||||||
} // endif Registering
|
} // endif Registering
|
||||||
|
|
||||||
} else
|
} // endfor nsp
|
||||||
xmlXPathFreeNodeSetList(Xop); // To be checked
|
|
||||||
|
} else {
|
||||||
|
if (trace)
|
||||||
|
htrc("Calling xmlXPathFreeNodeSetList Xop=%p\n", Xop);
|
||||||
|
|
||||||
|
if (Nofreelist) {
|
||||||
|
// Making Nlist that must not be freed yet
|
||||||
|
xmlXPathFreeNodeSetList(Xop); // Caused memory leak
|
||||||
|
Nofreelist = false;
|
||||||
|
} else
|
||||||
|
xmlXPathFreeObject(Xop); // Caused node not found
|
||||||
|
|
||||||
|
} // endif Ctxp
|
||||||
|
|
||||||
// Set the context to the calling node
|
// Set the context to the calling node
|
||||||
Ctxp->node = np;
|
Ctxp->node = np;
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("Calling xmlXPathEval %s Ctxp=%p\n", xp, Ctxp);
|
||||||
|
|
||||||
// Evaluate table xpath
|
// Evaluate table xpath
|
||||||
if (!(Xop = xmlXPathEval(BAD_CAST xp, Ctxp))) {
|
if (!(Xop = xmlXPathEval(BAD_CAST xp, Ctxp))) {
|
||||||
sprintf(g->Message, MSG(XPATH_EVAL_ERR), xp);
|
sprintf(g->Message, MSG(XPATH_EVAL_ERR), xp);
|
||||||
@ -439,6 +700,9 @@ int XML2NODE::GetType(void)
|
|||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
PXNODE XML2NODE::GetNext(PGLOBAL g)
|
PXNODE XML2NODE::GetNext(PGLOBAL g)
|
||||||
{
|
{
|
||||||
|
if (trace)
|
||||||
|
htrc("GetNext\n");
|
||||||
|
|
||||||
if (!Nodep->next)
|
if (!Nodep->next)
|
||||||
Next = NULL;
|
Next = NULL;
|
||||||
else if (!Next)
|
else if (!Next)
|
||||||
@ -452,6 +716,9 @@ PXNODE XML2NODE::GetNext(PGLOBAL g)
|
|||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
PXNODE XML2NODE::GetChild(PGLOBAL g)
|
PXNODE XML2NODE::GetChild(PGLOBAL g)
|
||||||
{
|
{
|
||||||
|
if (trace)
|
||||||
|
htrc("GetChild\n");
|
||||||
|
|
||||||
if (!Nodep->children)
|
if (!Nodep->children)
|
||||||
Children = NULL;
|
Children = NULL;
|
||||||
else if (!Children)
|
else if (!Children)
|
||||||
@ -467,6 +734,9 @@ RCODE XML2NODE::GetContent(PGLOBAL g, char *buf, int len)
|
|||||||
{
|
{
|
||||||
RCODE rc = RC_OK;
|
RCODE rc = RC_OK;
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("GetContent\n");
|
||||||
|
|
||||||
if (Content)
|
if (Content)
|
||||||
xmlFree(Content);
|
xmlFree(Content);
|
||||||
|
|
||||||
@ -505,18 +775,24 @@ RCODE XML2NODE::GetContent(PGLOBAL g, char *buf, int len)
|
|||||||
} else
|
} else
|
||||||
*buf = '\0';
|
*buf = '\0';
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("GetContent: %s\n", buf);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
} // end of GetText
|
} // end of GetContent
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
/* Set the content of a node. */
|
/* Set the content of a node. */
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
bool XML2NODE::SetContent(PGLOBAL g, char *txtp, int len)
|
bool XML2NODE::SetContent(PGLOBAL g, char *txtp, int len)
|
||||||
{
|
{
|
||||||
|
if (trace)
|
||||||
|
htrc("SetContent: %s\n", txtp);
|
||||||
|
|
||||||
xmlChar *buf = xmlEncodeEntitiesReentrant(Docp, BAD_CAST txtp);
|
xmlChar *buf = xmlEncodeEntitiesReentrant(Docp, BAD_CAST txtp);
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("SetContent %s -> %s\n", txtp, buf);
|
htrc("SetContent: %s -> %s\n", txtp, buf);
|
||||||
|
|
||||||
xmlNodeSetContent(Nodep, buf);
|
xmlNodeSetContent(Nodep, buf);
|
||||||
xmlFree(buf);
|
xmlFree(buf);
|
||||||
@ -528,6 +804,9 @@ bool XML2NODE::SetContent(PGLOBAL g, char *txtp, int len)
|
|||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
PXNODE XML2NODE::Clone(PGLOBAL g, PXNODE np)
|
PXNODE XML2NODE::Clone(PGLOBAL g, PXNODE np)
|
||||||
{
|
{
|
||||||
|
if (trace)
|
||||||
|
htrc("Clone: np=%p\n", np);
|
||||||
|
|
||||||
if (np) {
|
if (np) {
|
||||||
((PNODE2)np)->Nodep = Nodep;
|
((PNODE2)np)->Nodep = Nodep;
|
||||||
return np;
|
return np;
|
||||||
@ -542,7 +821,7 @@ PXNODE XML2NODE::Clone(PGLOBAL g, PXNODE np)
|
|||||||
PXLIST XML2NODE::GetChildElements(PGLOBAL g, char *xp, PXLIST lp)
|
PXLIST XML2NODE::GetChildElements(PGLOBAL g, char *xp, PXLIST lp)
|
||||||
{
|
{
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("GetChildElements %s\n", xp);
|
htrc("GetChildElements: %s\n", xp);
|
||||||
|
|
||||||
return SelectNodes(g, (xp) ? xp : (char*)"*", lp);
|
return SelectNodes(g, (xp) ? xp : (char*)"*", lp);
|
||||||
} // end of GetChildElements
|
} // end of GetChildElements
|
||||||
@ -553,7 +832,7 @@ PXLIST XML2NODE::GetChildElements(PGLOBAL g, char *xp, PXLIST lp)
|
|||||||
PXLIST XML2NODE::SelectNodes(PGLOBAL g, char *xp, PXLIST lp)
|
PXLIST XML2NODE::SelectNodes(PGLOBAL g, char *xp, PXLIST lp)
|
||||||
{
|
{
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("SelectNodes %s\n", xp);
|
htrc("SelectNodes: %s\n", xp);
|
||||||
|
|
||||||
xmlNodeSetPtr nl = ((PXDOC2)Doc)->GetNodeList(g, Nodep, xp);
|
xmlNodeSetPtr nl = ((PXDOC2)Doc)->GetNodeList(g, Nodep, xp);
|
||||||
|
|
||||||
@ -571,7 +850,7 @@ PXLIST XML2NODE::SelectNodes(PGLOBAL g, char *xp, PXLIST lp)
|
|||||||
PXNODE XML2NODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np)
|
PXNODE XML2NODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np)
|
||||||
{
|
{
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("SelectSingleNode %s\n", xp);
|
htrc("SelectSingleNode: %s\n", xp);
|
||||||
|
|
||||||
xmlNodeSetPtr nl = ((PXDOC2)Doc)->GetNodeList(g, Nodep, xp);
|
xmlNodeSetPtr nl = ((PXDOC2)Doc)->GetNodeList(g, Nodep, xp);
|
||||||
|
|
||||||
@ -593,7 +872,7 @@ PXNODE XML2NODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np)
|
|||||||
PXATTR XML2NODE::GetAttribute(PGLOBAL g, char *name, PXATTR ap)
|
PXATTR XML2NODE::GetAttribute(PGLOBAL g, char *name, PXATTR ap)
|
||||||
{
|
{
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("GetAttribute %s\n", name);
|
htrc("GetAttribute: %s\n", name);
|
||||||
|
|
||||||
xmlAttrPtr atp = xmlHasProp(Nodep, BAD_CAST name);
|
xmlAttrPtr atp = xmlHasProp(Nodep, BAD_CAST name);
|
||||||
|
|
||||||
@ -618,7 +897,7 @@ PXNODE XML2NODE::AddChildNode(PGLOBAL g, char *name, PXNODE np)
|
|||||||
char *p, *pn, *pf = NULL;
|
char *p, *pn, *pf = NULL;
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("AddChildNode %s\n", name);
|
htrc("AddChildNode: %s\n", name);
|
||||||
|
|
||||||
// Is a prefix specified
|
// Is a prefix specified
|
||||||
if ((pn = strchr(name, ':'))) {
|
if ((pn = strchr(name, ':'))) {
|
||||||
@ -669,7 +948,7 @@ PXNODE XML2NODE::AddChildNode(PGLOBAL g, char *name, PXNODE np)
|
|||||||
PXATTR XML2NODE::AddProperty(PGLOBAL g, char *name, PXATTR ap)
|
PXATTR XML2NODE::AddProperty(PGLOBAL g, char *name, PXATTR ap)
|
||||||
{
|
{
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("AddProperty %s\n", name);
|
htrc("AddProperty: %s\n", name);
|
||||||
|
|
||||||
xmlAttrPtr atp = xmlNewProp(Nodep, BAD_CAST name, NULL);
|
xmlAttrPtr atp = xmlNewProp(Nodep, BAD_CAST name, NULL);
|
||||||
|
|
||||||
@ -692,7 +971,7 @@ PXATTR XML2NODE::AddProperty(PGLOBAL g, char *name, PXATTR ap)
|
|||||||
void XML2NODE::AddText(PGLOBAL g, char *txtp)
|
void XML2NODE::AddText(PGLOBAL g, char *txtp)
|
||||||
{
|
{
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("AddText %s\n", txtp);
|
htrc("AddText: %s\n", txtp);
|
||||||
|
|
||||||
// This is to avoid a blank line when inserting a new line
|
// This is to avoid a blank line when inserting a new line
|
||||||
xmlNodePtr np = xmlGetLastChild(Nodep);
|
xmlNodePtr np = xmlGetLastChild(Nodep);
|
||||||
@ -711,6 +990,9 @@ void XML2NODE::AddText(PGLOBAL g, char *txtp)
|
|||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
void XML2NODE::DeleteChild(PGLOBAL g, PXNODE dnp)
|
void XML2NODE::DeleteChild(PGLOBAL g, PXNODE dnp)
|
||||||
{
|
{
|
||||||
|
if (trace)
|
||||||
|
htrc("DeleteChild: node=%p\n", dnp);
|
||||||
|
|
||||||
xmlNodePtr np = ((PNODE2)dnp)->Nodep;
|
xmlNodePtr np = ((PNODE2)dnp)->Nodep;
|
||||||
xmlNodePtr text = np->next;
|
xmlNodePtr text = np->next;
|
||||||
|
|
||||||
@ -750,7 +1032,7 @@ int XML2NODELIST::GetLength(void)
|
|||||||
PXNODE XML2NODELIST::GetItem(PGLOBAL g, int n, PXNODE np)
|
PXNODE XML2NODELIST::GetItem(PGLOBAL g, int n, PXNODE np)
|
||||||
{
|
{
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("GetItem %d\n", n);
|
htrc("GetItem: %d\n", n);
|
||||||
|
|
||||||
if (!Listp || Listp->nodeNr <= n)
|
if (!Listp || Listp->nodeNr <= n)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -781,7 +1063,7 @@ XML2ATTR::XML2ATTR(PXDOC dp, xmlAttrPtr ap, xmlNodePtr np)
|
|||||||
bool XML2ATTR::SetText(PGLOBAL g, char *txtp, int len)
|
bool XML2ATTR::SetText(PGLOBAL g, char *txtp, int len)
|
||||||
{
|
{
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("SetText %s %d\n", txtp, len);
|
htrc("SetText: %s %d\n", txtp, len);
|
||||||
|
|
||||||
xmlSetProp(Parent, Atrp->name, BAD_CAST txtp);
|
xmlSetProp(Parent, Atrp->name, BAD_CAST txtp);
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,144 +1,6 @@
|
|||||||
/******************************************************************/
|
#ifndef LIBDOC_H_INCLUDED
|
||||||
/* Declaration of XML document processing using libxml2 */
|
#define LIBDOC_H_INCLUDED
|
||||||
/* Author: Olivier Bertrand 2007-2012 */
|
void XmlInitParserLib(void);
|
||||||
/******************************************************************/
|
void XmlCleanupParserLib(void);
|
||||||
#include "plgxml.h"
|
void CloseXML2File(PGLOBAL, PFBLOCK, bool);
|
||||||
|
#endif
|
||||||
typedef class LIBXMLDOC *PXDOC2;
|
|
||||||
typedef class XML2NODE *PNODE2;
|
|
||||||
typedef class XML2ATTR *PATTR2;
|
|
||||||
typedef class XML2NODELIST *PLIST2;
|
|
||||||
|
|
||||||
/******************************************************************/
|
|
||||||
/* XML2 block. Must have the same layout than FBLOCK up to Type. */
|
|
||||||
/******************************************************************/
|
|
||||||
typedef struct _x2block { /* Loaded XML file block */
|
|
||||||
struct _x2block *Next;
|
|
||||||
LPCSTR Fname; /* Point on file name */
|
|
||||||
size_t Length; /* Used to tell if read mode */
|
|
||||||
short Count; /* Nb of times file is used */
|
|
||||||
short Type; /* TYPE_FB_XML */
|
|
||||||
int Retcode; /* Return code from Load */
|
|
||||||
xmlDocPtr Docp; /* Document interface pointer */
|
|
||||||
// xmlXPathContextPtr Ctxp;
|
|
||||||
// xmlXPathObjectPtr Xop;
|
|
||||||
} X2BLOCK, *PX2BLOCK;
|
|
||||||
|
|
||||||
/******************************************************************/
|
|
||||||
/* Declaration of libxml2 document. */
|
|
||||||
/******************************************************************/
|
|
||||||
class LIBXMLDOC : public XMLDOCUMENT {
|
|
||||||
friend class XML2NODE;
|
|
||||||
friend class XML2ATTR;
|
|
||||||
public:
|
|
||||||
// Constructor
|
|
||||||
LIBXMLDOC(char *nsl, char *nsdf, char *enc, PFBLOCK fp);
|
|
||||||
|
|
||||||
// Properties
|
|
||||||
virtual short GetDocType(void) {return TYPE_FB_XML2;}
|
|
||||||
virtual void *GetDocPtr(void) {return Docp;}
|
|
||||||
|
|
||||||
// Methods
|
|
||||||
virtual bool Initialize(PGLOBAL g);
|
|
||||||
virtual bool ParseFile(char *fn);
|
|
||||||
virtual bool NewDoc(PGLOBAL g, char *ver);
|
|
||||||
virtual void AddComment(PGLOBAL g, char *com);
|
|
||||||
virtual PXNODE GetRoot(PGLOBAL g);
|
|
||||||
virtual PXNODE NewRoot(PGLOBAL g, char *name);
|
|
||||||
virtual PXNODE NewPnode(PGLOBAL g, char *name);
|
|
||||||
virtual PXATTR NewPattr(PGLOBAL g);
|
|
||||||
virtual PXLIST NewPlist(PGLOBAL g);
|
|
||||||
virtual int DumpDoc(PGLOBAL g, char *ofn);
|
|
||||||
virtual void CloseDoc(PGLOBAL g, PFBLOCK xp);
|
|
||||||
virtual PFBLOCK LinkXblock(PGLOBAL g, MODE m, int rc, char *fn);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// bool CheckDocument(FILE *of, xmlNodePtr np);
|
|
||||||
xmlNodeSetPtr GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp);
|
|
||||||
int Decode(xmlChar *cnt, char *buf, int n);
|
|
||||||
xmlChar *Encode(PGLOBAL g, char *txt);
|
|
||||||
|
|
||||||
// Members
|
|
||||||
xmlDocPtr Docp;
|
|
||||||
xmlNodeSetPtr Nlist;
|
|
||||||
xmlXPathContextPtr Ctxp;
|
|
||||||
xmlXPathObjectPtr Xop;
|
|
||||||
char *Buf; // Temporary
|
|
||||||
}; // end of class LIBXMLDOC
|
|
||||||
|
|
||||||
/******************************************************************/
|
|
||||||
/* Declaration of libxml2 node. */
|
|
||||||
/******************************************************************/
|
|
||||||
class XML2NODE : public XMLNODE {
|
|
||||||
friend class LIBXMLDOC;
|
|
||||||
friend class XML2NODELIST;
|
|
||||||
public:
|
|
||||||
// Properties
|
|
||||||
virtual char *GetName(PGLOBAL g) {return (char*)Nodep->name;}
|
|
||||||
virtual int GetType(void);
|
|
||||||
virtual PXNODE GetNext(PGLOBAL g);
|
|
||||||
virtual PXNODE GetChild(PGLOBAL g);
|
|
||||||
|
|
||||||
// Methods
|
|
||||||
virtual RCODE GetContent(PGLOBAL g, char *buf, int len);
|
|
||||||
virtual bool SetContent(PGLOBAL g, char *txtp, int len);
|
|
||||||
virtual PXNODE Clone(PGLOBAL g, PXNODE np);
|
|
||||||
virtual PXLIST GetChildElements(PGLOBAL g, char *xp, PXLIST lp);
|
|
||||||
virtual PXLIST SelectNodes(PGLOBAL g, char *xp, PXLIST lp);
|
|
||||||
virtual PXNODE SelectSingleNode(PGLOBAL g, char *xp, PXNODE np);
|
|
||||||
virtual PXATTR GetAttribute(PGLOBAL g, char *name, PXATTR ap);
|
|
||||||
virtual PXNODE AddChildNode(PGLOBAL g, char *name, PXNODE np);
|
|
||||||
virtual PXATTR AddProperty(PGLOBAL g, char *name, PXATTR ap);
|
|
||||||
virtual void AddText(PGLOBAL g, char *txtp);
|
|
||||||
virtual void DeleteChild(PGLOBAL g, PXNODE dnp);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Constructor
|
|
||||||
XML2NODE(PXDOC dp, xmlNodePtr np);
|
|
||||||
|
|
||||||
// Members
|
|
||||||
xmlDocPtr Docp;
|
|
||||||
xmlChar *Content;
|
|
||||||
xmlNodePtr Nodep;
|
|
||||||
}; // end of class XML2NODE
|
|
||||||
|
|
||||||
/******************************************************************/
|
|
||||||
/* Declaration of libxml2 node list. */
|
|
||||||
/******************************************************************/
|
|
||||||
class XML2NODELIST : public XMLNODELIST {
|
|
||||||
friend class LIBXMLDOC;
|
|
||||||
friend class XML2NODE;
|
|
||||||
public:
|
|
||||||
// Methods
|
|
||||||
virtual int GetLength(void);
|
|
||||||
virtual PXNODE GetItem(PGLOBAL g, int n, PXNODE np);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Constructor
|
|
||||||
XML2NODELIST(PXDOC dp, xmlNodeSetPtr lp);
|
|
||||||
|
|
||||||
// Members
|
|
||||||
xmlNodeSetPtr Listp;
|
|
||||||
}; // end of class XML2NODELIST
|
|
||||||
|
|
||||||
/******************************************************************/
|
|
||||||
/* Declaration of libxml2 attribute. */
|
|
||||||
/******************************************************************/
|
|
||||||
class XML2ATTR : public XMLATTRIBUTE {
|
|
||||||
friend class LIBXMLDOC;
|
|
||||||
friend class XML2NODE;
|
|
||||||
public:
|
|
||||||
// Properties
|
|
||||||
//virtual char *GetText(void);
|
|
||||||
|
|
||||||
// Methods
|
|
||||||
virtual bool SetText(PGLOBAL g, char *txtp, int len);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Constructor
|
|
||||||
XML2ATTR(PXDOC dp, xmlAttrPtr ap, xmlNodePtr np);
|
|
||||||
|
|
||||||
// Members
|
|
||||||
xmlAttrPtr Atrp;
|
|
||||||
xmlNodePtr Parent;
|
|
||||||
}; // end of class XML2ATTR
|
|
||||||
|
@ -426,6 +426,8 @@ int MYCAT::GetColCatInfo(PGLOBAL g, PTABDEF defp)
|
|||||||
PCOLDEF cdp, lcdp= NULL, tocols= NULL;
|
PCOLDEF cdp, lcdp= NULL, tocols= NULL;
|
||||||
PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO));
|
PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO));
|
||||||
|
|
||||||
|
memset(pcf, 0, sizeof(COLINFO));
|
||||||
|
|
||||||
// Get a unique char identifier for type
|
// Get a unique char identifier for type
|
||||||
tc= (defp->Catfunc == FNC_NO) ? GetTypeID(type) : TAB_PRX;
|
tc= (defp->Catfunc == FNC_NO) ? GetTypeID(type) : TAB_PRX;
|
||||||
|
|
||||||
@ -468,7 +470,7 @@ int MYCAT::GetColCatInfo(PGLOBAL g, PTABDEF defp)
|
|||||||
} // endswitch tc
|
} // endswitch tc
|
||||||
|
|
||||||
do {
|
do {
|
||||||
field= Hc->GetColumnOption(field, pcf);
|
field= Hc->GetColumnOption(g, field, pcf);
|
||||||
} while (field && (*pcf->Name =='*' /*|| pcf->Flags & U_VIRTUAL*/));
|
} while (field && (*pcf->Name =='*' /*|| pcf->Flags & U_VIRTUAL*/));
|
||||||
|
|
||||||
if (tc == TAB_DBF && pcf->Type == TYPE_DATE && !pcf->Datefmt) {
|
if (tc == TAB_DBF && pcf->Type == TYPE_DATE && !pcf->Datefmt) {
|
||||||
|
@ -311,6 +311,8 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
|
|||||||
const char *user, const char *pwd,
|
const char *user, const char *pwd,
|
||||||
int pt)
|
int pt)
|
||||||
{
|
{
|
||||||
|
uint cto = 60, nrt = 120;
|
||||||
|
|
||||||
m_DB = mysql_init(NULL);
|
m_DB = mysql_init(NULL);
|
||||||
|
|
||||||
if (!m_DB) {
|
if (!m_DB) {
|
||||||
@ -318,11 +320,12 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
|
|||||||
return RC_FX;
|
return RC_FX;
|
||||||
} // endif m_DB
|
} // endif m_DB
|
||||||
|
|
||||||
// Notice that the client and server use separate group names.
|
// Removed to do like FEDERATED do
|
||||||
// This is critical, because the server will not accept the
|
//mysql_options(m_DB, MYSQL_READ_DEFAULT_GROUP, "client-mariadb");
|
||||||
// client's options, and vice versa.
|
|
||||||
mysql_options(m_DB, MYSQL_READ_DEFAULT_GROUP, "PlugDB_CLIENT");
|
|
||||||
mysql_options(m_DB, MYSQL_OPT_USE_REMOTE_CONNECTION, NULL);
|
mysql_options(m_DB, MYSQL_OPT_USE_REMOTE_CONNECTION, NULL);
|
||||||
|
mysql_options(m_DB, MYSQL_OPT_CONNECT_TIMEOUT, &cto);
|
||||||
|
mysql_options(m_DB, MYSQL_OPT_READ_TIMEOUT, &nrt);
|
||||||
|
//mysql_options(m_DB, MYSQL_OPT_WRITE_TIMEOUT, ...);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (pwd && !strcmp(pwd, "*")) {
|
if (pwd && !strcmp(pwd, "*")) {
|
||||||
|
@ -394,22 +394,22 @@ CREATE TABLE t1
|
|||||||
(
|
(
|
||||||
a BLOB
|
a BLOB
|
||||||
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
|
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
|
||||||
ERROR HY000: Unsupported type for column 'a'
|
ERROR HY000: Unsupported type for column a
|
||||||
CREATE TABLE t1
|
CREATE TABLE t1
|
||||||
(
|
(
|
||||||
a TINYBLOB
|
a TINYBLOB
|
||||||
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
|
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
|
||||||
ERROR HY000: Unsupported type for column 'a'
|
ERROR HY000: Unsupported type for column a
|
||||||
CREATE TABLE t1
|
CREATE TABLE t1
|
||||||
(
|
(
|
||||||
a MEDIUMBLOB
|
a MEDIUMBLOB
|
||||||
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
|
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
|
||||||
ERROR HY000: Unsupported type for column 'a'
|
ERROR HY000: Unsupported type for column a
|
||||||
CREATE TABLE t1
|
CREATE TABLE t1
|
||||||
(
|
(
|
||||||
a LONGBLOB
|
a LONGBLOB
|
||||||
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
|
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
|
||||||
ERROR HY000: Unsupported type for column 'a'
|
ERROR HY000: Unsupported type for column a
|
||||||
#
|
#
|
||||||
# Testing DATE
|
# Testing DATE
|
||||||
#
|
#
|
||||||
|
57
storage/connect/mysql-test/connect/r/mul.result
Normal file
57
storage/connect/mysql-test/connect/r/mul.result
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#
|
||||||
|
# Testing multiple 1
|
||||||
|
#
|
||||||
|
CREATE TABLE `t1` (
|
||||||
|
`a` char(10) DEFAULT NULL,
|
||||||
|
`b` char(10) DEFAULT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=CSV `sep_char`=';';
|
||||||
|
Warnings:
|
||||||
|
Warning 1105 No file name. Table will use t1.csv
|
||||||
|
INSERT INTO t1 VALUES('test1','bla');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b
|
||||||
|
test1 bla
|
||||||
|
CREATE TABLE `t2` (
|
||||||
|
`a` char(10) DEFAULT NULL,
|
||||||
|
`b` char(10) DEFAULT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=CSV `sep_char`=';';
|
||||||
|
Warnings:
|
||||||
|
Warning 1105 No file name. Table will use t2.csv
|
||||||
|
INSERT INTO t2 VALUES('test2','blub');
|
||||||
|
SELECT * FROM t2;
|
||||||
|
a b
|
||||||
|
test2 blub
|
||||||
|
CREATE TABLE `t_all` (
|
||||||
|
`a` char(10) DEFAULT NULL,
|
||||||
|
`b` char(10) DEFAULT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=CSV `file_name`='t*.csv' `sep_char`=';' `multiple`=1;
|
||||||
|
SELECT * FROM t_all order by `a`;
|
||||||
|
a b
|
||||||
|
test1 bla
|
||||||
|
test2 blub
|
||||||
|
#
|
||||||
|
# Testing multiple 2
|
||||||
|
#
|
||||||
|
CREATE table fnlist (
|
||||||
|
fn char(8) not null
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 table_type=DOS;
|
||||||
|
Warnings:
|
||||||
|
Warning 1105 No file name. Table will use fnlist.dos
|
||||||
|
INSERT INTO fnlist VALUES('t1.csv'),('t2.csv');
|
||||||
|
SELECT fn FROM fnlist;
|
||||||
|
fn
|
||||||
|
t1.csv
|
||||||
|
t2.csv
|
||||||
|
CREATE TABLE `tblist` (
|
||||||
|
`a` char(10) DEFAULT NULL,
|
||||||
|
`b` char(10) DEFAULT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=CSV `file_name`='fnlist.dos' `sep_char`=';' `multiple`=2;
|
||||||
|
SELECT * FROM tblist;
|
||||||
|
a b
|
||||||
|
test1 bla
|
||||||
|
test2 blub
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE t_all;
|
||||||
|
DROP TABLE fnlist;
|
||||||
|
DROP TABLE tblist;
|
43
storage/connect/mysql-test/connect/t/mul.test
Normal file
43
storage/connect/mysql-test/connect/t/mul.test
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
--echo #
|
||||||
|
--echo # Testing multiple 1
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE `t1` (
|
||||||
|
`a` char(10) DEFAULT NULL,
|
||||||
|
`b` char(10) DEFAULT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=CSV `sep_char`=';';
|
||||||
|
INSERT INTO t1 VALUES('test1','bla');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
CREATE TABLE `t2` (
|
||||||
|
`a` char(10) DEFAULT NULL,
|
||||||
|
`b` char(10) DEFAULT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=CSV `sep_char`=';';
|
||||||
|
INSERT INTO t2 VALUES('test2','blub');
|
||||||
|
SELECT * FROM t2;
|
||||||
|
|
||||||
|
CREATE TABLE `t_all` (
|
||||||
|
`a` char(10) DEFAULT NULL,
|
||||||
|
`b` char(10) DEFAULT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=CSV `file_name`='t*.csv' `sep_char`=';' `multiple`=1;
|
||||||
|
SELECT * FROM t_all order by `a`;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Testing multiple 2
|
||||||
|
--echo #
|
||||||
|
CREATE table fnlist (
|
||||||
|
fn char(8) not null
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 table_type=DOS;
|
||||||
|
INSERT INTO fnlist VALUES('t1.csv'),('t2.csv');
|
||||||
|
SELECT fn FROM fnlist;
|
||||||
|
|
||||||
|
CREATE TABLE `tblist` (
|
||||||
|
`a` char(10) DEFAULT NULL,
|
||||||
|
`b` char(10) DEFAULT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=CSV `file_name`='fnlist.dos' `sep_char`=';' `multiple`=2;
|
||||||
|
SELECT * FROM tblist;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE t_all;
|
||||||
|
DROP TABLE fnlist;
|
||||||
|
DROP TABLE tblist;
|
@ -3,21 +3,40 @@
|
|||||||
#
|
#
|
||||||
# To run this test, install SQLite3 ODBC Driver from
|
# To run this test, install SQLite3 ODBC Driver from
|
||||||
# http://www.ch-werner.de/sqliteodbc/
|
# http://www.ch-werner.de/sqliteodbc/
|
||||||
# The installer file is sqliteodbc.exe
|
#
|
||||||
|
# Note, the test does not need a DSN to be created
|
||||||
|
# (only the driver is required)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# On Windows:
|
||||||
|
# -----------
|
||||||
|
# Download and run the installer file sqliteodbc.exe
|
||||||
# Version sqliteodbc-0.991 is known to Work.
|
# Version sqliteodbc-0.991 is known to Work.
|
||||||
|
# After running the installer the test should start working automatically.
|
||||||
#
|
#
|
||||||
# On Windows the test should start working automatically
|
# On Linux:
|
||||||
|
# --------
|
||||||
|
# 1. Download the source tarball, e.g.: sqliteodbc-0.993.tar.gz
|
||||||
|
# 2. Unpack the sources:
|
||||||
|
# tar -zxf sqliteodbc-0.993.tar.gz
|
||||||
|
# 3. Compile the source and install:
|
||||||
|
# cd sqliteodbc-0.993
|
||||||
|
# ./configure --prefix=/opt/sqliteodbc
|
||||||
|
# make
|
||||||
|
# sudo make install
|
||||||
#
|
#
|
||||||
# On Linux add these lines into /etc/odbcinst.ini
|
# (you can use a different --prefix, according to your preferences)
|
||||||
|
#
|
||||||
|
# 4. Add these lines into /etc/odbcinst.ini
|
||||||
#
|
#
|
||||||
#[SQLite3 ODBC Driver]
|
#[SQLite3 ODBC Driver]
|
||||||
#Description=SQLite3 ODBC Driver
|
#Description=SQLite3 ODBC Driver
|
||||||
#Driver=/opt/sqliteodbc/libsqlite3odbc.so
|
#Driver=/opt/sqliteodbc/libsqlite3odbc.so
|
||||||
#Setup=/opt/sqliteodbc/libsqlite3odbc.so
|
#Setup=/opt/sqliteodbc/libsqlite3odbc.so
|
||||||
#
|
#
|
||||||
# (adjust the directory "/opt/sqliteodbc/" according to your OS settings)
|
# Adjust the directory "/opt/sqliteodbc/" according to --prefix
|
||||||
|
# that you chose on step #3.
|
||||||
#
|
#
|
||||||
# Note, the test does not need a DSN to be created.
|
|
||||||
#
|
#
|
||||||
|
|
||||||
SET NAMES utf8;
|
SET NAMES utf8;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "plgdbsem.h"
|
#include "plgdbsem.h"
|
||||||
//#include "value.h"
|
//#include "value.h"
|
||||||
//#include "valblk.h"
|
//#include "valblk.h"
|
||||||
|
#include "myutil.h"
|
||||||
#define DLL_EXPORT // Items are exported from this DLL
|
#define DLL_EXPORT // Items are exported from this DLL
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
@ -304,6 +304,9 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *table,
|
|||||||
} else
|
} else
|
||||||
qrp = NULL;
|
qrp = NULL;
|
||||||
|
|
||||||
|
/* Cleanup */
|
||||||
|
ocp->Close();
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Return the result pointer for use by GetData routines. */
|
/* Return the result pointer for use by GetData routines. */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
@ -954,17 +957,17 @@ int ODBConn::Open(PSZ ConnectString, DWORD options)
|
|||||||
|
|
||||||
// Allocate the HDBC and make connection
|
// Allocate the HDBC and make connection
|
||||||
try {
|
try {
|
||||||
PSZ ver;
|
/*PSZ ver;*/
|
||||||
|
|
||||||
AllocConnect(options);
|
AllocConnect(options);
|
||||||
ver = GetStringInfo(SQL_ODBC_VER);
|
/*ver = GetStringInfo(SQL_ODBC_VER);*/
|
||||||
|
|
||||||
if (Connect(options)) {
|
if (Connect(options)) {
|
||||||
strcpy(g->Message, MSG(CONNECT_CANCEL));
|
strcpy(g->Message, MSG(CONNECT_CANCEL));
|
||||||
return 0;
|
return 0;
|
||||||
} // endif
|
} // endif
|
||||||
|
|
||||||
ver = GetStringInfo(SQL_DRIVER_ODBC_VER);
|
/*ver = GetStringInfo(SQL_DRIVER_ODBC_VER);*/
|
||||||
} catch(DBX *xp) {
|
} catch(DBX *xp) {
|
||||||
// strcpy(g->Message, xp->m_ErrMsg[0]);
|
// strcpy(g->Message, xp->m_ErrMsg[0]);
|
||||||
strcpy(g->Message, xp->GetErrorMessage(0));
|
strcpy(g->Message, xp->GetErrorMessage(0));
|
||||||
@ -1213,13 +1216,13 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols)
|
|||||||
b = false;
|
b = false;
|
||||||
|
|
||||||
if (m_hstmt) {
|
if (m_hstmt) {
|
||||||
RETCODE rc;
|
/*RETCODE rc;*/
|
||||||
|
|
||||||
// All this did not seems to make sense and was been commented out
|
// All this did not seems to make sense and was been commented out
|
||||||
// if (IsOpen())
|
// if (IsOpen())
|
||||||
// Close(SQL_CLOSE);
|
// Close(SQL_CLOSE);
|
||||||
|
|
||||||
rc = SQLFreeStmt(m_hstmt, SQL_CLOSE);
|
/*rc =*/ SQLFreeStmt(m_hstmt, SQL_CLOSE);
|
||||||
hstmt = m_hstmt;
|
hstmt = m_hstmt;
|
||||||
m_hstmt = NULL;
|
m_hstmt = NULL;
|
||||||
ThrowDBX(MSG(SEQUENCE_ERROR));
|
ThrowDBX(MSG(SEQUENCE_ERROR));
|
||||||
@ -1673,8 +1676,10 @@ int ODBConn::GetCatInfo(CATPARM *cap)
|
|||||||
// Attempt to set rowset size.
|
// Attempt to set rowset size.
|
||||||
// In case of failure reset it to 0 to use Fetch.
|
// In case of failure reset it to 0 to use Fetch.
|
||||||
if (m_Catver == 3) // ODBC Ver 3
|
if (m_Catver == 3) // ODBC Ver 3
|
||||||
rc = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE,
|
{
|
||||||
(SQLPOINTER)m_RowsetSize, 0);
|
SQLULEN tmp= m_RowsetSize;
|
||||||
|
rc = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, &tmp, 0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
rc = SQLSetStmtOption(hstmt, SQL_ROWSET_SIZE, m_RowsetSize);
|
rc = SQLSetStmtOption(hstmt, SQL_ROWSET_SIZE, m_RowsetSize);
|
||||||
|
|
||||||
@ -1831,7 +1836,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void ODBConn::Close()
|
void ODBConn::Close()
|
||||||
{
|
{
|
||||||
RETCODE rc;
|
/*RETCODE rc;*/
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Close any open recordsets
|
// Close any open recordsets
|
||||||
@ -1856,13 +1861,13 @@ void ODBConn::Close()
|
|||||||
|
|
||||||
if (m_hstmt) {
|
if (m_hstmt) {
|
||||||
// Is required for multiple tables
|
// Is required for multiple tables
|
||||||
rc = SQLFreeStmt(m_hstmt, SQL_DROP);
|
/*rc =*/ SQLFreeStmt(m_hstmt, SQL_DROP);
|
||||||
m_hstmt = NULL;
|
m_hstmt = NULL;
|
||||||
} // endif m_hstmt
|
} // endif m_hstmt
|
||||||
|
|
||||||
if (m_hdbc != SQL_NULL_HDBC) {
|
if (m_hdbc != SQL_NULL_HDBC) {
|
||||||
rc = SQLDisconnect(m_hdbc);
|
/*rc =*/ SQLDisconnect(m_hdbc);
|
||||||
rc = SQLFreeConnect(m_hdbc);
|
/*rc =*/ SQLFreeConnect(m_hdbc);
|
||||||
m_hdbc = SQL_NULL_HDBC;
|
m_hdbc = SQL_NULL_HDBC;
|
||||||
|
|
||||||
// AfxLockGlobals(CRIT_ODBC);
|
// AfxLockGlobals(CRIT_ODBC);
|
||||||
|
@ -202,19 +202,6 @@ BOOL MessageBeep(uint i)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
} /* end of MessageBeep */
|
} /* end of MessageBeep */
|
||||||
|
|
||||||
LPSTR _strerror(int errn)
|
|
||||||
{
|
|
||||||
static char buff[256];
|
|
||||||
|
|
||||||
sprintf(buff,"error: %d", errn);
|
|
||||||
return buff;
|
|
||||||
} /* end of _strerror */
|
|
||||||
|
|
||||||
int _isatty(int fileNo)
|
|
||||||
{
|
|
||||||
return isatty(fileNo);
|
|
||||||
} /* end of _isatty */
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* This function is ridiculous and should be revisited */
|
/* This function is ridiculous and should be revisited */
|
||||||
DWORD FormatMessage(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId,
|
DWORD FormatMessage(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId,
|
||||||
|
@ -565,7 +565,8 @@ DllExport void PlgDBfree(MBLOCK&);
|
|||||||
//lExport int GetIniSize(char *, char *, char *, char *);
|
//lExport int GetIniSize(char *, char *, char *, char *);
|
||||||
//lExport bool WritePrivateProfileInt(LPCSTR, LPCSTR, int, LPCSTR);
|
//lExport bool WritePrivateProfileInt(LPCSTR, LPCSTR, int, LPCSTR);
|
||||||
DllExport void NewPointer(PTABS, void *, void *);
|
DllExport void NewPointer(PTABS, void *, void *);
|
||||||
|
DllExport char *GetIni(int n= 0);
|
||||||
|
DllExport void SetTrc(void);
|
||||||
|
|
||||||
#define MSGID_NONE 0
|
#define MSGID_NONE 0
|
||||||
#define MSGID_CANNOT_OPEN 1
|
#define MSGID_CANNOT_OPEN 1
|
||||||
|
@ -127,7 +127,7 @@ void CloseXMLFile(PGLOBAL, PFBLOCK, bool);
|
|||||||
#endif // DOMDOC_SUPPORT
|
#endif // DOMDOC_SUPPORT
|
||||||
|
|
||||||
#ifdef LIBXML2_SUPPORT
|
#ifdef LIBXML2_SUPPORT
|
||||||
void CloseXML2File(PGLOBAL, PFBLOCK, bool);
|
#include "libdoc.h"
|
||||||
#endif // LIBXML2_SUPPORT
|
#endif // LIBXML2_SUPPORT
|
||||||
|
|
||||||
|
|
||||||
@ -222,7 +222,7 @@ int global_open(GLOBAL *g, int msgid, const char *path, int flags, int mode)
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* Utility for external callers (such as XDB) */
|
/* Utility for external callers (such as XDB) */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
DllExport char *GetIni(int n = 0)
|
DllExport char *GetIni(int n)
|
||||||
{
|
{
|
||||||
switch (n) {
|
switch (n) {
|
||||||
case 1: return plgxini; break;
|
case 1: return plgxini; break;
|
||||||
|
@ -69,6 +69,7 @@ class XMLDOCUMENT : public BLOCK {
|
|||||||
// Properties
|
// Properties
|
||||||
virtual short GetDocType(void) = 0;
|
virtual short GetDocType(void) = 0;
|
||||||
virtual void *GetDocPtr(void) = 0;
|
virtual void *GetDocPtr(void) = 0;
|
||||||
|
virtual void SetNofree(bool b) = 0;
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
virtual bool Initialize(PGLOBAL) = 0;
|
virtual bool Initialize(PGLOBAL) = 0;
|
||||||
|
@ -511,6 +511,23 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
|
|||||||
return (memp);
|
return (memp);
|
||||||
} /* end of PlugSubAlloc */
|
} /* end of PlugSubAlloc */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* This routine suballocate a copy of the passed string. */
|
||||||
|
/***********************************************************************/
|
||||||
|
char *PlugDup(PGLOBAL g, const char *str)
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (str && (len = strlen(str))) {
|
||||||
|
buf = (char*)PlugSubAlloc(g, NULL, len + 1);
|
||||||
|
strcpy(buf, str);
|
||||||
|
} else
|
||||||
|
buf = NULL;
|
||||||
|
|
||||||
|
return(buf);
|
||||||
|
} /* end of PlugDup */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* This routine makes a pointer from an offset to a memory pointer. */
|
/* This routine makes a pointer from an offset to a memory pointer. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@ -1047,7 +1047,7 @@ bool DOSCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void DOSCOL::ReadColumn(PGLOBAL g)
|
void DOSCOL::ReadColumn(PGLOBAL g)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p = NULL;
|
||||||
int i, rc;
|
int i, rc;
|
||||||
int field;
|
int field;
|
||||||
double dval;
|
double dval;
|
||||||
|
@ -327,7 +327,7 @@ BINCOL::BINCOL(BINCOL *col1, PTDB tdbp) : DOSCOL(col1, tdbp)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void BINCOL::ReadColumn(PGLOBAL g)
|
void BINCOL::ReadColumn(PGLOBAL g)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
PTDBFIX tdbp = (PTDBFIX)To_Tdb;
|
PTDBFIX tdbp = (PTDBFIX)To_Tdb;
|
||||||
|
|
||||||
|
79
storage/connect/tabmul.cpp
Normal file → Executable file
79
storage/connect/tabmul.cpp
Normal file → Executable file
@ -68,6 +68,8 @@
|
|||||||
#include "tabdos.h" // TDBDOS and DOSCOL class dcls
|
#include "tabdos.h" // TDBDOS and DOSCOL class dcls
|
||||||
#include "tabmul.h" // TDBMUL and MULCOL classes dcls
|
#include "tabmul.h" // TDBMUL and MULCOL classes dcls
|
||||||
|
|
||||||
|
extern "C" int trace;
|
||||||
|
|
||||||
/* ------------------------- Class TDBMUL ---------------------------- */
|
/* ------------------------- Class TDBMUL ---------------------------- */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -122,15 +124,25 @@ PTDB TDBMUL::Duplicate(PGLOBAL g)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool TDBMUL::InitFileNames(PGLOBAL g)
|
bool TDBMUL::InitFileNames(PGLOBAL g)
|
||||||
{
|
{
|
||||||
#define PFNZ 8192
|
#define PFNZ 4096
|
||||||
char *pfn[PFNZ], filename[_MAX_DRIVE+_MAX_DIR+_MAX_FNAME+_MAX_EXT];
|
#define FNSZ _MAX_DRIVE+_MAX_DIR+_MAX_FNAME+_MAX_EXT
|
||||||
|
char *pfn[PFNZ];
|
||||||
|
char *filename;
|
||||||
int rc, n = 0;
|
int rc, n = 0;
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("in InitFileName: fn[]=%d\n", FNSZ);
|
||||||
|
|
||||||
|
filename = (char*)PlugSubAlloc(g, NULL, FNSZ);
|
||||||
|
|
||||||
// The sub table may need to refer to the Table original block
|
// The sub table may need to refer to the Table original block
|
||||||
Tdbp->SetTable(To_Table); // Was not set at construction
|
Tdbp->SetTable(To_Table); // Was not set at construction
|
||||||
|
|
||||||
PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath());
|
PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath());
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("InitFileName: fn='%s'\n", filename);
|
||||||
|
|
||||||
if (Mul == 1) {
|
if (Mul == 1) {
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
/* To_File is a multiple name with special characters */
|
/* To_File is a multiple name with special characters */
|
||||||
@ -194,15 +206,28 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
|
|||||||
_splitpath(filename, NULL, direc, pattern, ftype);
|
_splitpath(filename, NULL, direc, pattern, ftype);
|
||||||
strcat(pattern, ftype);
|
strcat(pattern, ftype);
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("direc=%s pattern=%s ftype=%s\n", direc, pattern, ftype);
|
||||||
|
|
||||||
// Start searching files in the target directory.
|
// Start searching files in the target directory.
|
||||||
if (!(dir = opendir(direc))) {
|
if (!(dir = opendir(direc))) {
|
||||||
sprintf(g->Message, MSG(BAD_DIRECTORY), direc, strerror(errno));
|
sprintf(g->Message, MSG(BAD_DIRECTORY), direc, strerror(errno));
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("%s\n", g->Message);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} // endif dir
|
} // endif dir
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("dir opened: reading files\n");
|
||||||
|
|
||||||
while ((entry = readdir(dir)) && n < PFNZ) {
|
while ((entry = readdir(dir)) && n < PFNZ) {
|
||||||
strcat(strcpy(fn, direc), entry->d_name);
|
strcat(strcpy(fn, direc), entry->d_name);
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("%s read\n", fn);
|
||||||
|
|
||||||
if (lstat(fn, &fileinfo) < 0) {
|
if (lstat(fn, &fileinfo) < 0) {
|
||||||
sprintf(g->Message, "%s: %s", fn, strerror(errno));
|
sprintf(g->Message, "%s: %s", fn, strerror(errno));
|
||||||
return true;
|
return true;
|
||||||
@ -218,6 +243,10 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
|
|||||||
strcat(strcpy(filename, direc), entry->d_name);
|
strcat(strcpy(filename, direc), entry->d_name);
|
||||||
pfn[n] = (char*)PlugSubAlloc(g, NULL, strlen(filename) + 1);
|
pfn[n] = (char*)PlugSubAlloc(g, NULL, strlen(filename) + 1);
|
||||||
strcpy(pfn[n++], filename);
|
strcpy(pfn[n++], filename);
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("Adding pfn[%d] %s\n", n, filename);
|
||||||
|
|
||||||
} // endwhile readdir
|
} // endwhile readdir
|
||||||
|
|
||||||
// Close the dir handle.
|
// Close the dir handle.
|
||||||
@ -235,7 +264,7 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
while (n < PFNZ) {
|
while (n < PFNZ) {
|
||||||
if (!fgets(filename, sizeof(filename), stream)) {
|
if (!fgets(filename, FNSZ, stream)) {
|
||||||
fclose(stream);
|
fclose(stream);
|
||||||
break;
|
break;
|
||||||
} // endif fgets
|
} // endif fgets
|
||||||
@ -364,9 +393,12 @@ int TDBMUL::Cardinality(PGLOBAL g)
|
|||||||
int TDBMUL::GetMaxSize(PGLOBAL g)
|
int TDBMUL::GetMaxSize(PGLOBAL g)
|
||||||
{
|
{
|
||||||
if (MaxSize < 0) {
|
if (MaxSize < 0) {
|
||||||
int i;
|
int i;
|
||||||
int mxsz;
|
int mxsz;
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("TDBMUL::GetMaxSize: Filenames=%p\n", Filenames);
|
||||||
|
|
||||||
if (!Filenames && InitFileNames(g))
|
if (!Filenames && InitFileNames(g))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -420,10 +452,9 @@ int TDBMUL::RowNumber(PGLOBAL g, bool b)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool TDBMUL::OpenDB(PGLOBAL g)
|
bool TDBMUL::OpenDB(PGLOBAL g)
|
||||||
{
|
{
|
||||||
#ifdef DEBTRACE
|
if (trace)
|
||||||
htrc("MUL OpenDB: tdbp=%p tdb=R%d use=%d key=%p mode=%d\n",
|
htrc("MUL OpenDB: tdbp=%p tdb=R%d use=%d key=%p mode=%d\n",
|
||||||
this, Tdb_No, Use, To_Key_Col, Mode);
|
this, Tdb_No, Use, To_Key_Col, Mode);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (Use == USE_OPEN) {
|
if (Use == USE_OPEN) {
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
@ -451,7 +482,7 @@ bool TDBMUL::OpenDB(PGLOBAL g)
|
|||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Open the first table file of the list. */
|
/* Open the first table file of the list. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
//if (!Filenames && InitFileNames(g)) done in GetMaxSize
|
//if (!Filenames && InitFileNames(g)) // was done in GetMaxSize
|
||||||
// return true;
|
// return true;
|
||||||
|
|
||||||
if (Filenames[iFile = 0]) {
|
if (Filenames[iFile = 0]) {
|
||||||
@ -735,10 +766,9 @@ int TDBDIR::GetMaxSize(PGLOBAL g)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool TDBDIR::OpenDB(PGLOBAL g)
|
bool TDBDIR::OpenDB(PGLOBAL g)
|
||||||
{
|
{
|
||||||
#ifdef DEBTRACE
|
if (trace)
|
||||||
htrc("DIR OpenDB: tdbp=%p tdb=R%d use=%d mode=%d\n",
|
htrc("DIR OpenDB: tdbp=%p tdb=R%d use=%d mode=%d\n",
|
||||||
this, Tdb_No, Use, Mode);
|
this, Tdb_No, Use, Mode);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (Use == USE_OPEN) {
|
if (Use == USE_OPEN) {
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
@ -898,11 +928,9 @@ void DIRCOL::ReadColumn(PGLOBAL g)
|
|||||||
{
|
{
|
||||||
PTDBDIR tdbp = (PTDBDIR)To_Tdb;
|
PTDBDIR tdbp = (PTDBDIR)To_Tdb;
|
||||||
|
|
||||||
#ifdef DEBTRACE
|
if (trace)
|
||||||
fprintf(debug,
|
htrc("DIR ReadColumn: col %s R%d use=%.4X status=%.4X type=%d N=%d\n",
|
||||||
"DIR ReadColumn: col %s R%d use=%.4X status=%.4X type=%d N=%d\n",
|
Name, tdbp->GetTdb_No(), ColUse, Status, Buf_Type, N);
|
||||||
Name, tdbp->GetTdb_No(), ColUse, Status, Buf_Type, N);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Retrieve the information corresponding to the column number. */
|
/* Retrieve the information corresponding to the column number. */
|
||||||
@ -1304,10 +1332,9 @@ int TDBDHR::GetMaxSize(PGLOBAL g)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool TDBDHR::OpenDB(PGLOBAL g)
|
bool TDBDHR::OpenDB(PGLOBAL g)
|
||||||
{
|
{
|
||||||
#ifdef DEBTRACE
|
if (trace)
|
||||||
htrc("DHR OpenDB: tdbp=%p tdb=R%d use=%d mode=%d\n",
|
htrc("DHR OpenDB: tdbp=%p tdb=R%d use=%d mode=%d\n",
|
||||||
this, Tdb_No, Use, Mode);
|
this, Tdb_No, Use, Mode);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (Use == USE_OPEN) {
|
if (Use == USE_OPEN) {
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
@ -1442,11 +1469,9 @@ void DHRCOL::ReadColumn(PGLOBAL g)
|
|||||||
int rc;
|
int rc;
|
||||||
PTDBDHR tdbp = (PTDBDHR)To_Tdb;
|
PTDBDHR tdbp = (PTDBDHR)To_Tdb;
|
||||||
|
|
||||||
#ifdef DEBTRACE
|
if (trace)
|
||||||
fprintf(debug,
|
htrc("DHR ReadColumn: col %s R%d use=%.4X status=%.4X type=%d N=%d\n",
|
||||||
"DHR ReadColumn: col %s R%d use=%.4X status=%.4X type=%d N=%d\n",
|
Name, tdbp->GetTdb_No(), ColUse, Status, Buf_Type, N);
|
||||||
Name, tdbp->GetTdb_No(), ColUse, Status, Buf_Type, N);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Retrieve the information corresponding to the column number. */
|
/* Retrieve the information corresponding to the column number. */
|
||||||
|
@ -31,7 +31,10 @@
|
|||||||
/* IBM, Borland, GNU or Microsoft C++ Compiler and Linker */
|
/* IBM, Borland, GNU or Microsoft C++ Compiler and Linker */
|
||||||
/* */
|
/* */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
#define MYSQL_SERVER 1
|
||||||
#include "my_global.h"
|
#include "my_global.h"
|
||||||
|
#include "sql_class.h"
|
||||||
|
#include "sql_servers.h"
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
//#include <windows.h>
|
//#include <windows.h>
|
||||||
#else // !WIN32
|
#else // !WIN32
|
||||||
@ -64,7 +67,6 @@ void PrintResult(PGLOBAL, PSEM, PQRYRES);
|
|||||||
#endif // _CONSOLE
|
#endif // _CONSOLE
|
||||||
|
|
||||||
extern "C" int trace;
|
extern "C" int trace;
|
||||||
extern MYSQL_PLUGIN_IMPORT uint mysqld_port;
|
|
||||||
|
|
||||||
/* -------------- Implementation of the MYSQLDEF class --------------- */
|
/* -------------- Implementation of the MYSQLDEF class --------------- */
|
||||||
|
|
||||||
@ -86,6 +88,45 @@ MYSQLDEF::MYSQLDEF(void)
|
|||||||
Delayed = FALSE;
|
Delayed = FALSE;
|
||||||
} // end of MYSQLDEF constructor
|
} // end of MYSQLDEF constructor
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Get connection info from the declared server. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool MYSQLDEF::GetServerInfo(PGLOBAL g, const char *server_name)
|
||||||
|
{
|
||||||
|
THD *thd= current_thd;
|
||||||
|
MEM_ROOT *mem= thd->mem_root;
|
||||||
|
FOREIGN_SERVER *server, server_buffer;
|
||||||
|
DBUG_ENTER("GetServerInfo");
|
||||||
|
DBUG_PRINT("info", ("server_name %s", server_name));
|
||||||
|
|
||||||
|
if (!server_name || !strlen(server_name)) {
|
||||||
|
DBUG_PRINT("info", ("server_name not defined!"));
|
||||||
|
strcpy(g->Message, "server_name not defined!");
|
||||||
|
DBUG_RETURN(true);
|
||||||
|
} // endif server_name
|
||||||
|
|
||||||
|
// get_server_by_name() clones the server if exists and allocates
|
||||||
|
// copies of strings in the supplied mem_root
|
||||||
|
if (!(server= get_server_by_name(mem, server_name, &server_buffer))) {
|
||||||
|
DBUG_PRINT("info", ("get_server_by_name returned > 0 error condition!"));
|
||||||
|
/* need to come up with error handling */
|
||||||
|
strcpy(g->Message, "get_server_by_name returned > 0 error condition!");
|
||||||
|
DBUG_RETURN(true);
|
||||||
|
} // endif server
|
||||||
|
|
||||||
|
DBUG_PRINT("info", ("get_server_by_name returned server at %lx",
|
||||||
|
(long unsigned int) server));
|
||||||
|
|
||||||
|
// TODO: We need to examine which of these can really be NULL
|
||||||
|
Hostname = PlugDup(g, server->host);
|
||||||
|
Database = PlugDup(g, server->db);
|
||||||
|
Username = PlugDup(g, server->username);
|
||||||
|
Password = PlugDup(g, server->password);
|
||||||
|
Portnumber = (server->port) ? server->port : GetDefaultPort();
|
||||||
|
|
||||||
|
DBUG_RETURN(false);
|
||||||
|
} // end of GetServerInfo
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Parse connection string */
|
/* Parse connection string */
|
||||||
/* */
|
/* */
|
||||||
@ -135,54 +176,25 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
|
|||||||
if ((!strstr(url, "://") && (!strchr(url, '@')))) {
|
if ((!strstr(url, "://") && (!strchr(url, '@')))) {
|
||||||
// No :// or @ in connection string. Must be a straight
|
// No :// or @ in connection string. Must be a straight
|
||||||
// connection name of either "server" or "server/table"
|
// connection name of either "server" or "server/table"
|
||||||
strcpy(g->Message, "Using Federated server not implemented yet");
|
// ok, so we do a little parsing, but not completely!
|
||||||
return true;
|
if ((Tabname= strchr(url, '/'))) {
|
||||||
#if 0
|
// If there is a single '/' in the connection string,
|
||||||
/* ok, so we do a little parsing, but not completely! */
|
// this means the user is specifying a table name
|
||||||
share->parsed= FALSE;
|
*Tabname++= '\0';
|
||||||
/*
|
|
||||||
If there is a single '/' in the connection string, this means the user is
|
|
||||||
specifying a table name
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((share->table_name= strchr(share->connection_string, '/')))
|
// there better not be any more '/'s !
|
||||||
{
|
if (strchr(Tabname, '/'))
|
||||||
*share->table_name++= '\0';
|
return true;
|
||||||
share->table_name_length= strlen(share->table_name);
|
|
||||||
|
|
||||||
DBUG_PRINT("info",
|
} else
|
||||||
("internal format, parsed table_name "
|
// Otherwise, straight server name,
|
||||||
"share->connection_string: %s share->table_name: %s",
|
// use tablename of federatedx table as remote table name
|
||||||
share->connection_string, share->table_name));
|
Tabname= Name;
|
||||||
|
|
||||||
/*
|
if (trace)
|
||||||
there better not be any more '/'s !
|
htrc("server: %s Tabname: %s", url, Tabname);
|
||||||
*/
|
|
||||||
if (strchr(share->table_name, '/'))
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
Otherwise, straight server name, use tablename of federatedx table
|
|
||||||
as remote table name
|
|
||||||
*/
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Connection specifies everything but, resort to
|
|
||||||
expecting remote and foreign table names to match
|
|
||||||
*/
|
|
||||||
share->table_name= strmake_root(mem_root, table->s->table_name.str,
|
|
||||||
(share->table_name_length=
|
|
||||||
table->s->table_name.length));
|
|
||||||
DBUG_PRINT("info",
|
|
||||||
("internal format, default table_name "
|
|
||||||
"share->connection_string: %s share->table_name: %s",
|
|
||||||
share->connection_string, share->table_name));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((error_num= get_connection(mem_root, share)))
|
return GetServerInfo(g, url);
|
||||||
goto error;
|
|
||||||
#endif // 0
|
|
||||||
} else {
|
} else {
|
||||||
// URL, parse it
|
// URL, parse it
|
||||||
char *sport, *scheme = url;
|
char *sport, *scheme = url;
|
||||||
@ -247,7 +259,7 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
|
|||||||
if ((sport = strchr(Hostname, ':')))
|
if ((sport = strchr(Hostname, ':')))
|
||||||
*sport++ = 0;
|
*sport++ = 0;
|
||||||
|
|
||||||
Portnumber = (sport && sport[0]) ? atoi(sport) : mysqld_port;
|
Portnumber = (sport && sport[0]) ? atoi(sport) : GetDefaultPort();
|
||||||
|
|
||||||
if (Username[0] == 0)
|
if (Username[0] == 0)
|
||||||
Username = Cat->GetStringCatInfo(g, "User", "*");
|
Username = Cat->GetStringCatInfo(g, "User", "*");
|
||||||
@ -279,12 +291,14 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
||||||
{
|
{
|
||||||
char *url = Cat->GetStringCatInfo(g, "Connect", NULL);
|
char *url;
|
||||||
|
|
||||||
Desc = "MySQL Table";
|
Desc = "MySQL Table";
|
||||||
|
|
||||||
if (stricmp(am, "MYPRX")) {
|
if (stricmp(am, "MYPRX")) {
|
||||||
// Normal case of specific MYSQL table
|
// Normal case of specific MYSQL table
|
||||||
|
url = Cat->GetStringCatInfo(g, "Connect", NULL);
|
||||||
|
|
||||||
if (!url || !*url) {
|
if (!url || !*url) {
|
||||||
// Not using the connection URL
|
// Not using the connection URL
|
||||||
Hostname = Cat->GetStringCatInfo(g, "Host", "localhost");
|
Hostname = Cat->GetStringCatInfo(g, "Host", "localhost");
|
||||||
@ -293,24 +307,36 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname);
|
Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname);
|
||||||
Username = Cat->GetStringCatInfo(g, "User", "*");
|
Username = Cat->GetStringCatInfo(g, "User", "*");
|
||||||
Password = Cat->GetStringCatInfo(g, "Password", NULL);
|
Password = Cat->GetStringCatInfo(g, "Password", NULL);
|
||||||
Portnumber = Cat->GetIntCatInfo("Port", mysqld_port);
|
Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort());
|
||||||
} else if (ParseURL(g, url))
|
} else if (ParseURL(g, url))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
Bind = !!Cat->GetIntCatInfo("Bind", 0);
|
Bind = !!Cat->GetIntCatInfo("Bind", 0);
|
||||||
Delayed = !!Cat->GetIntCatInfo("Delayed", 0);
|
Delayed = !!Cat->GetIntCatInfo("Delayed", 0);
|
||||||
} else {
|
} else {
|
||||||
// MYSQL access from a PROXY table, not using URL
|
// MYSQL access from a PROXY table
|
||||||
Database = Cat->GetStringCatInfo(g, "Database", "*");
|
Database = Cat->GetStringCatInfo(g, "Database", "*");
|
||||||
Tabname = Name;
|
|
||||||
Isview = Cat->GetBoolCatInfo("View", FALSE);
|
Isview = Cat->GetBoolCatInfo("View", FALSE);
|
||||||
|
|
||||||
// We must get connection parms from the calling table
|
// We must get other connection parms from the calling table
|
||||||
Remove_tshp(Cat);
|
Remove_tshp(Cat);
|
||||||
Hostname = Cat->GetStringCatInfo(g, "Host", "localhost");
|
url = Cat->GetStringCatInfo(g, "Connect", NULL);
|
||||||
Username = Cat->GetStringCatInfo(g, "User", "*");
|
|
||||||
Password = Cat->GetStringCatInfo(g, "Password", NULL);
|
if (!url || !*url) {
|
||||||
Portnumber = Cat->GetIntCatInfo("Port", mysqld_port);
|
Hostname = Cat->GetStringCatInfo(g, "Host", "localhost");
|
||||||
|
Username = Cat->GetStringCatInfo(g, "User", "*");
|
||||||
|
Password = Cat->GetStringCatInfo(g, "Password", NULL);
|
||||||
|
Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort());
|
||||||
|
} else {
|
||||||
|
char *locdb = Database;
|
||||||
|
|
||||||
|
if (ParseURL(g, url))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
Database = locdb;
|
||||||
|
} // endif url
|
||||||
|
|
||||||
|
Tabname = Name;
|
||||||
} // endif am
|
} // endif am
|
||||||
|
|
||||||
if ((Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL)))
|
if ((Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL)))
|
||||||
@ -741,11 +767,6 @@ int TDBMYSQL::BindColumns(PGLOBAL g)
|
|||||||
} // endif prep
|
} // endif prep
|
||||||
#endif // MYSQL_PREPARED_STATEMENTS
|
#endif // MYSQL_PREPARED_STATEMENTS
|
||||||
|
|
||||||
for (PMYCOL colp = (PMYCOL)Columns; colp; colp = (PMYCOL)colp->Next)
|
|
||||||
if (colp->Buf_Type == TYPE_DATE)
|
|
||||||
// Format must match DATETIME MySQL type
|
|
||||||
((DTVAL*)colp->GetValue())->SetFormat(g, "YYYY-MM-DD hh:mm:ss", 19);
|
|
||||||
|
|
||||||
return RC_OK;
|
return RC_OK;
|
||||||
} // end of BindColumns
|
} // end of BindColumns
|
||||||
|
|
||||||
@ -775,6 +796,14 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
|
|||||||
|
|
||||||
} // endif Connected
|
} // endif Connected
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
/* Take care of DATE columns. */
|
||||||
|
/*********************************************************************/
|
||||||
|
for (PMYCOL colp = (PMYCOL)Columns; colp; colp = (PMYCOL)colp->Next)
|
||||||
|
if (colp->Buf_Type == TYPE_DATE)
|
||||||
|
// Format must match DATETIME MySQL type
|
||||||
|
((DTVAL*)colp->GetValue())->SetFormat(g, "YYYY-MM-DD hh:mm:ss", 19);
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Allocate whatever is used for getting results. */
|
/* Allocate whatever is used for getting results. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
@ -1165,10 +1194,6 @@ void MYSQLCOL::InitBind(PGLOBAL g)
|
|||||||
memset(Bind, 0, sizeof(MYSQL_BIND));
|
memset(Bind, 0, sizeof(MYSQL_BIND));
|
||||||
|
|
||||||
if (Buf_Type == TYPE_DATE) {
|
if (Buf_Type == TYPE_DATE) {
|
||||||
// Default format must match DATETIME MySQL type
|
|
||||||
// if (!((DTVAL*)Value)->IsFormatted())
|
|
||||||
((DTVAL*)Value)->SetFormat(g, "YYYY-MM-DD hh:mm:ss", 19);
|
|
||||||
|
|
||||||
Bind->buffer_type = PLGtoMYSQL(TYPE_STRING, false);
|
Bind->buffer_type = PLGtoMYSQL(TYPE_STRING, false);
|
||||||
Bind->buffer = (char *)PlugSubAlloc(g,NULL, 20);
|
Bind->buffer = (char *)PlugSubAlloc(g,NULL, 20);
|
||||||
Bind->buffer_length = 20;
|
Bind->buffer_length = 20;
|
||||||
@ -1231,7 +1256,7 @@ void MYSQLCOL::WriteColumn(PGLOBAL g)
|
|||||||
#if defined(MYSQL_PREPARED_STATEMENTS)
|
#if defined(MYSQL_PREPARED_STATEMENTS)
|
||||||
if (((PTDBMY)To_Tdb)->Prep) {
|
if (((PTDBMY)To_Tdb)->Prep) {
|
||||||
if (Buf_Type == TYPE_DATE) {
|
if (Buf_Type == TYPE_DATE) {
|
||||||
Value->ShowValue((char *)Bind->buffer, (int)*Bind->length);
|
Value->ShowValue((char *)Bind->buffer, (int)Bind->buffer_length);
|
||||||
Slen = strlen((char *)Bind->buffer);
|
Slen = strlen((char *)Bind->buffer);
|
||||||
} else if (IsTypeChar(Buf_Type))
|
} else if (IsTypeChar(Buf_Type))
|
||||||
Slen = strlen(Value->GetCharValue());
|
Slen = strlen(Value->GetCharValue());
|
||||||
|
@ -39,6 +39,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
|
|||||||
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
|
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
|
||||||
virtual PTDB GetTable(PGLOBAL g, MODE m);
|
virtual PTDB GetTable(PGLOBAL g, MODE m);
|
||||||
bool ParseURL(PGLOBAL g, char *url);
|
bool ParseURL(PGLOBAL g, char *url);
|
||||||
|
bool GetServerInfo(PGLOBAL g, const char *server_name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Members
|
// Members
|
||||||
|
@ -56,7 +56,7 @@ extern "C" int trace;
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Prepare and count columns in the column list. */
|
/* Prepare and count columns in the column list. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int PrepareColist(char *colist)
|
static int PrepareColist(char *colist)
|
||||||
{
|
{
|
||||||
char *p, *pn;
|
char *p, *pn;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
@ -137,3 +137,9 @@ class XCOLDEF: public COLDEF {
|
|||||||
friend class TDBOCCUR;
|
friend class TDBOCCUR;
|
||||||
}; // end of class XCOLDEF
|
}; // end of class XCOLDEF
|
||||||
|
|
||||||
|
|
||||||
|
bool OcrColumns(PGLOBAL g, PQRYRES qrp, const char *col,
|
||||||
|
const char *ocr, const char *rank);
|
||||||
|
|
||||||
|
bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col,
|
||||||
|
const char *ocr, const char *rank);
|
||||||
|
@ -324,7 +324,7 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
|
|||||||
{
|
{
|
||||||
char *colist, *tabname, *sql, buf[64];
|
char *colist, *tabname, *sql, buf[64];
|
||||||
LPCSTR ownp = NULL, qualp = NULL;
|
LPCSTR ownp = NULL, qualp = NULL;
|
||||||
int rc, len, ncol = 0;
|
int len, ncol = 0;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
PTABLE tablep = To_Table;
|
PTABLE tablep = To_Table;
|
||||||
PCOL colp;
|
PCOL colp;
|
||||||
@ -341,7 +341,7 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
|
|||||||
for (colp = Columns; colp; colp = colp->GetNext())
|
for (colp = Columns; colp; colp = colp->GetNext())
|
||||||
if (!colp->IsSpecial()) {
|
if (!colp->IsSpecial()) {
|
||||||
// Column name can be in UTF-8 encoding
|
// Column name can be in UTF-8 encoding
|
||||||
rc= Decode(colp->GetName(), buf, sizeof(buf));
|
/*rc=*/ Decode(colp->GetName(), buf, sizeof(buf));
|
||||||
|
|
||||||
if (Quote) {
|
if (Quote) {
|
||||||
if (first) {
|
if (first) {
|
||||||
@ -376,7 +376,7 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
|
|||||||
} // endif cnt
|
} // endif cnt
|
||||||
|
|
||||||
// Table name can be encoded in UTF-8
|
// Table name can be encoded in UTF-8
|
||||||
rc = Decode(TableName, buf, sizeof(buf));
|
/*rc = */Decode(TableName, buf, sizeof(buf));
|
||||||
|
|
||||||
// Put table name between identifier quotes in case in contains blanks
|
// Put table name between identifier quotes in case in contains blanks
|
||||||
tabname = (char*)PlugSubAlloc(g, NULL, strlen(buf) + 3);
|
tabname = (char*)PlugSubAlloc(g, NULL, strlen(buf) + 3);
|
||||||
|
@ -188,3 +188,9 @@ class SRCCOL : public PRXCOL {
|
|||||||
|
|
||||||
// Members
|
// Members
|
||||||
}; // end of class SRCCOL
|
}; // end of class SRCCOL
|
||||||
|
|
||||||
|
PQRYRES PivotColumns(PGLOBAL g, const char *tab, const char *src,
|
||||||
|
const char *picol, const char *fncol,
|
||||||
|
const char *host, const char *db,
|
||||||
|
const char *user, const char *pwd,
|
||||||
|
int port);
|
||||||
|
@ -223,12 +223,13 @@ bool TDBINI::OpenDB(PGLOBAL g)
|
|||||||
PINICOL colp;
|
PINICOL colp;
|
||||||
|
|
||||||
if (Use == USE_OPEN) {
|
if (Use == USE_OPEN) {
|
||||||
|
#if 0
|
||||||
if (To_Kindex)
|
if (To_Kindex)
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
/* Table is to be accessed through a sorted index table. */
|
/* Table is to be accessed through a sorted index table. */
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
To_Kindex->Reset();
|
To_Kindex->Reset();
|
||||||
|
#endif // 0
|
||||||
Section = NULL;
|
Section = NULL;
|
||||||
N = 0;
|
N = 0;
|
||||||
return false;
|
return false;
|
||||||
@ -262,6 +263,7 @@ int TDBINI::ReadDB(PGLOBAL g)
|
|||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Now start the pseudo reading process. */
|
/* Now start the pseudo reading process. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
#if 0 // INI tables are not indexable
|
||||||
if (To_Kindex) {
|
if (To_Kindex) {
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
/* Reading is by an index table. */
|
/* Reading is by an index table. */
|
||||||
@ -276,10 +278,11 @@ int TDBINI::ReadDB(PGLOBAL g)
|
|||||||
case -3: // Same record as last non null one
|
case -3: // Same record as last non null one
|
||||||
return RC_OK;
|
return RC_OK;
|
||||||
default:
|
default:
|
||||||
Section = (char*)recpos;
|
Section = (char*)recpos; // No good on 64 bit machines
|
||||||
} // endswitch recpos
|
} // endswitch recpos
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
#endif // 0
|
||||||
if (!Section)
|
if (!Section)
|
||||||
Section = Seclist;
|
Section = Seclist;
|
||||||
else
|
else
|
||||||
@ -289,7 +292,7 @@ int TDBINI::ReadDB(PGLOBAL g)
|
|||||||
htrc("INI ReadDB: section=%s N=%d\n", Section, N);
|
htrc("INI ReadDB: section=%s N=%d\n", Section, N);
|
||||||
|
|
||||||
N++;
|
N++;
|
||||||
} // endif To_Kindex
|
//} // endif To_Kindex
|
||||||
|
|
||||||
return (*Section) ? RC_OK : RC_EF;
|
return (*Section) ? RC_OK : RC_EF;
|
||||||
} // end of ReadDB
|
} // end of ReadDB
|
||||||
@ -655,6 +658,7 @@ int TDBXIN::ReadDB(PGLOBAL g)
|
|||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Now start the pseudo reading process. */
|
/* Now start the pseudo reading process. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
#if 0 // XIN tables are not indexable
|
||||||
if (To_Kindex) {
|
if (To_Kindex) {
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
/* Reading is by an index table. */
|
/* Reading is by an index table. */
|
||||||
@ -673,6 +677,7 @@ int TDBXIN::ReadDB(PGLOBAL g)
|
|||||||
} // endswitch recpos
|
} // endswitch recpos
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
#endif // 0
|
||||||
do {
|
do {
|
||||||
if (!Keycur || !*Keycur) {
|
if (!Keycur || !*Keycur) {
|
||||||
if (!Section)
|
if (!Section)
|
||||||
@ -691,7 +696,7 @@ int TDBXIN::ReadDB(PGLOBAL g)
|
|||||||
} while (!*Keycur);
|
} while (!*Keycur);
|
||||||
|
|
||||||
N++;
|
N++;
|
||||||
} // endif To_Kindex
|
//} // endif To_Kindex
|
||||||
|
|
||||||
return RC_OK;
|
return RC_OK;
|
||||||
} // end of ReadDB
|
} // end of ReadDB
|
||||||
|
@ -109,11 +109,12 @@ TBLDEF::TBLDEF(void)
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
||||||
{
|
{
|
||||||
char *tablist, *dbname;
|
char *tablist, *dbname, *def = NULL;
|
||||||
|
|
||||||
Desc = "Table list table";
|
Desc = "Table list table";
|
||||||
tablist = Cat->GetStringCatInfo(g, "Tablist", "");
|
tablist = Cat->GetStringCatInfo(g, "Tablist", "");
|
||||||
dbname = Cat->GetStringCatInfo(g, "Dbname", "*");
|
dbname = Cat->GetStringCatInfo(g, "Dbname", "*");
|
||||||
|
def = Cat->GetStringCatInfo(g, "Srcdef", NULL);
|
||||||
Ntables = 0;
|
Ntables = 0;
|
||||||
|
|
||||||
if (*tablist) {
|
if (*tablist) {
|
||||||
@ -134,7 +135,7 @@ bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
} // endif p
|
} // endif p
|
||||||
|
|
||||||
// Allocate the TBLIST block for that table
|
// Allocate the TBLIST block for that table
|
||||||
tbl = new(g) XTAB(pn);
|
tbl = new(g) XTAB(pn, def);
|
||||||
tbl->SetQualifier(pdb);
|
tbl->SetQualifier(pdb);
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
@ -231,16 +232,28 @@ PCOL TDBTBL::InsertSpecialColumn(PGLOBAL g, PCOL scp)
|
|||||||
bool TDBTBL::InitTableList(PGLOBAL g)
|
bool TDBTBL::InitTableList(PGLOBAL g)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
uint sln;
|
||||||
|
char *scs;
|
||||||
PTABLE tp, tabp;
|
PTABLE tp, tabp;
|
||||||
PCOL colp;
|
PCOL colp;
|
||||||
PTBLDEF tdp = (PTBLDEF)To_Def;
|
PTBLDEF tdp = (PTBLDEF)To_Def;
|
||||||
|
PCATLG cat = To_Def->GetCat();
|
||||||
|
PHC hc = ((MYCAT*)cat)->GetHandler();
|
||||||
|
|
||||||
|
scs = hc->get_table()->s->connect_string.str;
|
||||||
|
sln = hc->get_table()->s->connect_string.length;
|
||||||
// PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath());
|
// PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath());
|
||||||
|
|
||||||
for (n = 0, tp = tdp->Tablep; tp; tp = tp->GetNext()) {
|
for (n = 0, tp = tdp->Tablep; tp; tp = tp->GetNext()) {
|
||||||
if (TestFil(g, To_Filter, tp)) {
|
if (TestFil(g, To_Filter, tp)) {
|
||||||
tabp = new(g) XTAB(tp);
|
tabp = new(g) XTAB(tp);
|
||||||
|
|
||||||
|
if (tabp->GetSrc()) {
|
||||||
|
// Table list is a list of connections
|
||||||
|
hc->get_table()->s->connect_string.str = (char*)tabp->GetName();
|
||||||
|
hc->get_table()->s->connect_string.length = strlen(tabp->GetName());
|
||||||
|
} // endif Src
|
||||||
|
|
||||||
// Get the table description block of this table
|
// Get the table description block of this table
|
||||||
if (!(Tdbp = GetSubTable(g, tabp))) {
|
if (!(Tdbp = GetSubTable(g, tabp))) {
|
||||||
if (++Nbc > Maxerr)
|
if (++Nbc > Maxerr)
|
||||||
@ -269,6 +282,9 @@ bool TDBTBL::InitTableList(PGLOBAL g)
|
|||||||
|
|
||||||
} // endfor tp
|
} // endfor tp
|
||||||
|
|
||||||
|
hc->get_table()->s->connect_string.str = scs;
|
||||||
|
hc->get_table()->s->connect_string.length = sln;
|
||||||
|
|
||||||
//NumTables = n;
|
//NumTables = n;
|
||||||
To_Filter = NULL; // To avoid doing it several times
|
To_Filter = NULL; // To avoid doing it several times
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -163,3 +163,6 @@ class DllExport TDBTBM : public TDBTBL {
|
|||||||
int Nrc; // Number of remote connections
|
int Nrc; // Number of remote connections
|
||||||
int Nlc; // Number of local connections
|
int Nlc; // Number of local connections
|
||||||
}; // end of class TDBTBM
|
}; // end of class TDBTBM
|
||||||
|
|
||||||
|
|
||||||
|
pthread_handler_t ThreadOpen(void *p);
|
||||||
|
@ -49,7 +49,6 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
//#define strerror(X) _strerror(X)
|
|
||||||
#define NO_ERROR 0
|
#define NO_ERROR 0
|
||||||
#else
|
#else
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
@ -547,6 +547,7 @@ bool TDBXML::Initialize(PGLOBAL g)
|
|||||||
else
|
else
|
||||||
Nlist = TabNode->GetChildElements(g);
|
Nlist = TabNode->GetChildElements(g);
|
||||||
|
|
||||||
|
Docp->SetNofree(true); // For libxml2
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
} catch(_com_error e) {
|
} catch(_com_error e) {
|
||||||
// We come here if a DOM command threw an error
|
// We come here if a DOM command threw an error
|
||||||
|
@ -592,7 +592,7 @@ void CHRBLK::SetValue(char *sp, uint len, int n)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sp)
|
if (sp)
|
||||||
memcpy(p, sp, len);
|
memcpy(p, sp, Long);
|
||||||
|
|
||||||
if (Blanks) {
|
if (Blanks) {
|
||||||
// Suppress eventual ending zero and right fill with blanks
|
// Suppress eventual ending zero and right fill with blanks
|
||||||
@ -654,8 +654,11 @@ void CHRBLK::SetValues(PVBLK pv, int k, int n)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void CHRBLK::Move(int i, int j)
|
void CHRBLK::Move(int i, int j)
|
||||||
{
|
{
|
||||||
memcpy(Chrp + j * Long, Chrp + i * Long, Long);
|
if (i != j) {
|
||||||
MoveNull(i, j);
|
memcpy(Chrp + j * Long, Chrp + i * Long, Long);
|
||||||
|
MoveNull(i, j);
|
||||||
|
} // endif i
|
||||||
|
|
||||||
} // end of Move
|
} // end of Move
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@ -578,19 +578,25 @@ void TYPVAL<TYPE>::SetValue_char(char *p, int n)
|
|||||||
template <>
|
template <>
|
||||||
void TYPVAL<double>::SetValue_char(char *p, int n)
|
void TYPVAL<double>::SetValue_char(char *p, int n)
|
||||||
{
|
{
|
||||||
char *p2, buf[32];
|
if (p) {
|
||||||
|
char *p2, buf[32];
|
||||||
|
|
||||||
for (p2 = p + n; p < p2 && *p == ' '; p++) ;
|
for (p2 = p + n; p < p2 && *p == ' '; p++) ;
|
||||||
|
|
||||||
n = min(p2 - p, 31);
|
n = min(p2 - p, 31);
|
||||||
memcpy(buf, p, n);
|
memcpy(buf, p, n);
|
||||||
buf[n] = '\0';
|
buf[n] = '\0';
|
||||||
Tval = atof(buf);
|
Tval = atof(buf);
|
||||||
|
|
||||||
if (trace > 1)
|
if (trace > 1)
|
||||||
htrc(" setting double: '%s' -> %lf\n", buf, Tval);
|
htrc(" setting double: '%s' -> %lf\n", buf, Tval);
|
||||||
|
|
||||||
|
Null = false;
|
||||||
|
} else {
|
||||||
|
Reset();
|
||||||
|
Null = Nullable;
|
||||||
|
} // endif p
|
||||||
|
|
||||||
Null = false;
|
|
||||||
} // end of SetValue
|
} // end of SetValue
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -599,8 +605,14 @@ void TYPVAL<double>::SetValue_char(char *p, int n)
|
|||||||
template <class TYPE>
|
template <class TYPE>
|
||||||
void TYPVAL<TYPE>::SetValue_psz(PSZ s)
|
void TYPVAL<TYPE>::SetValue_psz(PSZ s)
|
||||||
{
|
{
|
||||||
Tval = GetTypedValue(s);
|
if (s) {
|
||||||
Null = false;
|
Tval = GetTypedValue(s);
|
||||||
|
Null = false;
|
||||||
|
} else {
|
||||||
|
Reset();
|
||||||
|
Null = Nullable;
|
||||||
|
} // endif p
|
||||||
|
|
||||||
} // end of SetValue
|
} // end of SetValue
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
@ -895,17 +907,23 @@ bool TYPVAL<PSZ>::SetValue_pval(PVAL valp, bool chktype)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void TYPVAL<PSZ>::SetValue_char(char *p, int n)
|
void TYPVAL<PSZ>::SetValue_char(char *p, int n)
|
||||||
{
|
{
|
||||||
n = min(n, Len);
|
if (p) {
|
||||||
strncpy(Strp, p, n);
|
n = min(n, Len);
|
||||||
|
strncpy(Strp, p, n);
|
||||||
|
|
||||||
for (p = Strp + n - 1; (*p == ' ' || *p == '\0') && p >= Strp; p--) ;
|
for (p = Strp + n - 1; (*p == ' ' || *p == '\0') && p >= Strp; p--) ;
|
||||||
|
|
||||||
*(++p) = '\0';
|
*(++p) = '\0';
|
||||||
|
|
||||||
if (trace > 1)
|
if (trace > 1)
|
||||||
htrc(" Setting string to: '%s'\n", Strp);
|
htrc(" Setting string to: '%s'\n", Strp);
|
||||||
|
|
||||||
|
Null = false;
|
||||||
|
} else {
|
||||||
|
Reset();
|
||||||
|
Null = Nullable;
|
||||||
|
} // endif p
|
||||||
|
|
||||||
Null = false;
|
|
||||||
} // end of SetValue_char
|
} // end of SetValue_char
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -913,8 +931,14 @@ void TYPVAL<PSZ>::SetValue_char(char *p, int n)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void TYPVAL<PSZ>::SetValue_psz(PSZ s)
|
void TYPVAL<PSZ>::SetValue_psz(PSZ s)
|
||||||
{
|
{
|
||||||
strncpy(Strp, s, Len);
|
if (s) {
|
||||||
Null = false;
|
strncpy(Strp, s, Len);
|
||||||
|
Null = false;
|
||||||
|
} else {
|
||||||
|
Reset();
|
||||||
|
Null = Nullable;
|
||||||
|
} // endif s
|
||||||
|
|
||||||
} // end of SetValue_psz
|
} // end of SetValue_psz
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -1010,7 +1034,6 @@ void TYPVAL<PSZ>::SetValue(char c)
|
|||||||
void TYPVAL<PSZ>::SetBinValue(void *p)
|
void TYPVAL<PSZ>::SetBinValue(void *p)
|
||||||
{
|
{
|
||||||
SetValue_char((char *)p, Len);
|
SetValue_char((char *)p, Len);
|
||||||
Null = false;
|
|
||||||
} // end of SetBinValue
|
} // end of SetBinValue
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@ -2368,7 +2368,6 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
|
|||||||
} // endif Mode
|
} // endif Mode
|
||||||
|
|
||||||
#else // UNIX
|
#else // UNIX
|
||||||
int rc = 0;
|
|
||||||
int oflag = O_LARGEFILE; // Enable file size > 2G
|
int oflag = O_LARGEFILE; // Enable file size > 2G
|
||||||
mode_t pmod = 0;
|
mode_t pmod = 0;
|
||||||
|
|
||||||
@ -2394,7 +2393,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
|
|||||||
Hfile= global_open(g, MSGID_OPEN_ERROR_AND_STRERROR, filename, oflag, pmod);
|
Hfile= global_open(g, MSGID_OPEN_ERROR_AND_STRERROR, filename, oflag, pmod);
|
||||||
|
|
||||||
if (Hfile == INVALID_HANDLE_VALUE) {
|
if (Hfile == INVALID_HANDLE_VALUE) {
|
||||||
rc = errno;
|
/*rc = errno;*/
|
||||||
#if defined(TRACE)
|
#if defined(TRACE)
|
||||||
printf("Open: %s\n", g->Message);
|
printf("Open: %s\n", g->Message);
|
||||||
#endif // TRACE
|
#endif // TRACE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user